Moved PS2 Keyboard driver out to module tree (still in kernel, but will move once...
authorJohn Hodge <[email protected]>
Sun, 8 May 2011 14:14:11 +0000 (22:14 +0800)
committerJohn Hodge <[email protected]>
Sun, 8 May 2011 14:14:11 +0000 (22:14 +0800)
- Adding a PS2 mouse driver too

Modules/Input/PS2KbMouse/Makefile [new file with mode: 0644]
Modules/Input/PS2KbMouse/kb.c [new file with mode: 0644]
Modules/Input/PS2KbMouse/kb_kbdus.h [new file with mode: 0644]
Modules/Input/PS2KbMouse/main.c [new file with mode: 0644]
Modules/Input/PS2KbMouse/ps2mouse.c [new file with mode: 0644]

diff --git a/Modules/Input/PS2KbMouse/Makefile b/Modules/Input/PS2KbMouse/Makefile
new file mode 100644 (file)
index 0000000..e30e472
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o kb.o ps2mouse.o
+NAME = PS2KbMouse
+
+-include ../Makefile.tpl
diff --git a/Modules/Input/PS2KbMouse/kb.c b/Modules/Input/PS2KbMouse/kb.c
new file mode 100644 (file)
index 0000000..507d575
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Acess2
+ * PS2 Keyboard Driver
+ */
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <tpl_drv_common.h>
+#include <tpl_drv_keyboard.h>
+#include "kb_kbdus.h"
+
+// === CONSTANTS ===
+#define        KB_BUFFER_SIZE  1024
+#define        USE_KERNEL_MAGIC        1
+
+// === IMPORTS ===
+extern void    Threads_ToggleTrace(int TID);
+extern void    Threads_Dump(void);
+extern void    Heap_Stats(void);
+
+// === PROTOTYPES ===
+ int   KB_Install(char **Arguments);
+void   KB_IRQHandler(int IRQNum);
+void   KB_AddBuffer(char ch);
+Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest);
+void   KB_UpdateLEDs(void);
+ int   KB_IOCtl(tVFS_Node *Node, int Id, void *Data);
+
+// === GLOBALS ===
+tDevFS_Driver  gKB_DevInfo = {
+       NULL, "PS2Keyboard",
+       {
+       .NumACLs = 0,
+       .Size = 0,
+       //.Read = KB_Read,
+       .IOCtl = KB_IOCtl
+       }
+};
+tKeybardCallback       gKB_Callback = NULL;
+Uint32 **gpKB_Map = gpKBDUS;
+Uint8  gbaKB_States[3][256];
+ int   gbKB_ShiftState = 0;
+ int   gbKB_CapsState = 0;
+ int   gbKB_KeyUp = 0;
+ int   giKB_KeyLayer = 0;
+#if USE_KERNEL_MAGIC
+ int   gbKB_MagicState = 0;
+ int   giKB_MagicAddress = 0;
+ int   giKB_MagicAddressPos = 0;
+#endif
+
+// === CODE ===
+/**
+ * \brief Install the keyboard driver
+ */
+int KB_Install(char **Arguments)
+{
+       Uint8   temp;
+       
+       // Attempt to get around a strange bug in Bochs/Qemu by toggling
+       // the controller on and off
+       temp = inb(0x61);
+       outb(0x61, temp | 0x80);
+       outb(0x61, temp & 0x7F);
+       inb(0x60);      // Clear keyboard buffer
+       
+       IRQ_AddHandler(1, KB_IRQHandler);
+       DevFS_AddDevice( &gKB_DevInfo );
+       //Log("KB_Install: Installed");
+       return MODULE_ERR_OK;
+}
+
+/**
+ * \brief Called on a keyboard IRQ
+ * \param IRQNum       IRQ number (unused)
+ */
+void KB_IRQHandler(int IRQNum)
+{
+       Uint8   scancode;
+       Uint32  ch;
+       // int  keyNum;
+
+       // Check port 0x64 to tell if this is from the aux port
+       //if( inb(0x64) & 0x20 )        return;
+
+       scancode = inb(0x60); // Read from the keyboard's data buffer
+       //Log_Debug("Keyboard", "scancode = %02x", scancode);
+
+       // Ignore ACKs
+       if(scancode == 0xFA) {
+               // Oh man! This is anarchic (I'm leaving it here to represent
+               // the mess that Acess once was)
+               //kb_lastChar = KB_ACK;
+               return;
+       }
+
+       // Layer +1
+       if(scancode == 0xE0) {
+               giKB_KeyLayer = 1;
+               return;
+       }
+       // Layer +2
+       if(scancode == 0xE1) {
+               giKB_KeyLayer = 2;
+               return;
+       }
+
+       #if KB_ALT_SCANCODES
+       if(scancode == 0xF0)
+       {
+               gbKB_KeyUp = 1;
+               return;
+       }
+       #else
+       if(scancode & 0x80)
+       {
+               scancode &= 0x7F;
+               gbKB_KeyUp = 1;
+       }
+       #endif
+
+       // Translate
+       ch = gpKB_Map[giKB_KeyLayer][scancode];
+       // Check for unknown key
+       if(!ch && !gbKB_KeyUp)
+               Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode);
+
+       // Key Up?
+       if (gbKB_KeyUp)
+       {
+               gbKB_KeyUp = 0;
+               gbaKB_States[giKB_KeyLayer][scancode] = 0;      // Unset key state flag
+
+               #if USE_KERNEL_MAGIC
+               if(ch == KEY_LCTRL)     gbKB_MagicState &= ~1;
+               if(ch == KEY_LALT)      gbKB_MagicState &= ~2;
+               #endif
+
+               if(ch == KEY_LSHIFT)    gbKB_ShiftState &= ~1;
+               if(ch == KEY_RSHIFT)    gbKB_ShiftState &= ~2;
+
+               // Call callback
+               if(ch != 0 && gKB_Callback)
+                       gKB_Callback( ch & 0x80000000 );
+
+               // Reset Layer
+               giKB_KeyLayer = 0;
+               return;
+       }
+
+       // Set the bit relating to the key
+       gbaKB_States[giKB_KeyLayer][scancode] = 1;
+       // Set shift key bits
+       if(ch == KEY_LSHIFT)    gbKB_ShiftState |= 1;
+       if(ch == KEY_RSHIFT)    gbKB_ShiftState |= 2;
+
+       // Check for Caps Lock
+       if(ch == KEY_CAPSLOCK) {
+               gbKB_CapsState = !gbKB_CapsState;
+               KB_UpdateLEDs();
+       }
+
+       // Reset Layer
+       giKB_KeyLayer = 0;
+
+       // Ignore Non-Printable Characters
+       if(ch == 0)             return;
+
+       // --- Check for Kernel Magic Combos
+       #if USE_KERNEL_MAGIC
+       if(ch == KEY_LCTRL) {
+               gbKB_MagicState |= 1;
+               //Log_Log("Keyboard", "Kernel Magic LCTRL Down\n");
+       }
+       if(ch == KEY_LALT) {
+               gbKB_MagicState |= 2;
+               //Log_Log("Keyboard", "Kernel Magic LALT Down\n");
+       }
+       if(gbKB_MagicState == 3)
+       {
+               switch(ch)
+               {
+               case '0':       case '1':       case '2':       case '3':
+               case '4':       case '5':       case '6':       case '7':
+               case '8':       case '9':       case 'a':       case 'b':
+               case 'c':       case 'd':       case 'e':       case 'f':
+                       {
+                       char    str[4] = {'0', 'x', ch, 0};
+                       if(giKB_MagicAddressPos == BITS/4)      return;
+                       giKB_MagicAddress |= atoi(str) << giKB_MagicAddressPos;
+                       giKB_MagicAddressPos ++;
+                       }
+                       return;
+               
+               // Instruction Tracing
+               case 't':
+                       Log("Toggle instruction tracing on %i\n", giKB_MagicAddress);
+                       Threads_ToggleTrace( giKB_MagicAddress );
+                       giKB_MagicAddress = 0;  giKB_MagicAddressPos = 0;
+                       return;
+               
+               // Thread List Dump
+               case 'p':       Threads_Dump(); return;
+               // Heap Statistics
+               case 'h':       Heap_Stats();   return;
+               // Dump Structure
+               case 's':       return;
+               }
+       }
+       #endif
+
+       // Capitals required?
+       if( (gbKB_ShiftState != 0) != (gbKB_CapsState != 0))
+       {
+               // TODO: Move this to the keyboard map header
+               switch(ch)
+               {
+               case 0: break;
+               case '`':       ch = '~';       break;
+               case '1':       ch = '!';       break;
+               case '2':       ch = '@';       break;
+               case '3':       ch = '#';       break;
+               case '4':       ch = '$';       break;
+               case '5':       ch = '%';       break;
+               case '6':       ch = '^';       break;
+               case '7':       ch = '&';       break;
+               case '8':       ch = '*';       break;
+               case '9':       ch = '(';       break;
+               case '0':       ch = ')';       break;
+               case '-':       ch = '_';       break;
+               case '=':       ch = '+';       break;
+               case '[':       ch = '{';       break;
+               case ']':       ch = '}';       break;
+               case '\\':      ch = '|';       break;
+               case ';':       ch = ':';       break;
+               case '\'':      ch = '"';       break;
+               case ',':       ch = '<';       break;
+               case '.':       ch = '>';       break;
+               case '/':       ch = '?';       break;
+               default:
+                       if('a' <= ch && ch <= 'z')
+                               ch -= 0x20;
+                       break;
+               }
+       }
+
+       if(gKB_Callback && ch != 0)     gKB_Callback(ch);
+}
+
+/**
+ * \fn void KB_UpdateLEDs(void)
+ * \brief Updates the status of the keyboard LEDs
+ */
+void KB_UpdateLEDs(void)
+{
+       Uint8   leds;
+
+       leds = (gbKB_CapsState ? 4 : 0);
+
+       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
+       outb(0x60, 0xED);       // Send update command
+
+       while( inb(0x64) & 2 ); // Wait for bit 2 to unset
+       outb(0x60, leds);
+}
+
+/**
+ * \fn int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Calls an IOCtl Command
+ */
+int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+       switch(Id)
+       {
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_KEYBOARD;
+       case DRV_IOCTL_IDENT:   memcpy(Data, "KB\0\0", 4);      return 1;
+       case DRV_IOCTL_VERSION: return 0x100;
+       case DRV_IOCTL_LOOKUP:  return 0;
+
+       // Sets the Keyboard Callback
+       case KB_IOCTL_SETCALLBACK:
+               // Sanity Check
+               if((Uint)Data < KERNEL_BASE)    return 0;
+               // Can only be set once
+               if(gKB_Callback != NULL)        return 0;
+               // Set Callback
+               gKB_Callback = Data;
+               return 1;
+
+       default:
+               return 0;
+       }
+}
diff --git a/Modules/Input/PS2KbMouse/kb_kbdus.h b/Modules/Input/PS2KbMouse/kb_kbdus.h
new file mode 100644 (file)
index 0000000..441b19a
--- /dev/null
@@ -0,0 +1,73 @@
+\r
+#ifndef _KBDUS_H\r
+#define _KBDUS_H\r
+\r
+// - BASE (NO PREFIX)\r
+Uint32 gpKBDUS1[256] = {\r
+/*00*/ 0,  KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t',\r
+/*10*/ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', KEY_LCTRL, 'a', 's',\r
+/*20*/ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', KEY_LSHIFT,'\\', 'z', 'x', 'c', 'v',\r
+/*30*/ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, KEY_KPSTAR,\r
+                       KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,\r
+/*40*/ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KPHOME,\r
+                       KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND,\r
+/*50*/ KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL, 0, 0, 0, KEY_F11,\r
+                       KEY_F12, 0, 0, 0, 0, 0, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+// - 0xE0 Prefixed\r
+Uint32 gpKBDUS2[256] = {\r
+//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
+/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
+/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_KPENTER, KEY_RCTRL, 0, 0,\r
+/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*30*/ 0, 0, 0, 0, 0, KEY_KPSLASH, 0, 0, KEY_RALT, 0, 0, 0, 0, 0, 0, 0,\r
+/*40*/ 0, 0, 0, 0, 0, 0, 0, KEY_HOME,\r
+                       KEY_UP, KEY_PGUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END,\r
+/*50*/ KEY_DOWN, KEY_PGDOWN, KEY_INS, KEY_DEL, 0, 0, 0, 0,\r
+                       0, 0, KEY_WIN, 0, 0, KEY_MENU, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+// - 0xE1 Prefixed\r
+Uint32 gpKBDUS3[256] = {\r
+//     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
+/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
+/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PAUSE, 0, 0,\r
+/*20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+\r
+\r
+Uint32 *gpKBDUS[3] = { gpKBDUS1, gpKBDUS2, gpKBDUS3 };\r
+\r
+#endif\r
diff --git a/Modules/Input/PS2KbMouse/main.c b/Modules/Input/PS2KbMouse/main.c
new file mode 100644 (file)
index 0000000..179bbb1
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Acess2
+ *
+ * PS/2 Keboard / Mouse Driver
+ */
+#include <acess.h>
+#include <modules.h>
+
+// === IMPORTS ===
+extern int     KB_Install(char **Arguments);
+extern int     Mouse_Install(char **Arguments);
+
+// === PROTOTYPES ===
+ int   PS2_Install(char **Arguments);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x0100, Input_PS2KbMouse, PS2_Install, NULL, NULL);
+
+// === CODE ===
+int PS2_Install(char **Arguments)
+{
+       KB_Install(Arguments);
+//     Mouse_Install(Arguments);
+       return MODULE_ERR_OK;
+}
diff --git a/Modules/Input/PS2KbMouse/ps2mouse.c b/Modules/Input/PS2KbMouse/ps2mouse.c
new file mode 100644 (file)
index 0000000..e87292a
--- /dev/null
@@ -0,0 +1,203 @@
+/*\r
+ * Acess2 Mouse Driver\r
+ */\r
+#define DEBUG  0\r
+#include <acess.h>\r
+#include <modules.h>\r
+#include <vfs.h>\r
+#include <fs_devfs.h>\r
+#include <tpl_drv_common.h>\r
+#include <tpl_drv_joystick.h>\r
+\r
+// == CONSTANTS ==\r
+#define PS2_IO_PORT    0x60\r
+#define MOUSE_BUFFER_SIZE      (sizeof(t_mouse_fsdata))\r
+#define MOUSE_SENS_BASE        5\r
+\r
+// == PROTOTYPES ==\r
+// - Internal -\r
+ int   PS2Mouse_Install(char **Arguments);\r
+void   PS2Mouse_IRQ(int Num);\r
+static void    mouseSendCommand(Uint8 cmd);\r
+static void    enableMouse();\r
+// - Filesystem -\r
+static Uint64  PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
+static int     PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
+\r
+typedef struct {\r
+       int x, y, buttons, unk;\r
+}      t_mouse_fsdata;\r
+\r
+// == GLOBALS ==\r
+ int   giMouse_Sensitivity = 1;\r
+t_mouse_fsdata gMouse_Data = {0, 0, 0, 0};\r
+ int giMouse_MaxX = 640, giMouse_MaxY = 480;\r
+ int   giMouse_Cycle = 0;      // IRQ Position\r
+Uint8  gaMouse_Bytes[4] = {0,0,0,0};\r
+tDevFS_Driver  gMouse_DriverStruct = {\r
+       NULL, "ps2mouse",\r
+       {\r
+       .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX,\r
+       .Read = PS2Mouse_Read, .IOCtl = PS2Mouse_IOCtl\r
+       }\r
+};\r
+\r
+// == CODE ==\r
+int Mouse_Install(char **Arguments)\r
+{\r
+       // Initialise Mouse Controller\r
+       IRQ_AddHandler(12, PS2Mouse_IRQ);       // Set IRQ\r
+       giMouse_Cycle = 0;      // Set Current Cycle position\r
+       enableMouse();          // Enable the mouse\r
+       \r
+       DevFS_AddDevice(&gMouse_DriverStruct);\r
+       \r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+/* Handle Mouse Interrupt\r
+ */\r
+void PS2Mouse_IRQ(int Num)\r
+{\r
+       Uint8   flags;\r
+       int     dx, dy;\r
+       //int   log2x, log2y;\r
+       \r
+       gaMouse_Bytes[giMouse_Cycle] = inb(0x60);\r
+       if(giMouse_Cycle == 0 && !(gaMouse_Bytes[giMouse_Cycle] & 0x8))\r
+               return;\r
+       giMouse_Cycle++;\r
+       if(giMouse_Cycle == 3)\r
+               giMouse_Cycle = 0;\r
+       else\r
+               return;\r
+       \r
+       if(giMouse_Cycle > 0)\r
+               return;\r
+       \r
+       // Read Flags\r
+       flags = gaMouse_Bytes[0];\r
+       if(flags & 0xC0)        // X/Y Overflow\r
+               return;\r
+               \r
+       #if DEBUG\r
+       //LogF(" PS2Mouse_Irq: flags = 0x%x\n", flags);\r
+       #endif\r
+       \r
+       // Calculate dX and dY\r
+       dx = (int) ( gaMouse_Bytes[1] | (flags & 0x10 ? ~0x00FF : 0) );\r
+       dy = (int) ( gaMouse_Bytes[2] | (flags & 0x20 ? ~0x00FF : 0) );\r
+       dy = -dy;       // Y is negated\r
+       LOG("RAW dx=%i, dy=%i\n", dx, dy);\r
+       dx = dx*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
+       dy = dy*MOUSE_SENS_BASE/giMouse_Sensitivity;\r
+       \r
+       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2x) : "a" ((Uint)gaMouse_Bytes[1]));\r
+       //__asm__ __volatile__ ("bsr %%eax, %%ecx" : "=c" (log2y) : "a" ((Uint)gaMouse_Bytes[2]));\r
+       //LogF(" PS2Mouse_Irq: dx=%i, log2x = %i\n", dx, log2x);\r
+       //LogF(" PS2Mouse_Irq: dy=%i, log2y = %i\n", dy, log2y);\r
+       //dx *= log2x;\r
+       //dy *= log2y;\r
+       \r
+       // Set Buttons\r
+       gMouse_Data.buttons = flags & 0x7;      //Buttons (3 only)\r
+       \r
+       // Update X and Y Positions\r
+       gMouse_Data.x += (int)dx;\r
+       gMouse_Data.y += (int)dy;\r
+       \r
+       // Constrain Positions\r
+       if(gMouse_Data.x < 0)   gMouse_Data.x = 0;\r
+       if(gMouse_Data.y < 0)   gMouse_Data.y = 0;\r
+       if(gMouse_Data.x >= giMouse_MaxX)       gMouse_Data.x = giMouse_MaxX-1;\r
+       if(gMouse_Data.y >= giMouse_MaxY)       gMouse_Data.y = giMouse_MaxY-1; \r
+}\r
+\r
+/* Read mouse state (coordinates)\r
+ */\r
+static Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+       if(Length < MOUSE_BUFFER_SIZE)\r
+               return -1;\r
+\r
+       memcpy(Buffer, &gMouse_Data, MOUSE_BUFFER_SIZE);\r
+               \r
+       return MOUSE_BUFFER_SIZE;\r
+}\r
+\r
+static const char *csaIOCtls[] = {DRV_IOCTLNAMES, NULL};\r
+/* Handle messages to the device\r
+ */\r
+static int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
+{\r
+       struct {\r
+                int    Num;\r
+                int    Value;\r
+       }       *info = Data;\r
+       switch(ID)\r
+       {\r
+       BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls);\r
+       \r
+       case JOY_IOCTL_GETSETAXISLIMIT:\r
+               if(!info)       return 0;\r
+               switch(info->Num)\r
+               {\r
+               case 0: // X\r
+                       if(info->Value != -1)\r
+                               giMouse_MaxX = info->Value;\r
+                       return giMouse_MaxX;\r
+               case 1: // Y\r
+                       if(info->Value != -1)\r
+                               giMouse_MaxY = info->Value;\r
+                       return giMouse_MaxY;\r
+               }\r
+               return 0;\r
+               \r
+       default:\r
+               return 0;\r
+       }\r
+}\r
+\r
+//== Internal Functions ==\r
+static inline void mouseOut64(Uint8 data)\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && inb(0x64) & 2 );    // Wait for Flag to clear\r
+       outb(0x64, data);       // Send Command\r
+}\r
+static inline void mouseOut60(Uint8 data)\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && inb(0x64) & 2 );    // Wait for Flag to clear\r
+       outb(0x60, data);       // Send Command\r
+}\r
+static inline Uint8 mouseIn60()\r
+{\r
+       int timeout=100000;\r
+       while( timeout-- && (inb(0x64) & 1) == 0);      // Wait for Flag to set\r
+       return inb(0x60);\r
+}\r
+static void mouseSendCommand(Uint8 cmd)\r
+{\r
+       mouseOut64(0xD4);\r
+       mouseOut60(cmd);\r
+}\r
+\r
+static void enableMouse()\r
+{\r
+       Uint8   status;\r
+       Log_Log("PS2 Mouse", "Enabling Mouse...");\r
+       \r
+       // Enable AUX PS/2\r
+       mouseOut64(0xA8);\r
+       \r
+       // Enable AUX PS/2 (Compaq Status Byte)\r
+       mouseOut64(0x20);       // Send Command\r
+       status = mouseIn60();   // Get Status\r
+       status &= 0xDF; status |= 0x02; // Alter Flags (Set IRQ12 (2) and Clear Disable Mouse Clock (20))\r
+       mouseOut64(0x60);       // Send Command\r
+       mouseOut60(status);     // Set Status\r
+       \r
+       //mouseSendCommand(0xF6);       // Set Default Settings\r
+       mouseSendCommand(0xF4); // Enable Packets\r
+}\r

UCC git Repository :: git.ucc.asn.au