?? kbscan.asm
字號:
ones_table:
db 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4
XPAGEON
count_ones:
push A ;save ACC
and A,0fh ;isolate low nibble
index ones_table ;get number of 1's in it
mov [ksc_work],A ;save temporarily
pop A ;get acc back
asr A
asr A
asr A
asr A
and A,0fh ;isolate high nibble
index ones_table ;get number of 1's in it
add A,[ksc_work] ;add two totals
ret ;and bug out
;phantom key detection routine.
check_phantom:
mov A,[ksc_row_hits] ;tally the number of 1's in ksc_row_hits (Nr)
call count_ones
cmp A,[ksc_col_hits] ;Get the larger of this and Nc
jnc .skip ;numbers into the ACC
mov A,[ksc_col_hits]
.skip:
cmp A,[ksc_key_count] ;if MAX (Nc,Nr) >= Nk, where Nk = number of total keys pressed
jnc .exit ;there is no phantom key
mov A,1
mov [ksc_phantom],A
.exit:
ret
;========================================================================
; Test debounce fifo to see if matrix address is still in it.
; If not, exit with zero flag set
;========================================================================
ksc_Debounce_test:
push X ; save X
mov X, DEBOUNCE_ARRAY_SIZE ; initialize
.db_loop:
cmp A, [X + ksc_db_keys - 1] ; test if matrix address is in the debounce array
jz .db_exit ; loop until found
dec X
jnz .db_loop ; or complete fifo tested
cmp A, 0FFh ; clear zero flag to show it is not here
.db_exit:
pop X ; restore X
ret
;========================================================================
; Put matrix address in A onto debounce ARRAY
;========================================================================
ksc_Debounce_keys:
push X ; save X and A
push A
mov X, DEBOUNCE_ARRAY_SIZE ; point to the 6th location in the array
.find_free_debounce_location:
mov A, [X + ksc_db_keys - 1] ; check if is a free position
cmp A, 0FFh
jz .start_key_debounce
dec X
jnz .find_free_debounce_location
jmp .db_keys_end ; if all 6 location are already loaded
; with a key the 7th key will ignore
.start_key_debounce:
mov A, [ksc_matrix_addr] ; store the key in the array
mov [X + ksc_db_keys - 1], A
mov A, [ksc_down_up] ; check if key went up or down
cmp A, 00h
jz .debounce_key_release ;key up (release)
mov A, DEBOUNCE_PRESS_TIME ;key down (press), the time constant for
mov [X + ksc_db_counts - 1], A ;key press debounce is loaded
jmp .db_keys_end
.debounce_key_release:
mov A, DEBOUNCE_RELEASE_TIME ;the time constant for
mov [X + ksc_db_counts - 1], A ;key release debounce is loaded
.db_keys_end:
pop A ; restore A
pop X ; restore X
ret
;========================================================================
; Decrement the time constant in the counter ARRAY
;========================================================================
ksc_Debounce_Task:
push X ; save X and A
push A
mov X, DEBOUNCE_ARRAY_SIZE ;load array size
.debounce_check:
mov A, [X + ksc_db_keys - 1] ;check if is a free location
cmp A, 0FFh ;if yes process another location
jz .next_value_process
mov A, [X + ksc_db_counts - 1] ;decrement the right counter in
dec A ;the array
mov [X + ksc_db_counts - 1], A ;if the value is different from 0
jnz .next_value_process ;process another location in the array
mov A, 0FFh ;if 0 (time expired) load 0FFh
mov [X + ksc_db_keys - 1] ,A ;(free position)
.next_value_process:
dec X ; decrement position
jnz .debounce_check ;check this new position (if not 0)
pop A ; restore A and X
pop X
ret
XPAGEOFF
mod_key_table:
db AT101KB_LEFTCTRL,AT101KB_LEFTSHIFT
db AT101KB_LEFTALT,AT101KB_LEFTGUI
db AT101KB_RIGHTCTRL,AT101KB_RIGHTSHIFT
db AT101KB_RIGHTALT,AT101KB_RIGHTGUI
; db AT101KB_APPLICATION
mod_bit_table:
db LEFT_CTRL_BIT,LEFT_SHIFT_BIT
db LEFT_ALT_BIT,LEFT_GUI_BIT
db RIGHT_CTRL_BIT,RIGHT_SHIFT_BIT
db RIGHT_ALT_BIT,RIGHT_GUI_BIT
; db APP_BIT
XPAGEON
;currently we are not counting the application key as a modifier key.
;so there are only 8 modifiers.
NUM_MODIFIERS: equ 8
ksc_modifier:
push X
push A
mov X,ksc_mod0 ;point X at mod0
;removed, not currently considering the application key as a modifier
;cmp A,AT101KB_APPLICATION ;if app key
;jnz .lp0
;mov X,ksc_mod1 ;point at mod1
.lp0:
mov [ksc_work],A ;store key in work byte
mov A,(NUM_MODIFIERS - 1) ;initialize A to number of modifiers
.lp1:
push A ;save index
index mod_key_table ;get lookup
cmp A,[ksc_work] ;compare to key
pop A ;restore index
jz .lp2 ;compare was a success, key found
dec A
jc .non_modifier ;index < 0, non-modifier
jmp .lp1
.lp2:
index mod_bit_table ;now index into bit to set/clear
push A ; clear or set modifier bit
mov A, [ksc_down_up] ; depending on if key went
cmp A, 00h ; up or down
pop A ; restore bit pattern
jz .mod0_up ; modifier key went down
or [X + 0], A ; set bit
jmp .done_putkey
.mod0_up: ; else, modifier key went up
cpl ; so clear bit
and [X + 0], A
.done_putkey: ;set carry indicating modifier found
SETC
.exit:
pop A ;restore A,X
pop X
ret
.non_modifier: ;clear carry indicating no modifier found
CLEARC
jmp .exit
ksc_init_ports:
mov A, 0ffh ; load all ones into accumulator
iowr PORT0_DATA_REG ; initialize port 0
mov [ksc_p0out], A ; save data written to port 0
iowr PORT1_DATA_REG ; initialize port 1
mov [ksc_p1out], A ; save data written to port 1
iowr PORT2_DATA_REG ; initialize port 2
mov A,[ksc_p3out]
IFDEF PS2KB
or A,(P3_LED_MASK+PS2_CONNECT+PS2_CLOCK_BIT+PS2_DATA_BIT)
ELSE
or A,P3_LED_MASK
ENDIF
mov [ksc_p3out], A ; save data written to port 3
iowr PORT3_DATA_REG ; initialize port 3
ret
ksc_init_keyscan:
; initialize variables
mov A,[ksc_p3out] ;this variable is the shadow of port 3's contents
;it is actually initialized on power-up to 0xff, then
;modified by hub code before this routine is called.
;it will be overwritten by the call to clear ram
;below, but we want to save it and restore it
;after the clear. It is the only crucial RAM location.
push A ;save shadow of P3
CLEARRAM ksc_ram_base,KSC_RAM_SIZE
pop A
mov [ksc_p3out],A
call ksc_init_ports
mov X, DEBOUNCE_ARRAY_SIZE ; clear debounce_array
mov A, FFh ; FFh is an illegal
; index into key_code_table
.clear_debounce_array:
mov [X + ksc_db_keys - 1], A
dec X
jnz .clear_debounce_array
ret
ksc_writeLED:
push A
mov A,[ksc_p3out]
and A, ~(P3_LED_MASK+80h) ; Not to make b7 as "1"
;
mov [ksc_p3out],A
pop A
cpl A
and A,P3_LED_MASK
or A,[ksc_p3out]
mov [ksc_p3out],a
iowr PORT3_DATA_REG
ret
;ksc_restore_ports:
; mov A, [ksc_p0out] ; restore column ports to pre-suspend values
; iowr PORT0_DATA_REG
; mov A, [ksc_p1out]
; iowr PORT1_DATA_REG
; mov A, [ksc_p3out]
; iowr PORT3_DATA_REG
; ret
delay:
mov [ksc_delay],A
;we got here with a fixed delay caused by the push A, mov, A, and
;call, equal to 4+10+5 = 19 cycles. At the end of the routine we
;incur another 8+ 5 due to the return and pop. This gives 32 cycles
;of delay.
;our fixed delay is now 37 cycles, or very close to 3 us.
;now eat up the rest of the us in this loop.
NOP ; 4 x 3 = 12 cycle
NOP
NOP
XPAGEOFF
loop: ;1us per revolution through this loop
dec [ksc_delay]
jnz loop
XPAGEON
pop A
ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -