aboutsummaryrefslogtreecommitdiff
path: root/kernel/io/keyboard/keyboard_handler.c
blob: 26b4586b482c12be1a33a43b7fb43e2d3e31e5c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "../../interrupt_descriptor_table.h"
#include "../../gpu/text_mode/display.h"
#include "scancode_map.h"

extern void keyboard_handler(void);
extern char read_port(unsigned short port);
extern void write_port(unsigned short port, unsigned char data);
extern void load_idt(unsigned long *idt_ptr);

struct idt_entry keyboard_idt[256];

void init_keyboard_idt()
{
  unsigned long keyboard_address;
  unsigned long idt_address;
  unsigned long idt_ptr[2];

  // Build IDT entry
  keyboard_address = (unsigned long) keyboard_handler;

  keyboard_idt[0x21].offset_lowerbits = keyboard_address & 0xffff;
  keyboard_idt[0x21].selector = 0x08; // Offset by 0x08
  keyboard_idt[0x21].zero = 0;
  keyboard_idt[0x21].type_attr = 0x8E; // Interrupt gate addr
  keyboard_idt[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16;

  idt_address = (unsigned long) keyboard_idt;
  idt_ptr[0] = (sizeof(struct idt_entry) * 256) + ((idt_address & 0xffff) << 16);
  idt_ptr[1] = idt_address >> 16;

  // Init PIC 1 @ 0x20
  write_port(0x20, 0x11);
  write_port(0x21, 0x20);
  write_port(0x21, 0x00);
  write_port(0x21, 0x01);
  write_port(0x21, 0xff);

  // PIC 2 @ 0xA0
  write_port(0xA0, 0x11);
  write_port(0xA1, 0x28);
  write_port(0xA1, 0x00);
  write_port(0xA1, 0x01);
  write_port(0xA1, 0xff);

  load_idt(idt_ptr);
}

void init_keyboard_handler()
{
  init_keyboard_idt();

  write_port(0x21, 0xFD);
}

int isKeyup(int scancode)
{
  return scancode & 0x80;
}

void handle_keypress() {

  // Ack the interrupt
  write_port(0x20, 0x20);

  unsigned char scancode = read_port(0x60);

  if(!isKeyup(scancode))
  {
    char pressed_key = scancode_map[scancode];
    switch(pressed_key)
    {
      case '\b':
        scrn_backspace();
        break;
      case '\n':
        scrn_newline();
        break;
      default:
        scrn_putchar(pressed_key);
    }
  }

}