summaryrefslogtreecommitdiffstats
path: root/driver/keyboard.c
diff options
context:
space:
mode:
authorneoraider <devnull@localhost>2005-04-18 17:18:02 +0200
committerneoraider <devnull@localhost>2005-04-18 17:18:02 +0200
commit2c7f83e006c3fee8d26e940eee801a4be9443e50 (patch)
treecb8273f74857305921b653aed0a0488b2d27c13a /driver/keyboard.c
downloadwinx-2c7f83e006c3fee8d26e940eee801a4be9443e50.tar
winx-2c7f83e006c3fee8d26e940eee801a4be9443e50.zip
Verzeichnisstruktur ver?ndertHEADmaster
Diffstat (limited to 'driver/keyboard.c')
-rw-r--r--driver/keyboard.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/driver/keyboard.c b/driver/keyboard.c
new file mode 100644
index 0000000..26a12f0
--- /dev/null
+++ b/driver/keyboard.c
@@ -0,0 +1,268 @@
+/* keyboard.c - keyboard functions */
+
+#include <system.h>
+#include <keyboard.h>
+#include <console.h>
+
+unsigned short keyflags = 0;
+unsigned short key_extended_buffer;
+unsigned char keybuffer[256];
+unsigned char keybuffer_pointer = 0, keybuffer_count = 0;
+
+unsigned char keydata[128] = {
+ 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xDF, '\'', '\b', '\t',
+ 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 0xFC, '+', '\n', 0, 'a', 's',
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0xF6, 0xE4, '^', 0, '#', 'y', 'x', 'c', 'v',
+ 'b', 'n', 'm', ',', '.', '-', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0,
+ 0, 0, 0, 0, 0, 0, '<', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char keydata_shift[128] = {
+ 0, 0, '!', '"', 0xA7, '$', '%', '&', '/', '(', ')', '=', '?', '`', '\b', '\t',
+ 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 0xDC, '*', '\n', 0, 'A', 'S',
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xD6, 0xC4, 0xB0, 0, '\'', 'Y', 'X', 'C', 'V',
+ 'B', 'N', 'M', ';', ':', '_', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0,
+ 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char keydata_extended[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char keydata_altgr[128] = {
+ 0, 0, 0, 0xB2, 0xB3, 0, 0, 0, '{', '[', ']', '}', '\\', 0, '\b', '\t',
+ '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', '\n', 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0xB5, 0, 0, 0, 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0B, 0, 0, '-', 0, 0, 0, '+', 0,
+ 0, 0, 0, 0, 0, 0, '|', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+unsigned char keydata_numlock[13] = {
+ '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','
+};
+
+
+void update_leds() {
+ register unsigned char al asm("%al");
+ do {
+ asm (
+ "in $0x64,%al\n"
+ "and $0b00000010,%al\n"
+ );
+ } while (al);
+ asm (
+ "mov $0xED,%al\n"
+ "out %al,$0x60\n"
+ );
+ do {
+ asm (
+ "in $0x64,%al\n"
+ "and $0b00000010,%al\n"
+ );
+ } while (al);
+ asm (
+ "mov %0,%%eax\n"
+ "and $0b11100000,%%al\n"
+ "shr $5,%%al\n"
+ "out %%al,$0x60\n"
+ : : "m" (keyflags)
+ );
+}
+
+
+void kb_write_keycode() {
+
+ unsigned char keycode;
+ unsigned long fullcode;
+ unsigned char ansicode = 0;
+
+ unsigned char *keytable = keydata;
+
+ asm ("mov %%al,%0" : "=m" (keycode));
+
+ fullcode = (keycode & KEY_CODE);
+
+ if(keycode==ACKNOWLEDGE_CODE) return;
+
+ else if(keycode==EXTENDED0_CODE) {keyflags |= FLAG_EXTENDED_KEY; key_extended_buffer = EXTENDED0_CODE;}
+
+ else if(keycode==EXTENDED1_CODE) {keyflags |= FLAG_EXTENDED_KEY; key_extended_buffer = EXTENDED1_CODE;}
+
+ else {
+
+ if(keyflags & FLAG_EXTENDED_KEY) {
+ if(key_extended_buffer==EXTENDED0_CODE) {
+ fullcode = ((keycode & KEY_CODE) | (EXTENDED0_CODE << 8));
+ keyflags &= ~FLAG_EXTENDED_KEY;
+ }
+ else if(key_extended_buffer==EXTENDED1_CODE) {
+ fullcode = ((keycode & KEY_CODE) | (EXTENDED1_CODE << 8));
+ key_extended_buffer = fullcode;
+ }
+ else {
+ fullcode = ((keycode & KEY_CODE) | (((unsigned long)key_extended_buffer) << 8));
+ keyflags &= ~FLAG_EXTENDED_KEY;
+ }
+ }
+
+
+ if(keycode & KEY_RELEASE) {
+ switch(fullcode) {
+ case NUMLOCK_CODE:
+ keyflags &= ~FLAG_NUMLOCK_PRESSED;
+ break;
+ case SCROLLLOCK_CODE:
+ keyflags &= ~FLAG_SCROLLLOCK_PRESSED;
+ break;
+ case CAPSLOCK_CODE:
+ keyflags &= ~FLAG_CAPSLOCK_PRESSED;
+ break;
+ case LSHIFT_CODE:
+ keyflags &= ~FLAG_LSHIFT_PRESSED;
+ break;
+ case RSHIFT_CODE:
+ keyflags &= ~FLAG_RSHIFT_PRESSED;
+ break;
+ case LALT_CODE:
+ keyflags &= ~FLAG_LALT_PRESSED;
+ break;
+ case RALT_CODE:
+ keyflags &= ~FLAG_RALT_PRESSED;
+ break;
+ case LCTRL_CODE:
+ keyflags &= ~FLAG_LCTRL_PRESSED;
+ break;
+ case RCTRL_CODE:
+ keyflags &= ~FLAG_RCTRL_PRESSED;
+ break;
+ default:
+ if((keyflags & FLAG_NUMLOCK_ACTIVE) && (0x47 <= (fullcode & ~KEY_RELEASE)) && ((fullcode & ~KEY_RELEASE) <= 0x53))
+ ansicode = keydata_numlock[(keycode & KEY_CODE) - 0x47];
+ else {
+ if((fullcode & (EXTENDED0_CODE << 8)) == (EXTENDED0_CODE << 8)) keytable = keydata_extended;
+ else if(keyflags & FLAG_RALT_PRESSED) keytable = keydata_altgr;
+ else if((keyflags & FLAG_LALT_PRESSED)/* && ((keyflags & FLAG_RCTRL_PRESSED)
+ || (keyflags & FLAG_LCTRL_PRESSED))*/) keytable = keydata_altgr;
+ else if(keyflags & (FLAG_LSHIFT_PRESSED | FLAG_RSHIFT_PRESSED | FLAG_CAPSLOCK_ACTIVE))
+ keytable = keydata_shift;
+ ansicode = keytable[keycode & KEY_CODE];
+ }
+ }
+ }
+ else {
+ switch(fullcode) {
+ case NUMLOCK_CODE:
+ if(keyflags & FLAG_NUMLOCK_PRESSED) return;
+ else {
+ keyflags |= FLAG_NUMLOCK_PRESSED;
+ if(keyflags & FLAG_NUMLOCK_ACTIVE) keyflags &= ~FLAG_NUMLOCK_ACTIVE;
+ else keyflags |= FLAG_NUMLOCK_ACTIVE;
+ update_leds();
+ }
+ break;
+ case SCROLLLOCK_CODE:
+ if(keyflags & FLAG_SCROLLLOCK_PRESSED) return;
+ else {
+ keyflags |= FLAG_SCROLLLOCK_PRESSED;
+ if(keyflags & FLAG_SCROLLLOCK_ACTIVE) keyflags &= ~FLAG_SCROLLLOCK_ACTIVE;
+ else keyflags |= FLAG_SCROLLLOCK_ACTIVE;
+ update_leds();
+ }
+ break;
+ case CAPSLOCK_CODE:
+ if(keyflags & FLAG_CAPSLOCK_PRESSED) return;
+ else {
+ keyflags |= FLAG_CAPSLOCK_PRESSED;
+ if(keyflags & FLAG_CAPSLOCK_ACTIVE) keyflags &= ~FLAG_CAPSLOCK_ACTIVE;
+ else keyflags |= FLAG_CAPSLOCK_ACTIVE;
+ update_leds();
+ }
+ break;
+ case LSHIFT_CODE:
+ keyflags |= FLAG_LSHIFT_PRESSED;
+ break;
+ case RSHIFT_CODE:
+ keyflags |= FLAG_RSHIFT_PRESSED;
+ break;
+ case LALT_CODE:
+ keyflags |= FLAG_LALT_PRESSED;
+ break;
+ case RALT_CODE:
+ keyflags |= FLAG_RALT_PRESSED;
+ break;
+ case LCTRL_CODE:
+ keyflags |= FLAG_LCTRL_PRESSED;
+ break;
+ case RCTRL_CODE:
+ keyflags |= FLAG_RCTRL_PRESSED;
+ break;
+ default:
+ if((keyflags & FLAG_NUMLOCK_ACTIVE) && (0x47 <= fullcode) && (fullcode <= 0x53))
+ ansicode = keydata_numlock[keycode - 0x47];
+ else {
+ if((fullcode & (EXTENDED0_CODE << 8)) == (EXTENDED0_CODE << 8)) keytable = keydata_extended;
+ else if(keyflags & FLAG_RALT_PRESSED) keytable = keydata_altgr;
+ else if(keyflags & (FLAG_LSHIFT_PRESSED | FLAG_RSHIFT_PRESSED | FLAG_CAPSLOCK_ACTIVE))
+ keytable = keydata_shift;
+ ansicode = keytable[keycode];
+ }
+ }
+ }
+ }
+ if(keyflags & FLAG_BUFFER_FULL) return;
+ keybuffer[(keybuffer_pointer + keybuffer_count++) & 0xFF] = keycode;
+ keybuffer[(keybuffer_pointer + keybuffer_count++) & 0xFF] = ansicode;
+ if(keybuffer_count==0) keyflags |= FLAG_BUFFER_FULL;
+}
+
+
+void kb_read_keycode() {
+ unsigned long keycode = 0;
+ unsigned char ansicode = 0;
+
+ if((keybuffer_count != 0) || (keyflags & FLAG_BUFFER_FULL)) {
+ keycode = keybuffer[keybuffer_pointer++];
+ ansicode = keybuffer[keybuffer_pointer++];
+ keybuffer_count-=2;
+ keyflags &= ~FLAG_BUFFER_FULL;
+ if(keycode == EXTENDED0_CODE) {
+ if(keybuffer_count != 0) {
+ keycode <<= 8;
+ keycode |= keybuffer[keybuffer_pointer++];
+ ansicode = keybuffer[keybuffer_pointer++];
+ keybuffer_count-=2;
+ }
+ }
+ else if(keycode == EXTENDED1_CODE) {
+ if(keybuffer_count != 0) {
+ keycode <<= 8;
+ keycode |= keybuffer[keybuffer_pointer++];
+ ansicode = keybuffer[keybuffer_pointer++];
+ keybuffer_count-=2;
+ if(keybuffer_count != 0) {
+ keycode <<= 8;
+ keycode |= keybuffer[keybuffer_pointer++];
+ ansicode = keybuffer[keybuffer_pointer++];
+ keybuffer_count-=2;
+ }
+ }
+ }
+ }
+ asm ("mov %0,%%eax; mov %1,%%dl" : : "m" (keycode), "m" (ansicode));
+}