rendered paste body; **********************************************************
; Name: PS/2 Keyboard & Mouse driver
; Type: Virtual Device Driver
; Autor: Toaster Burger
; Version: 1.00
; **********************************************************
[bits 32]
CPU 386
%define Type_User
%include "interface.asm"
%define Char(number2) number2
%define Param(number) [ebp+16 + 4*(number-1)]
%define Param1 [ebp+16 + 4*0]
%define Param2 [ebp+16 + 4*1]
%define Param3 [ebp+16 + 4*2]
%define Param4 [ebp+16 + 4*3]
%macro ack 0.nolist
ack_test:
in al,60h
cmp al,0FAh
jne ack_test
%endmacro
%macro kb_comm 2.nolist
; %2 = command
; %1 = error label
mov ah,%2
call kbCommand
jc %1
%endmacro
%macro kb_comm_low 2.nolist
; %2 = command
; %1 = error label
mov ah,%2
call kbCommand_low
jc %1
%endmacro
%macro kb_read 1.nolist
; %1 = error label
call kbRead
jc %1
%endmacro
%macro kb_write 2.nolist
; %1 = byte to write
; %2 = error label
mov ah,%2
call kbWrite
jc %1
%endmacro
%macro key_press 1.nolist
; PressedKeys
; bit 0: shift left
; bit 1: ctrl left
; bit 2: alt (unused)
; bit 3: del (unused)
; bit 4: caps lock
; bit 5: ctrl right
; bit 6: ctrl (unused)
; bit 7: shift right
; bit 8: shift (unused)
; for future: test with %if the code and set the unused (alt, ctrl, shift) values
; some definition... take care of it...
%define KeyEvent [ebp-8]
; if key_press(%1) (= key was down and key is now down) then exit
; in order to do not handle typematic codes
test [edx + PressedKeys],dword %1
jz %%continue
cmp KeyEvent,word WM_KEYDOWN
je Keyboard_Handler_Exit
; if here key event is key up, so clear the bit
clear_bit [edx + PressedKeys], %1
jmp %%exit
%%continue:
or [edx + PressedKeys],dword %1
%%exit:
%endmacro
jmp dword initialise
jmp dword Switch_Key_Table
jmp dword Set_Scroll_led
Switch_Key_Table:
; SPI Set_Keyboard_Layout, Table
; Table = "eu" for europe, "us" for american keyboard layout
Enter_System
call Get_address
cmp Param1,dword 'eu'
je Switch_Key_Table_eu
cmp Param1,dword 'us'
je Switch_Key_Table_us
jmp Switch_Key_Table_Exit
Switch_Key_Table_eu:
mov [edx + Take_Key_Table],dword 0
jmp Switch_Key_Table_Exit
Switch_Key_Table_us:
mov [edx + Take_Key_Table],dword 1
Switch_Key_Table_Exit:
Leave_System
ret
Set_Scroll_led:
; undocumented
Enter_System
call Get_address
; clear the led bit (default)
clear_bit [edx + Led_locks], 1
; only bit 0 is significant in the Param1
mov eax,Param1
or eax,1
or [edx + Led_locks],eax
; set the (maybe) new leds
call Set_leds
Leave_System
ret
Get_Key_states:
; SPI Get_Key_states
; return = record of
; {
; PressedKeys
; bit 0: shift left
; bit 1: ctrl left
; bit 2: alt (unused)
; bit 3: del (unused)
; bit 4: caps lock
; bit 5: ctrl right
; bit 6: ctrl (unused)
; bit 7: shift right
; bit 8: shift (unused)
; bit 9: rollen
; bit 10: num lock
;
; CapsLock (key state)
; NumLock (key state)
; Rollen (key state)
; Alt_Gr (key state)
;
; Led_locks
; Typematic_rate
; }
Enter_System
call Get_address
API New, 6
mov edi,eax
mov ax,[edx + PressedKeys]
stosw
mov al,[edx + CapsLock]
stosb
mov al,[edx + NumLock]
stosb
mov al,[edx + Rollen]
stosb
mov al,[edx + Alt_Gr]
stosb
mov al,[edx + Led_locks]
stosb
mov al,[edx + Typematic_rate]
stosb
mov eax,edi
sub eax,6
Leave_System
ret
Return_last_key:
; SPI Return_last_key
; return = record of
; {
;
; LastKey
; LastKeyExt
; LastKeyEvent
;
; }
Enter_System
call Get_address
API New, 12
mov edi,eax
mov eax,[edx + LastKey]
stosd
mov eax,[edx + LastKeyExt]
stosd
mov eax,[edx + LastKeyEvent]
stosd
mov eax,edi
sub eax,12
Leave_System
ret
Resend_last_key:
; SPI Resend_last_key
; resends the last key to the user, as it was
Enter_System
call Get_address
; send the key to the top (active) window
mov esi,Top_Window
mov edi,TWC_link.Handle(esi)
API Send_Message, TWC_link.ProcessHandle(esi), edi, [edx + LastKeyEvent], [edx + LastKey], [edx + LastKeyExt]
Leave_System
ret
Retrieve_last_key:
; SPI Retrieve_last_key
; given direct to the keyboard, resend last scancode
Enter_System
call Get_address
; Keyboard command
; FEh sngl resend last scancode
kb_comm_low Public_Keyboard_Error, 0feh
xor eax,eax
Leave_System
ret
Public_Keyboard_Error:
mov eax,Keyboard_abort
Leave_System
ret
Get_address:
mov edx,dword 0FFFF00FFh
; other method:
; set the start address
; mov edx,[Global_Offset_Table + 1*16 + 7]
ret
initialise:
; Param1 = base of vxd
Enter_System
pushfd
cli
mov edx,Param1
mov [edx + Get_address + 1],edx
; ---- keyboard control ----
Keyboard_Control:
; link the IRQ 1 with the Keyboard Handler
mov ebx,Param1
add ebx,Keyboard_Handler
API Set_IRQ, 1, ebx
; set the Scancode Set
kb_comm Keyboard_init_abort, 0f0h
kb_write Keyboard_init_abort, 1
; set the leds
call Set_leds
jc Keyboard_init_abort
; set the Typematic rate
kb_comm Keyboard_init_abort, 0f3h
kb_write Keyboard_init_abort, [edx + Typematic_rate]
; enable the Keyboard and start scanning
kb_comm Keyboard_init_abort, 0f4h
; set default key values
mov [edx + CapsLock],byte 0
mov [edx + NumLock],byte 0
mov [edx + Rollen],byte 0
mov [edx + PressedKeys],byte 0
mov [edx + Extended_key],byte 0
mov [edx + Keyboard],dword 1
; ---- mouse control ----
Mouse_Control:
; link the IRQ 12 with the Mouse Handler
mov ebx,Param1
add ebx,Mouse_Handler
API Set_IRQ, 12, ebx
; enable the mouse port
kb_comm Mouse_abort, 0a8h
; reset the mouse (100 samples/sec, 4 counts/mm, 1:1)
kb_comm Mouse_abort, 0d4h
kb_comm Mouse_abort, 0f6h
; enable data reporting
kb_comm Mouse_abort, 0d4h
kb_comm Mouse_abort, 0f4h
%ifdef homix_os_use
kb_comm Mouse_abort, 0a8h
kb_comm Mouse_abort, 020h
kb_comm Mouse_abort, 060h
kb_comm Mouse_abort, 0d4h
kb_comm Mouse_abort, 0f4h
%endif
; mark the Mouse as available
mov [edx+Mouse],dword 1
Connect_Exit:
popfd
Leave_System
clc
ret
Keyboard_init_abort:
; create a timer ???
; resume the mouse mounting
jmp Mouse_Control
Mouse_abort:
; create a timer ???
jmp Connect_Exit
Keyboard_Handler:
; define the variables
%define ScanCode [ebp-4]
%define KeyEvent [ebp-8]
%define ExtCode [ebp-12]
%define System_Stack 12
Enter_driver
call Get_address
xor eax,eax
mov KeyEvent,dword 0
mov ScanCode,dword 0
mov ExtCode,dword 0
; check if there is a scancode
in al,64h
test al,00000001b
jz Keyboard_Handler_Exit
; input the scancode
in al,60h
; are one (E0h) or two (E1h) scancodes following ?
cmp al,0E0h
je Keyboard_Handler_E?h
cmp al,0E1h
je Keyboard_Handler_E?h
cmp al,0FAh
je Keyboard_Handler_Exit
; if extended jump
cmp [edx + Extended_key],byte 1
je Take_Extended_Key_Table
; set the KeyEvent
; If EventCode = 0 then
; KeyEvent = KEY_DOWN
; Else
; KeyEvent = KEY_UP;
Set_Key_Event:
test al,10000000b
jz Keyboard_Handler_down
Keyboard_Handler_up:
mov KeyEvent,dword WM_KEYUP
jmp Keyboard_Handler_ok
Keyboard_Handler_down:
mov KeyEvent,dword WM_KEYDOWN
Keyboard_Handler_ok:
; only the scancode is significant
and eax,01111111b
; take the correct Key Tables for ascii keys
cmp [edx + Take_Key_Table],byte 0
jne Take_Key_Table_american
Take_Key_Table_europe:
; sort out ascii keys
check_bounds 2, 13, 2, Take_Key_Table_europe_ascii
check_bounds 16, 27, 2+2, Take_Key_Table_europe_ascii
check_bounds 30, 41, 2+2+2, Take_Key_Table_europe_ascii
check_bounds 43, 53, 2+2+2+1, Take_Key_Table_europe_ascii
check_bounds 86, 86, 2+2+2+1+32, Take_Key_Table_europe_ascii
; sort out imm keys
check_bounds 0, 1, 0, Take_Key_Table_imm
check_bounds 14, 15, 12, Take_Key_Table_imm
check_bounds 28, 28, 12*2, Take_Key_Table_imm
check_bounds 57, 57, 12*2+28, Take_Key_Table_imm
check_bounds 59, 68, 12*2+28+1, Take_Key_Table_imm
check_bounds 87, 88, 12*2+28+1+18, Take_Key_Table_imm
; sort out numblock keys
check_bounds 69, 69, 0, Take_Key_Table_num_lock
check_bounds 71, 83, 71, Take_Key_Table_numblock
check_bounds 55, 55, 0, Take_Key_Table_numblock_mul
; sort out direct translation keys
check_bounds 58, 58, 0, Take_Key_Table_caps_lock
check_bounds 29, 29, 0, Take_Key_Table_ctrl_left
check_bounds 42, 42, 0, Take_Key_Table_shift_left
check_bounds 54, 54, 0, Take_Key_Table_shift_right
check_bounds 56, 56, 0, Take_Key_Table_alt_left
check_bounds 70, 70, 0, Take_Key_Table_rollen
; store the unknown key for intelli genuine ToasterOS use
mov [edx + UnknownKey],al
mov bl,KeyEvent
mov [edx + UnknownKey + 1],bl
jmp Keyboard_Handler_Exit
Take_Key_Table_american:
; sort out ascii keys
check_bounds 2, 13, 2, Take_Key_Table_american_ascii
check_bounds 16, 27, 2+2, Take_Key_Table_american_ascii
check_bounds 30, 41, 2+2+2, Take_Key_Table_american_ascii
check_bounds 43, 53, 2+2+2+1, Take_Key_Table_american_ascii
check_bounds 86, 86, 2+2+2+1+32, Take_Key_Table_american_ascii
; sort out imm keys
check_bounds 0, 1, 0, Take_Key_Table_imm
check_bounds 14, 15, 12, Take_Key_Table_imm
check_bounds 28, 28, 12*2, Take_Key_Table_imm
check_bounds 57, 57, 12*2+28, Take_Key_Table_imm
check_bounds 59, 68, 12*2+28+1, Take_Key_Table_imm
check_bounds 87, 88, 12*2+28+1+18, Take_Key_Table_imm
; sort out numblock keys
check_bounds 69, 69, 0, Take_Key_Table_num_lock
check_bounds 71, 83, 71, Take_Key_Table_numblock
check_bounds 55, 55, 0, Take_Key_Table_numblock_mul
; sort out direct translation keys
check_bounds 58, 58, 0, Take_Key_Table_caps_lock
check_bounds 29, 29, 0, Take_Key_Table_ctrl_left
check_bounds 42, 42, 0, Take_Key_Table_shift_left
check_bounds 54, 54, 0, Take_Key_Table_shift_right
check_bounds 56, 56, 0, Take_Key_Table_alt_left
check_bounds 70, 70, 0, Take_Key_Table_rollen
; store the unknown key for intelli genuine ToasterOS use
mov [edx + UnknownKey],al
mov bl,KeyEvent
mov [edx + UnknownKey + 1],bl
jmp Keyboard_Handler_Exit
Take_Extended_Key_Table:
mov [edx + Extended_key],byte 0
; sort out (extra) break codes, AAh and 2Ah are not significant
check_bounds 170, 170, 0, Keyboard_Handler_Exit
check_bounds 42, 42, 0, Keyboard_Handler_Exit
; suppose make code
mov KeyEvent,dword WM_KEYDOWN
; sort out middle block keys
check_bounds 71, 73, 71, Take_Key_Table_middle_block
check_bounds 75, 75, 71+1, Take_Key_Table_middle_block
check_bounds 77, 77, 71+1+1, Take_Key_Table_middle_block
check_bounds 79, 83, 71+1+1+1, Take_Key_Table_middle_block
; sort out direct translation keys
check_bounds 53, 53, 0, Take_Key_Table_numblock_div
check_bounds 55, 55, 0, Take_Key_Table_print_screen
check_bounds 56, 56, 0, Take_Key_Table_alt_gr
check_bounds 84, 84, 0, Take_Key_Table_print_screen
check_bounds 86, 86, 0, Set_Key_Event
check_bounds 91, 91, 0, Take_Key_Table_left_win
check_bounds 92, 92, 0, Take_Key_Table_right_win
check_bounds 93, 93, 0, Take_Key_Table_popup
; suppose break code
mov KeyEvent,dword WM_KEYUP
; sort out middle block keys
check_bounds 198, 198, 0, Take_Key_Table_pause
check_bounds 199, 201, 199, Take_Key_Table_middle_block
check_bounds 203, 203, 199+1, Take_Key_Table_middle_block
check_bounds 205, 205, 199+1+1, Take_Key_Table_middle_block
check_bounds 207, 211, 199+1+1+1, Take_Key_Table_middle_block
; sort out direct translation keys
check_bounds 181, 181, 0, Take_Key_Table_numblock_div
check_bounds 183, 183, 0, Take_Key_Table_print_screen
check_bounds 184, 184, 0, Take_Key_Table_alt_gr
check_bounds 212, 212, 0, Take_Key_Table_print_screen
check_bounds 214, 214, 0, Set_Key_Event
check_bounds 219, 219, 0, Take_Key_Table_left_win
check_bounds 220, 220, 0, Take_Key_Table_right_win
check_bounds 221, 221, 0, Take_Key_Table_popup
; the most special pause key
Test_Key_Pause_scan_code1:
cmp al,01Dh
jne Test_Key_Pause_scan_code3
mov [edx + Extended_key],byte 1
jmp Keyboard_Handler_Exit
; the 2nd code 45h won't be test, because if its one of the make code, the next e0h
; activates this handler by default
Test_Key_Pause_scan_code3:
cmp al,09Dh
jne Test_Key_Pause_scan_code4
mov [edx + Extended_key],byte 1
jmp Keyboard_Handler_Exit
Test_Key_Pause_scan_code4:
cmp al,197
je Take_Key_Table_pause
; store the unknown key for intelli genuine ToasterOS use
mov [edx + UnknownKey],al
mov bl,KeyEvent
mov [edx + UnknownKey + 1],bl
jmp Keyboard_Handler_Exit
Take_Key_Table_europe_ascii:
; ascii means keys which are visible
cmp [edx + Alt_Gr],byte 1
je Take_Key_Table_europe_ascii_alt_gr
cmp [edx + CapsLock],byte 1
je Take_Key_Table_europe_ascii_shift
Take_Key_Table_europe_ascii_normal:
movzx ebx,byte [edx + Key_Table_europe_ascii + eax]
jmp Send_Key
Take_Key_Table_europe_ascii_shift:
movzx ebx,byte [edx + Key_Table_europe_ascii_shift + eax]
jmp Send_Key
Take_Key_Table_europe_ascii_alt_gr:
check_bounds 3, 4, 3, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 8, 12, 3*2, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 16, 16, 3*3, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 18, 18, 3*3+1, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 27, 27, 3*3+1+8, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 50, 50, 3*3+1+8+22, Take_Key_Table_europe_ascii_alt_gr_set
check_bounds 86, 86, 3*3+1+8+22+35, Take_Key_Table_europe_ascii_alt_gr_set
jmp Keyboard_Handler_Exit
Take_Key_Table_europe_ascii_alt_gr_set:
movzx ebx,byte [edx + Key_Table_europe_ascii_alt_gr + eax]
jmp Send_Key
Take_Key_Table_american_ascii:
; ascii means keys which are visible
cmp [edx + CapsLock],byte 1
je Take_Key_Table_american_ascii_shift
Take_Key_Table_american_ascii_normal:
movzx ebx,byte [edx + Key_Table_american_ascii + eax]
jmp Send_Key
Take_Key_Table_american_ascii_shift:
movzx ebx,byte [edx + Key_Table_american_ascii_shift + eax]
jmp Send_Key
Take_Key_Table_imm:
; imm means keys which are immediately to translate and send
movzx ebx,byte [edx + Key_Table_imm + eax]
jmp Send_Key
Take_Key_Table_numblock:
; numblock means keys of the numblock
cmp [edx + NumLock],byte 1
je Take_Key_Table_numblock_num
cmp [edx + NumLock],byte 2
je Take_Key_Table_numblock_tec
movzx ecx,byte [edx + Key_Table_numblock_tec + eax]
mov ExtCode,ecx
movzx ebx,byte [edx + Key_Table_numblock + eax]
jmp Send_Key
Take_Key_Table_numblock_tec:
movzx ebx,byte [edx + Key_Table_numblock_tec + eax]
mov ExtCode,ebx
jmp Send_Key
Take_Key_Table_numblock_num:
movzx ecx,byte [edx + Key_Table_numblock_tec + eax]
mov ExtCode,ecx
movzx ebx,byte [edx + Key_Table_numblock_num + eax]
jmp Send_Key
Take_Key_Table_numblock_mul:
; key = mul (some part of the direct translation keys)
mov ebx,'*'
mov ExtCode,dword VK_MULTIPLY
jmp Send_Key
Take_Key_Table_numblock_div:
; key = div (part of the direct translation keys)
mov ebx,'/'
mov ExtCode,dword VK_DIVIDE
jmp Send_Key
Take_Key_Table_num_lock:
; key = num lock (some part of the direct translation keys)
; if key event != key first then exit
cmp KeyEvent,word WM_KEYDOWN
jne Take_Key_Table_num_lock_clearbit
key_press 10000000000b
invert_bool byte [edx + NumLock]
invert_bit [edx + Led_locks], 10b
call Set_leds
jmp Keyboard_Handler_Exit
Take_Key_Table_num_lock_clearbit:
clear_bit [edx + PressedKeys], 10000000000b
jmp Keyboard_Handler_Exit
Take_Key_Table_caps_lock:
; key = caps lock (part of the direct translation keys)
; if key event != key first then exit
cmp KeyEvent,word WM_KEYDOWN
jne Take_Key_Table_caps_lock_clearbit
key_press 10000b
invert_bool byte [edx + CapsLock]
invert_bit [edx + Led_locks], 100b
call Set_leds
jmp Keyboard_Handler_Exit
Take_Key_Table_caps_lock_clearbit:
clear_bit [edx + PressedKeys], 10000b
jmp Keyboard_Handler_Exit
Take_Key_Table_rollen:
; rollen = scroll lock
; if key event <> key first then exit
cmp KeyEvent,word WM_KEYDOWN
jne Take_Key_Table_rollen_clearbit
key_press 1000000000b
invert_bool byte [edx + Rollen]
invert_bit [edx + Led_locks], 1b
call Set_leds
jmp Keyboard_Handler_Exit
Take_Key_Table_rollen_clearbit:
clear_bit [edx + PressedKeys], 1000000000b
jmp Keyboard_Handler_Exit
Take_Key_Table_ctrl_left:
; key = ctrl left (part of the direct translation keys)
; make and break code (bit 1: ctrl left)
key_press 10b
mov ExtCode,dword VK_LCONTROL
mov ebx,VK_CONTROL
jmp Send_Key
Take_Key_Table_shift_left:
; key = shift left (part of the direct translation keys)
; make and break code (bit 0: shift left)
key_press 1b
invert_bool byte [edx + CapsLock]
mov ExtCode,dword VK_LSHIFT
mov ebx,VK_SHIFT
jmp Send_Key
Take_Key_Table_shift_right:
; key = shift right (part of the direct translation keys)
; make and break code (bit 7: shift right)
key_press 10000000b
invert_bool byte [edx + CapsLock]
mov ExtCode,dword VK_RSHIFT
mov ebx,VK_SHIFT
jmp Send_Key
Take_Key_Table_alt_left:
; key = alt left (part of the direct translation keys)
; make and break code (bit 2: alt left)
key_press 100b
mov ExtCode,dword VK_LMENU
mov ebx,VK_MENU
jmp Send_Key
Take_Key_Table_alt_gr:
; only make code
; alt gr = alt (for american)
cmp [edx + Take_Key_Table],byte 0
jne Take_Key_Table_alt_left
invert_bool byte [edx + Alt_Gr]
jmp Keyboard_Handler_Exit
Take_Key_Table_print_screen:
; copy screen to clipboard
; - ?
mov ebx,VK_SNAPSHOT
jmp Send_Key
Take_Key_Table_left_win:
; show the win 3.1 Toolbar/menu
; - ?
mov ebx,VK_LWIN
jmp Send_Key
Take_Key_Table_right_win:
; show the win 3.1 Toolbar/menu
; - ?
mov ebx,VK_RWIN
jmp Send_Key
Take_Key_Table_popup:
mov ebx,VK_APPS
jmp Send_Key
Take_Key_Table_pause:
; idle the system
; - ?
mov ebx,VK_PAUSE
jmp Send_Key
Take_Key_Table_middle_block:
; middle block = keys of the middle block
movzx ebx,byte [edx + Key_Table_middle_block + eax]
jmp Send_Key
Send_Key:
mov ScanCode,ebx
mov [edx + LastKey],ebx
mov ecx,ExtCode
mov [edx + LastKeyExt],ecx
mov ecx,KeyEvent
mov [edx + LastKeyEvent],ecx
; if key <> 0 then send_key
or ebx,ebx
jz Keyboard_Handler_Exit
; send the key to the top (active) window
mov esi,Top_Window
mov edi,TWC_link.Handle(esi)
API Send_Message, TWC_link.ProcessHandle(esi), edi, KeyEvent, ScanCode, ExtCode
jmp Keyboard_Handler_Exit
Keyboard_Handler_E?h:
mov [edx + Extended_key],byte 1
jmp Keyboard_Handler_Exit
Keyboard_Handler_Exit:
Leave_driver
EOI_Master
iret
Set_leds:
; sets the leds by means of the led locks
kb_comm_low Set_leds_Exit, 0edh
kb_write Set_leds_Exit, [edx + Led_locks]
Set_leds_Exit:
ret
kbWrite:
; a public OS developer routine to write something to the Keyboard
; input(ah) = byte to send
; return = 0 if successful, otherwise error (abort)
; test for a transmit timeout
mov ecx,0FFFFh
Test_loop_1:
in al,64h
test al,00100000b
jz Test_loop_1_ok
loop Test_loop_1
stc
jmp kbWrite_Exit
Test_loop_1_ok:
; test if the input buffer is full
mov ecx,0FFFFh
Test_loop_2:
in al,64h
test al,00000010b
jz Test_loop_2_ok
loop Test_loop_2
stc
jmp kbWrite_Exit
Test_loop_2_ok:
; send the byte out to port 60h
mov al,ah
out 60h,al
clc
kbWrite_Exit:
ret
kbRead:
; a public OS developer routine to read something of the Keyboard
; return = read byte
; test if the output buffer is full
mov ecx,0FFFFh
Test_loop_3:
in al,64h
test al,00000001b
jz Test_loop_3_ok
loop Test_loop_3
stc
jmp kbWrite_Exit
Test_loop_3_ok:
; delay for a short time
delay 32
; input the byte
in al,60h
ret
kbCommand:
; a public OS developer routine to send a command to the Keyboard
; input(ah) = command to send
; test if the input buffer is full
mov ecx,0FFFFh
Test_loop_4:
in al,64h
test al,00000010b
jz Test_loop_4_ok
loop Test_loop_4
stc
jmp kbWrite_Exit
Test_loop_4_ok:
; send the command
mov al,ah
out 64h,al
; test if the command acception
mov ecx,0FFFFh
Test_loop_5:
in al,64h
test al,00000010b
jz Test_loop_5_ok
loop Test_loop_5
stc
jmp kbWrite_Exit
Test_loop_5_ok:
clc
ret
kbCommand_low:
; a public OS developer routine to send a command to the Keyboard
; input(ah) = command to send to port 60h instead of 64h
; test if the input buffer is full
mov ecx,0FFFFh
Test_loop_6:
in al,64h
test al,00000010b
jz Test_loop_6_ok
loop Test_loop_6
stc
jmp kbWrite_Exit
Test_loop_6_ok:
; send the command (at this time to port 60h)
mov al,ah
out 60h,al
; test if the command acception
mov ecx,0FFFFh
Test_loop_7:
in al,64h
test al,00000010b
jz Test_loop_7_ok
loop Test_loop_7
stc
jmp kbWrite_Exit
Test_loop_7_ok:
clc
ret
Mouse_Handler:
; define the variables
%define Buttons [ebp-1]
%define Movement_X [ebp-2]
%define Movement_Y [ebp-3]
%define System_Stack 3
Enter_driver
call Get_address
; check if there are the 3 bytes
in al,64h
test al,00000001b
jz Mouse_Handler_Exit
; store the 3 bytes (Buttons, X Movement, Y Movement)
in al,60h
mov Buttons,al
in al,60h
mov Movement_X,al
in al,60h
mov Movement_Y,al
; update the position
API Update_Cursor_position, Buttons, Movement_X, Movement_Y
Mouse_Handler_Exit:
Leave_driver
EOI_Slave
iret
Mouse_Handler_intelli:
; currently not supported
iret
; Keyboard and Mouse are boolean values if they are available
Keyboard dd 0
Mouse dd 0
; Keyboard state
Typematic_rate dd 00101000b
Led_locks dd 000b
; key states
CapsLock dd 0
NumLock dd 0
Rollen dd 0
Alt_Gr dd 0
PressedKeys dd 0
UnknownKey dd 0
Extended_key dd 0
LastKey dd 0
LastKeyExt dd 0
LastKeyEvent dd 0
; 0 = europe, 1 = american
Take_Key_Table dd 0
; the Key tables (for europe keyboards)
Key_Table_europe_ascii db '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'ß', '´', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '^', '#', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', '<'
Key_Table_europe_ascii_shift db '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?', '`', 'Q', 'W', 'E', 'R', 'T', 'Z', 'I', 'I', 'O', 'P', 'Ü', '*', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ö', 'Ä', '°', 27h, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_', '>'
Key_Table_europe_ascii_alt_gr db '²', '³', '{', '[', ']', '}', '\', '@', '', '~', 'µ', '|'
; the Key tables (for american keyboards)
Key_Table_american_ascii db '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '-', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 27h, '`', '\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\'
Key_Table_american_ascii_shift db '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 'Q', 'W', 'E', 'R', 'T', 'Y', 'I', 'I', 'O', 'P', '{', '}', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '|'
; the Key tables (for europe & american keyboards)
Key_Table_imm db VK_NULL, VK_ESCAPE, VK_BACK, VK_TAB, VK_RETURN, VK_SPACE, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12
Key_Table_numblock db VK_HOME, VK_UP, VK_PRIOR, '-', VK_LEFT, VK_NUMPAD5, VK_RIGHT, '+', VK_END, VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE
Key_Table_numblock_num db '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', VK_DELETE
Key_Table_numblock_tec db VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_SUBTRACT, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_ADD, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, VK_DELETE
Key_Table_middle_block db VK_HOME, VK_UP, VK_PRIOR, VK_LEFT, VK_RIGHT, VK_END, VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE
; bits of Led_locks (0=Off 1=On):
; 0 = Scroll Lock
; 1 = Num Lock
; 2 = Caps Lock
; rest = 0
; bits of Typematic_rate
; bit 0 -> 4: rate. Timings:
; 0: 30 keys/sec 10: 10
; 1: 26.7 13: 9
; 2: 24 16: 7.5
; 4: 20 20: 5
; 8: 15 31: 2
;
; bit 5 & 6: pause before repeat:
; 0: 250 ms
; 1: 500
; 2: 750
; 4: 1000
;
; bit 7: Always 0
; PressedKeys
; bit 0: shift left
; bit 1: ctrl left
; bit 2: alt (unused)
; bit 3: del (unused)
; bit 4: caps lock
; bit 5: ctrl right
; bit 6: ctrl (unused)
; bit 7: shift right
; bit 8: shift (unused)
; bit 9: rollen
; bit 10: num lock