📄 usbkbd.asm
字号:
;-------------------------------;
mov al,20h
call out_to_64 ; send command to 8042
call in_from_60 ; read data from 8042
mov ccb,al
test ah,1
jnz klp_05x ; MS data
test al,10h
jnz klp_04 ; keyboard disabled
call get_char_buffer
xchg al,ah
call sis_write_kb_cntlr_data
jmp klp_04
;-------------------------------;
klp_05x:
test kbmsflag,08h
jz klp_07 ; USB mouse data buffer has data
test al,20h
jz klp_04x ; mouse enabled
mov ms_buff_head,offset ms_buff_start
mov ms_buff_tail,offset ms_buff_start
jmp klp_04
klp_04x:
push ds
push ax
xor ax,ax
mov ds,ax
mov ds,ds:[40eh]
mov al,ds:[26h]
and al,7
pop ax
pop ds
jnz klp_04 ; PS/2 mouse data packet not over
mov al,0a7h
call out_to_64 ; send command to 8042
klp_07:
call get_mouse_buffer
xchg al,ah
call sis_write_kb_cntlr_data
and kbmsflag,0f7h ; first byte over
push ax
mov ax,ms_buff_head
cmp ax,ms_buff_tail
pop ax
jnz klp_04
jmp klp_03
klp_01:
test al,20h ; 0/1 = kb/mouse data
mov al,0aeh ; enable keyboard interface
jz klp_02
klp_03:
test kbmsflag,08h
mov al,0a8h ; enable mouse interface
jnz klp_02
push ax
mov ax,ms_buff_head
cmp ax,ms_buff_tail
pop ax
jz klp_02
mov al,0a7h ; disable mouse interface
klp_02:
call out_to_64 ; send command to 8042
klp_04:
call EnablePeriodicInterrupt
klp_06:
popa
ret
;---------------------------------------;
check_auto_repeat:
cmp last_scan_index,00h
jz car_1 ; no auto repeat
inc repeat_counter
mov ax,repeat_counter
cmp ax,repeat_rate
jb car_1
mov al,typematic_rate
and ax,1fh ; bit 4..0 = typematic rate
shl ax,1
mov bx,ax
mov ax,[bx+cgroup:tr_table+orgbase]
mov repeat_rate,ax
mov repeat_counter,0000h
mov ax,ch_buff_head
cmp ax,ch_buff_tail
jnz car_1 ; character buffer not empty
mov al,last_scan_index
call generate_make_code
car_1:
ret
;---------------------------------------;
; InitUSBKbDataArea ;
;---------------------------------------;
; called once to init USB KB data area ;
; Input: DS = ES = HCD Data Area ;
; Output: Nothing ;
; Destroys: Nothing ;
;---------------------------------------;
InitUSBKbDataArea:
pusha
mov di,offset host_kb_data_start
mov cx,offset host_kb_data_end - offset host_kb_data_start
xor al,al
rep stosb ; clear host keyboard data area
mov flag_8042,0ffh ; assume 8042 present
call init_typematic_scan_3 ; init typematic/rate, scan-3 table
call init_scan_char_buff ; init scanner/character buffer
mov scanner_flag,02h ; scan code set 2
mov ms_buff_head,offset ms_buff_start
mov ms_buff_tail,offset ms_buff_start
;-------------------------------;
; restore LED status ;
;-------------------------------;
test flag_byte_1,80h ; 1=64/60 emulation active
jnz ikbd_0
push ds
xor ax,ax
mov ds,ax
mov al,ds:[417h] ; Caps-lock, Num-lock, Scroll-lock (IBM)
pop ds
and al,70h
shr al,1 ; Scroll-lock, Caps-lock, Num-lock (USB)
test al,08h
jz ikbd_1
xor al,48h
jmp short ikbd_1
ikbd_0:
mov al,flag_byte_1
and al,70h
ikbd_1:
mov flag_byte,al
;-------------------------------;
; restore command byte ;
;-------------------------------;
ikbd_2:
in al,64h
test al,2
jnz ikbd_2
; 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
call out_to_64 ; send command to 8042
in al,64h
mov ah,al ; save status
test al,1
jz ikbd_3 ; no data
in al,60h
ikbd_3:
push ax
mov al,20h
call out_to_64 ; send command to 8042
call in_from_60 ; read data from 8042
mov ccb,al
pop ax
xchg al,ah
test al,1
jz ikbd_4 ; no data exit
test al,20h
mov al,0d2h ; kb data
jz ikbd_5
mov al,0d3h ; ms data
ikbd_5:
call sis_write_kb_cntlr_data
ikbd_4:
popa
ret
sis_write_kb_cntlr_data:
push cx
extrn pm_fixed_delay:near
mov cx,160h
call pm_fixed_delay
pop cx
call write_kb_cntlr_data
ret
;-------------------------------;
; ProcessMouseData ;
;------------------------------------------------------------------------------;
; This function is called at regular intervals with USB mouse report data. ;
; This function handles the translation of USB mouse data into PS/2 ;
; mouse data, and makes the PS/2 data available to software using ports ;
; 60/64 to communicate with a PS/2 mouse. ;
; ;
; Input: DS:SI = Offset of 3 byte data packet received from USB mouse ;
; Byte 0: Modifier keys ;
; Bit 0: If set, button 1 is presseed ;
; Bit 1: If set, button 2 is presseed ;
; Bit 2: If set, button 3 is presseed ;
; Bit 3-7: Reserved ;
; Byte 1: X displacement ;
; Byte 2: Y displacement ;
; AH = USB device address of the mouse that supplied the data ;
; (useful if more than one mouse 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 ;
;------------------------------------------------------------------------------;
ProcessMouseData proc near
ifdef DOS_DEBUG
ret
endif
push ds
push 40h
pop ds
test byte ptr ds:[10h],04h
pop ds
jnz pmd_6 ; mouse present
pmd_1:
ret
pmd_6:
test flag_byte_1,80h ; 1=64/60 emulation active
jz pmd_2
test kbmsflag,40h
jz pmd_1 ; mouse disabled
pmd_2:
pusha
mov ax,ms_buff_head
cmp ax,ms_buff_tail
jnz pmd_5 ; mouse data buffer has data
mov al,[si] ; status
mov cx,[si+1] ; X,Y
neg ch ; Y sign is opposite in USB than PS/2
and al,07h ; bit2,1,0 = middle,right,left button
or al,08h ; bit-3 always 1
;-------------------------------;
; enable this code to scale X,Y ;
;-------------------------------;
;;;; push ax
;;;; mov al,2 ; X*2
;;;; mul cl
;;;; mov cl,al
;;;; mov al,2 ; Y*2
;;;; mul ch
;;;; mov ch,al
;;;; pop ax
;-------------------------------;
or cl,cl
jns pmd_3
or al,10h ; negative X
pmd_3:
or ch,ch
jns pmd_4
or al,20h ; negative Y
pmd_4:
call put_mouse_buffer
mov al,cl
call put_mouse_buffer
mov al,ch
call put_mouse_buffer
or kbmsflag,08h ; mouse data ready
pmd_5:
popa
jmp OutKeyboardData
ProcessMouseData endp
;-------------------------------;
; PUT MOUSE BUFFER ;
;-------------------------------;
; register used (none). ;
; input: ;
; (al) = character ;
; output: ;
; none ;
; mouse buffer ptr updated ;
;-------------------------------;
put_mouse_buffer:
push bx
mov bx,ms_buff_head
mov [bx],al ; put character in buffer
inc bx ; advance buffer pointer
cmp bx,offset ms_buff_end
jnz pmb_1 ; if buff end, back to buff start
mov bx,offset ms_buff_start
pmb_1:
mov ms_buff_head,bx ; advance head pointer
pop bx
ret
;-------------------------------;
; GET MOUSE BUFFER ;
;-------------------------------;
; register used (none). ;
; input: ;
; none. ;
; output: ;
; (al) = character. ;
; mouse buffer ptr updated ;
;-------------------------------;
get_mouse_buffer:
push bx
mov bx,ms_buff_tail
mov al,0
xchg al,[bx] ; get data from mouse buffer
inc bx ; advance buffer tail pointer
cmp bx,offset ms_buff_end
jnz gmb_1 ; if buff end, back to buff start
mov bx,offset ms_buff_start
gmb_1:
mov ms_buff_tail,bx ; advance mouse buffer tail pointer
pop bx
ret
;-------------------------------;
; IN_FROM_60 ;
;-------------------------------;
in_from_60:
i60_2:
in al,64h
test al,1
jz i60_2
in al,60h
ret ; (zf) = 1, not valid data
;-------------------------------;
; OUT_TO_64 ;
;-------------------------------;
out_to_64:
out 64h,al
push ax
ot64_2:
in al,64h
test al,2
jnz ot64_2
pop ax
ret
;-------------------------------;
; OUT_TO_60 ;
;-------------------------------;
out_to_60:
out 60h,al
push ax
ot60_2:
in al,64h
test al,2
jnz ot60_2
pop ax
ret
;-------------------------------;
; LED_ON ;
;-------------------------------;
led_on:
mov al,flag_byte
push ax ; save flag_byte
shr al,4 ; bit 2,1,0 = Scroll, Caps, Num
and al,07h
mov flag_byte,al
mov cx,(offset device_list_end - offset device_list)/2
mov si,offset device_list
lon_1:
lodsw ; device id.
movzx dx,ah ; (dx) = interface number
or al,al
jz lon_2 ; no device
push cx
push si
mov ah,00 ; send to endpoint-0
mov si,0001h ; wLength, 1 byte LED data length
mov bx,0921h ; set-report, request type = Interface
mov cx,0200h ; wValue, (ch) = "report type" = output
mov di,offset flag_byte
call USBDeviceRequest
pop si
pop cx
lon_2:
loop lon_1
pop ax
mov flag_byte,al ; restore flag_byte
ret
;-------------------------------;
; INIT_TYPEMATIC_SCAN_3 ;
;-------------------------------;
init_typematic_scan_3:
mov typematic_rate,2bh ; 500 milisecond, 10.9 characters/sec
mov di,offset scan_3_table
mov si,offset cgroup:scan_3_table_data+orgbase
mov cx,32
db 2eh ; cs:
rep movsb
ret
;-------------------------------;
; INIT_SCAN_CHAR_BUFF ;
; INIT_CHAR_BUFF ;
;-------------------------------;
init_scan_char_buff:
mov sc_buff_ptr,offset sc_buff_start
mov last_scan_index,00h
and typematic_rate,(not auto_repeat_bitx)
init_char_buff:
mov ch_buff_head,offset ch_buff_start
mov ch_buff_tail,offset ch_buff_start
ret
;---------------------------------------;
; Handle64Read ;
;---------------------------------------;--------------------------------------;
; This trap function is called when any software reads port 64h. ;
; Input: Nothing ;
; Output: AL = Simulated data as if read from port 64h ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
Handle64Read proc near
in al,64h ;Do actual read for now
ret
Handle64Read endp
;---------------------------------------;
; Handle60Read ;
;---------------------------------------;--------------------------------------;
; This trap function is called when any software reads port 60h. ;
; Input: Nothing ;
; Output: AL = Simulated data as if read from port 60h ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
Handle60Read proc near
in al,60h ;Do actual read for now
mov port_60_char,al
ret
Handle60Read endp
;---------------------------------------;
; Handle60Write ;
;---------------------------------------;--------------------------------------;
; This trap function is called when any software writes to port 60h. ;
; Input: AL = Data to be written to port 60h ;
; Output: Nothing ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
Handle60Write proc near
pusha
call out_60
popa
ret
Handle60Write endp
;---------------------------------------;
; Handle64Write ;
;---------------------------------------;--------------------------------------;
; This trap function is called when any software writes to port 64h. ;
; Input: AL = Data to be written to port 64h ;
; Output: Nothing ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
Handle64Write proc near
pusha
call out_64
popa
ret
Handle64Write endp
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;-------------------------------;
; KEYBOARD CONTROLLER / SCANNER ;
;-------------------------------;
lalt equ 11h ; left alt code (scan code set-2)
lctl equ 14h ; left control code (scan code set-2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -