?? kbusb.asm
字號:
;========================================================================
; FILE: usbkey.asm
;
; This file contains the code that implements the usb-specific
; routines to handle key scans.
;========================================================================
;BTH v1.68
;
;major modifications to handle MM and power key reporting
;
;
USB_NO_REPORT: equ 0
USB_REPORT_ERROR: equ 1
USB_REPORT_KEY: equ 2
;========================================================================
; Send_Keyboard2_Report sends a power or MM key report out on endpoint 2
;========================================================================
Send_Keyboard2_Report:
mov A, [usb_power_idle_period_ctr] ; if idle_period is zero, then we only send
cmp A, 0 ; reports on change
jz .mm ; so skip reset
dec A
mov [usb_power_idle_period_ctr],A ; else decrement idle period
jnz .mm ; if idle period expired
mov A,[usb_power_idle_period] ; reset idle period
mov [usb_power_idle_period_ctr],A
mov A,TX_POWER_MASK ; set flag indicating transmission required
or [usb_tx_flags],A
.mm:
mov A, [usb_mm_idle_period_ctr] ; if idle_period is zero, then we only send
cmp A, 0 ; reports on change
jz .xmit ; so skip rest
dec A
mov [usb_mm_idle_period_ctr],A ; else decrement idle period
jnz .xmit ; if idle period expired
mov A,[usb_mm_idle_period] ; reset idle period
mov [usb_mm_idle_period_ctr],A
mov A,TX_MM_MASK ; set flag indicating transmit required
or [usb_tx_flags],A
.xmit:
mov A,[KB_PROTOCOL]
cmp A,BOOT_PROTOCOL
jz .exit ;don't report in boot mode
mov A,[usb_current_state] ;don't report if error situation
cmp A,USB_REPORT_ERROR
jz .exit
iord EP_A2_Mode ; are we currently transmitting a report?
and A, USB_MODE_MASK
cmp A, ACKIN
jz .exit ; yes, then exit
mov A,[usb_tx_flags] ; if power, sleep, or wake keys
AND A,(TX_POWER_MASK | TX_MM_MASK)
jz .exit
AND A,TX_POWER_MASK
jz .mm1 ;
mov A,~TX_POWER_MASK
and [usb_tx_flags],A
mov A,EndpointA2
call Copy_power_buffer
iord EP_A2_Counter
and A, DATATOGGLE ; keep data toggle setting
or A, POWER_REPORT_LEN ; packet size
jmp .send
.mm1:
mov A,~TX_MM_MASK
and [usb_tx_flags],A
mov A,EndpointA2
call Copy_MM_buffer
iord EP_A2_Counter
and A, DATATOGGLE ; keep data toggle setting
or A, MM_REPORT_LEN ; packet size
.send:
iowr EP_A2_Counter
mov A, ACKIN ; enable packet transmission
iowr EP_A2_Mode
.exit:
ret
;========================================================================
; Send keyboard report to host
;========================================================================
Send_Keyboard_Report:
mov A,[usb_tx_flags]
AND A,TX_KBD_MASK
cmp A,0 ; if nothing to report
jz .idle ; check idle status
cmp A,USB_REPORT_ERROR ; else if we've got to send an error report
jnz .send
cmp A,[last_key_report] ; and the last one sent was not an error
jnz .send ; we can send this one too
.idle: ; else check idle status
mov A, [kbd_idle_period_ctr] ; if idle_period is zero, then we only send
cmp A, 0 ; reports on change
jz .exit ; exit task
dec A
mov [kbd_idle_period_ctr],A ; decrement idle period
jnz .exit ; and exit if idle period not expired
mov A,[last_key_report] ; otherwize get type of last report
.send: ;ok, we're REALLY going to send a new report
push A
iord EP_A1_Mode ; are we currently transmitting a report?
and A, USB_MODE_MASK
cmp A, ACKIN
pop A ; pop current request into A
jz .out ; yes, then exit (so we don't mess up
; the current transmission)
;
mov [last_key_report],A
mov A,~TX_KBD_MASK
and [usb_tx_flags],A
mov A,KBBuffer
call Copy_report_buffer ; copy report buffer
call Enable_EP1_Transmission ; enable EP1 transmission
.out:
mov A,[kbd_idle_period]
mov [kbd_idle_period_ctr],A ;reset idle period
.exit:
ret
;========================================================================
; Copy report_buffer copies key buffer to endpoint buffer pointed to by contents of A
;
; A points to either EP0 buffer (for getreport function)
; or EP1 (for normal key reporting)
;========================================================================
Copy_report_buffer:
push X
mov X, 7 ;count 8 of the darn things
add A,7 ;advance base address
copy_report_buffer_loop:
push X ;save count
push A ;push buffer base address
mov A,[last_key_report]
cmp A,USB_REPORT_ERROR
jz .error
mov A, [X + usb_report_buffer] ;assume we're sending a key stroke
jmp .next
.error:
mov A,X
index key_error_buffer ;else get error code byte
.next:
pop X ;pop buffer base into X
mov [X], A ;put key code into ep buffer
mov A,X ;put buffer base address back into A
dec A ;decrement buffer address
pop X ;get back index
dec X
jnc copy_report_buffer_loop ;do next one
pop X
ret
;========================================================================
; Copy_power_buffer copies power buffer to endpoint buffer pointed to by contents of A
;
; A points to either EP0 buffer (for getreport function)
; or EP1 (for normal key reporting)
;========================================================================
Copy_power_buffer:
push X ;save X
mov X,A ;get index to ep buffer
mov A,POWER_REPORT_ID ; set report ID
mov [X],A
mov A,[usb_power_keys] ; get power keys
mov [X+1],A
pop X ;restore X
ret
;========================================================================
; Copy_MM_buffer copies MM buffer to endpoint buffer pointed to by contents of A
;
; A points to either EP0 buffer (for getreport function)
; or EP1 (for normal key reporting)
;========================================================================
Copy_MM_buffer:
push X
mov X,A
mov A,MM_REPORT_ID ; set report ID
mov [X],A
mov A,[usb_mm_keys] ; get bit field
mov [X+1],A
mov A,[usb_mm_keys+1] ; get bit field
mov [X+2],A
pop X
ret
XPAGEOFF
key_error_buffer:
db 00,00,01,01,01,01,01,01
XPAGEON
;========================================================================
; Enable transmission from EP1 FIFO
;========================================================================
Enable_EP1_Transmission:
push A ; save accumulator on stack
iord EP_A1_Counter
and A, DATATOGGLE ; keep data toggle setting
or A, 8h ; packet size
iowr EP_A1_Counter
mov A, ACKIN ; enable packet transmission
iowr EP_A1_Mode
pop A ; restore accumulator
ret ; return
;========================================================================
; 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -