aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/input/ps2/keyboard.c
blob: 72943495846daad96e77989744fd1122628d3111 (plain) (blame)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <kernel/interrupts/interrupts.h>
#include <kernel/io/io.h>
#include <kernel/graphics/vesa.h>

int shift_pressed;
int control_pressed;

char keymap[128] = {
        0 /*E*/, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
        '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
        17 /*C*/, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 14 /*LS*/,
        '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 14 /*RS*/, '*',
        0, // Alt key
        ' ', // Space bar
        15, // Caps lock
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F keys
        0, // Num lock
        0, // Scroll lock
        0, // Home key
        0, // Up arrow
        0, // Page up
        '-',
        0, // Left arrow
        0,
        0, // Right arrow
        '+',
        0, // End key
        0, // Down arrow
        0, // Page down
        0, // Insert key
        0, // Delete key
        0, 0, 0,
        0, // F11
        0, // F12
        0, // Other keys
};

char shift_keymap[128] = {
        0 /*E*/, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
        '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',
        17 /*C*/, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 14 /*LS*/,
        '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 14 /*RS*/, '*',
        0, // Alt key
        ' ', // Space bar
        15, // Caps lock
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F keys
        0, // Num lock
        0, // Scroll lock
        0, // Home key
        0, // Up arrow
        0, // Page up
        '-',
        0, // Left arrow
        0,
        0, // Right arrow
        '+',
        0, // End key
        0, // Down arrow
        0, // Page down
        0, // Insert key
        0, // Delete key
        0, 0, 0,
        0, // F11
        0, // F12
        0, // Other keys
};

char *handle_shift(int scan_code)
{
    char *current_keymap = keymap;
    if (shift_pressed) current_keymap = shift_keymap;

    if ((scan_code & 0x80) == 0) { // PRESS
        // TODO: Fix caps lock deactivation when pressing shift while (locked) shifted
        if (current_keymap[scan_code] == 14 || (current_keymap[scan_code] == 15 && !shift_pressed)) {
            shift_pressed = 1;
        } else if (current_keymap[scan_code] == 15 && shift_pressed) {
            shift_pressed = 0;
        }
    } else { // RELEASE
        char key = current_keymap[scan_code];
        if (key == 14) shift_pressed = 0;
    }

    return current_keymap;
}

void keyboard_handler(struct regs *r)
{
    unsigned char scan_code;

    scan_code = inb(0x60);
    char *current_keymap = handle_shift(scan_code);

    if ((scan_code & 0x80) == 0) { // PRESS
        if (current_keymap[scan_code] == 17)
            control_pressed = 1;

        if (control_pressed && current_keymap[scan_code] == 'l') {
            vesa_clear();
            return;
        }

        vesa_keyboard_char(current_keymap[scan_code]);
    } else { // RELEASE
        if (current_keymap[scan_code] == -107) // TODO: IDK WHY -107?!
            control_pressed = 0;
    }
}

void keyboard_acknowledge()
{
    while (inb(0x60) != 0xfa);
}

void keyboard_rate()
{
    outb(0x60, 0xF3);
    keyboard_acknowledge();
    outb(0x60, 0x0); // Rate{00000} Delay{00} 0
}

// Installs the keyboard handler into IRQ1
void keyboard_install()
{
    keyboard_rate();
    irq_install_handler(1, keyboard_handler);
    shift_pressed = 0;
    info("Installed keyboard handler");
}