📄 kbd9.asm
字号:
MOV R0,#PS2_BUFFER
MOV R7,#6 ;MAX 6 KEYS IN BUFFER
COMPARE_ONE_KEY:
MOV A,@R0
JZ ADD_KEY_IN_BUFFER ;KEY NOT IN BUFFER
CLR C
SUBB A,R2
JZ END_MAKE_KEY ;KEY ALREADY IN BUFFER(REPEAT KEY), RETURN
INC R0
DJNZ R7,COMPARE_ONE_KEY ;COMPARE NEXT KEY
ROLLOVER:
SETB PS2_ERROR_ROLLOVER ;KEY ROLLOVER ERROR OCCURE(MORE THAN 6 KEYS)
SETB PS2_BUFFER_CHANGED
SJMP END_MAKE_KEY
ADD_KEY_IN_BUFFER:
MOV A,R2
MOV @R0,A ;ADD KEY IN BUFFER
INC PS2_LAST_KEY ;LAST KEY POSITION INCREMENT
SETB PS2_BUFFER_CHANGED
END_MAKE_KEY:
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
BREAK_KEY:
MOV R2,A
MOV R0,#PS2_BUFFER
MOV R7,#6 ;MAX 6 KEYS IN BUFFER
COMPARE_KEY1:
MOV A,@R0
JZ END_BREAK_KEY ;BREAK KEY NOT FOUND, ERROR
CLR C
SUBB A,R2
JZ BREAK_KEY_FOUND ;BREAK KEY IS IN BUFFER
INC R0
DJNZ R7,COMPARE_KEY1
SJMP END_BREAK_KEY ;BREAK KEY NOT FOUND, ERROR
BREAK_KEY_FOUND:
MOV R1,PS2_LAST_KEY
MOV @R0,#0
XCH A,@R1
XCH A,@R0 ;CLEAR THIS KEY, STORE LAST KEY HERE
DEC PS2_LAST_KEY ;ONE KEY LESS IN BUFFER
SETB PS2_BUFFER_CHANGED ;SET BUFFER CHANGE FLAG
END_BREAK_KEY:
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
WAIT_CLK_LOW: PUSH ACC
CLR C
MOV R7,#10 ;max 10ms
WAIT_LOOP:
DEC R7
MOV A,R7
JZ END_WAIT_CLK_LOW
MOV A,#200 ;1ms (200*5us)
WAIT_LOOP1: DEC A
; NOP
; NOP
JZ WAIT_LOOP
JB PS2_CLK, WAIT_LOOP1
SETB C
END_WAIT_CLK_LOW: POP ACC
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
WAIT_FALLING_CLK: PUSH ACC
MOV A,#200 ; MAX 1ms
CLR C
NEXT_CLK_HI_SAMPLE: DEC A
; NOP
; NOP
JZ END_WAIT_FALLING_CLK
JB PS2_CLK, NEXT_CLK_HI_SAMPLE
SETB C
END_WAIT_FALLING_CLK: POP ACC
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
WAIT_RISING_CLK: PUSH ACC
MOV A,#200 ; 5 CYCLES * 200 = 1 ms
CLR C
NEXT_CLK_LO_SAMPLE: DEC A ; 1 CYCLES
; NOP
; NOP
JZ END_WAIT_RISING_CLK ; 2 CYCLES
JNB PS2_CLK, NEXT_CLK_LO_SAMPLE ; 2 CYCLES
SETB C
END_WAIT_RISING_CLK: POP ACC
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
READ_PS2_BYTE:
MOV A,#0CCH ;SET DEFAULT VALUE
MOV R0, #8 ; 8 BITS TO SHIFT
LCALL WAIT_CLK_LOW ;WAIT PS2_CLK TO BE LOW, MAX 10ms
JNC END_READ_PS2_BYTE; TIMED-OUT
JB PS2_DATA, END_READ_PS2_BYTE ;START BIT MUST BE ZERO
READ_NEXT_PS2_BIT:
LCALL WAIT_RISING_CLK
JNC END_READ_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK
JNC END_READ_PS2_BYTE; TIMED-OUT
MOV C, PS2_DATA
RRC A
DJNZ R0, READ_NEXT_PS2_BIT
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK ;parity bit
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK ;stop bit
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
SETB C ;read one byte successful
END_READ_PS2_BYTE:
SETB PS2_DATA
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
WRITE_PS2_BYTE:
CLR PS2_DATA ; START BIT, HOST WANTS TO SEND COMMAND
MOV R1, #0 ; PARITY, COUNT NO OF '1'
MOV R0, #8 ; 8 BITS TO SHIFT
LCALL WAIT_CLK_LOW ; WAIT RESPONSE FROM KEYBOARD, MAX 10MS
JNC END_WRITE_PS2_BYTE; TIMED-OUT
NEXT_PS2_BIT: RRC A
MOV PS2_DATA, C ;CHANGE DATA LINE AFTER CLK LOW AND BEFORE CLOCK HIGH
JNC WAIT_CLK
INC R1
WAIT_CLK: LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
DJNZ R0, NEXT_PS2_BIT ; 8 DATA BITS, LSB FIRST
MOV A, R1
RRC A
CPL C
MOV PS2_DATA, C ; ODD PARITY BIT
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
SETB PS2_DATA ; STOP BIT 'HI'
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_FALLING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
LCALL WAIT_RISING_CLK
JNC END_WRITE_PS2_BYTE; TIMED-OUT
MOV C,PS2_DATA
CPL C ;ACKNOLEDGE BIT 'LOW'
END_WRITE_PS2_BYTE:
SETB PS2_DATA
RET
;*******************************************************************************
;ROUTINE :
;FUNCTION:
;INPUTS :
;OUTPUTS :
;CHANGED :
;---------------------------------------
KBD_SET_LED:
PUSH ACC
CLR EX1
MOV A,#0EDH ; REQUEST SEND STATUS TO KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_SET_LED ; KEYBOARD ACK
MOV A,LED_STATUS ; SEND LED STATUS BYTE TO KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_SET_LED ; KEYBOARD ACK
END_KBD_SET_LED:
SETB EX1
POP ACC
RET
KBD_GET_ID:
PUSH ACC
CLR C
MOV A,#0F2H ; REQUEST GET ID FROM KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_GET_ID
LCALL READ_PS2_BYTE
CJNE A,#0ABH,END_KBD_GET_ID
LCALL READ_PS2_BYTE
CJNE A,#83H,END_KBD_GET_ID
SETB KBD_ID_OK
SETB C
END_KBD_GET_ID:
POP ACC
RET
KBD_SET_SCAN:
PUSH ACC
CLR C
MOV A,#0F0H ; REQUEST SETSCAN CODE SET TO KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_SET_SCAN
MOV A,#03H ; SET SCAN CODE SET 3
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_SET_SCAN
SETB C
END_KBD_SET_SCAN:
POP ACC
RET
KBD_GET_SCAN:
PUSH ACC
CLR C
MOV A,#0F0H ; REQUEST SETSCAN CODE SET TO KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_GET_SCAN
MOV A,#00H ; GET SCAN CODE SET NO FROM KEYBOARD
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
CJNE A,#0FAH,END_KBD_GET_SCAN
LCALL READ_PS2_BYTE ; READ SCAN SET NO BYTE
CJNE A,#01H,SCAN_SET_2
SETB KBD_SELECT_SCANSET_1 ; SCAN CODE SET 1 CURRENTLY USED
LJMP EXIT_SCANSET
SCAN_SET_2:
CJNE A,#02H,SCAN_SET_3
SETB KBD_SELECT_SCANSET_2 ; SCAN CODE SET 2 CURRENTLY USED
LJMP EXIT_SCANSET
SCAN_SET_3:
CJNE A,#03H,END_KBD_GET_SCAN
SETB KBD_SELECT_SCANSET_3 ; SCAN CODE SET 3 CURRENTLY USED
EXIT_SCANSET:
SETB C
END_KBD_GET_SCAN:
POP ACC
RET
KBD_PS3_SAK_MB:
PUSH ACC
MOV A,#0F8H
LCALL WRITE_PS2_BYTE
LCALL READ_PS2_BYTE
END_KBD_PS3_SAK_MB:
POP ACC
RET
;*************************************************************************
;* HID device (Keyboard BOOT protocal) report descriptor
;*************************************************************************
RptDsc:
db 5h,1h ; USAGE_PAGE (Generic Desktop)
db 9h,6h ; USAGE (Keyboard)
db 0a1h,1h ; COLLECTION (Application)
db 5h,7h ; USAGE_PAGE (Keyboard)
db 19h,0e0h ; USAGE_MINIMUM (Keyboard LeftControl)
db 29h,0e7h ; USAGE_MAXIMUM (Keyboard Right GUI)
db 15h,0h ; LOGICAL_MINIMUM (0)
db 25h,1h ; LOGICAL_MAXIMUM (1)
db 75h,1h ; REPORT_SIZE (1)
db 95h,8h ; REPORT_COUNT (8)
db 81h,2h ; INPUT (Data,Var,Abs) ;MODIFIER BYTE
db 95h,1h ; REPORT_COUNT (1)
db 75h,8h ; REPORT_SIZE (8)
db 81h,1h ; INPUT (Constant) ;RESERVED BYTE
db 95h,5h ; REPORT_COUNT (5)
db 75h,1h ; REPORT_SIZE (1)
db 5h,8h ; USAGE_PAGE (LEDs)
db 19h,1h ; USAGE_MINIMUM (Num Lock)
db 29h,5h ; USAGE_MAXIMUM (Kana)
db 91h,2h ; OUTPUT (Data,Var,Abs) ;LED REPORT
db 95h,1h ; REPORT_COUNT (1)
db 75h,3h ; REPORT_SIZE (3)
db 91h,1h ; OUTPUT (Constant) ;LED REPORT PADDING
db 95h,6h ; REPORT_COUNT (6)
db 75h,8h ; REPORT_SIZE (8)
db 15h,0h ; LOGICAL_MINIMUM (0)
db 25h,65h ; LOGICAL_MAXIMUM (101)
db 5h,7h ; USAGE_PAGE (Keyboard)
db 19h,0h ; USAGE_MINIMUM (Reserved (no event indicated))
db 29h,65h ; USAGE_MAXIMUM (Keyboard Application)
db 81h,0h ; INPUT (Data,Ary) ;6 KEYCODE BYTES
db 0c0h ; END_COLLECTION
RptDscend:
rpt_lngh equ RptDscend-RptDsc
; Strings
USBString0:
; Sring 0, LANGIDs
db 04h,03h ; bLength and bDescriptorType
; dw 0409h ; String
dw 0009h ; LANGID, ENGLISH
; Unicode Strings
USBString1:
;String 1, Manufacturer
DB manu_len ; manufacturer, Descriptor Index = 01h
DB 03h ; String Descriptor
DB 'P',00 ; string value
DB 'h',00
DB 'i',00
DB 'l',00
DB 'i',00
DB 'p',00
DB 's',00
db ' ',00
db 'S',00
db 'e',00
db 'm',00
db 'i',00
db 'c',00
db 'o',00
db 'n',00
db 'd',00
db 'u',00
db 'c',00
db 't',00
db 'o',00
db 'r',00
db 's',00
USBString2:
manu_len equ USBString2-USBString1
;USB string 2, Product name
DB prod_len ; Product name, Descriptor Index = 02h
DB 03h ; String Descriptor
DB 'U',00 ; string value
DB 'S',00
DB 'B',00
DB ' ',00
DB 't',00
DB 'o',00
DB ' ',00
DB 'P',00
DB 'S',00
DB '/',00
DB '2',00
db ' ',00
db 'K',00
db 'e',00
db 'y',00
db 'b',00
db 'o',00
db 'a',00
db 'r',00
db 'd',00
db ' ',00
db 'c',00
db 'o',00
db 'n',00
db 'v',00
db 'e',00
db 'r',00
db 't',00
db 'e',00
db 'r',00
db ' ',00
db 'v',00
db 'e',00
db 'r',00
db 's',00
db 'i',00
db 'o',00
db 'n',00
db '0',00
db '.',00
db '8',00
USBString3:
prod_len equ USBString3-USBString2
;USB string 3, Serial number
DB 06h ; Serial number, Descritpor Index = 03h
DB 03h ; String Descriptor
DB '0', 00 ; string value
DB '1', 00
;****************************
;* STANDARD DEVICE DESCRIPTOR
;****************************
;Descriptors
USBDvcDsc:
db 12h ; bLength
db 01h ; bDescriptorType
dw 0001h ; bcdUSB
db 00h ; bDeviceClass
db 00h ; bDeviceSubClass
db 00h ; bDeviceProtocol
db 08h ; bMaxPacketSize0
dw 0feffh ; idVendor
dw 0feffh ; idProduct
dw 0000h ; bcdDevice
db 01h ; iManufacturer
db 02h ; iProduct
db 03h ; iSerialNumber
db 01h ; bNumConfigurations
USBCnfDsc:
db 09h ; bLength
db 02h ; bDescriptorType
db USBCnf_lngh ; low byte of wTotalLength
db 00h ; high byte of wTotalLength
db 01h ; bNumInterfaces
db 01h ; bConfigurationValue
db 00h ; iConfiguration
db 0a0h ; bmAttributes, remote wakeup and bus-power
db 05h ; MaxPower, 100mA
USBInfDsc:
db 09h ; bLength
db 04h ; bDescriptorType
db 00h ; bInterfaceNumber
db 00h ; bAlternateSetting
db 01h ; bNumEndpoints
db 03h ; bInterfaceClass
db 01h ; bInterfaceSubClass
db 01h ; bInterfaceProtocol
db 00h ; iInterface
USBHIDDsc:
db 09h ; bLength
db 21h ; bDescriptorType
dw 0001h ; bcdHID
db 21h ; bCountryCode
db 01h ; bNumDescriptors
db 22h ; cd[0].bDescriptorType
db rpt_lngh ; cd[0].wDescriptorLength
db 00h
USBEPInDsc:
db 07h ; bLength
db 05h ; bDescriptorType
db 81h ; bEndpointAddress
db 03h ; bmAttributes
dw 0800h ; wMaxPacketSize
db 0ffh ; bInterval
USBdsc_end:
USBCNF_lngh equ USBdsc_end-USBCnfdsc
;---------------------------------------------------------------------------------------------------------
TBL_PS2_TO_HID: ; ps2 scan code set 2 to hid keycode look-up table
; 00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h, 08h, 09h, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh
;---------------------------------------------------------------------------------------------------------
db 01h, 42h, 00h, 3eh, 3ch, 3ah, 3bh, 45h, 00h, 43h, 41h, 3fh, 3dh, 2bh, 35h, 00h ;00-0f
db 00h, 00h,0E1h, 00h, 00h, 14h, 1eh, 00h, 00h, 00h, 1dh, 16h, 04h, 1ah, 1fh, 00h ;10-1f
db 00h, 06h, 1bh, 07h, 08h, 21h, 20h, 00h, 00h, 2ch, 19h, 09h, 17h, 15h, 22h, 65h ;20-2f
db 00h, 11h, 05h, 0bh, 0ah, 1ch, 23h, 00h, 00h, 00h, 10h, 0dh, 18h, 24h, 25h, 00h ;30-3f
db 00h, 36h, 0eh, 0ch, 12h, 27h, 26h, 00h, 00h, 37h, 38h, 0fh, 33h, 13h, 2dh, 00h ;40-4f
db 00h, 00h, 34h, 00h, 2fh, 2eh, 00h, 00h, 39h, 00h, 28h, 30h, 00h, 31h, 00h, 00h ;50-5f
db 00h, 00h, 00h, 00h, 00h, 00h, 2ah, 00h, 00h, 59h, 00h, 5ch, 5fh, 00h, 00h, 00h ;60-6f
db 62h, 63h, 5ah, 5dh, 5eh, 60h, 29h, 53h, 44h, 57h, 5bh, 56h, 55h, 61h, 47h, 00h ;70-7f
db 00h, 00h, 00h, 40h, 46h ;80-84
;----------------------------------------------------------------------------------------------------------
TBL_PS2EXTRA_TO_HID: ;arrow keys and page control keys, start with E0 in PS/2 format, offset 4ah
;---------------------------------------------------------------------------------------------------------
DB 54H, 00H, 00H, 00H, 00H, 00H ;4a-4f
DB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H, 58H, 00H, 00H, 00H, 00H, 00H ;50-5f
DB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H, 4dH, 00H, 50H, 4aH, 00H, 00H, 00H ;60-6f
DB 49H, 4cH, 51H, 00H, 4fH, 52H, 00H, 48H, 00H, 00H, 4eH, 00H, 46H, 4bH, 48H, 00H ;70-7f
;----------------------------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------------------------
TBL_PS3_TO_HID: ; ps2 scan code set 3 to hid keycode look-up table
; 00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h, 08h, 09h, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh
;---------------------------------------------------------------------------------------------------------
db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 3Ah, 29h, 00h, 00h, 00h, 00h, 2Bh, 35h, 3Bh ;00-0f
db 00h,0E0h,0E1h, 00h, 39h, 14h, 1eh, 3Ch, 00h,0E2h, 1dh, 16h, 04h, 1ah, 1fh, 3Dh ;10-1f
db 00h, 06h, 1bh, 07h, 08h, 21h, 20h, 3Eh, 00h, 2ch, 19h, 09h, 17h, 15h, 22h, 3Fh ;20-2f
db 00h, 11h, 05h, 0bh, 0ah, 1ch, 23h, 40h, 00h, 00h, 10h, 0dh, 18h, 24h, 25h, 41h ;30-3f
db 00h, 36h, 0eh, 0ch, 12h, 27h, 26h, 42h, 00h, 37h, 38h, 0fh, 33h, 13h, 2dh, 43h ;40-4f
db 00h, 00h, 34h, 00h, 2fh, 2eh, 44h, 46h,0E4h,0E5h, 28h, 30h, 31h, 00h, 45h, 47h ;50-5f
db 51h, 50h, 48h, 52h, 4Ch, 4Dh, 2ah, 49h, 00h, 59h, 4Fh, 5ch, 5fh, 4Eh, 4Ah, 4Bh ;60-6f
db 62h, 63h, 5ah, 5dh, 5eh, 60h, 53h, 54h, 00h, 58h, 5bh, 00h, 57h, 61h, 55h, 00h ;70-7f
db 00h, 00h, 00h, 00h, 56h ;80-84
;----------------------------------------------------------------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -