; ********************************************************** ; Name: PS/2 Keyboard & Mouse driver ; Type: Virtual Device Driver ; Autor: Peter Kleissner ; 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] ; function splitter ; ; API invoke_driver, driver, function, Param1, Param2, ... Enter_System ; Initialize? cmp Param2,dword 0 je initialize ; set address call Get_address ; Switch Key Table? cmp Param2,dword 1 je Switch_Key_Table ; Set Scroll Led? cmp Param2,dword 2 je Set_Scroll_led ; Get Key states? cmp Param2,dword 3 je Get_Key_states ; Return last Key? cmp Param2,dword 4 je Return_last_key ; Resend last Key? cmp Param2,dword 5 je Resend_last_key ; Retrieve last Key? cmp Param2,dword 6 je Retrieve_last_key Leave_System Invalid_Function, 1 ret initialize: ; Param3 = base of vxd Enter_nonInterruption mov edx,Param3 mov [edx + Get_address + 1],edx ; ---- keyboard control ---- Keyboard_Control: ; link the IRQ 1 with the Keyboard Handler mov ebx,Param3 add ebx,Keyboard_Handler API Set_IRQ, 1, ebx ; set the Scancode Set kb_comm_low Keyboard_init_abort, 0f0h kb_write Keyboard_init_abort, 0 ; set the leds call Set_leds jc Keyboard_init_abort ; set the Typematic rate kb_comm_low Keyboard_init_abort, 0f3h kb_write Keyboard_init_abort, [edx + Typematic_rate] ; enable the Keyboard and start scanning ;kb_comm Keyboard_init_abort, 0f4h kb_comm_low 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: %if 0 = 1 ; link the IRQ 12 with the Mouse Handler mov ebx,Param3 add ebx,Mouse_Handler API Set_IRQ, 12, ebx ; deactivate the Keyboard kb_comm Mouse_abort, 0adh ; enable the mouse port kb_comm Mouse_abort, 0a8h ;kb_read Mouse_abort m_read ; enable the device kb_comm Mouse_abort, 020h kb_read Mouse_abort ;m_read or al,3 push ax kb_comm Mouse_abort, 060h pop ax kb_write Mouse_abort, al ; reset the mouse (100 samples/sec, 4 counts/mm, 1:1) kb_comm Mouse_abort, 0d4h kb_comm_low Mouse_abort, 0f6h ; enable data reporting kb_comm Mouse_abort, 0d4h kb_comm_low Mouse_abort, 0f4h kb_read Mouse_abort ;m_read ; activate the Keyboard kb_comm Mouse_abort, 0aeh ; mark the Mouse as available mov [edx+Mouse],dword 1 %endif ; ---- external mouse control ---- %if 0 = 1 ; link the IRQ 12 with the Mouse Handler mov ebx,Param3 add ebx,Mouse_Handler API Set_IRQ, 12, ebx call PS2_External_Mouse_Control jmp PS2_Main_Control PS2_External_Mouse_Control: incbin "PS2Mouse.bin" PS2_Main_Control: %endif ; ---- PS/2 main control ---- ; input 3 bytes, else the driver wouldn't work (???) in al,60h Leave_nonInterruption Connect_Exit: Leave_System ret Keyboard_init_abort: ; create a timer ; resume the mouse mounting jmp Mouse_Control Mouse_abort: ; create a timer ; activate the Keyboard (it may be left in a deactivated state) kb_comm Connect_Exit, 0aeh Leave_nonInterruption jmp Connect_Exit Switch_Key_Table: ; SPI Set_Keyboard_Layout, Table ; Table = "eu" for europe, "us" for american keyboard layout cmp Param3,dword 'eu' je Switch_Key_Table_eu cmp Param3,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 ; clear the led bit (default) clear_bit [edx + Led_locks], 1 ; only bit 0 is significant in the Param3 mov eax,Param3 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 ; } 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 ; ; } 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 ; 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 ; 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 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 topmost (active) window - if available mov esi,Top_Window or esi,esi jnz Send_Key_process_known Send_Key_process_unknown: API Send_Message, 0, 0, KeyEvent, ScanCode, ExtCode jmp Keyboard_Handler_Exit Send_Key_process_known: 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 EOI_Slave 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 ; /* Public Keyboard Help Functions */ 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: ; ??? ;in al,60h ; 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 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 acceptation 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 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 jnz Test_loop_3_ok loop Test_loop_3 stc ret Test_loop_3_ok: ; delay for a short time delay 32 ; input the byte in al,60h clc 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 ret Test_loop_4_ok: ; send the command mov al,ah out 64h,al ; test if the command has been accepted mov ecx,0FFFFh Test_loop_5: in al,64h test al,00000010b jz Test_loop_5_ok loop Test_loop_5 stc ret Test_loop_5_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 ; 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 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', 'U', '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 switzer keyboards, thanks to noooooooos) Key_Table_switzer_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_switzer_ascii_shift db '+', '"', '*', 'ç', '%', '&', '/', '(', ')', '=', '?', '`', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 'Ü', '*', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ö', 'Ä', '°', 27h, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_', '>' Key_Table_switzer_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