X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fkeyboard.c;fp=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fkeyboard.c;h=0000000000000000000000000000000000000000;hp=409d9a4755e37974fc75172b4f54e651ddd56c5a;hb=a70930549d1b741704dd7af4e6bb0e89f6f8a519;hpb=afb634a80f946634454a5d067a92aa600227bd93 diff --git a/misc/test_vm/src/geekos/keyboard.c b/misc/test_vm/src/geekos/keyboard.c deleted file mode 100644 index 409d9a4..0000000 --- a/misc/test_vm/src/geekos/keyboard.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Keyboard driver - * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.1 $ - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "COPYING". - */ - -/* - * Information sources: - * - Chapter 8 of _The Undocumented PC_, 2nd ed, by Frank van Gilluwe, - * ISBN 0-201-47950-8. - * - Pages 400-409 of _The Programmers PC Sourcebook_, by Thom Hogan, - * ISBN 1-55615-118-7. - */ - -/* - * Credits: - * - Peter Gnodde added support for - * the CTRL and ALT modifiers - */ - -/* - * TODO list: - * - Right now we're assuming an 83-key keyboard. - * Should add support for 101+ keyboards. - * - Should toggle keyboard LEDs. - */ - -#include -#include -#include -#include -#include -#include - -/* ---------------------------------------------------------------------- - * Private data and functions - * ---------------------------------------------------------------------- */ - -/* - * Current shift state. - */ -#define LEFT_SHIFT 0x01 -#define RIGHT_SHIFT 0x02 -#define LEFT_CTRL 0x04 -#define RIGHT_CTRL 0x08 -#define LEFT_ALT 0x10 -#define RIGHT_ALT 0x20 -#define SHIFT_MASK (LEFT_SHIFT | RIGHT_SHIFT) -#define CTRL_MASK (LEFT_CTRL | RIGHT_CTRL) -#define ALT_MASK (LEFT_ALT | RIGHT_ALT) -static unsigned s_shiftState = 0; - -/* - * Queue for keycodes, in case they arrive faster than consumer - * can deal with them. - */ -#define QUEUE_SIZE 256 -#define QUEUE_MASK 0xff -#define NEXT(index) (((index) + 1) & QUEUE_MASK) -static Keycode s_queue[QUEUE_SIZE]; -static int s_queueHead, s_queueTail; - -/* - * Wait queue for thread(s) waiting for keyboard events. - */ -static struct Thread_Queue s_waitQueue; - -/* - * Translate from scan code to key code, when shift is not pressed. - */ -static const Keycode s_scanTableNoShift[] = { - KEY_UNKNOWN, ASCII_ESC, '1', '2', /* 0x00 - 0x03 */ - '3', '4', '5', '6', /* 0x04 - 0x07 */ - '7', '8', '9', '0', /* 0x08 - 0x0B */ - '-', '=', ASCII_BS, '\t', /* 0x0C - 0x0F */ - 'q', 'w', 'e', 'r', /* 0x10 - 0x13 */ - 't', 'y', 'u', 'i', /* 0x14 - 0x17 */ - 'o', 'p', '[', ']', /* 0x18 - 0x1B */ - '\r', KEY_LCTRL, 'a', 's', /* 0x1C - 0x1F */ - 'd', 'f', 'g', 'h', /* 0x20 - 0x23 */ - 'j', 'k', 'l', ';', /* 0x24 - 0x27 */ - '\'', '`', KEY_LSHIFT, '\\', /* 0x28 - 0x2B */ - 'z', 'x', 'c', 'v', /* 0x2C - 0x2F */ - 'b', 'n', 'm', ',', /* 0x30 - 0x33 */ - '.', '/', KEY_RSHIFT, KEY_PRINTSCRN, /* 0x34 - 0x37 */ - KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, /* 0x38 - 0x3B */ - KEY_F2, KEY_F3, KEY_F4, KEY_F5, /* 0x3C - 0x3F */ - KEY_F6, KEY_F7, KEY_F8, KEY_F9, /* 0x40 - 0x43 */ - KEY_F10, KEY_NUMLOCK, KEY_SCRLOCK, KEY_KPHOME, /* 0x44 - 0x47 */ - KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, /* 0x48 - 0x4B */ - KEY_KPCENTER, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND, /* 0x4C - 0x4F */ - KEY_KPDOWN, KEY_KPPGDN, KEY_KPINSERT, KEY_KPDEL, /* 0x50 - 0x53 */ - KEY_SYSREQ, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, /* 0x54 - 0x57 */ -}; -#define SCAN_TABLE_SIZE (sizeof(s_scanTableNoShift) / sizeof(Keycode)) - -/* - * Translate from scan code to key code, when shift *is* pressed. - * Keep this in sync with the unshifted table above! - * They must be the same size. - */ -static const Keycode s_scanTableWithShift[] = { - KEY_UNKNOWN, ASCII_ESC, '!', '@', /* 0x00 - 0x03 */ - '#', '$', '%', '^', /* 0x04 - 0x07 */ - '&', '*', '(', ')', /* 0x08 - 0x0B */ - '_', '+', ASCII_BS, '\t', /* 0x0C - 0x0F */ - 'Q', 'W', 'E', 'R', /* 0x10 - 0x13 */ - 'T', 'Y', 'U', 'I', /* 0x14 - 0x17 */ - 'O', 'P', '{', '}', /* 0x18 - 0x1B */ - '\r', KEY_LCTRL, 'A', 'S', /* 0x1C - 0x1F */ - 'D', 'F', 'G', 'H', /* 0x20 - 0x23 */ - 'J', 'K', 'L', ':', /* 0x24 - 0x27 */ - '"', '~', KEY_LSHIFT, '|', /* 0x28 - 0x2B */ - 'Z', 'X', 'C', 'V', /* 0x2C - 0x2F */ - 'B', 'N', 'M', '<', /* 0x30 - 0x33 */ - '>', '?', KEY_RSHIFT, KEY_PRINTSCRN, /* 0x34 - 0x37 */ - KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, /* 0x38 - 0x3B */ - KEY_F2, KEY_F3, KEY_F4, KEY_F5, /* 0x3C - 0x3F */ - KEY_F6, KEY_F7, KEY_F8, KEY_F9, /* 0x40 - 0x43 */ - KEY_F10, KEY_NUMLOCK, KEY_SCRLOCK, KEY_KPHOME, /* 0x44 - 0x47 */ - KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, /* 0x48 - 0x4B */ - KEY_KPCENTER, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND, /* 0x4C - 0x4F */ - KEY_KPDOWN, KEY_KPPGDN, KEY_KPINSERT, KEY_KPDEL, /* 0x50 - 0x53 */ - KEY_SYSREQ, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, /* 0x54 - 0x57 */ -}; - -static __inline__ bool Is_Queue_Empty(void) -{ - return s_queueHead == s_queueTail; -} - -static __inline__ bool Is_Queue_Full(void) -{ - return NEXT(s_queueTail) == s_queueHead; -} - -static __inline__ void Enqueue_Keycode(Keycode keycode) -{ - if (!Is_Queue_Full()) { - s_queue[ s_queueTail ] = keycode; - s_queueTail = NEXT(s_queueTail); - } -} - -static __inline__ Keycode Dequeue_Keycode(void) -{ - Keycode result; - KASSERT(!Is_Queue_Empty()); - result = s_queue[ s_queueHead ]; - s_queueHead = NEXT(s_queueHead); - return result; -} - -/* - * Handler for keyboard interrupts. - */ -static void Keyboard_Interrupt_Handler(struct Interrupt_State* state) -{ - uchar_t status, scanCode; - unsigned flag = 0; - bool release = false, shift; - Keycode keycode; - - Begin_IRQ(state); - - status = In_Byte(KB_CMD); - IO_Delay(); - - if ((status & KB_OUTPUT_FULL) != 0) { - /* There is a byte available */ - scanCode = In_Byte(KB_DATA); - IO_Delay(); -/* - * Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : ""); - */ - - if (scanCode & KB_KEY_RELEASE) { - release = true; - scanCode &= ~(KB_KEY_RELEASE); - } - - if (scanCode >= SCAN_TABLE_SIZE) { - Print("Unknown scan code: %x\n", scanCode); - goto done; - } - - /* Process the key */ - shift = ((s_shiftState & SHIFT_MASK) != 0); - keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode]; - - /* Update shift, control and alt state */ - switch (keycode) { - case KEY_LSHIFT: - flag = LEFT_SHIFT; - break; - case KEY_RSHIFT: - flag = RIGHT_SHIFT; - break; - case KEY_LCTRL: - flag = LEFT_CTRL; - break; - case KEY_RCTRL: - flag = RIGHT_CTRL; - break; - case KEY_LALT: - flag = LEFT_ALT; - break; - case KEY_RALT: - flag = RIGHT_ALT; - break; - default: - goto noflagchange; - } - - if (release) - s_shiftState &= ~(flag); - else - s_shiftState |= flag; - - /* - * Shift, control and alt keys don't have to be - * queued, flags will be set! - */ - goto done; - -noflagchange: - /* Format the new keycode */ - if (shift) - keycode |= KEY_SHIFT_FLAG; - if ((s_shiftState & CTRL_MASK) != 0) - keycode |= KEY_CTRL_FLAG; - if ((s_shiftState & ALT_MASK) != 0) - keycode |= KEY_ALT_FLAG; - if (release) - keycode |= KEY_RELEASE_FLAG; - - /* Put the keycode in the buffer */ - Enqueue_Keycode(keycode); - - /* Wake up event consumers */ - Wake_Up(&s_waitQueue); - - /* - * Pick a new thread upon return from interrupt - * (hopefully the one waiting for the keyboard event) - */ - g_needReschedule = true; - } - -done: - End_IRQ(state); -} - -/* ---------------------------------------------------------------------- - * Public functions - * ---------------------------------------------------------------------- */ - -void Init_Keyboard(void) -{ - ushort_t irqMask; - - Print("Initializing keyboard...\n"); - - /* Start out with no shift keys enabled. */ - s_shiftState = 0; - - /* Buffer is initially empty. */ - s_queueHead = s_queueTail = 0; - - /* Install interrupt handler */ - Install_IRQ(KB_IRQ, Keyboard_Interrupt_Handler); - - /* Enable IRQ1 (keyboard) */ - irqMask = Get_IRQ_Mask(); - irqMask &= ~(1 << KB_IRQ); - Set_IRQ_Mask(irqMask); -} - -/* - * Poll for a key event. - * Returns true if a key is available, - * false if not. If a key event is available, - * it will be stored in the location pointed to - * by keycode. - */ -bool Read_Key(Keycode* keycode) -{ - bool result, iflag; - - iflag = Begin_Int_Atomic(); - - result = !Is_Queue_Empty(); - if (result) { - *keycode = Dequeue_Keycode(); - } - - End_Int_Atomic(iflag); - - return result; -} - -/* - * Wait for a keycode to arrive. - * Uses the keyboard wait queue to sleep until - * a keycode arrives. - */ -Keycode Wait_For_Key(void) -{ - bool gotKey, iflag; - Keycode keycode = KEY_UNKNOWN; - - iflag = Begin_Int_Atomic(); - - do { - gotKey = !Is_Queue_Empty(); - if (gotKey) - keycode = Dequeue_Keycode(); - else - Wait(&s_waitQueue); - } - while (!gotKey); - - End_Int_Atomic(iflag); - - return keycode; -}