📄 ps2key.asm
字号:
;========================================================================
; FILE: ps2key.asm
;
; This file contains the code that implements the ps2-specific
; routines to handle key scans.
;
; REVISION HISTORY:
;
; 3/26/99 fixed putch so that it leaves room for 1 byte in the buffer
;
;
;========================================================================
LAST_SCAN1_CODE: equ 079h
LAST_SCAN3_CODE: equ 08fh
BUFFER_LEN: equ 17
PS2_DEFAULT_TYPEMATIC_DELAY: equ 125 ;default delay = 500mS
PS2_DFFAULT_TYPEMATIC_INTERVAL: equ 22 ;default period = 92mS (= 10.9cps)
EndOfTable: equ 00h
;define a useful macro for determining if the recent key press was up or down
;
;
MACRO TSTMAKE
mov A,[ksc_down_up]
cmp A,0h
ENDM
;define local flags to this module
PS2KEY_OVERFLOW_FLAG: equ 1h
PS2KEY_EXTENDED_FLAG: equ 2h
PS2KEY_MAKE_FLAG: equ 4h
PS2KEY_GHOST_FLAG: equ 8h
GHOST_750MS_TIMEOUT: equ 750/4
GHOST_500MS_TIMEOUT: equ 500/4
;========================================================================
; FUNCTION:ps2_scan_keys
;
; This is the main entry point for the start of key scanning.
; This function calls the key scanner, which will generate calls to
; ps2key_putkey from the internal scanning loop of the key scanner.
;
;
;
;========================================================================
ps2_scan_keys:
mov A,0
mov [ps2key_flags],A ;clear all flags
mov A,[ps2key_key_count] ;save current buffer size
push A
mov A,[ps2key_inptr] ;and in pointer
push A
mov [ps2key_old_inptr],A
call ksc_scan_keys ; check for new keys
jc .ghost ; phantom situation, go there
pop A ; no, correct stack
pop A
call ps2key_check_typematic ; check state of typematic keys
CLRBIT PS2KEY_GHOST_FLAG,ps2key_flags ;clear ghost flag
mov A,GHOST_750MS_TIMEOUT ;maximize ghost counter
mov [ps2key_ghost_counter],A ;and get out
jmp .exit
.ghost: ;yes, a ghost condition exists
call ps2key_disable_typematic_action ;disable any
pop A
mov [ps2key_inptr],A ;restore in pointer
pop A
mov [ps2key_key_count],A ;and current buffer size
dec [ps2key_ghost_counter]
mov A,[ps2key_ghost_counter] ;get ghost counter
jnz .exit ;if counter expired
mov A,GHOST_500MS_TIMEOUT ;reset it
mov [ps2key_ghost_counter],A
call put_error ;put an error code
.exit:
ret ; return from task
; return from task
;========================================================================
; FUNCTION:ps2_putkey
;
;handles key presses in ps2 environment.
;
; This function is called from within the key scanning loop, each time a
; valid key event has been recognized. A key event is defined as whenever
; an individual key changes state, either up or down. the key is
; identified by a unique number in the accumulator from 1 to XXX,
; where XXX is GENERALLY the corresponding AT101 keyboard number, with
; few execptions (see at101.inc).
;========================================================================
ps2key_putkey:
push X
mov X,A ;keep copy of key code in X
TSTBIT PS2KEY_OVERFLOW_FLAG,ps2key_flags ;if overflow flag is currently set,
jz .continue ;don't go any further.
pop X
ret
.continue:
CLRBIT PS2KEY_EXTENDED_FLAG,ps2key_flags ;otherwise, start by clearing extension flag
;for this character
;save the current in buffer pointer and key count. If this scan code
;turns out not to fit in the key buffer, we'll restore the buffer pointer
;and count to their positions prior to the overflow.
mov A,[ps2key_key_count] ;save current buffer size
mov [ps2key_old_count],A ;
mov A,[ps2key_inptr] ;and in pointer
mov [ps2key_old_inptr],A
IFDEF SCANSET3
mov A,[ps2key_scan_set] ;if we are using scan set 3
cmp A,SCAN_SET_3
ENDIF
mov A,X
IFDEF SCANSET3
jnz .scan1or2
call scan3 ;handle scan set 3, it is easiest
jmp .exit
ENDIF
.scan1or2:
call scan1or2 ;otherwise handle 1 or 2
.exit:
TSTBIT PS2KEY_OVERFLOW_FLAG,ps2key_flags ;check if code resulted in buffer overflow
jz .no_errors
mov A,[ps2key_old_count] ;yes it did. restore buffer ptr and count
mov [ps2key_key_count],A ;to values prior to overflow
mov A,[ps2key_old_inptr]
mov [ps2key_inptr],A
call put_error ;and insert an error code
call ps2key_disable_typematic_action ;clear out any typematic stuff
.no_errors:
pop X
ret
;========================================================================
; FUNCTION:scan1or2
;
; handles scan set 1 and 2 scan code generation. With the exception
; of the actual codes used for make/break, the rules regarding scan
; code generation are the same; such as shift/unshift appending and prepending,
; numlock on/off, etc.
;
; entered with key code in A and X
;
; Returns: nothing
;
;
;========================================================================
scan1or2:
cmp A,AT101KB_RESERVED ;if no key code
jz .l1 ;exit
call ksc_modifier ;first, trap modifier keys.
call test_numlock ;then check for numlock toggle
call test_153_154 ;check for lang1,lang2 keys
jc .exit
call test_126 ;check for key 126 Pause/Break
jc .exit
call test_124 ;check for key 124 Print Screen
jc .exit
call test_95 ;check for key 95 Keypad Slash
jc .exit
call test_75_89 ;check for keys 75 through 89 Navigation/Edit Keys
jc .exit
call test_extended_codes ;check for any extended codes
jc .exit
call base_case ;otherwise, handle key
.exit:
;now handle possible typematic functions
TSTMAKE ;check if make/break
mov A,X
jz .break
.make: ;if a make,
call ps2key_disable_typematic_action ;reset typematic action
call check_non_typematic_key ;if a typematic key,
jz .l1
call ps2key_enable_typematic_action ;start up typematic action
jmp .l1 ;for this new make
.break:
call check_typematic_break ;else it was a break,
;check it
.l1:
ret
;========================================================================
; FUNCTION:check_non_typematic_key
;
; checks to see if the key code in A is a non_typematic key
;
; entered with key code in A
;
; Returns:
; zero bit clear if key is non-typematic
;
;
;========================================================================
XPAGEOFF
non_typematic_table:
db AT101KB_PAUSE,AT101KB_MUTE,AT101KB_PLAY_PAUSE,AT101KB_STOP
db AT101KB_EMAIL,AT101KB_CALCULATOR,AT101KB_WWW_SEARCH,AT101KB_WWW_HOME
db AT101KB_WWW_FAVORITES, AT101KB_LOGITECH,AT101KB_SLEEP
non_typematic_table_end:
NON_TYPEMATIC_LEN: EQU (non_typematic_table_end - non_typematic_table)
XPAGEON
check_non_typematic_key:
push A
.lp0:
mov [ps2_temp0],A ;store key in work byte
mov A,(NON_TYPEMATIC_LEN - 1) ;initialize A to number of power keys
.lp1:
push A ;save index
index non_typematic_table ;get lookup
cmp A,[ps2_temp0] ;compare to key
pop A ;restore index
jz .found ;compare was a success, key found
dec A
jnc .lp1 ;
.found:
pop A
ret
;========================================================================
; FUNCTION:scan3
;
; handles scan set 3 scan code generation. This set is the simplest to
; implement.
;
; entered with key code in A and X
;
; Returns:
;
;
;========================================================================
IFDEF SCANSET3
scan3:
push A ;save A and X
push X
push A ;save at101 code
index scan_set_3_table ;get its scan code
call ps2key_get_key_type ;get type of key in X register
TSTMAKE
pop A ;restore at101 code
jz .break
.make:
;it's a make
call ps2key_disable_typematic_action ;reset typematic action
swap A,X ;get type into A,code in X
cmp A,MAKE_BREAK ;if the key is not typematic
jz .out ;just generate the make code
cmp A,MAKE
jz .out
swap A,X ;get code back in A
call ps2key_enable_typematic_action ;else start up typematic action
swap A,X ;get code back into X
jmp .out ;now generate scan code
.break:
;it's a break
call check_typematic_break ;see if it stops the typematic action
swap A,X ;type now in A, code in X
cmp A,MAKE_BREAK ;if we need to report breaks
jz .out ; generate the code
cmp A,TYPEMATIC_MAKE_BREAK
jz .out
jmp .exit ;else skip break code generation
.out: ;char in X where base case expects it
call base_case ;this'll generate scan code
.exit:
pop X
pop A
ret
ENDIF
;========================================================================
; FUNCTION:
;
;
; Returns:test_numlock
;
; Handles numlock functionality
;
; Returns:
;
;========================================================================
test_numlock:
push A ;save acc
cmp A,AT101KP_NUMLOCK ;test for numlock key
jnz .no
TSTMAKE ;test for make of this key
jz .no
mov A,[ps2key_numlock] ;if a make, toggle numlock
cpl A
and A,NUM_LOCK_LED
mov [ps2key_numlock],A
.no:
pop A
ret
;========================================================================
; FUNCTION:
;
;
; Returns:test_126 [AT101KB_PAUSE]
;
; Handles scan codes for key 126 in scan sets 1 and 2.
;
; Returns:
; C = 1 if key was handled
; C = 0 if not
;
;
;========================================================================
test_126:
cmp A,126
jnz .no ;if key126
push X
TSTMAKE
jz .yes ;and a make of this key
mov A,[ksc_mod0]
and A,(LEFT_CTRL_BIT + RIGHT_CTRL_BIT) ;check for control key pressed
jz .make
call extended_make_break
jmp .yes
.make:
mov X,0 ;otherwise, we'll be putting out
;a string
.loop:
mov A,[ps2key_scan_set] ;if scan set 1
cmp A,SCAN_SET_1
mov A,X
jnz .scan2 ; use scan set 1 string
index ss1_key126_make_scan_code
jmp .l1
.scan2:
index ss2_key126_make_scan_code ;else use scan set 2 string
.l1:
cmp A,0 ;exit if end of string
jz .yes
call putch ;else put character and continue
inc X
jmp .loop
.yes:
pop X
SETC
ret
.no:
CLEARC
ret
;========================================================================
; FUNCTION:
;
;
; Returns:test_153_154
;
; Handles scan codes for keys 153 and 154 scan sets 1 and 2.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -