📄 usbkbd.asm
字号:
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;****************************************************************************;
;---------------------------------------;
public ProcessKeyboardData
public ProcessMouseData
public EnableKBCTraps
public Handle60Read
public Handle64Read
public Handle60Write
public Handle64Write
public InitUSBKbDataArea
public PeriodicInterruptHandler
public OneSecondPeriodicHandler
extrn DisablePeriodicInterrupt:near
extrn EnablePeriodicInterrupt :near
extrn write_kb_cntlr_data :near
extrn USBDeviceRequest :near
;---------------------------------------;
include makeflag.equ
include usb.equ
if MKF_USB_UHCI
include uhci.equ
endif
if MKF_USB_OHCI
include ohci.equ
endif
include usbdata.dat
cgroup group _text
_text segment word public 'CODE'
assume cs:cgroup
assume ds:usbdgroup
assume es:usbdgroup
.386
;-------------------------------;
; Called to set keyboard traps ;
; Input: nothing ;
; Destroys: nothing ;
; Output: (CL) ;
; bit 0 set for 60 read trap ;
; bit 1 set for 60 write trap ;
; bit 2 set for 64 read trap ;
; bit 3 set for 64 write trap ;
;-------------------------------;
EnableKBCTraps proc near
ifdef DOS_DEBUG
mov cl,00h
else
; push ax
; extrn q_usb_6460_emulation:abs
; mov al,q_usb_6460_emulation
; db 9ah ; CALL FAR F000:EED5
; dw 0eed5h ; check_cmos_data
; dw 0f000h
; pop ax
; mov cl,00h
; jz ekbt_1
; mov cl,0ah
;ekbt_1:
mov cl,00h
endif
ret
EnableKBCTraps endp
;---------------------------------------;
; ConnectDevice ;
;---------------------------------------;
; This function registers device id. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; (ah) = device type ;
; 01h HID Boot keyboard ;
; 02h HID Boot mouse ;
; (dx) = interface number ;
; ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
ConnectDevice proc near
ifdef DOS_DEBUG
ret
endif
cmp ah,BIOS_DEV_TYPE_KEYBOARD
jne @F
call ConnectKeyboard
ret
@@:
cmp ah,BIOS_DEV_TYPE_MOUSE
jne @F
call ConnectMouse
@@:
ret
ConnectDevice endp
;---------------------------------------;
; ConnectKeyboard ;
;---------------------------------------;
; This function registers keyboard. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; (ah) = device type ;
; (dx) = interface number ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
ConnectKeyboard proc near
ifdef DOS_DEBUG
ret
endif
pusha
mov bl,al ; device id
xor bh,bh
shl bx,1
mov ah,dl ; interface number (dh=0)
mov [bx+device_list],ax
mov ah,00 ; send to endpoint-0
mov bx,0a21h ; set-idle, request type = Interface
;;;; mov cx,0000h ; wValue, (ch)=0 (infinite wait), (255*4 milisec max)
;;;; mov cx,0200h ; wValue, (ch)=2*4 milisec = 8 milisec
mov cx,7d00h ; wValue, (ch)=125*4 milisec = 500 milisec
mov si,0000h ; wLength = 0
if ALPS_KBD_0896
%Out For ALPS Keyboard Only.....Other compliant USB Devices May NOT work !!!!!
else
call USBDeviceRequest
;; Issue Remote Wakeup Freture (Legacy Mode)
mov bx,0300h ;request " set feature", request type
mov cx,1 ;value
sub dx,dx
call USBDeviceRequest
;;; Issue Boot Protocol
;; BH = Request, BL = Request Type
; mov bx,0b21h ; "boot protocol", request type
;; CX = wValue request parameter (meaning varies with each request type) ;
;; DX = wIndex request parameter (meaning varies with each request type) ;
;; SI = wLength request parameter, number of bytes of data to be ;
; mov cx,0 ; value
; sub dx,dx ; index
; sub si,si ; index
; call USBDeviceRequest
endif
call led_on
popa
ret
ConnectKeyboard endp
;---------------------------------------;
; ConnectMouse ;
;---------------------------------------;
; This function registers mouse. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; (ah) = device type ;
; (dx) = interface number ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
ConnectMouse proc near
pusha
;; Issue Remote Wakeup Freture (Legacy Mode)
mov ah,00 ; send to endpoint-0
mov bx,0300h ;request " set feature", request type
mov cx,1 ;value
sub dx,dx
mov si,0000h ; wLength = 0
call USBDeviceRequest
popa
ret
ConnectMouse endp
;---------------------------------------;
; DisconnectDevice ;
;---------------------------------------;
; This function removes device id. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; (ah) = device type ;
; 01h HID Boot keyboard ;
; 02h HID Boot mouse ;
; ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
DisconnectDevice proc near
ifdef DOS_DEBUG
ret
endif
cmp ah,BIOS_DEV_TYPE_KEYBOARD
jne @F
call DisconnectKeyboard
ret
@@:
cmp ah,BIOS_DEV_TYPE_MOUSE
jne @F
call DisconnectMouse
@@:
ret
DisconnectDevice endp
;---------------------------------------;
; DisconnectKeyboard ;
;---------------------------------------;
; This function removes a keyboard. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
DisconnectKeyboard proc near
pusha
mov bl,al ; device id
xor bh,bh
shl bx,1
mov [bx+device_list],000h ; clear device id, interface number
mov ah,al
mov si,offset ip_buff_start
mov ds:dword ptr [si],0
mov ds:dword ptr [si+4],0
call scanner
popa
ret
DisconnectKeyboard endp
;---------------------------------------;
; DisconnectMouse ;
;---------------------------------------;
; This function removes a mouse. ;
; Input: DS = ES = HCD Data Area ;
; (al) = device id. (1/2/3/4/5/6/7/8) ;
; ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
DisconnectMouse proc near
ret
DisconnectMouse endp
;---------------------------------------;
; ProcessKeyboardData ;
;---------------------------------------;--------------------------------------;
; This function is called at regular intervals with USB keyboard report data. ;
; This function handles the translation of USB keyboard data into PS/2 ;
; keyboard data, and makes the PS/2 data available to software using ports ;
; 60/64 to communicate with a PS/2 keyboard. ;
; ;
; Input: DS:DI.TD_Control_Status = packet length - 1 ; 0/1/7 ;
; DS:SI = Offset of 8 byte data packet received from USB keyboard ;
; Byte 0: Modifier keys ;
; Byte 1: Reserved ;
; Byte 2: Keycode of 1st key that is currently pressed ;
; Byte 3: Keycode of 2nd key that is currently pressed ;
; Byte 4: Keycode of 3rd key that is currently pressed ;
; Byte 5: Keycode of 4th key that is currently pressed ;
; Byte 6: Keycode of 5th key that is currently pressed ;
; Byte 7: Keycode of 6th key that is currently pressed ;
; AH = USB device address of the keyboard that supplied the data ;
; (useful if more than one keyboard is active) ;
; CX = 11 bit time stamp value in units of 1ms (count wraps to 0 ;
; after reaching 7FFh) ;
; DS = ES = usbdseg ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
ProcessKeyboardData:
ifdef DOS_DEBUG
ret
endif
if MKF_USB_UHCI
cmp ds:byte ptr (Transfer_Descriptor ptr [di]).TD_Control_Status,1
jz oldkb2 ; 1 = 2 byte format
jb oldkb1 ; 0 = 1 byte format
endif
jmp scanner ; 7 = 8 byte format
oldkb2:
pusha
lodsb ; (al) bit 7..4 = upper 4 bit
shl ax,4
lodsb ; (al) bit 7..4 = lower 4 bit
shl ax,4 ; (ah) = data
jmp oldkb12
oldkb1:
pusha
mov ah,[si] ; (ah) = data
oldkb12:
mov al,1
call check_cbfull
jz pkd_1 ; buffer full, exit
mov al,ah
call put_char_buffer
pkd_1:
popa
ret
;---------------------------------------;
; OneSecondPeriodicHandler ;
;---------------------------------------;
; This function called every 1sec. ;
; Input: DS = ES = HCD Data Area ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
OneSecondPeriodicHandler:
ifdef DOS_DEBUG
ret
endif
test kbmsflag,80h
jnz osph_5 ; already inside LED_ON routine, exit
pusha
test flag_byte_1,80h ; 1=64/60 emulation active
jnz osph_0
push ds
xor ax,ax
mov ds,ax
mov al,ds:[417h] ; Caps-lock, Num-lock, Scroll-lock (IBM)
pop ds
mov ah,flag_byte
and ax,7070h
shr al,1 ; Scroll-lock, Caps-lock, Num-lock (USB)
test al,08h
jz osph_1
xor al,48h
jmp short osph_1
osph_0:
mov al,flag_byte_1
mov ah,flag_byte
and ax,7070h
osph_1:
cmp al,ah
jz osph_2
and flag_byte,(not caps_lock_bitx+num_lock_bitx+scroll_lock_bitx)
or flag_byte,al
or kbmsflag,80h ; LED_ON active
call led_on
and kbmsflag,7fh ; LED_ON over
osph_2:
;-------------------------------;
mov al,bk_device_id ; check for breakcode generation
or al,al
jz osph_4 ; do not generate break code
mov ah,0
osph_3:
inc ah ; form device id (1,2,3,4,5,6,7,8)
shr al,1
jnc osph_3
mov si,offset ip_buff_start ; scratch to generate break code
mov ds:dword ptr [si],0
mov ds:dword ptr [si+4],0
call scanner ; generate break code
osph_4:
popa
osph_5:
ret
;---------------------------------------;
; PeriodicInterruptHandler ;
;---------------------------------------;
; This function called every 16 milisec.;
; Input: DS = ES = HCD Data Area ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
PeriodicInterruptHandler:
call OneSecondPeriodicHandler
call OutKeyboardData
ret
;---------------------------------------;
; OutKeyboardData ;
;---------------------------------------;
; This function called every 2 milisec ;
; by periodic interrupt handler ;
; Send data to system, generate IRQ1. ;
; Input: DS = ES = HCD Data Area ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
OutKeyboardData:
ifdef DOS_DEBUG
ret
endif
pusha
call check_auto_repeat
cmp flag_60,0000h
jnz klp_04 ; 64/60 sequence in progress, exit
mov al,kbmsflag
and al,30h ; 00/10 => MS..KB
cmp al,20h ; 20 => KB..MS
jnz klp_10 ; check MS... then KB...
;------ check KB... then MS...
mov ax,ch_buff_head
cmp ax,ch_buff_tail
mov ah,0d2h ; KB data
jnz klp_00 ; character found
mov ax,ms_buff_head
cmp ax,ms_buff_tail
mov ah,0d3h ; MS data
jnz klp_00 ; character found
jmp short klp_11
klp_10:
;------ check MS... then KB...
mov ax,ms_buff_head
cmp ax,ms_buff_tail
mov ah,0d3h ; MS data
jnz klp_00 ; character found
mov ax,ch_buff_head
cmp ax,ch_buff_tail
mov ah,0d2h ; KB data
jnz klp_00 ; character found
klp_11:
cmp last_scan_index,00h
jnz klp_04 ; auto repeat, enable periodic interrupt
mov ax,sc_buff_ptr
sub ax,offset sc_buff_start
jnz klp_04 ; scanner buffer not empty
call DisablePeriodicInterrupt
jmp klp_06 ; exit
;-------------------------------;
klp_00:
mov al,0bh
out 20h,al
pusha
popa
in al,20h
test al,02h
jnz klp_04 ; inside IRQ1
mov al,0bh
out 0a0h,al
pusha
popa
in al,0a0h
test al,10h
jnz klp_04 ; inside IRQ12
klp_00x:
in al,64h
test al,2
jnz klp_00x
; one of these commands must work
;;;; mov al,0d1h ; write output port command
;;;; mov al,0d4h ; write to aux port command
mov al,60h ; write command byte command
out 64h,al
jcxz $+2
klp_05:
in al,64h
test al,1 ; op buffer full ?
jnz klp_01 ; yes
test al,2 ; ip buffer free ?
jnz klp_05 ; no
;-------------------------------;
add kbmsflag,10h
mov al,kbmsflag
and al,30h ; 00/10 = first check MS then KB
cmp al,30h ; 20 = first check KB then mouse
jnz klp_05y
and kbmsflag,0cfh ; reset sequence flag
klp_05y:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -