diff --git a/kernel/char/keyboard.c b/kernel/char/keyboard.c index 2e9a1bd..06bcde2 100644 --- a/kernel/char/keyboard.c +++ b/kernel/char/keyboard.c @@ -6,14 +6,16 @@ #include "hos_defines.h" #include "char/keyboard.h" #include "sys/io.h" -#include "sys/pic.h" #include "functions.h" +#include "lang/conv.h" // asciiSwitchCase() + #include "kout.h" +#include "console.h" #define KBD_BUFFER_LENGTH 64 u8_t kbdFlags = 0; // holds current keyboard flags - caps/num/scroll/shift/ctrl/alt -char lastWasE0 = 0; // was the last byte 0x0E ? +u8_t lastWasE0 = 0; // was the last byte 0x0E ? u32_t kbdBuffer[KBD_BUFFER_LENGTH]; // a buffer for all keypresses int kbdBufferStart = 0; // position of next key in buffer int kbdBufferLen = 0; // number of keys left in the buffer @@ -22,7 +24,7 @@ u8_t ackReason = 0; // used to record the reason why we would get an acknowled //these arrays convert a keyboard scan code to an ASCII character value -const u8_t SCAN2ASCII[129] = +const u8_t SCAN2ASCII[129] = // for normal keys "\000\0331234567890-=\010\011" // null,esc,1234567890-=,bksp,tab "qwertyuiop[]\n\000as" // qwertyuiop[],enter,lctrl,as "dfghjkl;'`\000\\zxcv" // dfghjkl;'`,lshift,\zxcv @@ -31,199 +33,129 @@ const u8_t SCAN2ASCII[129] = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" // down,pgdn,ins,del,?,?,?,f11,f12,?,?,winL,winR,menu,?,? "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" // ? "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; // ? -const u8_t SCAN2ASCII2[129] = - "\000\033!@#$%^&*()_+\010\011" - "QWERTYUIOP{}\n\000AS" - "DFGHJKL:\"~\000|ZXCV" - "BNM<>?\000*\000 \000\000\000\000\000\000" - "\000\000\000\000\000\000\000789-456+1" - "230.\000\000\000\000\000\000\000\000\000\000\000\000" - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; +const u8_t SCAN2ASCII2[129] = // for shifted or numlocked keys + "\000\033!@#$%^&*()_+\010\011" // null,esc,!@#$%^&*()_+,bksp,tab + "QWERTYUIOP{}\n\000AS" // QWERTYUIOP{},enter,lctrl,AS + "DFGHJKL:\"~\000|ZXCV" // DFGHJKL:"~,lshift,|ZXCV + "BNM<>?\000*\000 \000\000\000\000\000\000" // BNM<>?,rshift,*,alt,space,caps,f1,f2,f3,f4,f5 + "\000\000\000\000\000\000\000789-456+1" // f6,f7,f8,f9,f10,num,scrl,789-456+1 + "230.\000\000\000\000\000\000\000\000\000\000\000\000" // 230.,?,?,?,f11,f12,?,?,winL,winR,menu,?,? + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" // ? + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; // ? -//====FUNCTIONS: // The Keyboard Interrupt Service Routine void isr_keyboard() { - kbdScan = inportb(0x60); - kprintf("KEYBOARD INTERRUPT: 0x%x\n", kbdScan); + u8_t kbdScan = inportb(0x60); u8_t inState = inportb(0x61); outportb(0x61, inState|0x80); outportb(0x61, inState); - return; - //printf("IRQ 1: %x\n", kbdScan); - - if (kbdScan == 0xFA) //250 //ACKnowledge + if (kbdScan == 0xFA) //250 // ACKnowledge { //printf("KBD_ACK 0x%x!\n", ackReason); - if (ackReason == 0xED) //reset LEDs + switch (ackReason) { + case 0xED: // reset LEDs outportb(0x60, (kbdFlags & 0x07)); + break; } ackReason = 0; } - if (kbdScan == 224) // 0xE0 == extended key + if (rawIgnore) // ignore keycodes { - kbdExt = 1; - pic_eoi(); + rawIgnore--; return; } - if (kbdScan == 225) // 0xE1 == 2nd-set-extended key + if (lastWasE0 && (kbdScan == 0x2A || kbdScan == 0xAA)) // ignore extended "shift" { - kbdExt2 = 2; - pic_eoi(); + lastWasE0 = 0; return; } - -//====handle control keys:: - kbdAscii = 2; - switch (kbdScan) //control keys + if (kbdScan == 0xE0) // 0xE0 == extended key { - case KBD_SCAN_LSHIFT: - kbdFlags |= KBD_SHIFT; - kbdAscii = 1; - break; - case KBD_SCAN_RSHIFT: - kbdFlags |= KBD_SHIFT; - kbdAscii = 1; - break; - case KBD_SCAN_LCTRL: - kbdFlags |= KBD_CTRL; - kbdAscii = 1; - break; - case KBD_SCAN_LALT: - kbdFlags |= KBD_ALT; - kbdAscii = 1; - break; - - case KBD_SCAN_LSHIFT + KBD_SCAN_RELEASED: - kbdFlags &= (KBD_SHIFT ^ 0xFF); - kbdAscii = 1; - break; - case KBD_SCAN_RSHIFT + KBD_SCAN_RELEASED: - kbdFlags &= (KBD_SHIFT ^ 0xFF); - kbdAscii = 1; - break; - case KBD_SCAN_LCTRL + KBD_SCAN_RELEASED: - kbdFlags &= (KBD_CTRL ^ 0xFF); - kbdAscii = 1; - break; - case KBD_SCAN_LALT + KBD_SCAN_RELEASED: - kbdFlags &= (KBD_ALT ^ 0xFF); - kbdAscii = 1; - break; - - case KBD_SCAN_CAPS+KBD_SCAN_RELEASED: - kbdFlags ^= KBD_CAPS; - kbdAscii = 1; - kbd_resetLEDs(); //update LEDs - break; - case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED: - kbdFlags ^= KBD_SCROLL; - kbdAscii = 1; - kbd_resetLEDs(); //update LEDs - break; - case KBD_SCAN_NUM+KBD_SCAN_RELEASED: - kbdFlags ^= KBD_NUM; - kbdAscii = 1; - kbd_resetLEDs(); //update LEDs - break; - } - if (kbdAscii == 1) - { - if (kbdExt > 0) - kbdExt--; - pic_eoi(); + lastWasE0 = 1; return; } -//====determine ASCII value of key:: - if (kbdExt > 0) //extended key, kbdScan holds extended key + if (kbdScan == 0xE1) // 0xE1 == 2nd-set-extended key { - kbdExt--; - kbdAscii = 1; - switch (kbdScan) - { - case KBD_SCANE_ENTER: - kbdAscii = '\n'; break; - case 53: // '/' character (divide on numpad) - kbdAscii = '/'; break; - } + rawIgnore = 2; + return; } - else if (kbdExt2 > 0) //extended key 2 + + + switch (kbdScan) // handle control keys { - kbdExt2--; -// if (kbdScan == 69) // (pause|break) -// kbdAscii = 2; //flag ascii value of 1 means control character (pausebreak) -// else - kbdAscii = 2; //flag ascii value of 2 means ignore key (or unknown value) - } - else //not an extended key - { - // if letter key - if (((kbdScan >= 16) && (kbdScan <= 25)) || ((kbdScan >= 30) && (kbdScan <= 38)) || ((kbdScan >= 44) && (kbdScan <= 50))) - { - // if caps and shift are different (either one pressed, not both) - if (((kbdFlags & KBD_SHIFT) != 0) & ((kbdFlags & KBD_CAPS) != 0)) - kbdAscii = SCAN2ASCII[kbdScan & 0x7F]; - else if (((kbdFlags & KBD_SHIFT) == 0) & ((kbdFlags & KBD_CAPS) == 0)) - kbdAscii = SCAN2ASCII[kbdScan & 0x7F]; - else - kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F]; - } - // if numpad key - else if ((kbdScan >= 71) && (kbdScan <= 83)) - { - // if numlock on - if (kbdFlags & KBD_NUM) - kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F]; - else - kbdAscii = SCAN2ASCII[kbdScan & 0x7F]; - } - // other key - else - { - if ((kbdFlags & KBD_SHIFT) != 0) - kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F]; - else - kbdAscii = SCAN2ASCII[kbdScan & 0x7F]; - } + case KBD_SCAN_LSHIFT: + kbdFlags |= KBDF_SHIFT; + break; + case KBD_SCAN_RSHIFT: + kbdFlags |= KBDF_SHIFT; + break; + case KBD_SCAN_CTRL: + kbdFlags |= KBDF_CTRL; + break; + case KBD_SCAN_ALT: + kbdFlags |= KBDF_ALT; + break; + + case KBD_SCAN_LSHIFT + KBD_SCAN_RELEASED: + kbdFlags &= (KBDF_SHIFT ^ 0xFF); + break; + case KBD_SCAN_RSHIFT + KBD_SCAN_RELEASED: + kbdFlags &= (KBDF_SHIFT ^ 0xFF); + break; + case KBD_SCAN_CTRL + KBD_SCAN_RELEASED: + kbdFlags &= (KBDF_CTRL ^ 0xFF); + break; + case KBD_SCAN_ALT + KBD_SCAN_RELEASED: + kbdFlags &= (KBDF_ALT ^ 0xFF); + break; + case KBD_SCAN_CAPS+KBD_SCAN_RELEASED: + kbdFlags ^= KBDF_CAPS; + kbd_resetLEDs(); // update LEDs + break; + case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED: + kbdFlags ^= KBDF_SCROLL; + kbd_resetLEDs(); // update LEDs + break; + case KBD_SCAN_NUM+KBD_SCAN_RELEASED: + kbdFlags ^= KBDF_NUM; + kbd_resetLEDs(); // update LEDs + break; } + u8_t kbdAscii; + // shift or (numlock and key from numpad) + if ( (kbdFlags & KBDF_SHIFT) || ((kbdFlags & KBDF_NUM) && (kbdScan >= 71) && (kbdScan <= 83)) ) + kbdAscii = SCAN2ASCII2[kbdScan & 0x7F]; + else // normal key + kbdAscii = SCAN2ASCII[kbdScan & 0x7F]; + if (kbdFlags & KBDF_CAPS) + kbdAscii = asciiSwitchCase(kbdAscii); // won't affect non-letter characters //====do something with key:: -// printf("kbdScan == %d\nkbdAscii == %d\nkbdFlags == %d\n", kbdScan, kbdAscii, kbdFlags); - if ((kbdScan == 83) && (kbdFlags & KBD_CTRL) && (kbdFlags & KBD_ALT)) +// kprintf("kbdScan = \e[31;1m0x%x\e[0m\tkbdAscii = \e[1;32m0x%x\e[0m (\e[35m%c\e[0m)\tkbdFlags = \e[34m0x%x\e[0m\n", kbdScan, kbdAscii, kbdAscii, kbdFlags); + if ((kbdScan == 83) && (kbdFlags & KBDF_CTRL) && (kbdFlags & KBDF_ALT)) { kprintf("Initiating reboot."); restart(); } - if (kbdAscii == 2) //unknown key / ignore key - { - pic_eoi(); - return; - } - if (kbdScan < KBD_SCAN_RELEASED) //a key was pressed, save it - { - if (kbdBufferLen >= KBD_BUFFER_LENGTH) //no key slots available - { - pic_eoi(); - return; - } - else - { - kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (u32_t) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii); -// printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]); - } - } + if (kbdScan & KBD_SCAN_RELEASED) + kbdAscii = 0; + if (kbdBufferLen < KBD_BUFFER_LENGTH) //no key slots available + kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (u32_t) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii); - pic_eoi(); + if (kbdAscii) + kprintf("%c", kbdAscii); + if (kbdScan >= 0x3B && kbdScan <= 0x40) + console_activate(kbdScan - 0x3A); } //Gets a key from the buffer, returns 0 if no keys available, returns immediately u32_t kbdGetKey() { - if (kbdBufferLen == 0) //buffer empty + if (kbdBufferLen == 0) // buffer empty return 0; u32_t retVal = kbdBuffer[kbdBufferStart]; kbdBufferStart++; @@ -238,7 +170,7 @@ u32_t kbdWaitKey() { for (;;) { - if (kbdBufferLen != 0) //buffer empty + if (kbdBufferLen != 0) // buffer empty break; } u32_t retVal = kbdBuffer[kbdBufferStart]; diff --git a/kernel/char/keyboard.h b/kernel/char/keyboard.h index b6e1a2d..223e5b9 100644 --- a/kernel/char/keyboard.h +++ b/kernel/char/keyboard.h @@ -1,7 +1,7 @@ // keyboard.h // Author: Josh Holtrop // Created: 04/17/03 -// Modified: 08/02/04 +// Modified: 08/20/04 #include "hos_defines.h" @@ -15,30 +15,16 @@ #define KBDF_CTRL 0x20 #define KBDF_ALT 0x40 -#define KBD_SCAN_RELEASED 128 +#define KBD_SCAN_RELEASED 0x80 -#define KBD_SCAN_LCTRL 29 +#define KBD_SCAN_CTRL 29 #define KBD_SCAN_LSHIFT 42 #define KBD_SCAN_RSHIFT 54 -#define KBD_SCAN_LALT 56 +#define KBD_SCAN_ALT 56 #define KBD_SCAN_SCROLL 70 #define KBD_SCAN_CAPS 58 #define KBD_SCAN_NUM 69 -#define KBD_SCANE_PRINTSCREEN 55 -#define KBD_SCANE_INS 82 -#define KBD_SCANE_HOME 71 -#define KBD_SCANE_PGUP 73 -#define KBD_SCANE_DEL 83 -#define KBD_SCANE_END 79 -#define KBD_SCANE_PGDN 81 -#define KBD_SCANE_ENTER 28 - -#define KBD_SCANE_NULL 42 - - - -//====PROTOTYPES: void isr_keyboard(); void kbd_resetLEDs(); diff --git a/kernel/kernel.c b/kernel/kernel.c index 4c0c55c..475ee83 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -18,6 +18,7 @@ #include "console.h" #include "sys/io.h" #include "sys/pic.h" +#include "char/keyboard.h" mb_info_t mb_info_block; mb_mmap_t mb_mmap[MAX_MMAP]; diff --git a/kernel/kout.c b/kernel/kout.c index d036b81..a4f8055 100644 --- a/kernel/kout.c +++ b/kernel/kout.c @@ -9,6 +9,8 @@ #include "lang/conv.h" #include "fs/devices.h" +extern int activeConsole; + char buffer[64]; // print a character @@ -17,7 +19,7 @@ void putc(int c) #ifdef PARALLEL_DEBUG char_write(MAJORC_PARALLEL, 0, c); #endif - char_write(MAJORC_VCONSOLE, 1, c); + char_write(MAJORC_VCONSOLE, activeConsole, c); } diff --git a/kernel/lang/conv.c b/kernel/lang/conv.c index 00cf8af..850fd8e 100644 --- a/kernel/lang/conv.c +++ b/kernel/lang/conv.c @@ -81,3 +81,13 @@ int utoa(u32_t num, char *buf) } +char asciiSwitchCase(char chr) +{ + if (chr >= 'A' && chr <= 'Z') + return chr + ('a' - 'A'); + if (chr >= 'a' && chr <= 'z') + return chr - ('a' - 'A'); + return chr; +} + + diff --git a/kernel/lang/conv.h b/kernel/lang/conv.h index 05e2bd8..35b37be 100644 --- a/kernel/lang/conv.h +++ b/kernel/lang/conv.h @@ -12,5 +12,7 @@ int itox(u32_t num, char *buf); int itoa(int num, char *buf); int utoa(u32_t num, char *buf); +char asciiSwitchCase(char chr); + #endif