2 * Acess2 Mouse Driver
\r
8 #include <fs_devfs.h>
\r
9 #include <tpl_drv_common.h>
\r
10 #include <tpl_drv_joystick.h>
\r
13 #define PS2_IO_PORT 0x60
\r
14 #define MOUSE_BUFFER_SIZE (sizeof(t_mouse_fsdata))
\r
15 #define MOUSE_SENS_BASE 5
\r
19 int PS2Mouse_Install(char **Arguments);
\r
20 void PS2Mouse_IRQ(int Num);
\r
21 static void mouseSendCommand(Uint8 cmd);
\r
22 static void enableMouse();
\r
24 static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
\r
25 static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);
\r
28 int x, y, buttons, unk;
\r
32 int giMouse_Sensitivity = 1;
\r
33 t_mouse_fsdata gMouse_Data = {0, 0, 0, 0};
\r
34 int giMouse_MaxX = 640, giMouse_MaxY = 480;
\r
35 int giMouse_Cycle = 0; // IRQ Position
\r
36 Uint8 gaMouse_Bytes[4] = {0,0,0,0};
\r
37 tDevFS_Driver gMouse_DriverStruct = {
\r
40 .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX,
\r
41 .Read = PS2Mouse_Read, .IOCtl = PS2Mouse_IOCtl
\r
46 int Mouse_Install(char **Arguments)
\r
48 // Initialise Mouse Controller
\r
49 IRQ_AddHandler(12, PS2Mouse_IRQ); // Set IRQ
\r
50 giMouse_Cycle = 0; // Set Current Cycle position
\r
51 enableMouse(); // Enable the mouse
\r
53 DevFS_AddDevice(&gMouse_DriverStruct);
\r
55 return MODULE_ERR_OK;
\r
58 /* Handle Mouse Interrupt
\r
60 void PS2Mouse_IRQ(int Num)
\r
66 gaMouse_Bytes[giMouse_Cycle] = inb(0x60);
\r
67 if(giMouse_Cycle == 0 && !(gaMouse_Bytes[giMouse_Cycle] & 0x8))
\r
70 if(giMouse_Cycle == 3)
\r
75 if(giMouse_Cycle > 0)
\r
79 flags = gaMouse_Bytes[0];
\r
80 if(flags & 0xC0) // X/Y Overflow
\r
84 //LogF(" PS2Mouse_Irq: flags = 0x%x\n", flags);
\r
87 // Calculate dX and dY
\r
88 dx = (int) ( gaMouse_Bytes[1] | (flags & 0x10 ? ~0x00FF : 0) );
\r
89 dy = (int) ( gaMouse_Bytes[2] | (flags & 0x20 ? ~0x00FF : 0) );
\r
90 dy = -dy; // Y is negated
\r
91 LOG("RAW dx=%i, dy=%i\n", dx, dy);
\r
92 dx = dx*MOUSE_SENS_BASE/giMouse_Sensitivity;
\r
93 dy = dy*MOUSE_SENS_BASE/giMouse_Sensitivity;
\r
95 //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2x) : "a" ((Uint)gaMouse_Bytes[1]));
\r
96 //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2y) : "a" ((Uint)gaMouse_Bytes[2]));
\r
97 //LogF(" PS2Mouse_Irq: dx=%i, log2x = %i\n", dx, log2x);
\r
98 //LogF(" PS2Mouse_Irq: dy=%i, log2y = %i\n", dy, log2y);
\r
103 gMouse_Data.buttons = flags & 0x7; //Buttons (3 only)
\r
105 // Update X and Y Positions
\r
106 gMouse_Data.x += (int)dx;
\r
107 gMouse_Data.y += (int)dy;
\r
109 // Constrain Positions
\r
110 if(gMouse_Data.x < 0) gMouse_Data.x = 0;
\r
111 if(gMouse_Data.y < 0) gMouse_Data.y = 0;
\r
112 if(gMouse_Data.x >= giMouse_MaxX) gMouse_Data.x = giMouse_MaxX-1;
\r
113 if(gMouse_Data.y >= giMouse_MaxY) gMouse_Data.y = giMouse_MaxY-1;
\r
116 /* Read mouse state (coordinates)
\r
118 static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
\r
120 if(Length < MOUSE_BUFFER_SIZE)
\r
123 memcpy(Buffer, &gMouse_Data, MOUSE_BUFFER_SIZE);
\r
125 return MOUSE_BUFFER_SIZE;
\r
128 static const char *csaIOCtls[] = {DRV_IOCTLNAMES, NULL};
\r
129 /* Handle messages to the device
\r
131 static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)
\r
139 BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls);
\r
141 case JOY_IOCTL_GETSETAXISLIMIT:
\r
142 if(!info) return 0;
\r
146 if(info->Value != -1)
\r
147 giMouse_MaxX = info->Value;
\r
148 return giMouse_MaxX;
\r
150 if(info->Value != -1)
\r
151 giMouse_MaxY = info->Value;
\r
152 return giMouse_MaxY;
\r
161 //== Internal Functions ==
\r
162 static inline void mouseOut64(Uint8 data)
\r
164 int timeout=100000;
\r
165 while( timeout-- && inb(0x64) & 2 ); // Wait for Flag to clear
\r
166 outb(0x64, data); // Send Command
\r
168 static inline void mouseOut60(Uint8 data)
\r
170 int timeout=100000;
\r
171 while( timeout-- && inb(0x64) & 2 ); // Wait for Flag to clear
\r
172 outb(0x60, data); // Send Command
\r
174 static inline Uint8 mouseIn60()
\r
176 int timeout=100000;
\r
177 while( timeout-- && (inb(0x64) & 1) == 0); // Wait for Flag to set
\r
180 static void mouseSendCommand(Uint8 cmd)
\r
186 static void enableMouse()
\r
189 Log_Log("PS2 Mouse", "Enabling Mouse...");
\r
194 // Enable AUX PS/2 (Compaq Status Byte)
\r
195 mouseOut64(0x20); // Send Command
\r
196 status = mouseIn60(); // Get Status
\r
197 status &= 0xDF; status |= 0x02; // Alter Flags (Set IRQ12 (2) and Clear Disable Mouse Clock (20))
\r
198 mouseOut64(0x60); // Send Command
\r
199 mouseOut60(status); // Set Status
\r
201 //mouseSendCommand(0xF6); // Set Default Settings
\r
202 mouseSendCommand(0xF4); // Enable Packets
\r