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

📄 usbkey.asm

📁 CY7C63743 usb键盘的源码
💻 ASM
字号:
;========================================================================
;   FILE: usbkey.asm
;
;   This file contains the code that implements the usb-specific
;   routines to handle key scans.
;
;   REVISIONS:
;
;   02/2/99
;   rewrote usb_scan_keys, moved idle function into usbmain instead
;   12/28/98
;   removed RAM allocation for error code buffer to save space.
;   The error codes are now sent from a ROM table (see changes
;   to usbmain.asm)
;   11/9/98 modified to send bit-field for power, sleep, and wake
;   in accordance with latest PC98 specifications. This change
;   accompanies changes to the endpoint 2 descriptor and code
;   in usbmain to send the new usage.
;
;   modified scan codes for power, sleep, and wake keys to be old
;   style 0x66,0x67, and 0x68, respectively.  This passes the current
;   (August 98) Keyboard WHQL tests.
;
;========================================================================


;========================================================================
; Global Variables
;========================================================================



USB_KEY_BUFFER_SIZE:            EQU 8

; keyboard duplicate input report buffer (8 bytes)
; This buffer is sent to the host as a USB keyboard packet

usb_current_state:  		    equ (usbkey_ram_base + 0);storage for type of last report
                                                            ;(error report or key report)

usb_key_count:                  equ  (usbkey_ram_base + 1)        ; indicates number of keys pressed
usb_tx_required:                equ  (usbkey_ram_base + 2)        ; indicates a key(s) changed state
usb_power_id:                   equ  (usbkey_ram_base + 3)
usb_power_keys:			  equ  (usbkey_ram_base + 4)
usb_power_flag:                 equ  (usbkey_ram_base + 5)
usb_consumer_id:			  equ  (usbkey_ram_base + 6)
usb_consumer_keys:		  equ  (usbkey_ram_base + 7)
usb_consumer_flag:              equ  (usbkey_ram_base + 8)
usb_report_buffer:              equ  (usbkey_ram_base + 9)  
usb_last_mod:                   equ  usb_report_buffer         ; last modifier
USBKEY_RAM_SIZE:                equ   9 + USB_KEY_BUFFER_SIZE


USB_NO_REPORT:      equ 0
USB_REPORT_ERROR:   equ 1
USB_REPORT_KEY:     equ 2
;========================================================================
; FUNCTION:usb_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
;   usbkey_putkey from the internal scanning loop of the key scanner.
;
;
;
;========================================================================
usbkey_scan_keys:
    call    ksc_scan_keys                           ; scan the keys
    jc      .send_error                             ; phantom situation,send error to host
	mov     A, [usb_key_count]                      ; are there more than 6 keys pressed?
	cmp     A, 7
	jnc    .send_error                              ; yes, then send error to host
    mov     A,0                                     ; no errors, clear the error byte
    mov     [usb_current_state],A                   ; and return
    jmp     .exit
                                                    
.send_error:                                     
 												
    mov     A,USB_REPORT_ERROR                      ; there's currently an error,
    mov     [usb_tx_required],A
    mov     [usb_current_state],A                   ; mark as such
.exit:
    ret



;========================================================================
; FUNCTION:usbkey_putkey 
;
;handles key presses in usb 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).
;========================================================================


usbkey_putkey:
    call    usb_power_key
    jc     .done_putkey

    call	usb_consumer_key
    jc	.done_putkey
    
    call    ksc_modifier                           ;check for a modifier
    jnc      .non_modifiers
 	mov		A, USB_REPORT_KEY                      ; show that a report is required
	mov		[usb_tx_required], A
    mov     A,[ksc_mod0]
    mov     [usb_last_mod],A
    jmp     .done_putkey

.non_modifiers:
    index   usb_usage_table
	push	X                                       ; save X on stack
	push	A                                       ; save key code on stack

	mov		A, USB_REPORT_KEY                       ; show that a report is required
	mov		[usb_tx_required], A

	mov		A, [ksc_down_up]
	cmp		A, 0
	jnz		.add_key_to_buffer				        ; key down
													; otherwise, key is up


.remove_key_from_buffer:                            ; key is up, so remove if from buffer
	mov		A, [usb_key_count]
	cmp		A, 0                                    ; decrement key count (unless it's 0)
	jz		.skip_decrement_key_count
	dec		[usb_key_count]
.skip_decrement_key_count:
	mov		X, 2
.find_key_in_buffer:                                ; find the key in the report buffer
	pop		A
	push	A
	cmp		A, [X + usb_report_buffer]
	jz		.clear_buffer_position
	inc		X
	mov		A, X
	cmp		A, 8
	jc		.find_key_in_buffer
	pop		A
	jmp		.non_modifiers_done                     ; done search

.clear_buffer_position:                             ; key found in buffer, so clear position
	pop		A
	mov		A, 0
	mov		[X + usb_report_buffer], A
	jmp		.non_modifiers_done

	
.add_key_to_buffer:                                 ; key went down, so put it in the buffer
	mov		A, [usb_key_count]
	cmp		A, FFh                                  ; increment key count (unless it's 255)
	jz		.skip_increment_key_count
	inc		[usb_key_count]
.skip_increment_key_count:
	mov		X, 2
.find_free_buffer_position:                         ; find a free buffer position
	mov		A, 0
	cmp		A, [X + usb_report_buffer]
	jz .put_key_in_buffer_position
	inc		X
	mov		A, X
	cmp		A, 8
	jc		.find_free_buffer_position
	pop		A
	jmp		.non_modifiers_done                     ; could not find a free position
						                            ; more than 6 keys pressed

.put_key_in_buffer_position:                        ; found a free buffer position, so put key code there
	pop		A
	mov		[X + usb_report_buffer], A

.non_modifiers_done:
	pop		X  

.done_putkey:
    ret  


    XPAGEOFF
power_key_table:
    db      AT101KB_POWER,AT101KB_SLEEP,AT101KB_WAKE
power_bit_table:
    db      1,2,4

consumer_key_table:
    db	AT101KB_VOL_INC, AT101KB_VOL_DEC, AT101KB_MUTE
consumer_bit_table:
    db	1,2,4

    XPAGEON

NUM_POWER_KEYS:    equ 3
NUM_CONSUMER_KEYS: equ 3

;========================================================================
; FUNCTION:usb_power_key 
;
;handles power, sleep, and wake key presses in usb environment.
;
; This function was invented to trap the power, sleep, and wake key presses
; and maintain a single byte whose format is as follows:
;
; bit 1:  1 = power key pressed
; bit 2:  1 = sleep key pressed
; bit 3   1 = wake key pressed
;
; if any of these three keys changes state, the corresponding bit in the
; bit field is modified and the usb_power_flag is set to indicate that the
; state of the power keys has changed.
;========================================================================


usb_power_key:

    push	X
    push    A
    mov		X,usb_power_keys

.lp0:
    mov     [ksc_work],A                            ;store key in work byte
    mov     A,(NUM_POWER_KEYS - 1)                   ;initialize A to number of power keys
.lp1:
    push    A                                       ;save index
    index   power_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-power key
    jmp     .lp1

.lp2:
    index   power_bit_table                           ;now index into bit to set/clear
	push	A										; clear or set 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                                ; key went down
	or		[X + 0], A                              ; set bit
	jmp		.done_putkey
.mod0_up:									        ; else, key went up
	cpl                                             ; so clear bit
	and		[X + 0], A       
.done_putkey:                                       ;set carry indicating key found
    mov     A,0ffh
    mov     [usb_power_flag],A
    SETC    
.exit:
    pop     A                                       ;restore A,X
	pop		X
	ret

.non_modifier:                                      ;clear carry indicating no key found
    CLEARC                  
    jmp     .exit

    

usb_init_keyscan:
    CLEARRAM    usbkey_ram_base,USBKEY_RAM_SIZE
    mov A,POWER_REPORT_ID
    mov [usb_power_id],A
    mov A,CONSUMER_REPORT_ID
    mov [usb_consumer_id], A
    ret

;========================================================================
; FUNCTION:usb_consumer_key 
;
;handles volume inc, volume dec, and mute key presses in usb environment.
;
; This function was invented to trap the consumer key presses
; and maintain a single byte whose format is as follows:
;
; bit 1:  1 = volume inc key pressed
; bit 2:  1 = volume dec key pressed
; bit 3:   1 = mute key pressed
;
; if any of these three keys changes state, the corresponding bit in the
; bit field is modified and the usb_consumer_flag is set to indicate that the
; state of the consumer keys has changed.
;========================================================================

usb_consumer_key:

    push	X
    push    A

    mov		X,usb_consumer_keys

.lp0:
    mov     [ksc_work],A                            ;store key in work byte
    mov     A,(NUM_CONSUMER_KEYS - 1)                   ;initialize A to number of consumer keys
.lp1:
    push    A                                       ;save index
    index  consumer_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-power key
    jmp     .lp1

.lp2:
    index   consumer_bit_table                           ;now index into bit to set/clear
	push	A										; clear or set 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                                ; key went down
	or		[X + 0], A                              ; set bit
	jmp		.done_putkey
.mod0_up:									        ; else, key went up

	cpl                                             ; so clear bit
	and		[X + 0], A       
.done_putkey:                                       ;set carry indicating key found
    mov     A,0ffh
    mov     [usb_consumer_flag],A
    SETC    
.exit:
    pop     A                                       ;restore A,X
	pop		X
	ret

.non_modifier:                                      ;clear carry indicating no key found
    CLEARC                  
    jmp     .exit

    
usb_init_keyscan2:
    CLEARRAM    usbkey_ram_base,USBKEY_RAM_SIZE
    mov A,CONSUMER_REPORT_ID
    mov [usb_consumer_id],A
    ret

    XPAGEOFF

usb_usage_table:
	db			000h,035h,01eh,01fh,020h,021h,022h,023h	;0-7
	db			024h,025h,026h,027h,02dh,02eh,000h,02ah	;8-15
	db			02bh,014h,01ah,008h,015h,017h,01ch,018h	;16-23
	db			00ch,012h,013h,2fh,030h,031h,039h,004h	;24-31
	db			016h,007h,009h,00ah,00bh,00dh,00eh,00fh ;32-39
	db			033h,034h,032h,028h,0e1h,064h,01dh,01bh	;40-47
	db			006h,019h,005h,011h,010h,036h,037h,038h	;48-55
	db			000h,0e5h,0e0h,000h,0e2h,02ch,0e6h,000h	;56-63
	db			0e4h,000h,000h,000h,000h,000h,000h,000h ;64-71
	db			000h,000h,000h,049h,04ch,000h,000h,050h ;72-79
	db			04ah,04dh,000h,052h,051h,04bh,04eh,000h	;80-87
	db			000h,04fh,053h,05fh,05ch,059h,000h,054h	;88-95
	db			060h,05dh,05ah,062h,055h,061h,05eh,05bh	;96-103
	db			063h,056h,057h,000h,058h,000h,029h,000h	;104-111
	db			03ah,03bh,03ch,03dh,03eh,03fh,040h,041h	;112-119
	db			042h,043h,044h,045h,046h,047h,048h,0e3h	;120-127
	db			0e7h,065h,066h,067h,068h,000h,000h,000h	;128-235

    XPAGEON

⌨️ 快捷键说明

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