📄 usbkbd.asm
字号:
;----------------------------------------------------------------------------
pUSBKeyCodeToScanCodeSet2Table LABEL BYTE
;------ USA ENGLISH keyboard -------; USB Key Code to Scan Code Set 2
DB 00h,00h,00h,00h,1Ch,32h,21h,23h ; 00 - 07h
DB 24h,2Bh,34h,33h,43h,3Bh,42h,4Bh ; 08 - 0Fh
DB 3Ah,31h,44h,4Dh,15h,2Dh,1Bh,2Ch ; 10 - 17h
DB 3Ch,2Ah,1Dh,22h,35h,1Ah,16h,1Eh ; 18 - 1Fh
DB 26h,25h,2Eh,36h,3Dh,3Eh,46h,45h ; 20 - 27h
DB 5Ah,76h,66h,0Dh,29h,4Eh,55h,54h ; 28 - 2Fh
DB 5Bh,5Dh,5Dh,4Ch,52h,0Eh,41h,49h ; 30 - 37h
DB 4Ah,58h,05h,06h,04h,0Ch,03h,0Bh ; 38 - 3Fh
DB 83h,0Ah,01h,09h ; 40 - 43h
DB 78h,07h, PRINT_SCREEN,7Eh ; 44 - 47h
DB PAUSE_KEY, INSERT_KEY, HOME_KEY ; 48 - 4Ah
DB PAGE_UP_KEY, DEL_KEY, END_KEY ; 4B - 4Dh
DB PAGE_DOWN_KEY, RIGHT_KEY ; 4E - 4Fh
DB LEFT_KEY, DOWN_KEY, UP_KEY, 77h ; 50 - 53h
DB SLASH_KEY, 7Ch, 7Bh, 79h ; 54 - 57h
DB RIGHT_ENTER, 69h, 72h, 7Ah ; 58 - 5Ch
DB 6Bh, 73h, 74h, 6Ch ; 5D - 5Fh
DB 75h,7Dh,70h,71h,61h, APP_MS_KEY,00h,00h ; 60 - 67h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; 68 - 6Fh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; 70 - 77h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; 78 - 7Fh
DB 00h,00h,00h,00h,00h,00h,00h,51h ; 80 - 87h
DB 13h,6Ah,64h,67h,00h,00h,00h,00h ; 88 - 8Fh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; 90 - 97h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; 98 - 9Fh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; A0 - A7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; A8 - AFh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; B0 - B7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; B8 - BFh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; C0 - C7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; C8 - CFh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; D0 - D7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; D8 - DFh
DB 14h,12h,11h, LEFT_MS_KEY ; E0 - E3h
DB RIGHT_CTRL, 59h, RIGHT_ALT, RIGHT_MS_KEY; E4 - E7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; E8 - EFh
DB 00h,00h,00h,00h,00h,00h,00h,00h ; F0 - F7h
DB 00h,00h,00h,00h,00h,00h,00h,00h ; F8 - FFh
;----------------------------------------------------------------------------
; Table used to find length of scan code needed. Please refer to comments
; in the code below (somewhere) for the usage.
pScanCodeLengthTable_1112 LABEL BYTE
DB 001h, 001h, 001h, 002h
pScanCodeLengthTable_2223 LABEL BYTE
DB 002h, 002h, 002h, 003h
pScanCodeLengthTable_4446 LABEL BYTE
DB 004h, 004h, 004h, 006h
pScanCodeLengthTable_4500 LABEL BYTE
DB 004h, 005h, 000h, 000h
pScanCodeLengthTable_4545 LABEL BYTE
DB 004h, 005h, 004h, 005h
pScanCodeLengthTable_6800 LABEL BYTE
DB 006h, 008h, 000h, 000h
;----------------------------------------------------------------------------
; Typematic rate delay table will have counts to generate 250, 500, 750 &
; 1000 msec delay between character repeat. Since the periodic interrupt is
; set to 8msec the following repeat times will generate necessary delay
pTypematicRateDelayTable DB 16, 32, 48, 64
;----------------------------------------------------------------------------
PUBLIC _USBKBD_STAT_TABLE_END
_USBKBD_STAT_TABLE_END LABEL BYTE
;----------------------------------------------------------------------------
; USB HID Related Generic Functions
;----------------------------------------------------------------------------
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDInitialize
;
; Description: This routine is called once to initialize the USB HID data
; area.
;
; Input: Nothing
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDInitialize PROC NEAR SYSCALL PUBLIC USES AX CX SI DI ES
; Initialize the data area by filling it with 0
push ds
pop es
mov di, OFFSET USBKBC_DataStart
mov cx, OFFSET USBKBC_DataEnd - OFFSET USBKBC_DataStart
xor al, al
rep stosb
call USBKBD_InitKeyboard
; Get the keyboard LED status from the non-USB keyboards and update it
; in the local variable to update USB keyboards
; Get the keyboard LED status from the BIOS data area
push ds
xor ax, ax
mov ds, ax
mov al, BYTE PTR ds:[417h] ; Caps-lock, Num-lock, Scroll-lock (IBM)
pop ds
; Convert the keyboard LED status from IBM standard to USB keyboard way
and al, 70h
shr al, 1 ; Scroll-lock, Caps-lock, Num-lock (USB)
test al, 08h
jz UHI_UpdateUSBKBCVariable
xor al, 48h
UHI_UpdateUSBKBCVariable:
mov bUSBKBShiftKeyStatus, al
IF MKF_USB_KBC_EMULATION
and bNonUSBKBShiftKeyStatus, NOT (BIT4+BIT5+BIT6)
or bNonUSBKBShiftKeyStatus, al
ENDIF
; Get the keyboard controller command byte (CCB) and store it locally
call USBKBC_GetAndStoreCCB
ret
USBKBDInitialize ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBD_InitKeyboard
;
; Description: This routine initializes the keyboard related data fields
;
; Input: Nothing
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBD_InitKeyboard PROC NEAR
push ax
; Initialize the typematic rate to 500 ms, 10.9 Char/Sec and auto repeat flag
; to disabled
or wUSBKBC_StatusFlag, (KBC_SET_TYPE_RATE_11CHARS_SEC + \
KBC_SET_TYPE_DELAY_500MSEC)
IF MKF_USB_KBC_EMULATION
call USBKBDInitScanCodeSet3Table
ENDIF
; Initialize the scanner buffer
mov pKBCScanCodeBufferPtr, OFFSET pKBCScanCodeBufferStart
mov bLastUSBKeyCode, al ; AL = 0
; Initialize the character buffer
mov ax, OFFSET pKBCCharacterBufferStart
mov pKBCCharacterBufferHead, ax
mov pKBCCharacterBufferTail, ax
; Set scan code set to 2 in the scanner flag
or wUSBKBC_StatusFlag, KBC_SET_SCAN_CODE_SET2
pop ax
ret
USBKBD_InitKeyboard ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDCheckForKeyboard
;
; Description: This routine checks for mouse type device from the
; interface data provided
;
; Input: DL+ USB base class code
; DH USB sub-class code
; DL USB protocol code
;
; Output: AX BIOS_DEV_TYPE_KEYBOARD type on success or 0FFH
; on error
;
; Modified: AX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDCheckForKeyboard PROC NEAR SYSCALL PUBLIC
push edx
xor ax, ax
mov al, 0FFH ; Device type unknown
; If legacy keyboard support is disabled. Do not enumerate USB keyboard
test dUSBInitFlag, USB_LEGACY_KEYBOARD_BIT
jz UKCFK_Done
; Check the BaseClass, SubClass and Protocol for a HID/Boot/Keyboard device.
cmp dh, SUB_CLASS_BOOT_DEVICE
jne UKCFK_Done ;Br if this interface is not a boot device
cmp dl, PROTOCOL_KEYBOARD
jne UKCFK_Done ;Br if this interface is not a keyboard
shr edx, 8
cmp dh, BASE_CLASS_HID
jne UKCFK_Done ;Br if this interface is not a HID device
mov ax, BIOS_DEV_TYPE_KEYBOARD
UKCFK_Done:
pop edx
ret
USBKBDCheckForKeyboard ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDConfigureKeyboard
;
; Description: This routine checks an interface descriptor of the USB device
; detected to see if it describes a HID/Boot/Keyboard device.
; If the device matches the above criteria, then the device is
; configured and initialized
;
; Input: BX Device information structure pointer
; DI Pointer to the descriptor structure
; CX End offset of the device descriptor
;
; Output: ZR On error
; NZ On success
; BX - New DeviceInfo structure
;
; Modified: BX
;
; Referrals: HCStruc, DeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDConfigureKeyboard PROC NEAR SYSCALL PUBLIC
push ax
; Set the BiosDeviceType field in DeviceInfo[0]. This serves as a flag
; that indicates a usable interface has been found in the current configuration.
; This is needed so we can check for other usable interfaces in the current
; configuration (i.e. composite device), but not try to search in other
; configurations.
mov (DeviceInfo PTR [bx]).bDeviceType, BIOS_DEV_TYPE_KEYBOARD
mov (DeviceInfo PTR [bx]).pDeviceCallback, \
OFFSET cs:USBKBDProcessKeyboardData
mov (DeviceInfo PTR [bx]).pDevDriverPtr, \
OFFSET USBKBDDeviceHeader
; Set keyboard present flag
or bUSBDeviceList, USB_TYPE_KEYBOARD
; If new device is a keyboard, notify keyboard code about the new device
call USBKBDConnectKeyboard ; BX - DevInfo
jz UCK_Done ; Error while connecting
mov (DeviceInfo PTR [bx]).pPollTDPtr, 0
; Start polling the new device's interrupt endpoint.
; BX - DeviceInfo structure
call USBActivateDevicePolling
or (DeviceInfo PTR [bx]).bFlag, (DEV_INFO_VALID_STRUC OR DEV_INFO_DEV_PRESENT)
; Return success
or sp, sp ; Clear zero flag
UCK_Done:
pop ax
ret
USBKBDConfigureKeyboard ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDConnectKeyboard
;
; Description: This routine activates the USB keyboard by sending the
; set idle command and also updates the LED status
;
; Input: BX Pointer to DeviceInfo structure
;
; Output: ZR On error
; NZ On success
;
; Modified: None
;
; Referrals: USBKBDFindUSBKBDeviceTableEntry
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDConnectKeyboard PROC NEAR SYSCALL PUBLIC
push eax
push ebx
push si
; Look for a free slot in the pUSBKBDeviceTable
xor ax, ax
call USBKBDFindUSBKBDeviceTableEntry
jz UHCK_Error
mov WORD PTR [si], bx ; Store the device info
; Send the HID SET_IDLE request
; wValue = 0 (Indefinite) - Soft Model Keyboard needs this modification
; Also Windows use this value and it works for all the keyboards
; BX - DeviceInfo
mov eax, (HID_RQ_SET_IDLE SHL 16)
movzx ebx, bx ; Clear EBX+
call USBIssueControlTransferWithoutData
jz UHCK_Error
; Send the set protocol command
; wValue = 0 (Boot protocol)
mov eax, (HID_RQ_SET_PROTOCOL SHL 16)
call USBIssueControlTransferWithoutData
jz UHCK_Error
; Send device wakeup command to the keyboard
mov eax, (USB_RQ_SET_FEATURE SHL 16) + USB_FSEL_DEV_REMOTE_WAKEUP
call USBIssueControlTransferWithoutData
;(USB004)>
;Don't treat set RemoteWakeUp feature failure as an error,
;Because some HID device might not support this feature.
;This feature could be check in configuration descriptor's bmAttributes[5].
;X jz UHCK_Error
;<(USB004)
; Update the LED status on USB keyboard
call USBKB_LEDOn
; Clear ZR flag
or sp, sp
jmp SHORT UHCK_Exit
UHCK_Error:
mov ax, USB_ERR_KBCONNECT_FAILED
call USBLogError
cmp sp, sp ; Set ZR flag
UHCK_Exit:
pop si
pop ebx
pop eax
ret
USBKBDConnectKeyboard ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDDisconnectKeyboard
;
; Description: This routine disconnects the keyboard by freeing
; the USB keyboard device table entry
;
; Input: BX Pointer to DeviceInfo structure
;
; Output: ZR On error
; NZ On success
;
; Modified: None
;
; Referrals: USBKBDFindUSBKBDeviceTableEntry
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDDisconnectKeyboard PROC NEAR SYSCALL
push ax
push si
and (DeviceInfo PTR [bx]).bFlag, NOT (DEV_INFO_VALID_STRUC OR DEV_INFO_DEV_PRESENT)
; Look for the matching entry
mov ax, bx
call USBKBDFindUSBKBDeviceTableEntry ; SI - return value
jz UHDK_Error
mov WORD PTR [si], 0 ; Free the entry
; Return success. Clear ZR flag
or sp, sp
jmp SHORT UHDK_Exit
UHDK_Error:
; Log Error
mov ax, USB_ERR_KBCONNECT_FAILED
call USBLogError
; Indicate error set ZR flag
cmp sp, sp
UHDK_Exit:
pop si
pop ax
ret
USBKBDDisconnectKeyboard ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDProcessKeyboardData
;
; Description: This routine is called with USB keyboard report data. This
; routine handles the translation of USB keyboard data
; into PS/2 keyboard data, and makes the PS/2 data available
; to software using ports 60/64h by communicating with
; PS/2 keyboard controller.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -