From 6ebd66eb3bb753f7d09c0e32e87ed4c03b0fd65e Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Thu, 23 Feb 2023 22:12:06 -0600 Subject: [PATCH] tmp: implement mechanisms for a emu reset fn (currently crashes) --- src/core/cpu.zig | 8 ++++++++ src/core/emu.zig | 7 +++++++ src/core/scheduler.zig | 15 +++++++++++++-- src/imgui.zig | 7 +++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/core/cpu.zig b/src/core/cpu.zig index 669d195..e005c9e 100644 --- a/src/core/cpu.zig +++ b/src/core/cpu.zig @@ -314,6 +314,14 @@ pub const Arm7tdmi = struct { }; } + // FIXME: Resetting disables logging (if enabled) + pub fn reset(self: *Self) void { + const bus_ptr = self.bus; + const scheduler_ptr = self.sched; + + self.* = Self.init(scheduler_ptr, bus_ptr, null); + } + pub inline fn hasSPSR(self: *const Self) bool { const mode = getModeChecked(self, self.cpsr.mode.read()); return switch (mode) { diff --git a/src/core/emu.zig b/src/core/emu.zig index 11931d7..fe6dc9d 100644 --- a/src/core/emu.zig +++ b/src/core/emu.zig @@ -222,3 +222,10 @@ pub const EmuThing = struct { } } }; + +pub fn reset(cpu: *Arm7tdmi) void { + @breakpoint(); + cpu.sched.reset(); // Yes this is order sensitive, see the PPU reset for why + // cpu.bus.reset(); + cpu.reset(); +} diff --git a/src/core/scheduler.zig b/src/core/scheduler.zig index 8a57183..86ebab1 100644 --- a/src/core/scheduler.zig +++ b/src/core/scheduler.zig @@ -11,11 +11,11 @@ const log = std.log.scoped(.Scheduler); pub const Scheduler = struct { const Self = @This(); - tick: u64, + tick: u64 = 0, queue: PriorityQueue(Event, void, lessThan), pub fn init(allocator: Allocator) Self { - var sched = Self{ .tick = 0, .queue = PriorityQueue(Event, void, lessThan).init(allocator, {}) }; + var sched = Self{ .queue = PriorityQueue(Event, void, lessThan).init(allocator, {}) }; sched.queue.add(.{ .kind = .HeatDeath, .tick = std.math.maxInt(u64) }) catch unreachable; return sched; @@ -26,6 +26,17 @@ pub const Scheduler = struct { self.* = undefined; } + pub fn reset(self: *Self) void { + // `std.PriorityQueue` provides no reset function, so we will just create a new one + const allocator = self.queue.allocator; + self.queue.deinit(); + + var new_queue = PriorityQueue(Event, void, lessThan).init(allocator, {}); + new_queue.add(.{ .kind = .HeatDeath, .tick = std.math.maxInt(u64) }) catch unreachable; + + self.* = .{ .queue = new_queue }; + } + pub inline fn now(self: *const Self) u64 { return self.tick; } diff --git a/src/imgui.zig b/src/imgui.zig index 2dcf60f..5651d5d 100644 --- a/src/imgui.zig +++ b/src/imgui.zig @@ -48,7 +48,7 @@ pub const State = struct { } }; -pub fn draw(state: *State, tex_id: GLuint, cpu: *const Arm7tdmi) void { +pub fn draw(state: *State, tex_id: GLuint, cpu: *Arm7tdmi) void { const win_scale = config.config().host.win_scale; { @@ -77,7 +77,10 @@ pub fn draw(state: *State, tex_id: GLuint, cpu: *const Arm7tdmi) void { if (zgui.beginMenu("Emulation", true)) { defer zgui.endMenu(); - if (zgui.menuItem("Restart", .{})) log.warn("TODO: Restart Emulator", .{}); + if (zgui.menuItem("Restart", .{})) { + @breakpoint(); + emu.reset(cpu); + } } }