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, dword 0
	  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