You are viewing lukego

Luke's Weblog - PS/2 Mouse Decoding [entries|archive|friends|userinfo]
Luke Gorrie

[ website | My Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

PS/2 Mouse Decoding [May. 1st, 2009|07:27 pm]
Previous Entry Share Next Entry
[Tags|, ]
[Current Location |sydney]

Me and Ian Piumarta have been playing around with PS/2 mouse drivers and partly in Erlang. We came up with a neat way to parse the 3-byte report from a mouse that describes its position-change and button states. Here's the PS/2 mouse report format:

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Byte1 Yoverflow Xoverflow Ysign Xsign 1 MiddleBtn RightBtn LeftBtn
Byte2 X movement
Byte3 Y movement

This turns out to be pretty neat to decode with Erlang's bit syntax:

%% Decode a 3-byte PS/2 mouse report.
%% Return: {Xdelta, Ydelta, LeftButton, MiddleButton, RightButton}
decode_report(<<YO:1,XO:1,YS:1,XS:1,1:1,MMB:1,RMB:1,LMB:1,X:8,Y:8>>) ->
    {<<DX:10/signed>>,<<DY:10/signed>>} = {<<XS:1,XO:1,X:8>>, <<YS:1,YO:1,Y:8>>},
    {DX, DY, LMB, MMB, RMB}.
The DX and DY values are really 10-bit signed numbers, with the top two bits placed in the header byte, and the bit syntax has no trouble converting 10 bits from funky sources into signed numbers.

Here's a test function:

test_decode_report() ->
    {42+256, 42-512, 1, 0, 1} = decode_report(<<2#01101011, 42, 42>>).
LinkReply