2

Once a mouse has been initialized, a mouse sends 3 or 4 byte packets to communicate mouse movement, and mouse button press/release events. These packets show up asynchronously as data on IO port 0x60.

My question is how do I extract those 4 or 5 byte packets

In my assembly code I used 0xf4 mouse command to enable packet streaming

and I tried this code to extract the 3 or 4 bytes packets like this:

xor cx, cx
read:
in al, 0x64
test al, 1b
loopnz read

mov cx, 0xa0000 ; waiting 655 360 times
pause:
loop pause

in eax, 60h
mov [packets], eax

;and the values i get here is 250(0xfa) only 


Jmp $ 

I'm using NASM Assembler under Windows 10

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
  • 1
    Unclear what your problem is. Please provide a [mcve] – Stefan Becker Jan 30 '19 at 07:31
  • Possible duplicate of [Assembly Keyboard IO Port](https://stackoverflow.com/questions/3434827/assembly-keyboard-io-port) – Stefan Becker Jan 30 '19 at 07:32
  • Is the `c` tag there because you're looking for help in C or, since there's nothing about C in your question, can it be safely removed? – Federico klez Culloca Jan 30 '19 at 07:58
  • What environment are you running this code in? –  Jan 30 '19 at 07:59
  • 3
    I'd like to know the environment too. Real mode, protected mode? long mode? Don't think port 60h allows for 4 bytes to be read at a time. `mov cx, 0xa0000` is putting a value bigger than 16-bits into CX, so likely that will be truncated to 0 – Michael Petch Jan 30 '19 at 09:12
  • 1
    It's ironic that your loop named `pause` does not contain [a `pause` instruction](https://www.felixcloutier.com/x86/pause), only the `loop` instruction (although that is slow, except on AMD CPUs.) But anyway, I suspect that you need to read 1 or maybe 2 bytes at a time. Remember this stuff was designed before 32-bit existed. – Peter Cordes Jan 30 '19 at 09:52
  • @PeterCordes: That loop is broken. The PS/2 controller only has a 1-byte buffer, and when a byte arrives from a different PS/2 port (e.g. from keyboard) the buffer will be full, causing the loop to think data arrived from the mouse when it didn't, causing "random" corruption of data from mouse. For most (not all) PS/2 controllers, bit 5 of the status register is a "byte is/isn't from second PS/2 port" flag; but if that flag is tested (a "wait for byte from the right PS/2 port" loop) it'll wait forever (until the byte from the wrong device is removed by something running on a different CPU?). – Brendan Jan 31 '19 at 08:27

1 Answers1

4

A modern PS/2 mouse typically has a default mode ("2 button, no scrollwheel") that uses an older (3 bytes per packet) protocol; then one or more better modes ("5 button, with scrollwheel") that uses a different (4 bytes per packet) protocol. To switch modes there's a sequence of existing commands (and not a simple "change modes" command).

Specifically, to change from the default mode to "Intellimouse Extensions" mode (3 buttons with scrollwheel, 4 byte packet):

  • Set sample rate 200
  • Set sample rate 100
  • Set sample rate 80

And to change to "5 button mode" (up to 5 buttons with scrollwheel, 4 byte packet):

  • Set sample rate 200
  • Set sample rate 200
  • Set sample rate 80

For more (better) information, see: http://www.isdaman.com/alsos/hardware/mouse/ps2interface.htm

Note that you should never poll. Specifically, unless you are using IRQs (e.g. ISA IRQ1 for first PS/2 port, ISA IRQ 12 for 2nd PS/2 port) it's impossible to reliably (without race conditions) determine which PS/2 port a byte came from.

More specifically, the PS/2 controller driver should use IRQs, and should send bytes received on "1st PS/2 port" to whichever driver is being used for whichever device happens to be plugged into the 1st PS/2 port (keyboard, mouse, bar-code scanner, touchpad, ...); and send bytes received on "2st PS/2 port" to whichever driver is being used for whichever device happens to be plugged into the 2st PS/2 port. The mouse driver itself would receive the data (e.g. from a pipe or message or callback or who-knows-what) and add the byte to a (3 or 4 byte) packet buffer (while checking the "always 0" bit to ensure that it remains in sync with the device, and while handling special codes like "ACK" and "RESEND").

Brendan
  • 35,656
  • 2
  • 39
  • 66