PS/2 Mouse
The PS/2 mouse shares the exact same 8042 controller the PS/2 keyboard already covers, but through the controller’s second, auxiliary channel, and speaks a completely different packet-based protocol that has to be explicitly enabled before the device reports anything at all.
Enabling the second channel
Section titled “Enabling the second channel”The 8042 controller multiplexes two device ports behind the same pair of I/O ports (0x60 for data, 0x64 for commands), and the second one, conventionally wired to the mouse, is commonly left disabled until software explicitly turns it on: command 0xA8 enables it, and command 0x20 (read configuration byte) followed by 0x60 (write it back) with the second port’s interrupt-enable bit set is what lets the controller actually raise an interrupt when mouse data arrives, mirroring the same controller-command sequence the keyboard article already describes for the first channel.
mov al, 0xA8 ; enable second PS/2 portout 0x64, al
mov al, 0x20 ; read configuration byteout 0x64, alin al, 0x60or al, 0x02 ; set bit 1: enable IRQ12 (second-port interrupt)mov ah, almov al, 0x60 ; write configuration byteout 0x64, almov al, ahout 0x60, alWriting a byte to the mouse itself, rather than to the controller, additionally requires prefixing the write with command 0xD4 on port 0x64, which tells the controller to route the next data-port byte to the second channel instead of the first; omitting this prefix sends the byte to the keyboard channel instead, a common source of a mouse that silently never responds to what looks like a correctly formatted command.
Initialization sequence
Section titled “Initialization sequence”A mouse defaults to polling mode (reporting data only when explicitly asked) rather than reporting movement on its own, so a driver has to send the Enable Data Reporting command (0xF4), prefixed with 0xD4 as above, to switch it into streaming mode, where the device sends a packet automatically the moment it has new movement or button data rather than waiting to be polled.
mouse_write: mov al, 0xD4 out 0x64, al ; next byte goes to the mouse, not the keyboard mov al, 0xF4 ; Enable Data Reporting out 0x60, al ; expect 0xFA (ACK) back on port 0x60A well-behaved device acknowledges most commands with 0xFA before acting on them, which a driver should check for rather than assuming every command silently succeeds, since a mouse that never received the enable command at all simply stays quiet rather than reporting an error the driver could otherwise detect directly.
The packet format
Section titled “The packet format”Once streaming, the mouse sends a fixed-size packet, three bytes for a standard mouse or four when a scroll wheel is present, every time it has new data to report, always beginning with a byte whose bit 3 is set, a property a driver can use to resynchronize if a byte gets dropped or corrupted mid-stream.
Byte 0: Y-overflow | X-overflow | Y-sign | X-sign | 1 | middle-btn | right-btn | left-btnByte 1: X movement (signed, relative, -256 to 255)Byte 2: Y movement (signed, relative, -256 to 255)Byte 3: scroll delta (signed), present only with a scroll-wheel mouseX and Y movement are each a signed 8-bit relative delta, not an absolute position, with the corresponding sign bit in byte 0 extending that 8-bit value to a full signed integer before a driver adds it to whatever cursor position it’s tracking; the overflow bits in the same byte flag a movement large enough that the 8-bit field couldn’t represent it accurately, a rare but real condition a driver should either clamp or discard rather than silently accepting a wrapped, incorrect delta.
void handle_mouse_packet(uint8_t b0, uint8_t b1, uint8_t b2) { int dx = b1 - ((b0 << 4) & 0x100); // sign-extend using bit 4 of byte 0 int dy = b2 - ((b0 << 3) & 0x100); // sign-extend using bit 5 of byte 0
cursor_x += dx; cursor_y -= dy; // Y is typically inverted relative to screen coordinates}Implementation notes
Section titled “Implementation notes”Because both PS/2 channels raise interrupts on the same controller but on two different IRQ lines (IRQ1 for the keyboard, IRQ12 for the mouse), a driver’s mouse handler has to read exactly the number of bytes one packet requires and no more before returning, tracking packet-boundary state across interrupts the same way a keyboard driver tracks multi-byte scancode sequences, since a handler that reads one byte per interrupt without remembering which byte of the current packet it’s on will misalign every packet after the first dropped or extra byte. A scroll-wheel mouse has to be explicitly negotiated into its four-byte mode through a specific, otherwise-meaningless sequence of sample-rate-set commands (0xF3 with values 200, 100, 80 in sequence, then an identify command confirming the mouse responded by switching modes) rather than simply being detected from the hardware alone, a quirk of how this extension was retrofitted onto a protocol with no dedicated capability-negotiation mechanism of its own.
References
Section titled “References”- ^ IBM, Personal System/2 Hardware Interface Technical Reference: the same 8042 controller specification the keyboard article’s own citation covers, including the auxiliary (mouse) channel.
See also
Section titled “See also”- PS/2 Keyboard: the 8042 controller, its I/O ports, and the IRQ handling discussion this article’s second channel builds directly on.