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

📄 keyscan.asm

📁 CY7C63743 usb键盘的源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;REVISION HISTORY
;9/10/99 incorporated new keyscan routine to fix ps/2 ghosting problem
;8/13/98
; changed sense of usb connect bit in port 3
;========================================================================
;                       KEYBOARD SCAN TASK
; The keyboard is organized as 8 rows by 18 columns.  The I/O ports are
; assigned as:
; P2
; bit7               bit0
; r7 r6 r5 r4 r3 r2 r1 r0
;
; P3               P1                             P0
; bit7       bit4  bit7                     bit0  bit7               bit0
;         c17 c16  c15 c14 c13 c12 c11 c10 c9 c8  c7 c6 c5 c4 c3 c2 c1 c0
;
; The three LEDs are on port 3 bits[2:0]
; 
; The keycode table is organized as 18 columns with 8 rows per column.
;       ksc_x_index selects a column from 0 to 17
;       ksc_y_index selects a row from 0 to 7
;========================================================================
;------------------------------------------------------------------------
; ram variables to support the scan matrix
;------------------------------------------------------------------------
DEBOUNCE_ARRAY_SIZE:          equ       06h	; 6 keys debounced
LEFT_CTRL_BIT:		equ		01
LEFT_SHIFT_BIT:		equ		02
LEFT_ALT_BIT:		equ		04
LEFT_GUI_BIT:		equ		08
RIGHT_CTRL_BIT:		equ		10h
RIGHT_SHIFT_BIT:	equ		020h
RIGHT_ALT_BIT:		equ		040h
RIGHT_GUI_BIT:		equ		080h
APP_BIT:			equ		01h



ksc_x_index:            equ  ksc_ram_base
ksc_y_index:            equ  (ksc_ram_base + 1)




ksc_changes:            equ  (ksc_ram_base + 2)       ; keypress ksc_changes in a column
ksc_matrix_addr:        equ  (ksc_ram_base + 3)       ; keycode table index
ksc_down_up:            equ  (ksc_ram_base + 4)       ; 00h: key went up, FFh: key went down
ksc_phantom:            equ  (ksc_ram_base + 5)       ; flag indicates phantom key situation
							                          ; the debounce test.                                            ; 

ksc_p0out:              equ  (ksc_ram_base + 6)
ksc_p1out:              equ  (ksc_ram_base + 7)
ksc_p3out:              equ  (ksc_ram_base + 8)
;

; debounce_array contains 6 bytes
ksc_db_keys:            equ   (ksc_ram_base + 9)       ; define 6 bytes to debounce a
							                          ; maximum of 6 keys pressed


; ksc_db_counts contains 6 counters

ksc_db_counts:          equ  (ksc_ram_base + 15)      ; define 6 counter bytes for

;keyswitch image contains 18 bytes
ksc_image:              equ  (ksc_ram_base + 21)	  ;scan matrix image
ksc_mod0:			    equ  (ksc_ram_base + 39)	  ;modifier byte 0 	
ksc_mod1:			    equ  (ksc_ram_base + 40)      ;modifier byte 1
ksc_work:			    equ  (ksc_ram_base + 41)      ;modifier byte 1
ksc_delay:			    equ  (ksc_ram_base + 42)      ;delay byte

;the next three variables are used for phantom key detection
ksc_row_hits:			equ  (ksc_ram_base + 43)      ;bit field containing 
													  ;all rows with at least 1 key pressed
ksc_col_hits:			equ  (ksc_ram_base + 44)      ;current count of columns with at least
													  ;one key pressed
ksc_key_count:			equ  (ksc_ram_base + 45)      ;total number of keys pressed

KSC_RAM_SIZE:           equ  46

;========================================================================
; FUNCTION: ksc_putkey
;
; calls either ps2key_putkey or usbkey_putkey, depending upon the
; keyboard currently being supported.
;
;
;========================================================================

ksc_putkey:
    push    A
    mov     A,[dual_ifc_keyboard]
    cmp     A,PS2_KEYBOARD
    pop     A
    jnz     .usb
    call ps2key_putkey
    ret
.usb:
    call   usbkey_putkey
    ret


;========================================================================
; FUNCTION: ksc_scan_keys
;
; Keyboard scanning function
;
;========================================================================


ksc_scan_keys:
	call ksc_Debounce_Task          ; task for debounce
	mov A, 0                        ; init. phantom key flag to false
	mov [ksc_phantom], A
	mov [ksc_col_hits],A
	mov [ksc_row_hits],A
    mov [ksc_changes],A                
    mov [ksc_key_count],A
    mov [ksc_x_index],A


	mov X, 18                       ; 18 columns
	call ksc_StartScan              ; write initial scan pattern

.column_loop:
    DELAY   25
	iord  PORT2_DATA_REG            ; read input port
	cpl                             ; complement so down switch is '1'
	mov [ksc_mod1], A               ; save the port 2 data
    DELAY   25
	iord  PORT2_DATA_REG            ; read input port
	iord  PORT2_DATA_REG            ; read input port again
	cpl                     
	and [ksc_mod1], A               ; and with last look
	jz	.nokeysdown                 ; if keys are down in this column
    push A
    call    count_ones
    add A,[ksc_key_count]
    mov [ksc_key_count],A
    pop A
    or  [ksc_row_hits],A            ; keep track of all rows with keys down
    inc [ksc_col_hits]              ; and count of columns with a key down
.nokeysdown:
    mov A,[ksc_changes]                ; if key changes have already been found in a previous column
    cmp A, 0
    jnz .key_has_changed            ; skip to next column to scan for phantom situation
                                    ; else
	mov A, [X + ksc_image - 1]      ; get previous column data
	xor A, [ksc_mod1]               ; compare with current data
	mov [ksc_changes], A            ; and save positions where a change occurred
	cmp A, 0                        ; test for state change
	jnz .key_has_changed            ; if no key state change
    inc  [ksc_x_index]              ; increment the column
.key_has_changed:
	call ksc_NextPattern            ; write a new scan pattern
	dec X                           ; done yet?
	jnz .column_loop
.exit:

    mov A,[ksc_changes]                
    cmp A,0                         ; did we find any key changes from the above scan?
    jz  .exit1                      ; no, exit now
                                    ; yes, was there a phantom situation during the above scan?
    call check_phantom              ;
    jc  .exit1                      ; yes, exit now, because we cannot determine state of keys
    mov  A,[ksc_x_index]            ; else restore X to the proper column index
    cpl A                           ; based on the value of ksc_x_index
    add A,19
    mov X,A
    call ksc_KeyChanged             ; then call ksc_KeyChanged to record key changes
    CLEARC
.exit1:
	ret
;========================================================================
; initialize all columns to begin a keyboard scan
;       0 in c[0]
;       1 in c[19:1]
;       clear ksc_x_index to indicate column under test
;========================================================================
ksc_StartScan:
	push A                          ; save accumulator on stack
	mov A, feh                      ; write a zero to c[0]
	iowr  PORT0_DATA_REG            ; write ones to c[7:1]
	mov [ksc_p0out], A              ; remember what was written to Port0

	mov A, ffh                      ; write all ones to c[15:8]
	iowr  PORT1_DATA_REG     
	mov [ksc_p1out], A              ; remember what was written to Port1

	mov A, [ksc_p3out]              ; load data written to Port3
	or A, P3_KEY_MASK               ; write all ones to c[19:16]
	iowr PORT3_DATA_REG             ; LED data unchanged
	mov [ksc_p3out], A              ; remember what was written to Port3
	pop A                           ; restore accumulator from stack
	ret                             ; return

;========================================================================
; Write the columns with the next pattern in the keyboard scan.
; the pattern is generated as a left shift to walk the columns from zero
; to 19.  Increment the ksc_x_index to track the column under test.
;
; Port 3           Port 1                         Port 0
; bit7       bit4  bit7                     bit0  bit7               bit0
; c19 c18 c17 c16  c15 c14 c13 c12 c11 c10 c9 c8  c7 c6 c5 c4 c3 c2 c1 c0
;========================================================================
ksc_NextPattern:
	push A                          ; save accumulator on stack
	mov A, 0ffh                     ; set the carry bit
	rlc     
	mov A, [ksc_p0out]              ; load c[7:0] data
	rlc                             ; rotate left 
	mov [ksc_p0out], A              ; update memory copy
	iowr  PORT0_DATA_REG
	mov A, [ksc_p1out]              ; load c[15:8] data
	rlc                             ; rotate left 
	mov [ksc_p1out], A              ; update memory copy
	iowr PORT1_DATA_REG 

    mov A, [ksc_p3out]              ; load c[19:16] data
    jc .CarryIn 
    rlc                              ; rotate left
	and A, ~P3_KEY_LSBIT_MASK       ; clear bit we need to shift into
	jmp .WriteP3
.CarryIn:
    rlc
    or  A,P3_KEY_LSBIT_MASK        ; set bit we need to shift into
.WriteP3:
	and A, P3_KEY_MASK              ; clear all other bits
	push A                          ; save c[19:16] on stack
	mov A, [ksc_p3out]              ; load value from memory
	and A, ~P3_KEY_MASK             ; zero the column lines
	mov [ksc_p3out], A              ; store value back to memory
	pop A                           ; restore scan lines from stack
	or A, [ksc_p3out]               ; combine with the LED bits
	mov [ksc_p3out], A              ; save memory copy
	iowr PORT3_DATA_REG             ; write to the output port
	pop A                           ; restore accumulator from stack
	ret                             ; ret

;========================================================================
; A column had one or more buttons that changed state (up to down or down
; to up).  Scan the rows to find out which one(s) changed.
;========================================================================
ksc_KeyChanged:
	push A
	mov A, 0                        ; zero the row index
	mov [ksc_y_index], A

	mov A, 1                        ; initialize the scan bit
.row_loop:
	push A                          ; save scan bit on stack
	and A, [ksc_changes]            ; test bit position in row data
	jz .next_row                    ; keep testing
	call ksc_FoundKey               ; found a key
.next_row:
	inc [ksc_y_index]               ; increment row
	pop A                           ; restore scan bit
	rlc                             ; rotate left to test next bit
	jnc .row_loop

.done_KeyChanged:
	pop A
	ret                             ; return



;========================================================================
; We have a key identified by an ksc_x_index and a ksc_y_index.  Combine the two
; into a single index and lookup the keycode, check if up or down change.
;========================================================================
ksc_FoundKey:
	push A                              ; save accumulator on stack
	mov A, X
	mov [ksc_matrix_addr], A            ; save current scanned column
	pop A                               ; restore and save accumulator on stack
	push A

	and A, [X + ksc_image - 1]          ; see whether up or down change
	mov A, 00h                          ; key went up
	jnz .calc_matrix             
	mov A, FFh                          ; process this key make
.calc_matrix:                             ; calculate offset into code matrix
	mov [ksc_down_up], A                ; set flag
	mov X, [ksc_matrix_addr]            ; restore current column
	mov A, [ksc_x_index]                ; load column number
	asl                                 ; multiply by eight
	asl
	asl
	add A, [ksc_y_index]                ; add in the row index
	mov [ksc_matrix_addr], A            ; store

; test debounce array for match
	call ksc_Debounce_test              ; check if debounce in progress on this key

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -