Initial commit

This commit is contained in:
ktkk 2025-04-15 13:41:59 +00:00
commit dc6f7e486f
9 changed files with 427 additions and 0 deletions

135
src/Console.zig Normal file
View file

@ -0,0 +1,135 @@
const std = @import("std");
const Self = @This();
pub fn init() Self {
var self = Self{};
self.clear();
return self;
}
const vga_width = 80;
const vga_height = 25;
const vga_size = vga_width * vga_height;
pub const ConsoleColor = enum(u8) {
black = 0,
blue = 1,
green = 2,
cyan = 3,
red = 4,
magenta = 5,
brown = 6,
lightGray = 7,
darkGray = 8,
lightBlue = 9,
lightGreen = 10,
lightCyan = 11,
lightRed = 12,
lightMagenta = 13,
lightBrown = 14,
white = 15,
};
const default_color = vgaEntryColor(ConsoleColor.lightGray, ConsoleColor.black);
column: usize = 0,
color: u8 = default_color,
buffer: [*]volatile u16 = @ptrFromInt(0xb8000),
fn vgaEntryColor(fg: ConsoleColor, bg: ConsoleColor) u8 {
return @intFromEnum(fg) | (@intFromEnum(bg) << 4);
}
fn vgaEntry(uc: u8, new_color: u8) u16 {
const c: u16 = new_color;
return uc | (c << 8);
}
fn index(x: usize, y: usize) usize {
return y * vga_width + x;
}
pub fn setColor(self: *Self, fg: ConsoleColor, bg: ConsoleColor) void {
self.color = vgaEntryColor(fg, bg);
}
pub fn resetColor(self: *Self) void {
self.color = default_color;
}
pub fn clear(self: *Self) void {
@memset(self.buffer[0..vga_size], vgaEntry(' ', self.color));
}
fn clearRow(self: *Self, y: usize) void {
for (0..vga_width) |x| {
const i = index(x, y);
self.buffer[i] = vgaEntry(' ', self.color);
}
}
fn newLine(self: *Self) void {
for (1..vga_height) |y| {
for (0..vga_width) |x| {
const entry = self.getEntryAt(x, y);
self.putEntryAt(entry, x, y - 1);
}
}
self.clearRow(vga_height - 1);
self.column = 0;
}
pub fn putCharAt(self: *Self, c: u8, new_color: u8, x: usize, y: usize) void {
self.putEntryAt(vgaEntry(c, new_color), x, y);
}
fn putEntryAt(self: *Self, entry: u16, x: usize, y: usize) void {
const i = index(x, y);
self.buffer[i] = entry;
}
fn getEntryAt(self: *Self, x: usize, y: usize) u16 {
const i = index(x, y);
return self.buffer[i];
}
pub fn putChar(self: *Self, c: u8) void {
switch (c) {
'\n' => self.newLine(),
else => {
if (self.column >= vga_width) {
self.newLine();
}
const y = vga_height - 1;
const x = self.column;
self.putCharAt(c, self.color, x, y);
self.column += 1;
},
}
}
pub fn puts(self: *Self, data: []const u8) void {
for (data) |c| {
self.putChar(c);
}
}
const Writer = std.io.Writer(
*Self,
error{},
callback,
);
pub fn writer(self: *Self) Writer {
return .{ .context = self };
}
fn callback(self: *Self, string: []const u8) error{}!usize {
self.puts(string);
return string.len;
}
pub fn printf(self: *Self, comptime format: []const u8, args: anytype) void {
std.fmt.format(self.writer(), format, args) catch unreachable;
}