OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Jan 19, 2019 3:04 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: ps2 mouse driver in asm
PostPosted: Mon Oct 17, 2011 3:57 pm 
Offline
Member
Member
User avatar

Joined: Tue Feb 08, 2011 1:58 pm
Posts: 496
Here's a full (wheel, 4th, 5th button) ps2 mouse driver source in fasm syntax. Released under CC0 (public domain).

First, we need some misc functions to communicate with keyboard.
Code:
;dl=1 read, dl=2 write
ps2wait:   mov         ecx, 1000
@@:      in         al, 64h
      and         al, dl
      jnz         @f
      dec         ecx
      jnz         @b
@@:      ret
ps2wr:   mov         dh, al
      mov         dl, 2
      call         ps2wait
      mov         al, 0D4h
      out         64h, al
      call         ps2wait
      mov         al, dh
      out         60h, al
      ;no ret, fall into read code to read ack
.ps2rd:   mov         dl, 1
      call         ps2wait
      in         al, 60h
      ret

ps2wait waits until an operation can be done (read or write). ps2wr writes a byte, ps2rd reads, simple. The write does not return, it continues to read function to get acknowledge byte.

Now the initialization code, it's a bit ughly, but has to be done only once. Don't cause trouble if called several times.
Code:
      ;variables
packetsize: db 0
resolution: db 3
samplerate: db 200

      ;initialize legacy ps2 user input
      xor         rax, rax
      mov         dl, 2
      call         ps2wait
      mov         al, 0A8h
      out         64h, al
      ;get ack
      call         ps2rd
      ;some compaq voodoo magic to enable irq12
      mov         dl, 2
      call         ps2wait
      mov         al, 020h
      out         64h, al
      mov         dl, 1
      call         ps2wait
      in         al, 60h
      bts         ax, 1
      btr         ax, 5
      mov         bl, al
      mov         dl, 2
      call         ps2wait
      mov         al, 060h
      out         64h, al
      call         ps2wait
      mov         al, bl
      out         60h, al
      ;get optional ack
      mov         dl, 1
      call         ps2wait

      ;restore to defaults
      mov         al, 0F6h
      call         ps2wr
      ;enable Z axis
      mov         al, 0F3h
      call         ps2wr
      mov         al, 200
      call         ps2wr
      mov         al, 0F3h
      call         ps2wr
      mov         al, 100
      call         ps2wr
      mov         al, 0F3h
      call         ps2wr
      mov         al, 80
      call         ps2wr
      mov         al, 0F2h
      call         ps2wr
      call         ps2rd
      mov         byte [packetsize], 3
      or         al, al
      jz         .noZaxis
      mov         byte [packetsize], 4
.noZaxis:   ;enable 4th and 5th buttons
      mov         al, 0F3h
      call         ps2wr
      mov         al, 200
      call         ps2wr
      mov         al, 0F3h
      call         ps2wr
      mov         al, 200
      call         ps2wr
      mov         al, 0F3h
      call         ps2wr
      mov         al, 80
      call         ps2wr
      mov         al, 0F2h
      call         ps2wr
      call         ps2rd

      ;set sample rate
      mov         al, 0F3h
      call         ps2wr
      mov         al, byte[samplerate] ;200
      call         ps2wr
      ;set resolution
      mov         al, 0E8h
      call         ps2wr
      mov         al, byte [resolution] ;3
      call         ps2wr
      ;set scaling 1:1
      mov         al, 0E6h
      call         ps2wr
      ;enable
      mov         al, 0F4h
      call         ps2wr

      ;reset variables
      xor         eax, eax
      mov         dword [cnt], eax
      mov         dword [y], eax


And finally, the communication. You'll have to install an ISR calling this using your own PIC/IOAPIC, IDT implementation. Note that this code is not an ISR, it does not save and restore cpu state for example, it deals with the mouse only. When set up correctly, it will run every time you click or move the mouse. It calculates absolute pointer positions from delta values, but it's up to you what you do with the data.
Code:
      ;variables
packet: dd 0   ;raw packet
;keep them together
cnt: db 0      ;byte counter
buttons: db 0   ;buttons, each bit represents one button from bits 1-5, 0-released, 1-pressed
x: dw 0      ;position on x,y,z axis
y: dw 0
z: dw 0

      xor         ecx, ecx
      mov         cx, 1000
      xor         eax, eax
.waitkey:   in         al, 64h
      dec         cl
      jnz         @f
      ret
@@:      and         al, 20h
      jz         .waitkey
      in         al, 60h
      mov         cl, al
      in         al, 61h
      out         61h, al
      xor         ebx, ebx
      mov         bl, byte [cnt]
      add         ebx, packet
      mov         byte [ebx], cl
      inc         byte [cnt]
      mov         bl, byte [cnt]
      cmp         bl, byte [packetsize]
      jb         .end
      mov         byte [cnt], 0

      ;get buttons state
@@:      mov         al, byte [packet]
      and         al, 7
      mov         cl, byte [packet+3]
      and         cl, 0F0h
      cmp         cl, 0F0h
      je         .no45btn
      shr         cl, 1
      or         al, cl
.no45btn:   mov         byte [buttons], al
      ;get delta X
      movsx      eax, byte [packet+1]
      add         word [x], ax
      ;get delta Y
      movsx      eax, byte [packet+2]
      add         word [y], ax
      ;get delta Z
      mov         cl, byte [packet+3]
      and         cl, 0Fh
      cmp         cl, 8
      jb         @f
      or         cl, 0F0h
@@:      movsx      eax, cl
      add         word [z], ax

;buttons,x,y,z variables contains valid values now.
;here you possibly want to send a mouse event message to your gui process.
.end:      ret

Tested on Bochs, VirtualBox and real hardware. On real hardware it supports wheel-less mice and 3 button wheel mice. I did not have a mouse with 4th or 5th button to test with, but should work fine. Also worked with a legacy-mode USB wheel mouse. Brands: Genius, Logitech, Microsoft all ok.

ps.: sorry for the tabs, it looked fine in editor.


Top
 Profile  
 
 Post subject: Re: ps2 mouse driver in asm
PostPosted: Tue Oct 18, 2011 6:44 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,


berkus wrote:
turdus wrote:
ps.: sorry for the tabs, it looked fine in editor.


Point in favor of tabs2spaces conversion.


If you have a look at the page source, not only have the tabs been converted to spaces they've been converted to " " sequences (even though the page uses "charset=UTF-8" where a non-breaking space can be done as a normal character and needs no bloated "6 characters to represent one character" escape sequence).

Had the tabs been left as tabs it would've been up to the browser to handle it. In this case I doubt it'd look any worse (and I wouldn't be surprised if it looked a lot better). Ironically, all the indentation in the page's javascript uses tabs, and it causes no problems at all (when you do "view page source").

Point decidedly against (bad) tabs2spaces conversion... ;)


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: ps2 mouse driver in asm
PostPosted: Tue Oct 18, 2011 7:52 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7326
Location: Germany
Brendan wrote:
Ironically, all the indentation in the page's javascript uses tabs, and it causes no problems at all (when you do "view page source").


Well yes, but it just has to be executed, not displayed. ;-)

As for Turdus' recommendable contribution, how about putting it up on some website, then linking to it from the OSDev Wiki? This forum thread will soon sink down into the cesspits of the forum database, and be forgotten...

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: ps2 mouse driver in asm
PostPosted: Tue Oct 18, 2011 7:53 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9269
Location: An der schönen blauen Donau, watching muppets
If you mean the wiki, we can just do that ;)

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: ps2 mouse driver in asm
PostPosted: Tue Oct 18, 2011 8:11 am 
Offline
Member
Member
User avatar

Joined: Sat Jul 17, 2010 12:45 am
Posts: 487
Combuster wrote:
If you mean the wiki, we can just do that ;)
Yeah, linking to this thread from the relevant article of the Wiki will work best.

_________________
Programming is not about using a language to solve a problem, it's about using logic to find a solution !


Top
 Profile  
 
 Post subject: Re: ps2 mouse driver in asm
PostPosted: Wed Oct 26, 2011 8:32 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 08, 2011 1:58 pm
Posts: 496
Brendan is right (as usual), if I edit the post, I see tabs, and it look much better. Anyway, I linked this thread on wiki.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], Schol-R-LEA and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group