From 2c7f83e006c3fee8d26e940eee801a4be9443e50 Mon Sep 17 00:00:00 2001 From: neoraider Date: Mon, 18 Apr 2005 15:18:02 +0000 Subject: Verzeichnisstruktur ver?ndert --- driver/keyboard.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 driver/keyboard.c (limited to 'driver/keyboard.c') 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 +#include +#include + +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)); +} -- cgit v1.2.3