X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fkb.c;h=b67c8e31b305f2ab3490caf0b43997b56a1dc913;hb=046980a1afd982af07dc97aaadb186e31eebb340;hp=fc078974f552017f73b102864a863be0c5aaf9ec;hpb=2c4e2813c105e40b962e7982b40a348dc0b272e6;p=tpg%2Facess2.git diff --git a/Kernel/drv/kb.c b/Kernel/drv/kb.c index fc078974..b67c8e31 100644 --- a/Kernel/drv/kb.c +++ b/Kernel/drv/kb.c @@ -2,7 +2,7 @@ * Acess2 * PS2 Keyboard Driver */ -#include +#include #include #include #include @@ -11,73 +11,95 @@ // === CONSTANTS === #define KB_BUFFER_SIZE 1024 +#define USE_KERNEL_MAGIC 1 // === IMPORTS === -void Threads_Dump(); +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(); +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 KB_UpdateLEDs(void); int KB_IOCtl(tVFS_Node *Node, int Id, void *Data); // === GLOBALS === -MODULE_DEFINE(0, 0x0100, PS2Keybard, KB_Install, NULL, NULL); +MODULE_DEFINE(0, 0x0100, PS2Keyboard, KB_Install, NULL, NULL); tDevFS_Driver gKB_DevInfo = { NULL, "PS2Keyboard", { .NumACLs = 0, - .Size = -1, - .Read = KB_Read, + .Size = 0, + //.Read = KB_Read, .IOCtl = KB_IOCtl } }; tKeybardCallback gKB_Callback = NULL; -Uint8 **gpKB_Map = gpKBDUS; -Uint8 gbaKB_States[256]; +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 //Uint64 giKB_ReadBase = 0; -Uint8 gaKB_Buffer[KB_BUFFER_SIZE]; //!< Keyboard Ring Buffer -volatile int giKB_InsertPoint = 0; //!< Writing location marker -volatile int giKB_ReadPoint = 0; //!< Reading location marker -volatile int giKB_InUse = 0; //!< Lock marker +//Uint32 gaKB_Buffer[KB_BUFFER_SIZE]; //!< Keyboard Ring Buffer +//volatile int giKB_InsertPoint = 0; //!< Writing location marker +//volatile int giKB_ReadPoint = 0; //!< Reading location marker +//volatile int giKB_InUse = 0; //!< Lock marker // === CODE === /** - * \fn int KB_Install(char **Arguments) + * \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 ); - return 1; + //Log("KB_Install: Installed"); + return MODULE_ERR_OK; } /** - * \fn void KB_IRQHandler() * \brief Called on a keyboard IRQ + * \param IRQNum IRQ number (unused) */ -void KB_IRQHandler() +void KB_IRQHandler(int IRQNum) { Uint8 scancode; Uint32 ch; - int keyNum; + // int keyNum; + + // Check port 0x64 to tell if this is from the aux port + //if( inb(0x64) & 0x20 ) return; - //if( inportb(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; @@ -88,7 +110,7 @@ void KB_IRQHandler() giKB_KeyLayer = 2; return; } - + #if KB_ALT_SCANCODES if(scancode == 0xF0) { @@ -102,51 +124,105 @@ void KB_IRQHandler() gbKB_KeyUp = 1; } #endif - + // Translate ch = gpKB_Map[giKB_KeyLayer][scancode]; - keyNum = giKB_KeyLayer * 256 + scancode; + //keyNum = giKB_KeyLayer * 256 + scancode; // Check for unknown key if(!ch && !gbKB_KeyUp) - Warning("UNK %i %x", giKB_KeyLayer, scancode); - - // Reset Layer - giKB_KeyLayer = 0; - + Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode); + // Key Up? if (gbKB_KeyUp) { gbKB_KeyUp = 0; - gbaKB_States[ keyNum ] = 0; // Unset key state flag - - if( !gbaKB_States[KEY_LSHIFT] && !gbaKB_States[KEY_RSHIFT] ) - gbKB_ShiftState = 0; - - KB_AddBuffer(KEY_KEYUP); - KB_AddBuffer(ch); - + 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[keyNum] = 1; - if(ch == KEY_LSHIFT || ch == KEY_RSHIFT) - gbKB_ShiftState = 1; - + 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 || ch & 0x80) return; + 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; - // Is shift pressed - if(gbKB_ShiftState ^ gbKB_CapsState) + // 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; @@ -174,74 +250,23 @@ void KB_IRQHandler() break; } } - - // --- Check for Kernel Magic Combos - if(gbaKB_States[KEY_LSHIFT] && gbaKB_States[KEY_RSHIFT]) - { - switch(ch) - { - case 'D': __asm__ __volatile__ ("xchg %bx, %bx"); break; - case 'P': Threads_Dump(); break; - } - } - - if(gKB_Callback) gKB_Callback(ch); -} -/** - * \fn void KB_AddBuffer(char ch) - * \brief Add to the keyboard ring buffer - */ -void KB_AddBuffer(char ch) -{ - // Add to buffer - gaKB_Buffer[ giKB_InsertPoint++ ] = ch; - // - Wrap - if( giKB_InsertPoint == KB_BUFFER_SIZE ) giKB_InsertPoint = 0; - // - Force increment read pointer - if( giKB_InsertPoint == giKB_ReadPoint ) giKB_ReadPoint ++; -} - -/** - * \fn Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest) - * \brief Read from the ring buffer - * \param Node Unused - * \param Offset Unused (Character Device) - * \param Length Number of bytes to read - * \param Dest Destination - */ -Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest) -{ - int pos = 0; - char *dstbuf = Dest; - - if(giKB_InUse) return -1; - giKB_InUse = 1; - - while(giKB_ReadPoint != giKB_InsertPoint && pos < Length) - { - dstbuf[pos++] = gaKB_Buffer[ giKB_ReadPoint++ ]; - if( giKB_ReadPoint == KB_BUFFER_SIZE ) giKB_InsertPoint = 0; - } - - giKB_InUse = 0; - - return Length; + if(gKB_Callback && ch != 0) gKB_Callback(ch); } /** - * \fn void KB_UpdateLEDs() + * \fn void KB_UpdateLEDs(void) * \brief Updates the status of the keyboard LEDs */ -void KB_UpdateLEDs() +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); } @@ -258,7 +283,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data) 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 @@ -268,7 +293,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data) // Set Callback gKB_Callback = Data; return 1; - + default: return 0; }