/drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc |
---|
0,0 → 1,141 |
kbd_read: |
push ecx edx |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kr_loop: |
in al,0x64 |
test al,1 |
jnz kr_ready |
loop kr_loop |
mov ah,1 |
jmp kr_exit |
kr_ready: |
push ecx |
mov ecx,32 |
kr_delay: |
loop kr_delay |
pop ecx |
in al,0x60 |
xor ah,ah |
kr_exit: |
pop edx ecx |
ret |
kbd_write: |
push ecx edx |
mov dl,al |
in al,0x60 |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop: |
in al,0x64 |
test al,2 |
jz kw_ok |
loop kw_loop |
mov ah,1 |
jmp kw_exit |
kw_ok: |
mov al,dl |
out 0x60,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop3: |
in al,0x64 |
test al,2 |
jz kw_ok3 |
loop kw_loop3 |
mov ah,1 |
jmp kw_exit |
kw_ok3: |
mov ah,8 |
kw_loop4: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop5: |
in al,0x64 |
test al,1 |
jnz kw_ok4 |
loop kw_loop5 |
dec ah |
jnz kw_loop4 |
kw_ok4: |
xor ah,ah |
kw_exit: |
pop edx ecx |
ret |
kbd_cmd: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_wait: |
in al,0x64 |
test al,2 |
jz c_send |
loop c_wait |
jmp c_error |
c_send: |
mov al,bl |
out 0x64,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_accept: |
in al,0x64 |
test al,2 |
jz c_ok |
loop c_accept |
c_error: |
mov ah,1 |
jmp c_exit |
c_ok: |
xor ah,ah |
c_exit: |
ret |
mouse_cmd: |
mov [mouse_cmd_byte], al |
mov [mouse_nr_resends], 5 |
.resend: |
mov bl, 0xd4 |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov al, [mouse_cmd_byte] |
call kbd_write |
cmp ah, 1 |
je .fail |
call mouse_read |
cmp al, 0xFA |
jne .noack |
clc |
ret |
.noack: |
cmp al, 0xFE ; resend |
jne .noresend |
dec [mouse_nr_resends] |
jnz .resend |
.noresend: |
.fail: |
stc |
ret |
mouse_read: |
mov [mouse_nr_tries], 100 |
.repeat: |
call kbd_read |
cmp ah, 1 |
jne .fin |
mov esi, 10 |
call Sleep |
dec [mouse_nr_tries] |
jnz .repeat |
stc |
ret |
.fin: |
clc |
ret |
/drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc |
---|
0,0 → 1,135 |
;************************************** |
;* IRQ HANDLER FOR PS/2 MOUSE * |
;************************************** |
proc irq_handler |
call Wait8042BufferEmpty ;clear buffer |
in al,0x60 ;get scan-code |
cmp [mouse_byte],0 |
je .byte1 |
cmp [mouse_byte],1 |
je .byte2 |
cmp [mouse_byte],2 |
je .byte3 |
cmp [mouse_byte],3 |
je .byte4 |
jmp .error |
.byte1: |
test al,1000b ;first byte? |
jz .error |
mov [first_byte],al |
inc [mouse_byte] |
jmp .exit |
.byte2: |
mov [second_byte],al |
inc [mouse_byte] |
jmp .exit |
.byte3: |
mov [third_byte],al |
cmp [MouseType],MT_3B |
je .full_packet |
inc [mouse_byte] |
jmp .exit |
.byte4: |
mov [fourth_byte],al |
.full_packet: |
mov [mouse_byte],0 |
mov al,byte [first_byte] |
and eax,7 |
mov byte [ButtonState],al |
cmp [MouseType],MT_3B |
je .xy_moving |
mov al,[fourth_byte] |
cmp [MouseType],MT_3BScroll |
je .z_moving |
mov ah,al |
and ah,00110000b |
shr ah,1 |
or byte [ButtonState],ah |
and al,00001111b |
bt eax,3 |
jnc .z_moving |
or al,11110000b |
.z_moving: |
movsx eax,al |
mov [ZMoving],eax |
.xy_moving: |
mov ah,0 |
mov al,[first_byte] |
test al,10000b |
jz @f |
mov ah,0FFh |
@@: |
mov al,[second_byte] |
cwde |
mov [XMoving],eax |
mov ah,0 |
mov al,[first_byte] |
test al,100000b |
jz @f |
mov ah,0FFh |
@@: |
mov al,[third_byte] |
cwde |
@@: |
mov [YMoving],eax |
mov eax,[ZMoving] |
test eax,1 |
jnz .vert |
sar eax,1 |
push eax |
push 0 |
jmp @f |
.vert: |
push 0 |
push eax |
@@: |
stdcall SetMouseData, [ButtonState], [XMoving], [YMoving] |
jmp .exit |
.error: |
mov [mouse_byte],0 |
.exit: |
ret |
endp |
;*********************************************** |
;* Waiting for clearing I8042 buffer * |
;* Retutned state: * |
;* ZF is set - good ending, * |
;* ZF is cleared - time-out error. * |
;*********************************************** |
Wait8042BufferEmpty: |
push ecx |
xor ecx,ecx |
@@: |
in al,64h |
test al,00000010b |
loopnz @b |
pop ecx |
ret |
/drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm |
---|
0,0 → 1,268 |
format MS COFF |
include '../../../proc32.inc' |
include '../../../imports.inc' |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
public START |
public version |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
MT_3B equ 0 |
MT_3BScroll equ 3 |
MT_5BScroll equ 4 |
PS2_DRV_VER equ 1 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], DRV_ENTRY |
jne .fin |
.init: |
call detect_mouse |
test eax,eax |
jnz .exit |
mov [MouseType],MT_3B |
call try_mode_ID3 |
test eax,eax |
jnz .stop_try |
mov [MouseType],MT_3BScroll |
call try_mode_ID4 |
test eax,eax |
jnz .stop_try |
mov [MouseType],MT_5BScroll |
.stop_try: |
mov bl, 0x20 ; read command byte |
call kbd_cmd |
cmp ah,1 |
je .exit |
call kbd_read |
cmp ah,1 |
je .exit |
or al, 10b |
push eax |
mov bl, 0x60 ; write command byte |
call kbd_cmd |
cmp ah,1 |
je .exit |
pop eax |
call kbd_write |
cmp ah,1 |
je .exit |
mov al, 0xF4 ; enable data reporting |
call mouse_cmd |
mov bl, 0xAE ; enable keyboard interface |
call kbd_cmd |
stdcall AttachIntHandler, 12, irq_handler |
stdcall RegService, my_service, service_proc |
ret |
.fin: |
;stdcall DetachIntHandler, 12, irq_handler |
mov bl, 0xA7 ; disable mouse interface |
call kbd_cmd |
xor eax, eax |
ret |
.exit: |
mov bl, 0xA7 ; disable mouse interface |
call kbd_cmd |
mov bl, 0xAE ; enable keyboard interface |
call kbd_cmd |
xor eax, eax |
ret |
endp |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+IOCTL.io_code] |
test eax, eax |
jz .getversion |
cmp eax,1 |
jz .gettype |
.err: |
or eax, -1 |
ret |
.ok: |
xor eax, eax |
ret |
.getversion: |
cmp [edi+IOCTL.out_size], 4 |
jb .err |
mov edi, [edi+IOCTL.output] |
mov dword [edi], PS2_DRV_VER ; version of driver |
jmp .ok |
.gettype: |
cmp [edi+IOCTL.out_size], 4 |
jb .err |
mov edi, [edi+IOCTL.output] |
mov eax,[MouseType] |
mov dword [edi], eax ; mouse type |
jmp .ok |
endp |
detect_mouse: |
mov bl, 0xAD ; disable keyboard interface |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov bl, 0xA8 ; enable mouse interface |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov al, 0xFF ; reset |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0xAA |
jne .fail ; dead mouse |
; get device ID |
call mouse_read |
jc .fail |
cmp al, 0x00 |
jne .fail ; unknown device |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
try_mode_ID3: |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;200d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x64 ;100d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x50 ;80d |
call mouse_cmd |
jc .fail |
mov al, 0xF2 ;Get device id |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0x03 |
jne .fail |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
try_mode_ID4: |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;200d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;100d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x50 ;80d |
call mouse_cmd |
jc .fail |
mov al, 0xF2 ;Get device id |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0x04 |
jne .fail |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
include 'ps2m_iofuncs.inc' |
include 'ps2m_irqh.inc' |
section '.data' data readable writable align 16 |
version dd 0x00050005 |
my_service db 'ps2mouse',0 |
;iofuncs data |
mouse_cmd_byte db 0 |
mouse_nr_tries db 0 |
mouse_nr_resends db 0 |
;hid data |
mouse_byte dd 0 |
first_byte db 0 |
second_byte db 0 |
third_byte db 0 |
fourth_byte db 0 |
;main data |
MouseType dd 0 |
XMoving dd 0 |
YMoving dd 0 |
ZMoving dd 0 |
ButtonState dd 0 |
;timerTicks dd 0 |