# keyboard scancode table # ts is not a good way to write a driver lmao const KBD = " 1234567890-= qwertyuiop[] asdfghjkl;'` \\zxcvbnm,./ " const KBD_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 = { line = "", shift = :false, ext = :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 >= 128 return :nil # other releases if code == 28 return "\n" # enter if code == 14 return "\x08" # backspace if code < 2 return :nil if code >= KBD:len() return :nil const ch = if shell.shift KBD_SHIFT[code] else KBD[code] if ch == " " and code != 0x39 return :nil # blank cells = modifiers/unmapped ch end global on_key = fn(code) do if code == 0xe0 do shell.ext = :true return :nil end if shell.ext do shell.ext = :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 if final != 0 do stdin_deliver(27) stdin_deliver(91) stdin_deliver(final) end return :nil end const ch = decode_key(code) if ch == :nil return :nil if stdin_deliver(ch:ascii()) return :nil if ch == "\n" do puts("\n") run(shell.line) shell.line = "" return :nil end if ch == "\x08" do if shell.line:len() > 0 do shell.line = shell.line:sub(0, shell.line:len() - 1) puts("\x08 \x08") end return :nil end shell.line ~= ch puts(ch) end