PAGE_SIZE := 4096 MAX_ALLOC := 0xFF MAX_FREE := 0xFF calc_pages := fn($Expr: type, num: int): int { return 1 + @bitcast(@sizeof(Expr)) * num / PAGE_SIZE } alloc := fn($Expr: type, num: int): ^Expr { pages := @inline(calc_pages, Expr, num) if pages <= MAX_ALLOC { return @bitcast(request_page(@intcast(pages))) } ptr := request_page(0xFF) remaining := pages - MAX_ALLOC loop if remaining <= 0 break else { if remaining < MAX_ALLOC { request_page(@intcast(remaining)) } else { request_page(@intcast(MAX_ALLOC)) } remaining -= MAX_ALLOC } return @bitcast(ptr) } // ! is broked, somebody fix please :( free := fn($Expr: type, ptr: ^Expr, num: int, nullify: bool): void { if nullify { null := @as(u8, 0) set(u8, &null, @bitcast(ptr), @bitcast(num) * @bitcast(PAGE_SIZE)) } pages := @inline(calc_pages, Expr, num) if pages <= MAX_FREE { return release_page(@bitcast(ptr), @intcast(pages)) } page_ptr := @as(^[u8; PAGE_SIZE], @bitcast(ptr)) + 1 remaining := pages - MAX_FREE loop if remaining <= 0 break else { if remaining < MAX_FREE { release_page(@bitcast(page_ptr), @intcast(remaining)) } else { release_page(@bitcast(page_ptr), @intcast(MAX_FREE)) } remaining -= MAX_FREE page_ptr += 1 } return } RqPageMsg := packed struct {a: u8, count: u8} request_page := fn(count: u8): ^u8 { return @eca(3, 2, &RqPageMsg.(0, count), @sizeof(RqPageMsg)) } RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8} release_page := fn(ptr: ^u8, count: u8): void { return @eca(3, 2, &RlPageMsg.(1, count, ptr), @sizeof(RlPageMsg)) } OutbMsg := packed struct {a: u8, b: u8, addr: u16, value: u8} outb := fn(addr: u16, value: u8): void { return @eca(3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg)) } InbMsg := packed struct {a: u8, b: u8, addr: u16} inb := fn(addr: u16): u8 { return @eca(3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg)) } OutlMsg := packed struct {a: u8, b: u8, addr: u16, value: u32} outl := fn(addr: u16, value: u32): void { return @eca(3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg)) } InlMsg := packed struct {a: u8, b: u8, addr: u16} inl := fn(addr: u16): u32 { return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg)) } CopyMsg := packed struct {a: u8, count: uint, src: uint, dest: ^u8} copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg)) } SetMsg := packed struct {a: u8, count: uint, size: uint, src: ^u8, dest: ^u8} set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { return @eca(3, 2, &SetMsg.(5, count, @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg)) }