⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbscan.asm

📁 用cy7c66113开发的HUB
💻 ASM
📖 第 1 页 / 共 2 页
字号:
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 + -