kernel

hobby kernel
git clone git://git.evenfri.xyz/kernel.git
Log | Files | Refs | README | LICENSE

keyboard.c (1958B)


      1 #include <fns.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_asm(void);
     25 
     26 char keyboard_read(void) {
     27   while (1) {
     28     asm volatile("cli");
     29     if (buf_head != buf_tail) {
     30       char ch = buf[buf_head];
     31       buf_head = (buf_head + 1) % buf_size;
     32       asm volatile("sti");
     33       return ch;
     34     }
     35     asm volatile("sti; hlt");
     36   }
     37 }
     38 
     39 void keyboard_handler(void) {
     40   unsigned char scancode = inb(0x60);
     41 
     42   if (scancode == 0x2a || scancode == 0x36) {
     43     shift_state = 1;
     44     outb(0x20, 0x20);
     45     return;
     46   } else if (scancode == 0xaa || scancode == 0xb6) {
     47     shift_state = 0;
     48     outb(0x20, 0x20);
     49     return;
     50   }
     51 
     52   if (scancode < 0x80) {
     53     char ascii_char;
     54 
     55     if (shift_state) {
     56       ascii_char = upper_scancodes[scancode];
     57     } else {
     58       ascii_char = lower_scancodes[scancode];
     59     }
     60 
     61     if (ascii_char != 0) {
     62       unsigned int next_tail = (buf_tail + 1) % buf_size;
     63       if (next_tail != buf_head) {
     64         buf[buf_tail] = ascii_char;
     65         buf_tail = next_tail;
     66       }
     67     }
     68   }
     69 
     70   outb(0x20, 0x20);
     71 }
     72 
     73 void keyboard_init() {
     74   idt_register(33, keyboard_asm);
     75 }