📄 usbkbd.asm
字号:
;
; Input: SI Pointer to HCStruc
; BX Pointer to device information structure
; DI Pointer to the data buffer
;
; Output: Nothing
;
; Modified: Nothing
;
; Notes: TD's control status field has the packet length (0 based).
; It could be one of three values 0,1 or 7 indicating packet
; lengths of 1, 2 & 8 repectively.
; The format of 8 byte data packet is as follow:
; Byte Description
; -----------------------------------------------------------
; 0 Modifier key (like shift, cntr & LED status)
; 1 Reserved
; 2 Keycode of 1st key pressed
; 3 Keycode of 2nd key pressed
; 4 Keycode of 3rd key pressed
; 5 Keycode of 4th key pressed
; 6 Keycode of 5th key pressed
; 7 Keycode of 6th key pressed
; -----------------------------------------------------------
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDProcessKeyboardData PROC NEAR SYSCALL PUBLIC USES AX BX CX SI DI
; Save the device info pointer for later use
mov SavedHCStrucPtr, si
; SI HCStruc
; BX Device Info
; DI Pointer to data buffer
call USBKB_Scanner
; Update the LED status
mov al, 0FFh
call USBKB_UpdateLEDState
ret
USBKBDProcessKeyboardData ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDPeriodicInterruptHandler
;
; Description: This routine is called every 16ms and is used to send
; the characters read from USB keyboard to the keyboard
; controller for legacy operation. Also this function updates
; the keyboard LED status
;
; Input: SI Pointer to the HCStruc structure
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDPeriodicInterruptHandler PROC NEAR SYSCALL PUBLIC USES BX DX DI
; Save the HCStruc pointer for later use
mov SavedHCStrucPtr, si
; Update the LED status
xor al, al
call USBKB_UpdateLEDState
; Check for break code generation
mov al, bBreakCodeDeviceID
or al, al ; Check for break code generation
jz UHPIH_Continue
mov ah, 0
UHPIH_ContConversion:
inc ah ; Form device id (1,2,3,4,5,6,7,8)
shr al, 1
jnc UHPIH_ContConversion
mov dl, ah
; Get the corresponding device info structure
call USBGetDeviceInfoFromDevAddr ; DL - Device address
mov bx, ax
mov di, OFFSET pKBInputBuffer ; Scratch to generate break code
mov DWORD PTR ds:[di], 0
mov DWORD PTR ds:[di+4], 0
; Generate break code
; BX Device info pointer
; SI HCStruc pointer
; DI Pointer to the keyboard buffer buffer
call USBKB_Scanner
UHPIH_Continue:
; Check and send KBC data
INVOKE USBKBC_SendKBCData
UPIH_Exit:
ret
USBKBDPeriodicInterruptHandler ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBDFindUSBKBDeviceTableEntry
;
; Description: This routine searches for the HID table entry which matches
; the provided device info structure
;
; Input: AX Pointer to DeviceInfo structure
;
; Output: NZ Matching HID table structure found
; SI Matching HID table structure
; ZR 0 on error
;
; Modified: SI
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBDFindUSBKBDeviceTableEntry PROC NEAR SYSCALL
push cx
mov cx, MKF_HID_DEVICE_LIMIT
mov si, OFFSET pUSBKBDeviceTable
UHFHTE_CheckNextEntry:
cmp WORD PTR [si], ax
je UHFHTE_Found
add si, 2
loop UHFHTE_CheckNextEntry
cmp sp, sp ; Set zero flag
jmp SHORT UHFHTE_Exit
UHFHTE_Found:
or sp, sp ; Clear zero flag
UHFHTE_Exit:
pop cx
ret
USBKBDFindUSBKBDeviceTableEntry ENDP
;----------------------------------------------------------------------------
; END OF ROUTINES
;----------------------------------------------------------------------------
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_Scanner
;
; Description: This routine converts the USB keyboard input data into
; IBM PC format scan code
;
; Input: BX Pointer to the device info. structure
; DI Pointer to the 8byte USB keyboard data
;
; Output: Nothing
;
; Modified: Nothing
;
; Notes: The format of the 8byte USB keyboard data is as follows:
;----------------------------------------------------------------------------
; Byte Description
;----------------------------------------------------------------------------
; Byte 0 Contains modifier key bits like SHIFT, CTRL, ALT etc
; Byte 1 Reserved
; Byte 2 - 7 Keycode (1-6) of the keys pressed
;----------------------------------------------------------------------------
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_Scanner PROC NEAR SYSCALL PUBLIC USES AX BX CX SI DI ES
LOCAL bKeyCode:BYTE, wWorkOffset:WORD
; Set ES
push ds
pop es
mov si, di
mov ah, (DeviceInfo PTR [bx]).bDeviceAddress
; Convert the device address (1,2,3 .. 8) into
; device ID bit pattern (001h, 002h, 004h .. 080h)
; AH - Device Address
mov al, 80h
UKS_CheckNextID:
rol al, 1
dec ah
jnz UKS_CheckNextID
mov bCurrentDeviceID, al ; Save current device ID
; The 8 byte USB keyboard data is first copied into the input buffer
; for processing. Modifier bits are expanded into bytes.
; Convert modifier key bits to key code bytes. If bit 0 is set output
; 0E0h, 0E1h for bit 1 and so on.
mov di, OFFSET pKBInputBuffer
mov cx, 8 ; Number of bits to process
lodsb ; Load modifier byte
mov ah, 0E0h ; First modifier byte
xchg ah, al ; AL = 0E0h
UKS_CheckNextModBit:
shr ah, 1
jnc UKS_ModKeyNotPressed
; Modifier key pressed. Send appropriate byte to the input buffer
stosb
UKS_ModKeyNotPressed:
inc al
loop UKS_CheckNextModBit
; Discard the reserved byte from the USB KB input data stream
lodsb
; Process the remaining 6 input bytes
mov cx, 6
UKS_ProcessNextByte:
; Get next byte
lodsb
; Check whether it has valid data, if not skip it
or al, al
jz UKS_SkipCurrentByte
; Check whether the input is overrun. Overrun condition occurs if more than
; 6 keys are pressed at a same time. In that case, USB KB sends 01h in all
; its 6 key code bytes
cmp al, 01h ; Keyboard error roll over (overrun) ?
jne UKS_StoreData ; No. Put the data byte into the buffer
; Check the space availability for the overrun code in the character buffer
; Overrun code needs 1 byte (0+1)
xor al, al
call USBKBC_CheckCharacterBufferFull
jz UKS_Exit ; Buffer full, Exit.
mov al, 0FFh ; Scan code set 2 & 3 overrun code
IF MKF_USB_KBC_EMULATION
; The following routine returns overrun code depending upon the scan code
; set chosen. This facility is available only when 60/64h port trapping
; is enabled. Otherwise the scan code set is locked to set 2.
call USBTrap_GetOverrunCode
ENDIF
call USBKBC_SendToCharacterBuffer ; Data in AL
; Invalidate the last key code processed data
mov bLastUSBKeyCode, 000h
jmp UKS_Exit
UKS_StoreData:
stosb
UKS_SkipCurrentByte:
loop UKS_ProcessNextByte
; Null terminate the input buffer
xor al, al
stosb ; Null terminated
; Check for break code generation condition
mov cx, di
mov di, OFFSET pKBInputBuffer
sub cx, di ; CX - Length of the buffer
xor al, al
repz scasb
jnz UKS_KeyCodePresent ; Key is pressed in the keyboard
; No key pressed. Set flags to generate break code
mov al,bCurrentDeviceID
or bBreakCodeDeviceID, al ; set breakcode generation flag
UKS_KeyCodePresent:
mov si, OFFSET pKBInputBuffer
UKS_KeyCodeGenerateLoop:
lodsb
; Save the keycode in the local variable
mov bKeyCode, al
; Check end of the list
cmp bKeyCode, 0
je UKS_CheckBreakCodeGen ; EOL reached, check break code
; Get scan code buffer size
mov di, OFFSET pKBCScanCodeBufferStart
mov cx, pKBCScanCodeBufferPtr
sub cx, di
; Is scan code buffer is empty ?
jcxz UKS_ScanCodeBufEmpty ; Yes.
; Check whether the scan code buffer already have this key value
repnz scasb
jz UKS_AlreadyInBuffer ; Yes found.
; Check whether end of scan code buffer reached
cmp di, OFFSET pKBCScanCodeBufferEnd
jae UKS_CheckBreakCodeGen ; Yes buffer full ! Check break code.
UKS_ScanCodeBufEmpty:
; The key code is not in the buffer and also the buffer is not full. So
; generate the make code for the newly pressed key.
INVOKE USBKB_GenerateScanCode, USB_GEN_MAKE_CODE, bKeyCode, 0
mov bLastUSBKeyCode, al
mov BYTE PTR [di], al ; Put in scan code buffer
; Get the index
sub di, OFFSET pKBCScanCodeBufferStart
; Store the device ID
add di, OFFSET pKBCDeviceIDBufferStart
mov al, bCurrentDeviceID
mov BYTE PTR [di], al ; Store device ID
; Get the index
sub di, OFFSET pKBCDeviceIDBufferStart
; Store the shift key status
add di, OFFSET pKBCShiftKeyStatusBufferStart
mov al, bUSBKBShiftKeyStatus
mov BYTE PTR [di], al ; Store bUSBKBShiftKeyStatus info
; Update pointer
inc pKBCScanCodeBufferPtr
; Check and load typematic rate setting
mov ax, wUSBKBC_StatusFlag
and ax, KBC_TYPE_DELAY_BIT_MASK
shr ax, KBC_TYPE_DELAY_BIT_SHIFT
push bx
mov bx, ax
movzx ax, BYTE PTR [bx + cs:pTypematicRateDelayTable]
pop bx
mov wRepeatRate, ax
mov wRepeatCounter, 0
jmp UKS_KeyCodeGenerateLoop ; Continue
UKS_AlreadyInBuffer:
; Update pointer
dec di
; Get Index
sub di, OFFSET pKBCScanCodeBufferStart
; Save current device id
add di, OFFSET pKBCDeviceIDBufferStart
mov al, bCurrentDeviceID
or BYTE PTR [di], al ; Store device ID
jmp UKS_KeyCodeGenerateLoop ; Continue
UKS_CheckBreakCodeGen:
; SI - pKBInputBuffer
; Check for break code generation
; Update pointer
dec si
; Get index
sub si, OFFSET pKBInputBuffer
mov cx, si
mov si, OFFSET pKBCScanCodeBufferStart
UKS_ProcessNextCharacter:
cmp si, pKBCScanCodeBufferPtr
jae UKS_BreakCodeGenCompleted ; Breakcode generation over
; Get next input character
lodsb
mov di, OFFSET pKBInputBuffer
jcxz UKS_EndOfBufferReached
push cx
repnz scasb
pop cx
jz UKS_ProcessNextCharacter ; Found, continue
UKS_EndOfBufferReached:
; Update pointer
mov di, si
dec di
; Get Index
sub di, OFFSET pKBCScanCodeBufferstart
; Save the index
mov wWorkOffset, di
; Clear device ID
add di, OFFSET pKBCDeviceIDBufferStart
mov al, bCurrentDeviceID
not al
and BYTE PTR [di], al ; Clear device ID
jnz UKS_ProcessNextCharacter ; Continue
; Get Index
sub di, OFFSET pKBCDeviceIDBufferStart
; Get shift key status from the buffer
add di, OFFSET pKBCShiftKeyStatusBufferStart
mov al, BYTE PTR [di]
xchg al, bUSBKBShiftKeyStatus ; Modify bUSBKBShiftKeyStatus
; for break code generation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -