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
|
# keyboard scancode table
# ts is not a good way to write a driver lmao
const KEYMAP = " 1234567890-= qwertyuiop[] asdfghjkl;'` \\zxcvbnm,./ "
const KEYMAP_SHIFT = " !@#$%^&*()_+ QWERTYUIOP{} ASDFGHJKL:\"~ |ZXCVBNM<>? "
# 8259 pic
fn pic_remap() do
outb(0x20, 0x11) outb(0xa0, 0x11)
outb(0x21, 0x20) outb(0xa1, 0x28)
outb(0x21, 0x04) outb(0xa1, 0x02)
outb(0x21, 0x01) outb(0xa1, 0x01)
outb(0x21, 0xff) outb(0xa1, 0xff)
end
fn pic_unmask(line) outb(0x21, inb(0x21) band (255 bxor (1 shl line)))
# 8253/8254 pit channel 0, mode 3 (square wave)
# divisor 11931 -> ~100 hz (1193182 / 11931)
# the isr just counts ticks
fn pit_init() do
outb(0x43, 0x36)
outb(0x40, 11931 band 0xff)
outb(0x40, (11931 shr 8) band 0xff)
end
# she stroke my keys till i handle
# no fr this is just a key stroke handler
global shell = { shift = :false, extended = :false, ctrl = :false }
fn decode_key(code) do
if code == 0x2a or code == 0x36 do shell.shift = :true return :nil end # shift down
if code == 0xaa or code == 0xb6 do shell.shift = :false return :nil end # shift up
if code == 0x1d do shell.ctrl = :true return :nil end # ctrl down
if code == 0x9d do shell.ctrl = :false return :nil end # ctrl up
if code >= 128 return :nil # other releases
if code == 28 return "\n" # enter
if code == 14 do
if shell.ctrl do
return "\x7f"
end
return "\x08"
end # backspace (ctrl: word erase)
if code < 2 return :nil
if code >= KEYMAP:len() return :nil
const character = if shell.shift KEYMAP_SHIFT[code] else KEYMAP[code]
if character == " " and code != 0x39 return :nil # blank cells = modifiers/unmapped
if shell.ctrl return string.of_ascii(character:ascii() band 0x1f)
return character
end
global on_key = fn(code) do
if code == 0xe0 do shell.extended = :true return :nil end
if shell.extended do
shell.extended = :false
let final = 0
if code == 0x48 do final = 65 end # up
else if code == 0x50 do final = 66 end # down
else if code == 0x4d do final = 67 end # right
else if code == 0x4b do final = 68 end # left
else if code == 0x47 do final = 72 end # home
else if code == 0x4f do final = 70 end # end
if final != 0 do
tty:feed(27) tty:feed(91) tty:feed(final)
end
return :nil
end
const character = decode_key(code)
if character == :nil return :nil
tty:feed(character:ascii())
end
|