import mm
import term
import panic

Terminal kterm
int base_vma
ptr multiboot_data_physaddr

import irqio
import keymap_us
import "kapps/console.ort"
import mbdata

import serialdbg
import vgatest
import gfxterm
import util
import "profiling/err.ort"
import "profiling/profile.ort"

import paging
#import thunk

MultibootInfo mbinfo

function(ptr multiboot_struct_addr) kernel_main -> void does
multiboot_data_physaddr=multiboot_struct_addr
base_vma=0xC0000000

init_serial()
kswritecstr("Kernel debugger check!\n")

KMM::init(base_vma+0x300000) #(Hopefully) skip past all the multiboot data we care about
mbinfo = MultibootInfo::load(multiboot_struct_addr)
init_pm() #Early PM init so we can page the screen

int mappos=0x400000
while mappos < (0x400000*10) do
page_manager:get_pde_slot_addr(base_vma+mappos):set(mappos, 1|bool)
mappos+=0x400000
done


if mbinfo.text_mode do
kswritecstr("Text Mode\n")
kterm = Terminal::new(mbinfo.fb_addr|int, 80, 25, _null_updater|TerminalUpdateHook)
else do
kswritecstr("Graphical mode. Paging...\n")
page_manager:get_pde_slot_addr(mbinfo.fb_addr|int):set(mbinfo.fb_raw_addr, 1|bool)
page_manager:get_pde_slot_addr(mbinfo.fb_addr|int + 0x400000):set(mbinfo.fb_raw_addr, 1|bool)
kswritecstr("Paged\n")

if mbinfo.cmdline=="gfxtest" do
test_svga()
done

init_emulator(mbinfo)
kterm = Terminal::new(console_emulator.text_fb|int, console_emulator.vga_w, console_emulator.vga_h, _update_framebuffer|TerminalUpdateHook)
done

kswritecstr("Blanking...")
kterm:blank()
kswritecstr("*\n")

kterm:printl("Terminal ready")

kterm:printl(" ..---..")

kterm:printl(" / \\")
kterm:printl("| |")
kterm:printl(": ;")
kterm:print(" \\ \\")
kterm:printa(0x0E, "~")
kterm:printl("/ /")
kterm:printl(" `, Y ,'")
kterm:printl(" |_|_|")
kterm:printl(" |===|")
kterm:printl(" |===|")
kterm:printl(" \\_/")
kterm:printl("\nOrth OS. Louis G.")

kterm:print("Higher-Half addressing enabled, base_vma=")
kterm:dumphexi(base_vma)
kterm:print(". kterm.baseaddr=")
kterm:dumphexi(kterm.baseaddr|int)

kterm:print("\nCS=")
kterm:printi(__kgetcs())
kterm:print(" DS=")
kterm:printi(__kgetds())
kterm:print(" Installing GDT: ")

install_gdt()

kterm:print(" Done! ")

kterm:print("CS=")
kterm:printi(__kgetcs())
kterm:print(" DS=")
kterm:printi(__kgetds())

kterm:print("\nTesting (some) Memory: ")

int mt_x=kterm.cursor_x

kterm.serial_debug_enabled=0|bool
int testpos = 0
while testpos|int<0x100000 do
mm_pos:offset(testpos)[0]=0|byte
testpos+=8
done
kterm.serial_debug_enabled=1|bool

kterm:print("Done, at least ")
kterm:printi(testpos)
kterm:printl("b accessible off 'heap'")

kterm:print("Installing IRQs: ")

setup_irq()

kterm:printl("Installed!")

kterm:print("Mutiboot structure physaddr=")
kterm:dumphexi(multiboot_struct_addr|int)
kterm:print(". vaddr?=")
kterm:dumphexi(multiboot_struct_addr|int+base_vma)
if multiboot_struct_addr|int<0x400000 do
kterm:print(" OK\n")
else do
kterm:print(" OUTSIDE MAP!")
done

kterm:print("Heap ptr at ")
kterm:dumphexi(mm_head|int)
kterm:print(" , heap pos at ")
kterm:dumphexi(mm_pos|int)
kterm:print(" (")
kterm:printi((mm_pos|int)-(mm_head|int))
kterm:printl("b consumed)")

kterm:print("BG Colors 0-16, FG Colors:")

int bg_idx=0x0F

while bg_idx<=0xFF do
kterm:printa(bg_idx, ".")
bg_idx+=0x10
done

int fg_idx=0x00

while fg_idx<=0x0F do
kterm:printa(fg_idx, "X")
fg_idx+=1
done

init_keymap()

orth::internal::hooks::enable_err()

kterm:print("\n\nREADY")

#test_thunk()

kconsole_run()
return