diff options
| author | hachem <im@hachem.wtf> | 2026-09-12 10:59:26 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-12 10:59:26 +0200 |
| commit | d6d908e3386e107b41241e9eda7dc546581524df (patch) | |
| tree | 8219d02a7494152722ac7f32140d63c8a3b3daa7 /kernel/main.rv | |
| parent | 4f540af34d7a88547d60bed7bd28850e6d0e18ab (diff) | |
feat: basic keyboard driver + tester shell
Diffstat (limited to 'kernel/main.rv')
| -rw-r--r-- | kernel/main.rv | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/kernel/main.rv b/kernel/main.rv new file mode 100644 index 0000000..8fe3b81 --- /dev/null +++ b/kernel/main.rv @@ -0,0 +1,240 @@ +# font8x8_basic (printable ASCII 0x20..0x7f), one row of 8 glyphs per line +# each glyph is 8 bytes; bit 0 (LSB) of a byte is the leftmost pixel +global FONT = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00 }, + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00 }, + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00 }, + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00 }, + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00 }, + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00 }, + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00 }, + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00 }, + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00 }, + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00 }, + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00 }, + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00 }, + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00 }, + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00 }, + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 }, + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00 }, + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00 }, + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00 }, + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00 }, + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00 }, + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00 }, + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00 }, + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00 }, + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00 }, + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00 }, + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00 }, + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00 }, + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00 }, + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00 }, + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00 }, + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00 }, + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00 }, + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00 }, + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00 }, + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00 }, + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00 }, + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00 }, + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00 }, + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00 }, + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00 }, + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00 }, + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00 }, + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00 }, + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00 }, + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00 }, + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00 }, + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00 }, + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00 }, + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00 }, + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00 }, + { 0x38, 0x30, 0x30, 0x3E, 0x33, 0x33, 0x6E, 0x00 }, + { 0x00, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00 }, + { 0x1C, 0x36, 0x06, 0x0F, 0x06, 0x06, 0x0F, 0x00 }, + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F }, + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00 }, + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E }, + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00 }, + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00 }, + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00 }, + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00 }, + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F }, + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78 }, + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00 }, + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00 }, + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00 }, + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00 }, + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00 }, + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00 }, + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F }, + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00 }, + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00 }, + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00 }, + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +} + +const SCALE = 2 +const CW = 8 * SCALE +const CH = 8 * SCALE +const FG = 0xd0d0d0 +const CON_BG = 0x101018 +global con = { col = 0, row = 0 } + +fn con_cols() fb_width() / CW +fn con_rows() fb_height() / CH + +fn draw_glyph(col, row, ch) do + const x0 = col * CW + const y0 = row * CH + fill_rect(x0, y0, CW, CH, CON_BG) # clear the cell + const code = ch:ascii() + if code < 32 return :nil + if code > 127 return :nil + const g = FONT[code - 32] + for fy in 0..8 do + const bits = g[fy] + for fx in 0..8 do + if (bits shr fx) band 1 == 1 fill_rect(x0 + fx * SCALE, y0 + fy * SCALE, SCALE, SCALE, FG) + end + end +end + +fn con_newline() do + con.col = 0 + con.row = con.row + 1 + if con.row >= con_rows() do + fb_scroll(CH, CON_BG) + con.row = con_rows() - 1 + end +end + +# we dont do Shift/Cntrl +# thats a job for future me lmao +fn con_putc(ch) do + const code = ch:ascii() + if code == 10 do con_newline() return :nil end # \n + if code == 13 do con.col = 0 return :nil end # \r + if code == 8 do # backspace: move left + if con.col > 0 con.col = con.col - 1 + return :nil + end + if code < 32 return :nil + draw_glyph(con.col, con.row, ch) + con.col = con.col + 1 + if con.col >= con_cols() con_newline() +end + +# render a string to the screen and mirror to serial +fn puts(s) do + serial_puts(s) + for i in 0..s:len() do con_putc(s[i]) end +end + +# keyboard scancode table +# ts is NOT a good way to write a driver LMAO +const KBD = " 1234567890-= 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))) + +# this is just a simple prompt to test that shit is working +fn cmd_help() puts("commands: help, clear, bars, echo <text>, time\n") + +fn cmd_clear() do + fill_rect(0, 0, fb_width(), fb_height(), CON_BG) + con.col = 0 + con.row = 0 +end + +fn cmd_bars() do + const bars = { 0xff5555, 0xffaa00, 0xffff55, 0x55ff55, 0x55ffff, 0x5599ff, 0xaa55ff, 0xffffff } + const bw = fb_width() / 8 + for i in 0..8 do fill_rect(i * bw, 0, bw, 40, bars[i]) end + puts("painted 8 bars from revo\n") +end + +fn bcd(b) (b shr 4) * 10 + (b band 15) +fn rtc(reg) do + outb(0x70, reg) + inb(0x71) +end +fn cmd_time() puts("utc " ~ bcd(rtc(4)) ~ ":" ~ bcd(rtc(2)) ~ ":" ~ bcd(rtc(0)) ~ "\n") + +fn run(line) do + const words = line:split(" ") + const cmd = words[0] + if cmd == "help" do cmd_help() end + else if cmd == "clear" do cmd_clear() end + else if cmd == "bars" do cmd_bars() end + else if cmd == "time" do cmd_time() end + else if cmd == "echo" do + if line:len() > 5 puts(line:sub(5, line:len() - 5) ~ "\n") else puts("\n") + end + else if line:len() == 0 do :nil end + else do puts("unknown command: " ~ cmd ~ "\n") end + puts("> ") +end + +# she stroke my keys till i handle +# no fr this is just a key stroke handler +global sh = { line = "" } +global on_key = fn(code) do + if code >= 128 return :nil # key release + if code == 28 do # Enter + puts("\n") + run(sh.line) + sh.line = "" + return :nil + end + if code == 14 do # Backspace + if sh.line:len() > 0 do + sh.line = sh.line:sub(0, sh.line:len() - 1) + puts("\x08 \x08") + end + return :nil + end + if code < 2 return :nil + if code >= KBD:len() return :nil + const ch = KBD[code] + sh.line = sh.line ~ ch + puts(ch) +end + +# kmain +pic_remap() +pic_unmask(1) +cmd_clear() +puts("revel shell, live in revo. type `help`\n> ") |
