This commit is contained in:
Martin Vrhovšek 2025-04-26 00:05:11 +02:00
parent 3652df31f4
commit fd386888f4

View File

@ -4,7 +4,7 @@ const rl = @import("raylib");
const WIDTH = 64; const WIDTH = 64;
const HEIGHT = 32; const HEIGHT = 32;
const SCALE = 15; const SCALE = 15;
const FREQUENCY = 30; const FREQUENCY = 60;
const MEMORY_SIZE = 4096; const MEMORY_SIZE = 4096;
const FONT_START = 0x050; const FONT_START = 0x050;
@ -27,7 +27,7 @@ const Emulator = struct {
prng: std.Random.Xoshiro256, prng: std.Random.Xoshiro256,
pub fn init(allocator: std.mem.Allocator) !Emulator { pub fn init(allocator: std.mem.Allocator) !Emulator {
return Emulator{ .screen = clearScreen(), .memory = try initMemory(allocator), .stack = std.ArrayList(u16).init(allocator), .v = std.mem.zeroes([16]u8), .i = 0, .key_pressed = 0, .pc = PROGRAM_START, .delay_timer = FREQUENCY, .sound_timer = 0, .legacy = true, .legacy_memory = false, .add_index_exception = false, .prng = std.Random.DefaultPrng.init(blk: { return Emulator{ .screen = clearScreen(), .memory = try initMemory(allocator), .stack = std.ArrayList(u16).init(allocator), .v = std.mem.zeroes([16]u8), .i = 0, .key_pressed = 0, .pc = PROGRAM_START, .delay_timer = 0, .sound_timer = 0, .legacy = true, .legacy_memory = false, .add_index_exception = false, .prng = std.Random.DefaultPrng.init(blk: {
var seed: u64 = undefined; var seed: u64 = undefined;
try std.posix.getrandom(std.mem.asBytes(&seed)); try std.posix.getrandom(std.mem.asBytes(&seed));
break :blk seed; break :blk seed;
@ -40,9 +40,8 @@ const Emulator = struct {
pub fn instructionCycle(self: *Emulator) !void { pub fn instructionCycle(self: *Emulator) !void {
const instruction: u16 = @as(u16, self.memory[self.pc]) << 8 | @as(u16, self.memory[self.pc + 1]); const instruction: u16 = @as(u16, self.memory[self.pc]) << 8 | @as(u16, self.memory[self.pc + 1]);
var bd: [10]u8 = undefined; // var bd: [10]u8 = undefined;
_ = try std.fmt.bufPrint(&bd, "{X:0>4}", .{instruction}); // _ = try std.fmt.bufPrint(&bd, "{X:0>4}", .{instruction});
std.debug.print("Instruction: {s}\n\n", .{bd});
const first: u8 = @truncate(instruction >> 12); const first: u8 = @truncate(instruction >> 12);
const x: u8 = @truncate((instruction >> 8) & 0xF); const x: u8 = @truncate((instruction >> 8) & 0xF);
@ -126,9 +125,9 @@ const Emulator = struct {
}, },
0x6 => { 0x6 => {
// shifting v[x] right and saving the dropped bit into V[0xF] // shifting v[x] right and saving the dropped bit into V[0xF]
// if (self.legacy) { if (self.legacy) {
// self.v[x] = self.v[y]; self.v[x] = self.v[y];
// } }
self.v[0xF] = self.v[x] & 0x1; self.v[0xF] = self.v[x] & 0x1;
self.v[x] >>= 1; self.v[x] >>= 1;
@ -141,11 +140,11 @@ const Emulator = struct {
}, },
0xE => { 0xE => {
// shifting v[x] left and saving the dropped bit into V[0xF] // shifting v[x] left and saving the dropped bit into V[0xF]
// if (self.legacy) { if (self.legacy) {
// self.v[x] = self.v[y]; self.v[x] = self.v[y];
// } }
self.v[0xF] = (self.v[x] & 0x80) >> 7; self.v[0xF] = self.v[x] >> 7;
self.v[x] <<= 1; self.v[x] <<= 1;
}, },
else => {}, else => {},
@ -195,12 +194,12 @@ const Emulator = struct {
self.v[0xF] = 1; self.v[0xF] = 1;
} }
x_coord += 1; x_coord = (x_coord + 1) % WIDTH;
if (x_coord >= WIDTH) break; // if (x_coord >= WIDTH) break;
} }
x_coord = self.v[x] % WIDTH; x_coord = self.v[x] % WIDTH;
y_coord += 1; y_coord = (y_coord + 1) % HEIGHT;
if (y_coord >= HEIGHT) break; // if (y_coord >= HEIGHT) break;
} }
}, },
0xE => { 0xE => {
@ -217,13 +216,10 @@ const Emulator = struct {
}, },
0xF => { 0xF => {
switch (nn) { switch (nn) {
// set delay // set vx to delay
0x07 => self.v[x] = self.delay_timer, 0x07 => self.v[x] = self.delay_timer,
0x15 => { // set delay
// set delay, adjust fps 0x15 => self.delay_timer = self.v[x],
self.delay_timer = self.v[x];
rl.setTargetFPS(self.delay_timer);
},
// set sound timer // set sound timer
0x18 => self.sound_timer = self.v[x], 0x18 => self.sound_timer = self.v[x],
0x1E => { 0x1E => {
@ -399,16 +395,19 @@ pub fn main() !void {
rl.initWindow(WIDTH * SCALE, HEIGHT * SCALE, "CHIP-8 Emulator"); rl.initWindow(WIDTH * SCALE, HEIGHT * SCALE, "CHIP-8 Emulator");
defer rl.closeWindow(); defer rl.closeWindow();
rl.setTargetFPS(chip8.delay_timer); rl.setTargetFPS(FREQUENCY);
var cycle_count: usize = 0;
while (!rl.windowShouldClose()) { while (!rl.windowShouldClose()) {
cycle_count += 1;
std.debug.print("Cycle count: {d}\n", .{cycle_count});
chip8.getInput(); chip8.getInput();
try chip8.instructionCycle(); try chip8.instructionCycle();
chip8.draw(); chip8.draw();
// todo sound timer decrease i guess
if (chip8.delay_timer > 0) chip8.delay_timer -= 1;
if (chip8.sound_timer > 0) {
// todo sound implementation
chip8.sound_timer -= 1;
}
} }
} }