X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FInput%2FPS2KbMouse%2Fps2mouse.c;h=e80a14131d489b2c7113eae31a201487ddac7901;hb=ec0a3c65da8c3d47895ab2e5b4cec8cf2070f6eb;hp=e87292ad0658a0fdc99a30212c84aef12985065d;hpb=3764c294f21229bdf700f436fa4884f5e76e0d3a;p=tpg%2Facess2.git diff --git a/Modules/Input/PS2KbMouse/ps2mouse.c b/Modules/Input/PS2KbMouse/ps2mouse.c index e87292ad..e80a1413 100644 --- a/Modules/Input/PS2KbMouse/ps2mouse.c +++ b/Modules/Input/PS2KbMouse/ps2mouse.c @@ -6,36 +6,41 @@ #include #include #include -#include -#include +#include +#include +#include "common.h" // == CONSTANTS == -#define PS2_IO_PORT 0x60 -#define MOUSE_BUFFER_SIZE (sizeof(t_mouse_fsdata)) -#define MOUSE_SENS_BASE 5 +#define NUM_AXIES 2 // X+Y +#define NUM_BUTTONS 5 // Left, Right, Scroll Click, Scroll Up, Scroll Down // == PROTOTYPES == // - Internal - int PS2Mouse_Install(char **Arguments); -void PS2Mouse_IRQ(int Num); -static void mouseSendCommand(Uint8 cmd); -static void enableMouse(); +void PS2Mouse_HandleInterrupt(Uint8 InputByte); // - Filesystem - -static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); -static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data); - -typedef struct { - int x, y, buttons, unk; -} t_mouse_fsdata; +Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data); // == GLOBALS == +void (*gpMouse_EnableFcn)(void); +// - Settings int giMouse_Sensitivity = 1; -t_mouse_fsdata gMouse_Data = {0, 0, 0, 0}; - int giMouse_MaxX = 640, giMouse_MaxY = 480; + int giMouse_MaxX = 640, giMouse_MaxY = 480; +// - File Data +Uint8 gMouse_FileData[sizeof(tJoystick_FileHeader) + NUM_AXIES*sizeof(tJoystick_Axis) + NUM_BUTTONS]; +tJoystick_FileHeader *gMouse_FileHeader = (void *)gMouse_FileData; +tJoystick_Axis *gMouse_Axies; +Uint8 *gMouse_Buttons; +tJoystick_Callback gMouse_Callback; + int gMouse_CallbackArg; + int giMouse_AxisLimits[2]; +// - Internal State int giMouse_Cycle = 0; // IRQ Position Uint8 gaMouse_Bytes[4] = {0,0,0,0}; +// - Driver definition tDevFS_Driver gMouse_DriverStruct = { - NULL, "ps2mouse", + NULL, "PS2Mouse", { .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, .Read = PS2Mouse_Read, .IOCtl = PS2Mouse_IOCtl @@ -43,12 +48,21 @@ tDevFS_Driver gMouse_DriverStruct = { }; // == CODE == -int Mouse_Install(char **Arguments) +int PS2Mouse_Install(char **Arguments) { + + + // Set up variables + gMouse_Axies = (void*)&gMouse_FileData[4]; + gMouse_Buttons = (void*)&gMouse_Axies[NUM_AXIES]; + + gMouse_FileHeader->NAxies = 2; gMouse_FileHeader->NButtons = 3; + gMouse_Axies[0].MinValue = -10; gMouse_Axies[0].MaxValue = 10; + gMouse_Axies[1].MinValue = -10; gMouse_Axies[1].MaxValue = 10; + // Initialise Mouse Controller - IRQ_AddHandler(12, PS2Mouse_IRQ); // Set IRQ giMouse_Cycle = 0; // Set Current Cycle position - enableMouse(); // Enable the mouse + gpMouse_EnableFcn(); DevFS_AddDevice(&gMouse_DriverStruct); @@ -57,147 +71,132 @@ int Mouse_Install(char **Arguments) /* Handle Mouse Interrupt */ -void PS2Mouse_IRQ(int Num) +void PS2Mouse_HandleInterrupt(Uint8 InputByte) { Uint8 flags; - int dx, dy; - //int log2x, log2y; + int d[2], d_accel[2]; + int i; - gaMouse_Bytes[giMouse_Cycle] = inb(0x60); - if(giMouse_Cycle == 0 && !(gaMouse_Bytes[giMouse_Cycle] & 0x8)) - return; + // Gather mouse data + gaMouse_Bytes[giMouse_Cycle] = InputByte; + LOG("gaMouse_Bytes[%i] = 0x%02x", gMouse_Axies[0].MaxValue); + // - If bit 3 of the first byte is not set, it's not a valid packet? + if(giMouse_Cycle == 0 && !(gaMouse_Bytes[0] & 0x08) ) + return ; giMouse_Cycle++; - if(giMouse_Cycle == 3) - giMouse_Cycle = 0; - else - return; - - if(giMouse_Cycle > 0) - return; - - // Read Flags + if(giMouse_Cycle < 3) + return ; + + giMouse_Cycle = 0; + + // Actual Processing (once we have all bytes) flags = gaMouse_Bytes[0]; - if(flags & 0xC0) // X/Y Overflow - return; - - #if DEBUG - //LogF(" PS2Mouse_Irq: flags = 0x%x\n", flags); - #endif + + LOG("flags = 0x%x", flags); + // Check for X/Y Overflow + if(flags & 0xC0) return; + // Calculate dX and dY - dx = (int) ( gaMouse_Bytes[1] | (flags & 0x10 ? ~0x00FF : 0) ); - dy = (int) ( gaMouse_Bytes[2] | (flags & 0x20 ? ~0x00FF : 0) ); - dy = -dy; // Y is negated - LOG("RAW dx=%i, dy=%i\n", dx, dy); - dx = dx*MOUSE_SENS_BASE/giMouse_Sensitivity; - dy = dy*MOUSE_SENS_BASE/giMouse_Sensitivity; + d[0] = gaMouse_Bytes[1]; if(flags & 0x10) d[0] = -(256-d[0]); // x + d[1] = gaMouse_Bytes[2]; if(flags & 0x20) d[1] = -(256-d[1]); // y + d[1] = -d[1]; // Y is negated + LOG("RAW dx=%i, dy=%i\n", d[0], d[1]); + // Apply scaling + // TODO: Apply a form of curve to the mouse movement (dx*log(dx), dx^k?) + // TODO: Independent sensitivities? + // TODO: Disable acceleration via a flag? + d_accel[0] = d[0]*giMouse_Sensitivity; + d_accel[1] = d[1]*giMouse_Sensitivity; - //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2x) : "a" ((Uint)gaMouse_Bytes[1])); - //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2y) : "a" ((Uint)gaMouse_Bytes[2])); - //LogF(" PS2Mouse_Irq: dx=%i, log2x = %i\n", dx, log2x); - //LogF(" PS2Mouse_Irq: dy=%i, log2y = %i\n", dy, log2y); - //dx *= log2x; - //dy *= log2y; - - // Set Buttons - gMouse_Data.buttons = flags & 0x7; //Buttons (3 only) + // Set Buttons (Primary) + for( i = 0; i < 3; i ++ ) + { + Uint8 newVal = (flags & (1 << i)) ? 0xFF : 0; + if(newVal != gMouse_Buttons[i]) { + if( gMouse_Callback ) + gMouse_Callback(gMouse_CallbackArg, 0, i, newVal - gMouse_Buttons[i]); + gMouse_Buttons[i] = newVal; + } + } // Update X and Y Positions - gMouse_Data.x += (int)dx; - gMouse_Data.y += (int)dy; - - // Constrain Positions - if(gMouse_Data.x < 0) gMouse_Data.x = 0; - if(gMouse_Data.y < 0) gMouse_Data.y = 0; - if(gMouse_Data.x >= giMouse_MaxX) gMouse_Data.x = giMouse_MaxX-1; - if(gMouse_Data.y >= giMouse_MaxY) gMouse_Data.y = giMouse_MaxY-1; + for( i = 0; i < 2; i ++ ) + { + Sint16 newCursor = 0; + if( giMouse_AxisLimits[i] ) + newCursor = MIN( MAX(0, gMouse_Axies[i].CursorPos + d_accel[i]), giMouse_AxisLimits[i] );; + + if( gMouse_Callback ) + { + if(giMouse_AxisLimits[i] && gMouse_Axies[i].CursorPos != newCursor) + gMouse_Callback(gMouse_CallbackArg, 1, i, newCursor - gMouse_Axies[i].CursorPos); + if(!giMouse_AxisLimits[i] && gMouse_Axies[i].CurValue != d_accel[i]) + gMouse_Callback(gMouse_CallbackArg, 1, i, d_accel[i] - gMouse_Axies[i].CurValue); + } + + gMouse_Axies[i].CurValue = d_accel[i]; + gMouse_Axies[i].CursorPos = newCursor; + } + +// Log("Mouse at %ix%i", gMouse_Axies[0].CursorPos, gMouse_Axies[1].CursorPos); + + VFS_MarkAvaliable(&gMouse_DriverStruct.RootNode, 1); } /* Read mouse state (coordinates) */ -static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { - if(Length < MOUSE_BUFFER_SIZE) - return -1; + if(Offset > sizeof(gMouse_FileData)) return 0; + if(Length > sizeof(gMouse_FileData)) Length = sizeof(gMouse_FileData); + if(Offset + Length > sizeof(gMouse_FileData)) Length = sizeof(gMouse_FileData) - Offset; - memcpy(Buffer, &gMouse_Data, MOUSE_BUFFER_SIZE); - - return MOUSE_BUFFER_SIZE; + memcpy(Buffer, &gMouse_FileData[Offset], Length); + + VFS_MarkAvaliable(Node, 0); + return Length; } -static const char *csaIOCtls[] = {DRV_IOCTLNAMES, NULL}; +static const char *csaIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL}; /* Handle messages to the device */ -static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data) +int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data) { - struct { - int Num; - int Value; - } *info = Data; + tJoystick_NumValue *info = Data; + switch(ID) { BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls); + + case JOY_IOCTL_SETCALLBACK: // TODO: Implement + return -1; + + case JOY_IOCTL_SETCALLBACKARG: // TODO: Implement + return -1; case JOY_IOCTL_GETSETAXISLIMIT: if(!info) return 0; - switch(info->Num) - { - case 0: // X - if(info->Value != -1) - giMouse_MaxX = info->Value; - return giMouse_MaxX; - case 1: // Y - if(info->Value != -1) - giMouse_MaxY = info->Value; - return giMouse_MaxY; - } - return 0; - + if(info->Num < 0 || info->Num >= 2) return 0; + if(info->Value != -1) + giMouse_AxisLimits[info->Num] = info->Value; + return giMouse_AxisLimits[info->Num]; + + case JOY_IOCTL_GETSETAXISPOSITION: + if(!info) return 0; + if(info->Num < 0 || info->Num >= 2) return 0; + if(info->Value != -1) + gMouse_Axies[info->Num].CursorPos = info->Value; + return gMouse_Axies[info->Num].CursorPos; + + case JOY_IOCTL_GETSETAXISFLAGS: + return -1; + + case JOY_IOCTL_GETSETBUTTONFLAGS: + return -1; + default: return 0; } } -//== Internal Functions == -static inline void mouseOut64(Uint8 data) -{ - int timeout=100000; - while( timeout-- && inb(0x64) & 2 ); // Wait for Flag to clear - outb(0x64, data); // Send Command -} -static inline void mouseOut60(Uint8 data) -{ - int timeout=100000; - while( timeout-- && inb(0x64) & 2 ); // Wait for Flag to clear - outb(0x60, data); // Send Command -} -static inline Uint8 mouseIn60() -{ - int timeout=100000; - while( timeout-- && (inb(0x64) & 1) == 0); // Wait for Flag to set - return inb(0x60); -} -static void mouseSendCommand(Uint8 cmd) -{ - mouseOut64(0xD4); - mouseOut60(cmd); -} - -static void enableMouse() -{ - Uint8 status; - Log_Log("PS2 Mouse", "Enabling Mouse..."); - - // Enable AUX PS/2 - mouseOut64(0xA8); - - // Enable AUX PS/2 (Compaq Status Byte) - mouseOut64(0x20); // Send Command - status = mouseIn60(); // Get Status - status &= 0xDF; status |= 0x02; // Alter Flags (Set IRQ12 (2) and Clear Disable Mouse Clock (20)) - mouseOut64(0x60); // Send Command - mouseOut60(status); // Set Status - - //mouseSendCommand(0xF6); // Set Default Settings - mouseSendCommand(0xF4); // Enable Packets -}