include print: "./print.dsa"
include serial: "./serial.dsa"

dw idt: 0xFFFF0000
setup_base: func
    push rg0
    push rg1
    push rg2
    push rg3

    ldw idt, idr // load the IDT into the IDR

    // set all 256 interrupt addresses to point to guard
    lwi _guard, rg1     // load address of guard handler
    addi idr, 1024, rg2 // counter for 256 entries
_loop_start:
	stw rg1, rg2         // store guard into current IDT entry
	subi rg2, 4, rg2     // decrement counter
	ieq rg2, idr, rg3    // check if we've reached the base address
	jez rg3, _loop_start // repeat until all entries set

    // make sure we can handle an invalid interrupt
    lwi _handle_invalid_interrupt, rg0
    stw rg0, idr, 0

    pop rg3
    pop rg2
    pop rg1
    pop rg0
    return

setup_io: func
    push rg0

    lwi serial::isr, rg0
    stw rg0, idr, 128 // 32*4, interrupt idx 32

    pop rg0
    return


db _invalid_int: "FATAL: Invalid Interrupt!"
_handle_invalid_interrupt:
	call print::reset
	lwi _invalid_int, rg0
	push rg0
	call print::print
	pop zero
	hlt

db _err: "FATAL: Interrupt handler was not set!"
_guard:
    call print::reset
	lwi _err, rg0
	push rg0
	call print::print
	pop zero
	hlt
