pub inline fn outb(port: u16, value: u8) void { asm volatile ("outb %[value], %[port]" :: [port] "N{dx}" (port), [value] "{al}" (value), ); } const VGACell = packed struct { char: u8, foreground: u4 = 0xf, background: u4 = 0x0, }; const VGATerminal = struct { const width = 80; const height = 25; const vram: *[width * height]VGACell = @ptrFromInt(0xB8000); offset: u16 = 0, pub fn put(self: *VGATerminal, ch: u8) void { vram[self.offset] = VGACell{ .char = ch }; self.offset += 1; } fn checkpos(self: *VGATerminal) void { if (self.offset >= width * height) { const onebefore = (width - 1) * height; @memcpy(vram, vram[width..onebefore]); @memset(vram[onebefore..], 0); self.offset = onebefore; } } pub fn updatecursor(self: VGATerminal) void { outb(0x03d4, 0x0f); outb(0x03d5, @intCast(self.offset & 0xFF)); outb(0x03d4, 0x0e); outb(0x03d5, @intCast(self.offset >> 8)); } }; export fn zigit() void { var vga = VGATerminal{}; vga.put('H'); vga.put('i'); vga.updatecursor(); }