oxytoxin

unix-like kernel
git clone git://git.evenfri.xyz/oxytoxin.git
Log | Files | Refs | README | LICENSE

keyboard.c (2004B)


      1 #include "oxytoxin.h"
      2 #include "keyboard.h"
      3 
      4 unsigned int shift_state = 0;
      5 
      6 unsigned char buf[buf_size];
      7 unsigned int buf_head = 0;
      8 unsigned int buf_tail = 0;
      9 
     10 const char lower_scancodes[128] = {
     11   0,   0,    '1',  '2', '3',  '4', '5', '6', '7', '8', '9', '0', '-',
     12   '=', '\b', '\t', 'q', 'w',  'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
     13   '[', ']',  '\n', 0,   'a',  's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
     14   ';', '\'', '`',  0,   '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',',
     15   '.', '/',  0,    '*', 0,    ' ', 0,   0,   0,   0,   0,   0};
     16 
     17 const char upper_scancodes[128] = {
     18   0,   0,    '!',  '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
     19   '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
     20   '{', '}',  '\n', 0,   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
     21   ':', '\"', '~',  0,   '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<',
     22   '>', '?',  0,    '*', 0,   ' ', 0,   0,   0,   0,   0,   0};
     23 
     24 extern void keyboard_entry(void);
     25 
     26 char keyboard_read(void) {
     27   char ch;
     28 
     29   while (1) {
     30     asm volatile ("cli");
     31     if (buf_head != buf_tail) {
     32       ch = buf[buf_head];
     33       buf_head = (buf_head + 1) % buf_size;
     34       asm volatile ("sti");
     35       return ch;
     36     }
     37     asm volatile ("sti; hlt");
     38   }
     39 }
     40 
     41 void keyboard_handler(void) {
     42   unsigned char scancode;
     43   unsigned int next_tail;
     44   char ascii_char;
     45 
     46   scancode = inb(0x60);
     47 
     48   if (scancode == 0x2a || scancode == 0x36) {
     49     shift_state = 1;
     50     outb(0x20, 0x20);
     51     return;
     52   } else if (scancode == 0xaa || scancode == 0xb6) {
     53     shift_state = 0;
     54     outb(0x20, 0x20);
     55     return;
     56   }
     57 
     58 
     59   if (scancode < 0x80) {
     60     if (shift_state) {
     61       ascii_char = upper_scancodes[scancode];
     62     } else {
     63       ascii_char = lower_scancodes[scancode];
     64     }
     65 
     66     if (ascii_char != 0) {
     67       next_tail = (buf_tail + 1) % buf_size;
     68       if (next_tail != buf_head) {
     69         buf[buf_tail] = ascii_char;
     70         buf_tail = next_tail;
     71       }
     72     }
     73   }
     74 
     75   outb(0x20, 0x20);
     76 }
     77 
     78 void keyboard_init(void) {
     79   idt_register(33, keyboard_entry);
     80 }