hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/kernel/shell.rv
blob: 6e3c2e413ecbbf895d0890e351cdca5d3fefd02d (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
94
95
96
97
98
99
100
101
102
103
104
105
106
# this is just a simple prompt to test that shit is working
fn cmd_help() do
  puts("commands: help, clear, bars, echo <text>, time, mem, uptime, ps, run, zoom in|out\n")
  puts("fs: mkfs, ls, cat <name>, write <name> <text>, rm <name>\n")
end

fn cmd_write(line, words) do
  if words:len() < 2 do puts("usage: write <name> <text>\n") return :nil end
  const name = words[1]
  const start = 6 + name:len() + 1
  const text = if line:len() > start line:sub(start, line:len() - start) else ""
  fs_write(name, text)
end

fn zoom_by(delta) do
  let scale = con.scale + delta
  if scale < 1 do scale = 1 end
  if scale > 6 do scale = 6 end
  con.scale = scale
  cmd_clear()
  puts("zoom " ~ scale ~ "x\n")
end

fn cmd_zoom(words) do
  const dir = if words:len() > 1 words[1] else ""
  if dir == "in" do zoom_by(1) end
  else if dir == "out" do zoom_by(-1) end
  else do puts("usage: zoom in | zoom out\n") end
end

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(byte) (byte shr 4) * 10 + (byte 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")

# 0x prefixed 16 digit hex
fn hex(n) do
  const digits = "0123456789abcdef"
  let out = ""
  for i in 0..16 do out = out ~ digits[(n shr ((15 - i) * 4)) band 15] end
  "0x" ~ out
end

fn mem_type_name(kind) do
  if kind == 0 return "usable"
  if kind == 1 return "reserved"
  if kind == 2 return "acpi-reclaimable"
  if kind == 3 return "acpi-nvs"
  if kind == 4 return "bad"
  if kind == 5 return "bootloader-reclaimable"
  if kind == 6 return "kernel+modules"
  if kind == 7 return "framebuffer"
  "unknown"
end

# the boot memory map dump
fn dump_memmap() do
  puts("memory map:\n")
  for i in 0..memmap_count() do
    puts("  " ~ hex(memmap_base(i)) ~ " len=" ~ hex(memmap_len(i)) ~ " type=" ~ mem_type_name(memmap_kind(i)) ~ "\n")
  end
  puts("usable: " ~ (mem_total() shr 20) ~ " MiB, free: " ~ (mem_free() shr 20) ~ " MiB\n")
end

fn cmd_mem() puts((mem_free() shr 20) ~ " MiB free / " ~ (mem_total() shr 20) ~ " MiB usable\n")
fn cmd_uptime() puts(math.floor(uptime() / 100) ~ "s (" ~ uptime() ~ " ticks)\n")
fn cmd_ps() puts(proc_count() ~ " process(es) running\n")

fn run(line) do
  if line:trim():len() == 0 do puts("% ") return :nil end
  const words = line:split(" ")
  const cmd = words[0]
  if cmd == "run" do cmd_run() return :nil end
  match cmd
    | "help" => cmd_help()
    | "clear" => cmd_clear()
    | "bars" => cmd_bars()
    | "time" => cmd_time()
    | "mem" => cmd_mem()
    | "uptime" => cmd_uptime()
    | "ps" => cmd_ps()
    | "zoom" => cmd_zoom(words)
    | "mkfs" => fs_format()
    | "ls" => fs_ls()
    | "cat" => if words:len() > 1 fs_cat(words[1]) else puts("usage: cat <name>\n")
    | "write" => cmd_write(line, words)
    | "rm" => if words:len() > 1 fs_rm(words[1]) else puts("usage: rm <name>\n")
    | "echo" => if line:len() > 5 puts(line:sub(5, line:len() - 5) ~ "\n") else puts("\n")
    | _ => puts("unknown command: " ~ cmd ~ "\n")
  puts("% ")
end