X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fdevices%2Fkbd.c;h=1aa71f5a3062c1888b3d3342d9a2d6675765b4e6;hp=a26498477cb3397c5f1d771b06303c5c6c3ffaaf;hb=cc5c971c3cc498d528a2f74f4dc2f8e27a690311;hpb=838c30d0075a3ee0413ba4909944b37f4970a10d diff --git a/src/devices/kbd.c b/src/devices/kbd.c index a264984..1aa71f5 100644 --- a/src/devices/kbd.c +++ b/src/devices/kbd.c @@ -3,27 +3,23 @@ #include #include #include -#include "devices/intq.h" +#include "devices/input.h" +#include "threads/init.h" #include "threads/interrupt.h" #include "threads/io.h" /* Keyboard data register port. */ #define DATA_REG 0x60 -/* Shift state bits. */ -#define LSHIFT 0x01 /* Left Shift. */ -#define RSHIFT 0x02 /* Right Shift. */ -#define LALT 0x04 /* Left Alt. */ -#define RALT 0x08 /* Right Alt. */ -#define LCTRL 0x10 /* Left Ctrl. */ -#define RCTRL 0x20 /* Right Ctrl. */ -#define CAPS 0x40 /* Caps Lock. */ +/* Current state of shift keys. + True if depressed, false otherwise. */ +static bool left_shift, right_shift; /* Left and right Shift keys. */ +static bool left_alt, right_alt; /* Left and right Alt keys. */ +static bool left_ctrl, right_ctrl; /* Left and right Ctl keys. */ -/* Current shift state. */ -static unsigned shift_state; - -/* Keyboard buffer. */ -static struct intq buffer; +/* Status of Caps Lock. + True when on, false when off. */ +static bool caps_lock; /* Number of keys pressed. */ static int64_t key_cnt; @@ -34,23 +30,7 @@ static intr_handler_func keyboard_interrupt; void kbd_init (void) { - intq_init (&buffer, "keyboard"); - intr_register (0x21, 0, INTR_OFF, keyboard_interrupt, "8042 Keyboard"); -} - -/* Retrieves a key from the keyboard buffer. - If the buffer is empty, waits for a key to be pressed. */ -uint8_t -kbd_getc (void) -{ - enum intr_level old_level; - uint8_t key; - - old_level = intr_disable (); - key = intq_getc (&buffer); - intr_set_level (old_level); - - return key; + intr_register_ext (0x21, keyboard_interrupt, "8042 Keyboard"); } /* Prints keyboard statistics. */ @@ -74,14 +54,15 @@ struct keymap that we handle elsewhere. */ static const struct keymap invariant_keymap[] = { - {0x01, "\033"}, + {0x01, "\033"}, /* Escape. */ {0x0e, "\b"}, {0x0f, "\tQWERTYUIOP"}, - {0x1c, "\n"}, + {0x1c, "\r"}, {0x1e, "ASDFGHJKL"}, {0x2c, "ZXCVBNM"}, {0x37, "*"}, {0x39, " "}, + {0x53, "\177"}, /* Delete. */ {0, NULL}, }; @@ -115,10 +96,9 @@ static void keyboard_interrupt (struct intr_frame *args UNUSED) { /* Status of shift keys. */ - bool shift = (shift_state & (LSHIFT | RSHIFT)) != 0; - bool alt = (shift_state & (LALT | RALT)) != 0; - bool ctrl = (shift_state & (LCTRL | RCTRL)) != 0; - bool caps = (shift_state & CAPS) != 0; + bool shift = left_shift || right_shift; + bool alt = left_alt || right_alt; + bool ctrl = left_ctrl || right_ctrl; /* Keyboard scancode. */ unsigned code; @@ -144,7 +124,7 @@ keyboard_interrupt (struct intr_frame *args UNUSED) { /* Caps Lock. */ if (!release) - shift_state ^= CAPS; + caps_lock = !caps_lock; } else if (map_key (invariant_keymap, code, &c) || (!shift && map_key (unshifted_keymap, code, &c)) @@ -153,6 +133,10 @@ keyboard_interrupt (struct intr_frame *args UNUSED) /* Ordinary character. */ if (!release) { + /* Reboot if Ctrl+Alt+Del pressed. */ + if (c == 0177 && ctrl && alt) + reboot (); + /* Handle Ctrl, Shift. Note that Ctrl overrides Shift. */ if (ctrl && c >= 0x40 && c < 0x60) @@ -160,7 +144,7 @@ keyboard_interrupt (struct intr_frame *args UNUSED) /* A is 0x41, Ctrl+A is 0x01, etc. */ c -= 0x40; } - else if (shift == caps) + else if (shift == caps_lock) c = tolower (c); /* Handle Alt by setting the high bit. @@ -170,38 +154,41 @@ keyboard_interrupt (struct intr_frame *args UNUSED) c += 0x80; /* Append to keyboard buffer. */ - if (!intq_full (&buffer)) + if (!input_full ()) { key_cnt++; - intq_putc (&buffer, c); + input_putc (c); } } } else { - /* Table of shift keys. - Maps a keycode into a shift_state bit. */ - static const unsigned shift_keys[][2] = + /* Maps a keycode into a shift state variable. */ + struct shift_key + { + unsigned scancode; + bool *state_var; + }; + + /* Table of shift keys. */ + static const struct shift_key shift_keys[] = { - { 0x2a, LSHIFT}, - { 0x36, RSHIFT}, - { 0x38, LALT}, - {0xe038, RALT}, - { 0x1d, LCTRL}, - {0xe01d, RCTRL}, - {0, 0}, + { 0x2a, &left_shift}, + { 0x36, &right_shift}, + { 0x38, &left_alt}, + {0xe038, &right_alt}, + { 0x1d, &left_ctrl}, + {0xe01d, &right_ctrl}, + {0, NULL}, }; - const unsigned (*key)[2]; + const struct shift_key *key; /* Scan the table. */ - for (key = shift_keys; (*key)[0] != 0; key++) - if ((*key)[0] == code) + for (key = shift_keys; key->scancode != 0; key++) + if (key->scancode == code) { - if (release) - shift_state &= ~(*key)[1]; - else - shift_state |= (*key)[1]; + *key->state_var = !release; break; } }