2 #include <blt/syscall.h>
4 #include "SerialMouse.h"
9 const int kBaudRate
= 1200;
10 const int kPortBase
= 0x3f8;
12 SerialMouse::SerialMouse(int xmax
, int ymax
)
18 unsigned short divisor
= 115200 / kBaudRate
;
20 outb(0, kPortBase
+ 1); // No interrupts for now
21 outb(0, kPortBase
+ 4); // clear DTR and RTS
23 outb(0x80, kPortBase
+ 3); // load divisor latch
24 outb((divisor
& 0xff), kPortBase
); // divisor LSB
25 outb((divisor
>> 8), kPortBase
+ 1); // divisor MSB
26 outb(2, kPortBase
+ 3); // clear DLAB, set up for 7N1
28 outb(3, kPortBase
+ 4); // Say hello. Raise DTR and RTS
29 if (SerialRead() == 'M')
30 printf("Detected MS serial mouse\n");
34 // The data is sent in 3 byte packets in following format:
35 // D7 D6 D5 D4 D3 D2 D1 D0
36 // 1. X 1 LB RB Y7 Y6 X7 X6
37 // 2. X 0 X5 X4 X3 X2 X1 X0
38 // 3. X 0 Y5 Y4 Y3 Y2 Y1 Y0
39 void SerialMouse::GetPos(int *out_x
, int *out_y
, int *out_buttons
)
43 // loop until we get to the beginning of a packet
46 if ((b1
& (1 << 6)) != 0)
47 break; // beginning of packet
50 char b2
= SerialRead();
51 char b3
= SerialRead();
53 fXPos
+= (int)(char)((b1
<< 6) | (b2
& 0x3f));
54 fYPos
+= (int)(char)(((b1
<< 4) & 0xc0) | (b3
& 0x3f));
56 fXPos
= min(fXPos
, fXMax
);
57 fXPos
= max(fXPos
, 0);
58 fYPos
= min(fYPos
, fYMax
);
59 fYPos
= max(fYPos
, 0);
61 *out_buttons
= (b1
>> 4) & 3;
66 unsigned char SerialMouse::SerialRead()
70 while ((inb(kPortBase
+ 5) & 1) == 0)
74 outb(1, kPortBase
+ 1); // Interrupt on recieve ready
76 int id
= inb(kPortBase
+ 2);
77 if ((id
& 1) == 0 || (id
>> 1) != 2)
78 continue; // Not for me
84 return inb(kPortBase
);