📄 usbkbd.asm
字号:
mov BYTE PTR [di], al
dec si
INVOKE USBKB_GenerateScanCode, USB_GEN_BREAK_CODE, BYTE PTR [si],
wWorkOffset
; Restore shift key status
mov al, BYTE PTR [di]
xchg al, bUSBKBShiftKeyStatus ; Restore bUSBKBShiftKeyStatus
mov BYTE PTR [di], al
jz UKS_Exit ; Character buffer full, exit
mov al, BYTE PTR [si]
INVOKE USBKB_DiscardCharacter, di
; Update pointer
dec pKBCScanCodeBufferPtr
; Stop auto repeat
xor bLastUSBKeyCode, al
jz UKS_Continue
xor bLastUSBKeyCode, al
UKS_Continue:
jmp UKS_ProcessNextCharacter ; Continue
UKS_BreakCodeGenCompleted:
mov al, bCurrentDeviceID
not al
and bBreakCodeDeviceID, al ; Clear breakcode flag
UKS_Exit:
ret
USBKB_Scanner ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_ConvertUSBKeyCodeToScanCodeSet2
;
; Description: This routine converts the USB keycode into scan code set
; 2 scan code. Conversion is accomplished using a static table.
;
; Input: bKeyCode USB Key code
;
; Output: AL Set 2 scan code for the key
;
; Modified: AX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_ConvertUSBKeyCodeToScanCodeSet2 PROC NEAR C USES BX, bKeyCode:BYTE
mov al, bKeyCode
mov bx, OFFSET cs:pUSBKeyCodeToScanCodeSet2Table
db 2eh ; CS:
xlat
ret
USBKB_ConvertUSBKeyCodeToScanCodeSet2 ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_CheckModifierKeyPress
;
; Description: This routine checks whether any of the modifier keys, like
; shift, control or alternate keys, are pressed
;
; Input: bScanCode Scan code set 2 scan code
;
; Output: AX 0 None of the modifier keys are pressed
; AX Modifier key is pressed
; AH, AL = Modifier key identifier
;
; Modified: AX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_CheckModifierKeyPress PROC NEAR C bScanCode:BYTE
; Clear the output register
xor ax, ax
; Check for left shift key status
cmp bScanCode, LEFT_SHIFT
jnz UKCMK_NotLSHIFT
mov ah, KB_LSHIFT_KEY_BIT_MASK
UKCMK_NotLSHIFT:
; Check for right shift key status
cmp bScanCode, RIGHT_SHIFT
jnz UKCMK_NotRSHIFT
mov ah, KB_RSHIFT_KEY_BIT_MASK
UKCMK_NotRSHIFT:
; Check for left control key status
cmp bScanCode, LEFT_CTRL
jnz UKCMK_NotLCTRL
mov ah, KB_CTRL_KEY_BIT_MASK
mov al, RIGHT_CTRL
UKCMK_NotLCTRL:
; Check for right control key status
cmp bScanCode, RIGHT_CTRL
jnz UKCMK_NotRCTRL
mov ah, KB_CTRL_KEY_BIT_MASK
mov al, LEFT_CTRL
UKCMK_NotRCTRL:
; Check for left alternate key status
cmp bScanCode, LEFT_ALT
jnz UKCMK_NotLALT
mov ah, KB_ALT_KEY_BIT_MASK
mov al, RIGHT_ALT
UKCMK_NotLALT:
; Check for right alternate key status
cmp bScanCode, RIGHT_ALT
jnz UKCMK_NotRALT
mov ah, KB_ALT_KEY_BIT_MASK
mov al, LEFT_ALT
UKCMK_NotRALT:
ret
USBKB_CheckModifierKeyPress ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_GenerateScanCode
;
; Description: This routine generates the make/break code for th key
; pressed depending on the make/break flag
;
; Input: bCodeGenFlag Flag indicating whether it is a make or
; break code sequence
; bKeyCode USB key code for the key pressed
; wWorkOffset Offset into the buffers which has the
; code we are processing
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_GenerateScanCode PROC NEAR C PUBLIC USES AX BX CX SI,
bCodeGenFlag:BYTE, bKeyCode:BYTE,
wWorkOffset:WORD
; Set the flag to indicate that make code is generated
and wUSBKBC_StatusFlag, (NOT KBC_MK_BRK_CODE_BIT_MASK)
; Set the approprate flag indicating make or break code sequence
cmp bCodeGenFlag, USB_GEN_MAKE_CODE
je UKGSC_CodeUpdated
; Set the flag to indicate that break code is generated
or wUSBKBC_StatusFlag, (KBC_MK_BRK_CODE_BIT_MASK)
UKGSC_CodeUpdated:
mov al, bKeyCode
; Save the current USB key code
mov bCurrentUSBKeyCode, al
; Convert the USB key code into scan code (Set 2)
INVOKE USBKB_ConvertUSBKeyCodeToScanCodeSet2, al
; Save the make code in the temporary variable
mov bSet2ScanCode, al
; Check whether any modifier keys (ALT, CTRL & SHIFT) are pressed
INVOKE USBKB_CheckModifierKeyPress, al
or ah, ah
jz UKGSC_NonePressed ; No modifier keys are pressed
mov cx, ax
; Check whether it is a make or break code generation
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jz UKGSC_UpdateUSBKBModifierStatus
; Generating the break code, so clear the modifier status.
; Check for left/right shift key press
test ch, (KB_LSHIFT_KEY_BIT_MASK + KB_RSHIFT_KEY_BIT_MASK)
jnz UKGSC_ClearModifierStatus
; Left/right control and/or alternate key is pressed
mov bx, pKBCScanCodeBufferPtr
jmp SHORT UKGSC_CheckBufferEnd
UKGSC_CheckNextByte:
dec bx ; Decrement scan code buffer pointer
INVOKE USBKB_ConvertUSBKeyCodeToScanCodeSet2, (BYTE PTR [bx])
cmp al, cl ; Other alt/control present ?
jz UKGSC_NonePressed ; Yes, do not clear bit
UKGSC_CheckBufferEnd:
cmp bx, OFFSET pKBCScanCodeBufferStart
jnz UKGSC_CheckNextByte
UKGSC_ClearModifierStatus:
not ch
and bUSBKBShiftKeyStatus, ch ; Clear proper bits
mov bx, wWorkOffset
; Position the shift key flag we are processing
add bx, OFFSET pKBCShiftKeyStatusBufferStart
and BYTE PTR [bx], ch ; Clear proper bits
jmp UKGSC_NonePressed
UKGSC_UpdateUSBKBModifierStatus:
or bUSBKBShiftKeyStatus, ch ; Set proper bits
UKGSC_NonePressed:
IF MKF_USB_KBC_EMULATION
call USBTrap_GetCurrentScanCodeSetNumber
cmp al, 03h
jnz UKGSC_ScanCodeSet2_1
call USBTrap_ProcessScanCodeSet3
jmp UKGSC_Exit
ENDIF
UKGSC_ScanCodeSet2_1:
mov al, bSet2ScanCode ; Set 2 scan code
; Check and process pause key
cmp al, PAUSE_KEY
jne UKGSC_NotPauseKey
; It is scan code for pause key. No need to auto repeat pause key and
; also pause key doesn't have break key. Check the above two conditions
; and take care of them properly
; Check whether it is to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jnz UKGSC_Exit ; No break code for pause key
; It is not a break code check whether it is for auto repeat
; Compare old key code and the current key code
mov al, bLastUSBKeyCode
cmp al, bCurrentUSBKeyCode
jnz UKGSC_TwoKeysAreDifferent
; Two keys are different. Check the scan codes.
; Convert key code to set 2 scan code
INVOKE USBKB_ConvertUSBKeyCodeToScanCodeSet2, bLastUSBKeyCode
; Compare the previous scan code and the current scan code
cmp al, bSet2ScanCode
jnz UKGSC_TwoKeysAreDifferent
; Both scan codes are same but pause key doesn't have auto repeat so exit.
or sp, sp
jmp UKGSC_Exit
UKGSC_TwoKeysAreDifferent:
; Pause key can have
; 4 bytes of make code for scan code set 1, if CTRL key is also pressed
; 5 bytes of make code for scan code set 2, if CTRL key is also pressed
; 6 bytes of make code for scan code set 1, if CTRL key is not pressed
; 8 bytes of make code for scan code set 2, if CTRL key is not pressed
; 0 bytes if it is a break code for pause key.
; The above conditions are handled generically using two tables
; pScanCodeLengthTable_4500 & pScanCodeLengthTable_6800. If CTRL key is
; pressed then _4500 table will be used or else _6800 table will be used.
; The logic in the later stage of the code can then choose one entry from
; this table depending on whether it is make or break code and whether
; it is for scan code set 1 or 2.
mov bx, OFFSET cs:pScanCodeLengthTable_4500 ; CTRL + PAUSE
test bUSBKBShiftKeyStatus, KB_CTRL_KEY_BIT_MASK
jnz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_6800 ; PAUSE
jmp SHORT UKGSC_GenerateScanCode
UKGSC_NotPauseKey:
; Check and process print screen key
cmp al, PRINT_SCREEN
jnz UKGSC_NotPrintScreenKey
; Print screen key can have
; 1 bytes of make code for scan code set 1, if pressed with ALT key
; 1 bytes of make code for scan code set 2, if pressed with ALT key
; 1 bytes of break code for scan code set 1, if pressed with ALT key
; 2 bytes of break code for scan code set 2, if pressed with ALT key
; 2 bytes of make code for scan code set 1, if pressed with CTRL+SFT key
; 2 bytes of make code for scan code set 2, if pressed with CTRL+SFT key
; 2 bytes of break code for scan code set 1, if pressed with CTRL+SFT key
; 3 bytes of break code for scan code set 2, if pressed with CTRL+SFT key
; 4 bytes of make code for scan code set 1, if no other key is pressed
; 4 bytes of make code for scan code set 2, if no other key is pressed
; 4 bytes of break code for scan code set 1, if no other key is pressed
; 6 bytes of break code for scan code set 2, if no other key is pressed
; The above conditions are handled generically using three tables
; pScanCodeLengthTable_1112, pScanCodeLengthTable_2223
; & pScanCodeLengthTable_4446. If ALT key is pressed then _1112 table
; will be used. If CTRL key is pressed then _2223 table will be used or
; else _4446 table will be used.
; The logic in the later stage of the code can then choose one entry from
; this table depending on whether it is make or break code and whether
; it is for scan code set 1 or 2.
mov bx, OFFSET cs:pScanCodeLengthTable_1112 ; ALT + PRTSCRN
test bUSBKBShiftKeyStatus, KB_ALT_KEY_BIT_MASK
jnz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_2223 ; CTRL+SHIFT+PRTSCRN
test bUSBKBShiftKeyStatus, (KB_CTRL_KEY_BIT_MASK + \
KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jnz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_4446 ; only PRTSCRN
jmp SHORT UKGSC_GenerateScanCode
UKGSC_NotPrintScreenKey:
; Check for any numeric key pad key press and process it
mov al, bSet2ScanCode
call USBKB_CheckForNumericKeyPadKey
or al, al
jnz UKGSC_NotANumericKeyPadKey ; Not a numeric key pad key
; It is a numeric key pad key. It can have
; 2 bytes of make code for scan code set 1, if no other key is pressed
; 2 bytes of make code for scan code set 2, if no other key is pressed
; 2 bytes of break code for scan code set 1, if no other key is pressed
; 3 bytes of break code for scan code set 2, if no other key is pressed
; 4 bytes of make code for scan code set 1, if NUMLOCK is enabled
; 4 bytes of make code for scan code set 2, if NUMLOCK is enabled
; 4 bytes of break code for scan code set 1, if NUMLOCK is enabled
; 6 bytes of break code for scan code set 2, if NUMLOCK is enabled
; 4 bytes of make code for scan code set 1, if pressed with SHIFT key
; 5 bytes of make code for scan code set 2, if pressed with SHIFT key
; 4 bytes of break code for scan code set 1, if pressed with SHIFT key
; 5 bytes of break code for scan code set 2, if pressed with SHIFT key
; The above conditions are handled generically using three tables
; pScanCodeLengthTable_2223, pScanCodeLengthTable_4446
; & pScanCodeLengthTable_4545. If no other key is pressed then _2223 table
; will be used. If NUMLOCK is enabled then _4446 table will be used or
; else _4545 table will be used.
; The logic in the later stage of the code can then choose one entry from
; this table depending on whether it is make or break code and whether
; it is for scan code set 1 or 2.
mov bx, OFFSET cs:pScanCodeLengthTable_2223 ; Numeric key pad key
test bUSBKBShiftKeyStatus, (KB_NUM_LOCK_BIT_MASK + \
KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_4446 ; NUMKEYPAD + NUMLOCK
test bUSBKBShiftKeyStatus, KB_NUM_LOCK_BIT_MASK
jnz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_4545 ; SHIFT + NUMKEYPAD
jmp SHORT UKGSC_GenerateScanCode
UKGSC_NotANumericKeyPadKey:
; The extended keys will have
; 2 bytes of make code for scan code set 1
; 2 bytes of make code for scan code set 2
; 2 bytes of break code for scan code set 1
; 3 bytes of break code for scan code set 2
mov al, bSet2ScanCode
call USBKB_CheckForExtendedKey
or al, al
mov bx, OFFSET cs:pScanCodeLengthTable_2223 ; Extended key
jz UKGSC_GenerateScanCode ; Extended key
; Check for '/' key and process it
cmp bSet2ScanCode, SLASH_KEY
jne UKGSC_NotSlashKey
; The slash key will normally have
; 2 bytes of make code for scan code set 1
; 2 bytes of make code for scan code set 2
; 2 bytes of break code for scan code set 1
; 3 bytes of break code for scan code set 2
; But if pressed with slash key it has
; 4 bytes of make code for scan code set 1
; 5 bytes of make code for scan code set 2
; 4 bytes of break code for scan code set 1
; 5 bytes of break code for scan code set 2
test bUSBKBShiftKeyStatus, (KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jz UKGSC_GenerateScanCode
mov bx, OFFSET cs:pScanCodeLengthTable_4545 ; SHIFT + '/'
jmp UKGSC_GenerateScanCode
UKGSC_NotSlashKey:
; Regular keys will have
; 1 bytes of make code for scan code set 1
; 1 bytes of make code for scan code set 2
; 1 bytes of break code for scan code set 1
; 2 bytes of break code for scan code set 2
mov bx, OFFSET cs:pScanCodeLengthTable_1112 ; Regular keys
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -