From a6764896b9956cdeb7603604463ac88e57893265 Mon Sep 17 00:00:00 2001 From: kastigar Date: Mon, 14 May 2007 12:57:41 +0000 Subject: [PATCH] * Driver for ps/2 mouse with 2 wheels git-svn-id: svn://kolibrios.org@492 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/imports.inc | 151 ++++++++++ .../mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc | 141 +++++++++ drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc | 135 +++++++++ drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm | 268 ++++++++++++++++++ drivers/proc32.inc | 268 ++++++++++++++++++ 5 files changed, 963 insertions(+) create mode 100644 drivers/imports.inc create mode 100644 drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc create mode 100644 drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc create mode 100644 drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm create mode 100644 drivers/proc32.inc diff --git a/drivers/imports.inc b/drivers/imports.inc new file mode 100644 index 0000000000..c9642c402b --- /dev/null +++ b/drivers/imports.inc @@ -0,0 +1,151 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; all exported kernel functions and data + +if used RegService + extrn RegService +end if +if used GetService + extrn GetService +end if +if used ServiceHandler + extrn ServiceHandler +end if +if used AttachIntHandler + extrn AttachIntHandler +end if +if used FpuSave + extrn FpuSave +end if +if used FpuRestore + extrn FpuRestore +end if + +if used PciApi + extrn PciApi +end if +if used PciRead32 + extrn PciRead32 +end if +if used PciRead8 + extrn PciRead8 +end if +if used PciWrite8 + extrn PciWrite8 +end if + +if used AllocPage + extrn AllocPage +end if +if used AllocPages + extrn AllocPages +end if +if used FreePage + extrn FreePage +end if +if used MapPage + extrn MapPage +end if +if used MapSpace + extrn MapSpace +end if +if used GetPgAddr + extrn GetPgAddr +end if +if used CommitPages + extrn CommitPages +end if +if used ReleasePages + extrn ReleasePages +end if + +if used AllocKernelSpace + extrn AllocKernelSpace +end if +if used FreeKernelSpace + extrn FreeKernelSpace +end if +if used KernelAlloc + extrn KernelAlloc +end if +if used KernelFree + extrn KernelFree +end if +if used UserAlloc + extrn UserAlloc +end if +if used UserFree + extrn UserFree +end if +if used Kmalloc + extrn Kmalloc +end if +if used Kfree + extrn Kfree +end if + +if used CreateObject + extrn CreateObject +end if +if used DestroyObject + extrn DestroyObject +end if +if used CreateEvent + extrn CreateEvent +end if +if used RaiseEvent + extrn RaiseEvent +end if +if used WaitEvent + extrn WaitEvent +end if +if used DestroyEvent + extrn DestroyEvent +end if +if used ClearEvent + extrn ClearEvent +end if + +if used LoadCursor + extrn LoadCursor +end if +if used SetHwCursor + extrn SetHwCursor +end if +if used HwCursorRestore + extrn HwCursorRestore +end if +if used HwCursorCreate + extrn HwCursorCreate +end if + +if used SysMsgBoardStr + extrn SysMsgBoardStr +end if +if used GetCurrentTask + extrn GetCurrentTask +end if +if used LoadFile + extrn LoadFile +end if +if used SendEvent + extrn SendEvent +end if +if used SetMouseData + extrn SetMouseData +end if +if used Sleep + extrn Sleep +end if +if used GetTimerTicks + extrn GetTimerTicks +end if +if used LFBAddress + extrn LFBAddress +end if + diff --git a/drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc b/drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc new file mode 100644 index 0000000000..5c5d7d144e --- /dev/null +++ b/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 diff --git a/drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc b/drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc new file mode 100644 index 0000000000..e9724f0e53 --- /dev/null +++ b/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 diff --git a/drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm b/drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm new file mode 100644 index 0000000000..aa0b1969d1 --- /dev/null +++ b/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 diff --git a/drivers/proc32.inc b/drivers/proc32.inc new file mode 100644 index 0000000000..98a1bd3342 --- /dev/null +++ b/drivers/proc32.inc @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl }