blob: 666aa6bd7fed79b82c34ae0e4b7b06e5e451a02f (
plain) (
tree)
|
|
const bios = @import("bios.zig");
// -- ENTRY POINT ---------------------------------------------------------------
export fn _entry() linksection(".boot") callconv(.naked) noreturn {
asm volatile (
// Disable interrupts.
\\cli
// Clear segment selectors.
\\xor %%ax, %%ax
\\mov %%ax, %%ds
\\mov %%ax, %%es
\\mov %%ax, %%ss
\\mov %%ax, %%fs
\\mov %%ax, %%gs
\\mov $0x7c00, %sp
// Long jump to set cs to 0x0000, as some BIOSes load the MBR
// to either 07c0:0000 or 0000:7c000.
\\ljmp $0x0, $main
);
}
// -- MAIN ----------------------------------------------------------------------
// main should be "callconv(.naked)", once issue is fixed.
// https://github.com/ziglang/zig/issues/18183
export fn main() noreturn {
for (0..255) |i| {
if (i < bios.ROWS) {
bios.set_pos(@truncate(i));
} else {
// Once we reach the bottom of the screen start scrolling.
bios.scroll_up();
bios.set_pos(bios.ROWS - 1);
}
puts_dec(i + 1);
bios.putc(' ');
puts_hex(i + 1);
bios.putc(' ');
bios.putc(@truncate('a' + (i % 26)));
bios.putc(@truncate('a' + (i % 26)));
waste_time();
}
puts("\ndone");
while (true) {
asm volatile ("hlt");
}
}
// -- UTILS ---------------------------------------------------------------------
fn puts(str: []const u8) void {
for (str) |c| {
bios.putc(c);
}
}
fn puts_dec(init_val: u32) void {
var val = init_val;
var buf: [32]u8 = undefined;
var idx = buf.len;
while (val > 0 and idx != 0) : (val /= 10) {
idx -= 1;
buf[idx] = @as(u8, @truncate(val % 10)) + '0';
}
puts(buf[idx..]);
}
fn puts_hex(init_val: u32) void {
var val = init_val;
var buf: [32]u8 = undefined;
var idx = buf.len;
while (val > 0 and idx != 0) : (val /= 16) {
idx -= 1;
const digit = switch (@as(u8, @truncate(val % 16))) {
0...9 => |d| '0' + d,
10...15 => |d| 'a' + d - 10,
else => '?',
};
buf[idx] = digit;
}
puts(buf[idx..]);
}
fn rdtsc() u32 {
return asm volatile ("rdtsc"
: [eax] "={eax}" (-> u32),
:
: "edx"
);
}
fn waste_time() void {
const start = rdtsc();
var now = start;
var idx: usize = 0;
while (now - start < (1 << 28)) : (idx += 1) {
if (idx == 10_000) {
now = rdtsc();
idx = 0;
}
}
}
|