📄 kbdisr.asm
字号:
TITLE "KBDISR.ASM"
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; File: kbdisr.asm
; Author: Steve Roberts 8/2/96
; Description: Converts legacy PS/2 keyboard signals to USB format.
; This code is vectored to via the INT1 interrupt. The
; keyboard sends 11 clock pulses for data output and
; for receiving data from the system. Each of these
; pulses is a separate call to this ISR.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include donconst.inc
include externs.inc
include 82930.inc
extern SEND_KBD_REPORT_EP2
define KBDISR_VECTOR,SPACE=CODE, ORG=004013H ; For DEBUGGER
segment KBDISR_VECTOR
ejmp KBD_ISR
;define KBDISR_VECTOR,SPACE=CODE, ORG=FF0013H ; For burning FLASH
;segment KBDISR_VECTOR
; ejmp KBD_ISR
define KBDISR,SPACE=CODE
segment KBDISR
KBD_ISR:
push PSW1
push PSW
push R0
push R1
push R2
push R3
push WR16
push ACC
mov A, KBD_MODE ; Checks to see if it is a send
jz SEND ; to the kbd, or a reception
lcall RCV_FROM_KBD ; 0=send, 1=receive
jmp EXIT_KBD_ISR
SEND:
lcall SEND_TO_KBD
EXIT_KBD_ISR:
pop ACC
pop WR16
pop R3
pop R2
pop R1
pop R0
pop PSW
pop PSW1
reti
;--------------------------------------------------------------
; Function: RCV_FROM_KBD
; Description: Handles data bits from the keyboard and coverts
; them to bytes that are stored in the keyboard
; data buffer. Bytes are stored in the buffer as
; USB usage index codes - not keyboard make/break
; codes.
; Called from: Within kbdisr.asm
;---------------------------------------------------------------
RCV_FROM_KBD:
dec BIT_COUNT
mov A, BIT_COUNT
jz RPARITY
mov R1, #0FFh
cmp R1, BIT_COUNT ; BIT_COUNT=FF at stop bit
je STOP_BIT
mov A, P3 ; Handle d0-d7
anl A, #010h
rl A
rl A
rl A
mov R1, A
mov R0, DATA_FROM_KBD
orl R0, R1
mov DATA_FROM_KBD, R0
mov R1, #01h
cmp R1, BIT_COUNT ; Branch to shift if start-d6
jsl START_D6
ret ; When at d7, skip
START_D6:
mov R0, DATA_FROM_KBD
srl R0
mov DATA_FROM_KBD, R0
ljmp EXIT_RCV_FROM_KBD
RPARITY:
mov A, DATA_FROM_KBD ; From kbd receive parity
mov R1, PSW
anl R1, #01h ; If data has odd# bits=1 then r1=1
mov A, R1
rl A
rl A
rl A
rl A
anl A, P3 ; All ok if A=0
jnz RPARITY_ERROR
ljmp EXIT_RCV_FROM_KBD
RPARITY_ERROR:
mov KBD_MODE, #0 ; Set keybd to rcv mode
mov DATA_TO_KBD, #KBD_RESEND
mov BIT_COUNT, #0Ah
clr P3.4 ; RTS to kbd -
; Kbd will send clk pulses
ljmp EXIT_RCV_FROM_KBD
STOP_BIT:
jnb P3.4, RPARITY_ERROR ; Issue resend if no stop bit
mov BIT_COUNT, #0Ah
mov R0, DATA_FROM_KBD
cmp R0, #0FAh ; Different handling for kbd
je RCV_INIT_ACKS ; Initialization bytes
cmp R0, #0AAh
je RCV_INIT_ACKS
cmp R0, #0FEh
je RCV_INIT_ACKS
cmp R0, #0FCh
je RCV_INIT_ACKS
cmp R0, #0EEh
je RCV_INIT_ACKS
cmp R0, #0F0h ; KBD sends F0 before break code
je BREAK_CODE_COMING
mov DPTR, #KEY_CODE_TABLE ; Converts keycodes to USB usage
mov KEY_CODE_INDEX, #0 ; index codes
lcall KEY_CODE_LOOP
mov DATA_FROM_KBD, KEY_CODE_INDEX
mov R0, DATA_FROM_KBD
mov P1, DATA_FROM_KBD
mov R1, BREAK_CODE_MODE
cmp R1, #1
je REMOVE
lcall ADD_A_KEY
sjmp EXIT_RCV_FROM_KBD
REMOVE:
lcall REMOVE_A_KEY
sjmp EXIT_RCV_FROM_KBD
BREAK_CODE_COMING:
mov BREAK_CODE_MODE, #1
sjmp EXIT_RCV_FROM_KBD
RCV_INIT_ACKS:
mov KBD_COMMAND, R0
sjmp EXIT_RCV_FROM_KBD
;-------------------------------------------------------------------
; Function : KEY_CODE_LOOP
; Description : Converts keycodes to USB Usage Index Codes
; Called from : Within kbdisr.asm by function "RCV_FROM_KBD"
;-------------------------------------------------------------------
KEY_CODE_LOOP:
mov A, KEY_CODE_INDEX ; Does scan set 3 keycode
movc A, @A+DPTR ; conversion to USB Usage
mov R1, A ; Index code
cmp R0, R1
je EXIT_KEY_CODE_LOOP
inc KEY_CODE_INDEX
mov R1, #0E8h ; Watch for overrun of key code table
cmp R1, KEY_CODE_INDEX
je RESET_INDEX
ljmp KEY_CODE_LOOP
RESET_INDEX:
mov KEY_CODE_INDEX, #0 ; Start from the top again
ljmp KEY_CODE_LOOP ; No real good way to handle this
; but it SHOULD never happen
EXIT_KEY_CODE_LOOP:
ret
;-------------------------------------------------------------------
EXIT_RCV_FROM_KBD:
ret
;-------------------------------------------------------------------
;-------------------------------------------------------------------
; Function: ADD_A_KEY
; Description: Adds new keycodes to buffer
; Called from: Within kbdisr.asm by function "RCV_FROM_KBD"
;-------------------------------------------------------------------
ADD_A_KEY:
mov WR16, #KBD_BUFFER_START
;mov A, USB_PROTOCOL ; USB Boot protocol has different
;jz ADD_TO_BOOT_FORMAT ; report format than Item Protocol
ADD_TO_ITEM_FORMAT:
inc WR16, #1 ; To get past ID byte
cmp R0, #0E1h ; E1h is the left SHIFT key
je ADD_LEFT_SHIFT
cmp R0, #0E5h ; E5h is the right SHIFT key
je ADD_RIGHT_SHIFT
cmp R0, #0E0h ; E0h is the left CTRL key
je ADD_LEFT_CTRL
cmp R0, #0E4h ; E4h is the right CTRL key
je ADD_RIGHT_CTRL
cmp R0, #0E2h ; E2h is the left ALT key
je ADD_LEFT_ALT
cmp R0, #0E6h ; E6h is the right ALT key
je ADD_RIGHT_ALT
;inc WR16, #1
add WR16, #02h ; To get past mod & reserved bytes
ADD_LOOP:
mov R1, #0
cmp R1, @WR16
je WRITE_KEYCODE ; Find first empty location in buffer
inc WR16, #1
cmp WR16, #KBD_BUFFER_END
jg SEND_ERROR_ROLLOVER_STATE ; Too many keys hit - send all 01's
jmp ADD_LOOP
WRITE_KEYCODE:
mov @WR16, R0
sjmp EXIT_ADD_A_KEY
ADD_LEFT_SHIFT:
mov R0, @WR16 ; Modifier key bit-map (HID Spec 1.0):
orl R0, #002h ; d0= Left Ctrl
mov @WR16, R0 ; d1= Left Shift
sjmp EXIT_ADD_A_KEY ; d2= left Alt
; d3= Left GUI (not supported)
ADD_RIGHT_SHIFT: ; d4= Right Ctrl
mov R0, @WR16 ; d5= Right Shift
orl R0, #020h ; d6= Right Alt
mov @WR16, R0 ; d7= Right GUI (not supported)
sjmp EXIT_ADD_A_KEY
ADD_LEFT_CTRL:
mov R0, @WR16
orl R0, #001h
mov @WR16, R0
sjmp EXIT_ADD_A_KEY
ADD_RIGHT_CTRL:
mov R0, @WR16
orl R0, #010h
mov @WR16, R0
sjmp EXIT_ADD_A_KEY
ADD_LEFT_ALT:
mov R0, @WR16
orl R0, #004h
mov @WR16, R0
sjmp EXIT_ADD_A_KEY
ADD_RIGHT_ALT:
mov R0, @WR16
orl R0, #040h
mov @WR16, R0
sjmp EXIT_ADD_A_KEY
SEND_ERROR_ROLLOVER_STATE:
mov ERROR_ROLLOVER_STATE, #1 ; report_req_isr checks this var
sjmp EXIT_ADD_A_KEY
EXIT_ADD_A_KEY:
mov R0, IDLE_MODE ; If in idle mode, must fill FIFO
cmp R0, #0 ; with new key event info
je RETURN_ADD_A_KEY
cmp R0, #1 ; If in INDEF IDLE mode, leave timer alone
je CALL_SEND_KBD_REPORT_EP2
clr TCON.4 ; Disables timer0 until report is written
; Only done when in TIMED IDLE mode
CALL_SEND_KBD_REPORT_EP2:
lcall SEND_KBD_REPORT_EP2
RETURN_ADD_A_KEY:
ret
;-------------------------------------------------------------------
;-------------------------------------------------------------------
; Function: REMOVE_A_KEY
; Description: Deletes necessary keycodes from buffer
; Called from: Within kbdisr.asm by function "RCV_FROM_KBD"
;-------------------------------------------------------------------
REMOVE_A_KEY:
mov WR16, #KBD_BUFFER_START
inc WR16, #1 ; To get past ID byte
cmp R0, #0E1h ; E1h is the left SHIFT key
je REMOVE_LEFT_SHIFT
cmp R0, #0E5h ; E5h is the right SHIFT key
je REMOVE_RIGHT_SHIFT
cmp R0, #0E0h ; E0h is the left CTRL key
je REMOVE_LEFT_CTRL
cmp R0, #0E4h ; E4h is the right CTRL key
je REMOVE_RIGHT_CTRL
cmp R0, #0E2h ; E2h is the left ALT key
je REMOVE_LEFT_ALT
cmp R0, #0E6h ; E6h is the right ALT key
je REMOVE_RIGHT_ALT
; inc WR16, #1 ; To get past modifier byte
add WR16, #02h ; To get past mod & reserved bytes
REMOVAL_LOOP:
cmp R0, @WR16
je CLEAR_KEY_CODE
inc WR16, #1
cmp WR16, #KBD_BUFFER_END
jg KBD_BREAK_CODE_ERROR ; Happens when key was not placed (ERROR ROLLOVER STATE)
mov ERROR_ROLLOVER_STATE, #0 ; Since key is being removed, clear ER State
jmp REMOVAL_LOOP
CLEAR_KEY_CODE:
mov R0, #0
mov @WR16, R0
sjmp EXIT_REMOVE_A_KEY
REMOVE_LEFT_SHIFT:
mov R0, @WR16 ; Modifier key bit-map (HID Spec 1.0):
anl R0, #0FDh ; d0= Left Ctrl
mov @WR16, R0 ; d1= Left Shift
sjmp EXIT_REMOVE_A_KEY ; d2= Left Alt
; d3= Left GUI (not supported)
REMOVE_RIGHT_SHIFT: ; d4= Right Ctrl
mov R0, @WR16 ; d5= Right Shift
anl R0, #0CFh ; d6= Right Alt
mov @WR16, R0 ; d7= Left GUI (not supported)
sjmp EXIT_REMOVE_A_KEY
REMOVE_LEFT_CTRL:
mov R0, @WR16
anl R0, #0FEh
mov @WR16, R0
sjmp EXIT_REMOVE_A_KEY
REMOVE_RIGHT_CTRL:
mov R0, @WR16
anl R0, #0EFh
mov @WR16, R0
sjmp EXIT_REMOVE_A_KEY
REMOVE_LEFT_ALT:
mov R0, @WR16
anl R0, #0FBh
mov @WR16, R0
sjmp EXIT_REMOVE_A_KEY
REMOVE_RIGHT_ALT:
mov R0, @WR16
anl R0, #0BFh
mov @WR16, R0
sjmp EXIT_REMOVE_A_KEY
KBD_BREAK_CODE_ERROR:
sjmp EXIT_REMOVE_A_KEY ; Should reset system here (??)
EXIT_REMOVE_A_KEY:
mov R0, IDLE_MODE ; If in idle mode, must fill FIFO
cmp R0, #0 ; with new key event info
je RETURN_REMOVE_A_KEY
cmp R0, #1 ; If in INDEF IDLE mode, leave timer alone
je CALL2_SEND_KBD_REPORT_EP2
clr TCON.4 ; Disables timer0 until report is written
; Only done when in TIMED IDLE mode
CALL2_SEND_KBD_REPORT_EP2:
lcall SEND_KBD_REPORT_EP2
RETURN_REMOVE_A_KEY:
mov BREAK_CODE_MODE, #0
ret
;------------------------------------------------------------------
;------------------------------------------------------------------
; Function: SEND_TO_KBD
; Description: Sends commands to keyboard bit-by-bit.
; Called from: Within kbdisr.asm
;------------------------------------------------------------------
SEND_TO_KBD:
mov R1, #0Ah
cmp R1, BIT_COUNT
jne NOT_FIRST_PASS
mov MASK_BIT, #1
NOT_FIRST_PASS:
dec BIT_COUNT
mov R1, #0FFh
cmp R1, BIT_COUNT ; BIT_COUNT=FF when finished
jne D0_STOP
ACK:
jnb P3.4, OKAY ; To check for ACK (P3.4 low)
;**WHAT TO DO IF NO ACK? - RESEND?
sjmp EXIT_SEND_TO_KBD
OKAY:
mov BIT_COUNT, #0Ah ; ACK checked - all is ok
; Reset BIT_COUNT
mov KBD_MODE, #1 ; Set to "rcv from kbd" mode
setb P3.4 ; Tells kbd all is okay
setb P3.3
sjmp EXIT_SEND_TO_KBD
D0_STOP:
mov R1, #1
cmp R1, BIT_COUNT ; move_data until BIT_COUNT=1
jsl MOVE_DATA
SEND_PARITY:
mov R3, #0
cmp R3, BIT_COUNT
je SET_BIT ; Send stop bit if BIT_COUNT=0
mov A, DATA_TO_KBD ; For parity check
mov R2, PSW
anl R2, #1
cmp R1, R2 ; NOTE- kbd=odd parity; 82930=even
je CLR_BIT ; If equal, odd # of bits sent
jmp SET_BIT ; If not, even # of bits sent
MOVE_DATA:
mov R1, DATA_TO_KBD ; Move data out one bit at a time
anl R1, MASK_BIT
mov R0, MASK_BIT
sll R0
mov MASK_BIT, R0
mov A, R1
jz CLR_BIT
SET_BIT: ; Writes a data bit of "1"
setb P3.4
sjmp EXIT_SEND_TO_KBD
CLR_BIT: ; Writes a data bit of "0"
clr P3.4
sjmp EXIT_SEND_TO_KBD
EXIT_SEND_TO_KBD:
ret
;-------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -