⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbkbd.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
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 + -