const SYSCALL_TABLE_ADDR = 0
const NUM_SYSCALLS = 3

const PANIC_ADDR = SYSCALL_TABLE_ADDR + 1
const PRINTLN_ADDR = SYSCALL_TABLE_ADDR + 2

#! Initializes the kernel environment
pub proc init
    procref.is_valid_syscall
    mem_storew.SYSCALL_TABLE_ADDR
    procref.$kernel::sys::panic
    mem_storew.PANIC_ADDR
    procref.$kernel::io::println
    mem_storew.PRINTLN_ADDR
end

#! Execute one of this kernel's syscalls
#!
#! This allows downstream packages to link against the kernel, without requiring them to be
#! recompiled every time the kernel changes. This is because the only the starting memory address
#! of the syscall table is hardcoded here, so neither the number of syscalls, nor their procedure
#! digests, can cause the procedure root of this syscall to change
pub proc system_call
    # validate syscall id
    dup.0 mem_load.SYSCALL_TABLE_ADDR dynexec
    # invoke the syscall
    add.SYSCALL_TABLE_ADDR mem_loadw dynexec
end

proc is_valid_syscall
    lt.NUM_SYSCALLS assert
end
