blob: 760e172f33e8fedd55e52081f9ba44d78413d957 (
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
84
85
86
87
88
89
90
91
92
93
|
//! PS/2 Keyboard Driver
const ahci_const = @import("../../common/constants/ahci.zig");
const io = @import("../../asm/io.zig");
const kb_const = @import("../../common/constants/keyboard.zig");
const kb_limits = @import("../../common/limits/keyboard.zig");
const ports = @import("../../common/constants/ports.zig");
const scancode = @import("scancode.zig");
const sensei = @import("../../kata/sensei/sensei.zig");
const serial = @import("../serial/serial.zig");
var shift_pressed = false;
var ctrl_pressed = false;
var alt_pressed = false;
var caps_lock = false;
var key_buffer: [kb_limits.BUFFER_SIZE]u8 = undefined;
var read_pos: usize = 0;
var write_pos: usize = 0;
pub fn init() void {
serial.printf("Initializing PS/2 keyboard...\n", .{});
while ((io.in_byte(ports.KEYBOARD_STATUS) & 0x01) != 0) {
_ = io.in_byte(ports.KEYBOARD_DATA);
}
serial.printf("Keyboard ready\n", .{});
}
export fn keyboard_handler() void {
const code = io.in_byte(ports.KEYBOARD_DATA);
handle_scancode(code);
io.out_byte(ports.PIC1_CMD, ahci_const.PIC_EOI);
}
fn handle_scancode(code: u8) void {
const released = (code & kb_const.SCANCODE_RELEASED) != 0;
const key = code & ~kb_const.SCANCODE_RELEASED;
switch (key) {
kb_const.SCANCODE_LSHIFT, kb_const.SCANCODE_RSHIFT => {
shift_pressed = !released;
return;
},
kb_const.SCANCODE_LCTRL => {
ctrl_pressed = !released;
return;
},
kb_const.SCANCODE_LALT => {
alt_pressed = !released;
return;
},
kb_const.SCANCODE_CAPS => {
if (!released) caps_lock = !caps_lock;
return;
},
else => {},
}
if (released) return;
var ascii: u8 = if (shift_pressed) scancode.shifted[key] else scancode.normal[key];
if (caps_lock and ascii >= 'a' and ascii <= 'z') {
ascii -= kb_const.LOWERCASE_TO_UPPERCASE;
}
if (ascii != 0) {
enqueue(ascii);
}
}
fn enqueue(ascii: u8) void {
const next = (write_pos + 1) % kb_limits.BUFFER_SIZE;
if (next != read_pos) {
key_buffer[write_pos] = ascii;
write_pos = next;
sensei.wake_one_blocked_kata();
}
}
pub fn has_input() bool {
return read_pos != write_pos;
}
pub fn read_char() ?u8 {
if (read_pos == write_pos) return null;
const char = key_buffer[read_pos];
read_pos = (read_pos + 1) % kb_limits.BUFFER_SIZE;
return char;
}
|