61 lines
1.7 KiB
Zig
61 lines
1.7 KiB
Zig
const std = @import("std");
|
|
const cpu = @import("cpu.zig");
|
|
const Scheduler = @import("scheduler.zig").Scheduler;
|
|
const Display = @import("display.zig").Display;
|
|
const Allocator = std.mem.Allocator;
|
|
const Cpu = cpu.Cpu;
|
|
|
|
const FONT_SET: [80]u8 = [_]u8{
|
|
0xF0, 0x90, 0x90, 0x90, 0xF0,
|
|
0x20, 0x60, 0x20, 0x20, 0x70,
|
|
0xF0, 0x10, 0xF0, 0x80, 0xF0,
|
|
0xF0, 0x10, 0xF0, 0x10, 0xF0,
|
|
0x90, 0x90, 0xF0, 0x10, 0x10,
|
|
0xF0, 0x80, 0xF0, 0x10, 0xF0,
|
|
0xF0, 0x80, 0xF0, 0x90, 0xF0,
|
|
0xF0, 0x10, 0x20, 0x40, 0x40,
|
|
0xF0, 0x90, 0xF0, 0x90, 0xF0,
|
|
0xF0, 0x90, 0xF0, 0x10, 0xF0,
|
|
0xF0, 0x90, 0xF0, 0x90, 0x90,
|
|
0xE0, 0x90, 0xE0, 0x90, 0xE0,
|
|
0xF0, 0x80, 0x80, 0x80, 0xF0,
|
|
0xE0, 0x90, 0x90, 0x90, 0xE0,
|
|
0xF0, 0x80, 0xF0, 0x80, 0xF0,
|
|
0xF0, 0x80, 0xF0, 0x80, 0x80,
|
|
};
|
|
|
|
pub const Chip8 = struct {
|
|
cpu: Cpu,
|
|
mem: [0x1000]u8,
|
|
disp: Display,
|
|
|
|
pub fn fromFile(alloc: Allocator, scheduler: *Scheduler, path: []const u8) !Chip8 {
|
|
const file = try std.fs.cwd().openFile(path, .{ .read = true });
|
|
defer file.close();
|
|
|
|
// Read file into allocated buffer
|
|
const size = try file.getEndPos();
|
|
const rom_buf = try file.readToEndAlloc(alloc, size);
|
|
defer alloc.free(rom_buf);
|
|
|
|
var chip8 = Chip8{
|
|
.cpu = Cpu.new(scheduler),
|
|
.mem = [_]u8{0x00} ** 0x1000,
|
|
.disp = Display.new(),
|
|
};
|
|
|
|
std.mem.copy(u8, chip8.mem[0x0200..], rom_buf); // Copy ROM
|
|
std.mem.copy(u8, chip8.mem[0x50..0xA0], &FONT_SET); // Copy FONT_SET
|
|
|
|
return chip8;
|
|
}
|
|
|
|
pub fn step(self: *Chip8) u64 {
|
|
return cpu.step(&self.cpu, &self.disp, &self.mem);
|
|
}
|
|
|
|
pub fn getDisplay(self: *Chip8) *const Display {
|
|
return &self.disp;
|
|
}
|
|
};
|