📄 usbkbd.asm
字号:
UKGSC_GenerateScanCode:
; BX - Scan code length table (contains 4 entries)
; Find the appropriate scan code length from the table
; AL = Offset in the table
mov al, 00h ; Assume make code for set 1
; Check whether to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jz UKGSC_MakeCode ; Make code path
; Break code path. Adjust offset by 2
mov al, 02h ; Break code for set 1
UKGSC_MakeCode:
; Check whether to generate set 1 scan code or set 2
test bCCB, CCB_TRANSLATE_SCAN_CODE_BIT_MASK
jnz UKGSC_ConversionNeeded ; Conversion required
; Update offset (for scan code set 2)
inc al
UKGSC_ConversionNeeded:
DB 2Eh ; CS:
xlat
; AL = Length of scan code
; Check for buffer availability
; AL Size of data to be sent
call USBKBC_CheckCharacterBufferFull
jz UKGSC_Exit ; Buffer full! Exit ..
; We had found out correct scan code length to generate and also we
; verified we have enough space. Now generate the scan code
; Get the scan code in AL
mov al, bSet2ScanCode
; Check for pause key
cmp al, PAUSE_KEY
jnz UKGSC_NotPauseKey_1
; Check whether CTRL key is pressed
test bUSBKBShiftKeyStatus, KB_CTRL_KEY_BIT_MASK
jnz UKGSC_CTRLPauseProcessing ; CTRL+PAUSE processing
; Pause key scan code generation
mov al, 0E1h
call USBKBC_SendToCharacterBuffer ; Data in AL
mov bSet2ScanCode, 014h
INVOKE USBKB_GenerateType1MakeCode
mov bSet2ScanCode, 077h
INVOKE USBKB_GenerateType1MakeCode
mov al, 0E1h
call USBKBC_SendToCharacterBuffer ; Data in AL
mov bSet2ScanCode, 014h
INVOKE USBKB_GenerateType1BreakCode
mov bSet2ScanCode, 077h
INVOKE USBKB_GenerateType1BreakCode
jmp UKGSC_Exit
UKGSC_CTRLPauseProcessing:
; Process the CTRL+PAUSE key sequence
mov bSet2ScanCode, 07Eh
INVOKE USBKB_GenerateType2MakeCode
INVOKE USBKB_GenerateType2BreakCode
jmp UKGSC_Exit
UKGSC_NotPauseKey_1:
; Check and process PRNTSCRN key press
cmp al, PRINT_SCREEN
jnz UKGSC_NotPrintScreenKey_1
mov bSet2ScanCode, 07Ch ; PRNSCRN for scan code set 2
; Check for ALT+PRNSCRN key combination
test bUSBKBShiftKeyStatus, KB_ALT_KEY_BIT_MASK
jnz UKGSC_ALT_PRNSCRNKeyProcessing
; Check for CTRL or SHIFT+PRNSCRN key combination
test bUSBKBShiftKeyStatus, (KB_CTRL_KEY_BIT_MASK + \
KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jnz UKGSC_KeyCombination1
UKGSC_KeyCombination2:
; Process PRNSCRN only key processing, NUMLOCK + any numeric key press
; processing at this point. Generate either (E0,12,E0,xx) or
; (E0,F0,xx,E0,F0,12). Where xx bSet2ScanCode
; Check whether to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jnz UKGSC_BreakCodePath ; Break code path
mov al, bSet2ScanCode ; Orginal scan code set 2 code
push ax ; Save original scan code
mov bSet2ScanCode, 012h
INVOKE USBKB_GenerateType2MakeCode
pop ax ; Restore original scan code
mov bSet2ScanCode, al
UKGSC_MakeCodePath:
INVOKE USBKB_GenerateType2MakeCode ; 0E0h, xx
jmp UKGSC_Exit
UKGSC_BreakCodePath:
INVOKE USBKB_GenerateType2BreakCode ; 0E0h, 0F0h, xx
mov bSet2ScanCode, 012h
UKGSC_BreakCodePath1:
INVOKE USBKB_GenerateType2BreakCode ; 0E0h, 0F0h, 012h
jmp UKGSC_Exit
UKGSC_ALT_PRNSCRNKeyProcessing:
; Process ALT+PRNSCRN key press combination
mov bSet2ScanCode, 084h ; Scan code for ALT+PRNSCRN
UKGSC_ProcessRegularKey:
; Regular key press make & break code generation (xx or 0F0h, xx)
; Check whether to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jnz UKGSC_BreakCodePath2 ; Break code path
INVOKE USBKB_GenerateType1MakeCode
jmp UKGSC_Exit
UKGSC_BreakCodePath2:
INVOKE USBKB_GenerateType1BreakCode ; 0F0h, xx
jmp UKGSC_Exit
UKGSC_NotPrintScreenKey_1:
; Check for numeric key pad keys
mov al, bSet2ScanCode
call USBKB_CheckForNumericKeyPadKey
or al, al
jnz UKGSC_NotANumericKeyPadKey1 ; Not inside numeric key pad
and bSet2ScanCode, 07Fh
test bUSBKBShiftKeyStatus, (KB_NUM_LOCK_BIT_MASK + \
KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jz UKGSC_KeyCombination1 ; (E0,xx)(E0,F0,xx)
test bUSBKBShiftKeyStatus, KB_NUM_LOCK_BIT_MASK
jnz UKGSC_KeyCombination2 ; (E0,12,E0,xx)(E0,F0,xx,E0,F0,12)
UKGSC_KeyCombination3:
; The following code will generate scan code for SHIFT+Numeric key pad
; key combination. It will generate one of the following sequence
; (0E0h, 0F0h, 012H or 059h, 0E0h, xx) or
; (0E0h, 0F0h, xx, 0E0h, 012H or 059h)
; Check whether to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jnz UKGSC_BreakCodePath3 ; break code
mov al, bSet2ScanCode ; Save current scan code (xx)
push ax
test bUSBKBShiftKeyStatus, KB_LSHIFT_KEY_BIT_MASK
jz UKGSC_Cont0
mov bSet2ScanCode, 012h
INVOKE USBKB_GenerateType2BreakCode ; 0E0h, 0F0h, 012h
UKGSC_Cont0:
test bUSBKBShiftKeyStatus, KB_RSHIFT_KEY_BIT_MASK
jz UKGSC_Cont1
mov bSet2ScanCode, 059h
INVOKE USBKB_GenerateType2BreakCode ; 0E0h, 0F0h, 059h
UKGSC_Cont1:
pop ax
mov bSet2ScanCode, al ; Restore current code (xx)
INVOKE USBKB_GenerateType2MakeCode ; 0E0h, xx
jmp SHORT UKGSC_Exit
UKGSC_BreakCodePath3:
INVOKE USBKB_GenerateType2BreakCode ; 0E0h, 0F0h, xx
test bUSBKBShiftKeyStatus, KB_RSHIFT_KEY_BIT_MASK
jz UKGSC_Cont2
mov bSet2ScanCode, 059h
INVOKE USBKB_GenerateType2MakeCode ; 0E0h, 059h
UKGSC_Cont2:
test bUSBKBShiftKeyStatus, KB_LSHIFT_KEY_BIT_MASK
jz UKGSC_Cont3
mov bSet2ScanCode, 012h
INVOKE USBKB_GenerateType2MakeCode ; 0E0h, 012h
UKGSC_Cont3:
jmp SHORT UKGSC_Exit
UKGSC_NotANumericKeyPadKey1:
; Check and process extended key press
mov al, bSet2ScanCode
call USBKB_CheckForExtendedKey
or al, al
jnz UKGSC_NotAnExtendedKey ; Not inside extended key
and bSet2ScanCode, 07Fh
UKGSC_KeyCombination1:
; Following code processes the following key combinations:
; Extended key make & break code generation
; CTRL or SHIFT + PRNSCRN key combination
; Numeric key pad key code generation
; One of the following sequence will be generated (0E0h, xx) or
; (0E0h, 0F0h, xx)
; Check whether to generate make or break code
test wUSBKBC_StatusFlag, KBC_MK_BRK_CODE_BIT_MASK
jnz UKGSC_BreakCodePath1 ; Break code
jmp UKGSC_MakeCodePath ; Make code
UKGSC_NotAnExtendedKey:
; Check and process '/' key
cmp bSet2ScanCode, SLASH_KEY
jnz UKGSC_ProcessRegularKey ; Regular key press
; Generate make or break code for '/' key
mov bSet2ScanCode, 04Ah ; '/' key scan code set 2
test bUSBKBShiftKeyStatus, (KB_LSHIFT_KEY_BIT_MASK + \
KB_RSHIFT_KEY_BIT_MASK)
jz UKGSC_KeyCombination1 ; (E0,xx)(E0,F0,xx)
jmp UKGSC_KeyCombination3 ; (E0,F0,12/59,E0,XX)(E0,F0,XX,E0,12/59)
UKGSC_Exit:
ret
USBKB_GenerateScanCode ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBC_CheckCharacterBufferFull
;
; Description: This routine checks whether the character buffer can hold
; 'N'+1 character
;
; Input: AL Space needed in the buffer (in characters)
;
; Output: ZR If buffer is full
; NZ If enough space is available
;
; Modified: AL
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBC_CheckCharacterBufferFull PROC NEAR SYSCALL PUBLIC
push bx
mov bx, pKBCCharacterBufferHead
inc al ; One more byte for overrun character
UKCCBF_CheckAvailability:
inc bx
cmp bx, OFFSET pKBCCharacterBufferEnd
jnz UKCCBF_BufferOkay
; Buffer end reached ! Wrap around to the start ..
mov bx, OFFSET pKBCCharacterBufferStart
UKCCBF_BufferOkay:
; Check whether character buffer is full
cmp bx, pKBCCharacterBufferTail
je UKCCBF_Exit ; Yes, buffer full ! (Zero flag set)
; No. Buffer is not full. Check availability for next character
dec al
jnz UKCCBF_CheckAvailability
; Buffer has enough space
; Clear zero flag
or sp, sp
UKCCBF_Exit:
pop bx
ret
USBKBC_CheckCharacterBufferFull ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBC_SendToCharacterBuffer
;
; Description: This routine puts a character into the character buffer.
; Character buffer pointers are also updated
;
; Input: AL Character to be put in the character buffer
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBC_SendToCharacterBuffer PROC NEAR SYSCALL
push ax
push bx
push si
mov bx, pKBCCharacterBufferHead
mov BYTE PTR [bx], al ; Put the character in the buffer
inc bx ; Advance the buffer pointer
; Check whether the buffer end is reached
cmp bx, OFFSET pKBCCharacterBufferEnd
jnz UKSTCB_BufferPtrOkay
; Buffer end reached position the buffer pointer to the start
mov bx, OFFSET pKBCCharacterBufferStart
UKSTCB_BufferPtrOkay:
; Adjust the character buffer head
mov pKBCCharacterBufferHead, bx
; Get the pointer to the HC driver
mov si, SavedHCStrucPtr
mov bx, (HCStruc PTR [si]).pHCDPointer
; Enable the keyboard repeat
call (HCDHEADER PTR cs:[bx]).pHCDEnableKeyRepeat
pop si
pop bx
pop ax
ret
USBKBC_SendToCharacterBuffer ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKBC_GetFromCharacterBuffer
;
; Description: This routine gets a character from the character buffer.
; Character buffer pointers are also updated
;
; Input: Nothing
;
; Output: AL - Character taken from the character buffer
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKBC_GetFromCharacterBuffer PROC NEAR C PUBLIC USES BX
mov bx, pKBCCharacterBufferTail
mov al, BYTE PTR [bx] ; Get character from the buffer
inc bx ; Advance the buffer pointer
; Check for buffer end condition
cmp bx, OFFSET pKBCCharacterBufferEnd
jnz UKGFCB_BufferOkay
; End reached. Wrap around to the start ..
mov bx, OFFSET pKBCCharacterBufferStart
UKGFCB_BufferOkay:
; Update the pointer
mov pKBCCharacterBufferTail, bx
ret
USBKBC_GetFromCharacterBuffer ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_ConvertSet2CodeToSet1Code
;
; Description: Converts the set 2 scan code to set 1 scan code
;
; Input: AL Set 2 scan code
;
; Output: AL Set 1 scan code
;
; Modified: AL
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_ConvertSet2CodeToSet1Code PROC NEAR SYSCALL
push bx
mov bx, OFFSET CS:pStaticSet2ToSet1ScanCode
call USBKB_ConvertScanCodeBetweenCodeSet
pop bx
ret
USBKB_ConvertSet2CodeToSet1Code ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBKB_ConvertScanCodeBetweenCodeSet
;
; Description: Converts the set 2 scan code to set 3/1 scan code
;
; Input: AL Set 2 scan code
; BX Pointer to the code set conversion table
;
; Output: AL - Set 1/3 scan code
;
; Modified: AX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBKB_ConvertScanCodeBetweenCodeSet PROC NEAR SYSCALL
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -