?? 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_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)
;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 1
PS2KEY_EXTENDED_FLAG: equ 2
PS2KEY_MAKE_FLAG: equ 4
PS2KEY_GHOST_FLAG: equ 8
GHOST_750MS_TIMEOUT: equ 750/4
GHOST_500MS_TIMEOUT: equ 500/4
; keyboard duplicate input report buffer (8 bytes)
ps2key_key_count: equ (ps2key_ram_base + 0) ;count of keys in buffer
ps2key_inptr: equ (ps2key_ram_base + 1) ;in pointer to buffer
ps2key_outptr: equ (ps2key_ram_base + 2) ;out pointer to buffer
ps2key_old_count: equ (ps2key_ram_base + 3) ;storage for copy of count
ps2key_old_inptr: equ (ps2key_ram_base + 4) ;and in pointer
ps2key_scan_set: equ (ps2key_ram_base + 5) ;current scan set
ps2key_numlock: equ (ps2key_ram_base + 6) ;=0 if numlock off
ps2key_flags: equ (ps2key_ram_base + 7) ;flag byte
ps2key_type_delay: equ (ps2key_ram_base + 8) ;typematic delay
ps2key_type_period: equ (ps2key_ram_base + 9) ;typematic interval
ps2key_delay_ctr: equ (ps2key_ram_base + 10) ;typematic delay counter
ps2key_last_key_made: equ (ps2key_ram_base + 11) ;typematic key
ps2key_last_flags: equ (ps2key_ram_base + 12) ;typematic flags
ps2key_ghost_counter: equ (ps2key_ram_base + 13) ;ghost counter
ps2key_key_buffer: equ (ps2key_ram_base + 14) ; key buffer
ps2key_type_array: equ (ps2key_ram_base + 14 + BUFFER_LEN) ;Scan set 3 typematic settings table
PS2_TYPE_ARRAY_SIZE: equ 36
PS2KEY_RAM_SIZE: equ 14 + BUFFER_LEN + PS2_TYPE_ARRAY_SIZE + 1
key_buffer_end: equ ps2key_key_buffer + BUFFER_LEN ; key buffer end
;========================================================================
; 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
call ksc_scan_keys ; check for new keys
; phantom situation exists?
jc .ghost ; yep, go there
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 typematic action
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
;========================================================================
; 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
mov A,[ps2key_scan_set] ;if we are using scan set 3
cmp A,SCAN_SET_3
mov A,X
jnz .scan1or2
call scan3 ;handle scan set 3, it is easiest
jmp .exit
.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:
call ksc_modifier ;first, trap modifier keys.
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
cmp A,AT101KB_PAUSE ;if not the pause 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:scan3
;
; handles scan set 3 scan code generation. This set is the simplest to
; implement.
;
; entered with key code in A and X
;
; Returns:
;
;
;========================================================================
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
;========================================================================
; FUNCTION:
;
;
; Returns:test_126
;
; 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
SETBIT PS2KEY_EXTENDED_FLAG,ps2key_flags ;yes, generate an extended
SETBIT PS2KEY_MAKE_FLAG,ps2key_flags ;make and an extended break for this code
mov A,X
call put_code
CLRBIT PS2KEY_MAKE_FLAG,ps2key_flags
mov A,X
call put_code ;
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: test_extended_codes
;
; check for all special keys in scan sets 1 and 2 that require an extension
; byte (0xe0) prepended to their scan code, but with NO OTHER special rules
; applied to them
;
; Returns:
; C = 1 if key was handled
; C = 0 if not
;========================================================================
test_extended_codes:
cmp A,62 ; right now, keys 62,64, and 128
jz .yes ; R_Alt, R_Ctrl, R_GUI
cmp A,64 ; all meet this requirement
jz .yes
cmp A,108
jz .yes
; cmp A,133 ; check for keys 127 thru 133 inclusive
cmp A,151 ; check for keys 127 thru 149 inclusive
jnc .no ;
cmp A,127
jc .no
.yes:
call extended_base_case ; generate an extension code
SETC ; set carry to indicate we handled this char
ret
.no:
CLEARC ;clear carry to indicate we did not handle
ret ;the char
;========================================================================
; test_75_89
;
; keys 75 through 89 all have the same set of rules governing their code
; generation.
;
; Returns:
; C = 1 if key was handled
; C = 0 if not
;========================================================================
test_75_89:
cmp A,90 ;check for keys 75 through 89 inclusive
jnc .no
cmp A,75
jc .no
mov A,[ps2key_numlock] ;test for numlock on/off
cmp A,0
jnz .numlock_on
;numlock is off
mov A,[ksc_mod0] ;check for shift states
and A,(LEFT_SHIFT_BIT+RIGHT_SHIFT_BIT)
jz .base ;numlock off, some sort of shift
;
call shift_case ;so handle as shift case
jmp .yes
.base:
call extended_base_case ;numlock off, no shift, use extended base case
jmp .yes
.numlock_on: ;numlock on, check for shift states
mov A,[ksc_mod0]
and A,(LEFT_SHIFT_BIT + RIGHT_SHIFT_BIT)
jz .numlock_only
call extended_base_case ;numlock on, some shift, use extended base case
jmp .yes
.numlock_only:
call numlock_case ;numlock on only, use numlock case
.yes:
SETC ;set carry to indicate we handled this char
ret
.no:
CLEARC
ret
;========================================================================
; Function: test_95
;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -