From f8477714ae8bf1df0819877e4c544cb5608f0188 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 10 Mar 2023 02:27:31 -0600 Subject: [PATCH] feat: implement resetting --- src/core/Bus.zig | 2 +- src/core/apu.zig | 18 ++++++++++++------ src/core/ppu.zig | 20 ++++++++++++++++++++ src/core/ppu/Oam.zig | 4 ++++ src/core/ppu/Palette.zig | 4 ++++ src/core/ppu/Vram.zig | 4 ++++ src/util.zig | 8 ++++++-- 7 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/core/Bus.zig b/src/core/Bus.zig index 0c2d3a8..22b0b31 100644 --- a/src/core/Bus.zig +++ b/src/core/Bus.zig @@ -104,7 +104,7 @@ pub fn deinit(self: *Self) void { pub fn reset(self: *Self) void { self.bios.reset(); - // TODO: deinit ppu + self.ppu.reset(); self.apu.reset(); self.iwram.reset(); self.ewram.reset(); diff --git a/src/core/apu.zig b/src/core/apu.zig index 89204f9..a93ad0b 100644 --- a/src/core/apu.zig +++ b/src/core/apu.zig @@ -278,16 +278,20 @@ pub const Apu = struct { .is_buffer_full = false, }; - sched.push(.SampleAudio, apu.interval()); - sched.push(.{ .ApuChannel = 0 }, @import("apu/signal/Square.zig").interval); - sched.push(.{ .ApuChannel = 1 }, @import("apu/signal/Square.zig").interval); - sched.push(.{ .ApuChannel = 2 }, @import("apu/signal/Wave.zig").interval); - sched.push(.{ .ApuChannel = 3 }, @import("apu/signal/Lfsr.zig").interval); - sched.push(.FrameSequencer, FrameSequencer.interval); + Self.initEvents(apu.sched, apu.interval()); return apu; } + fn initEvents(scheduler: *Scheduler, apu_interval: u64) void { + scheduler.push(.SampleAudio, apu_interval); + scheduler.push(.{ .ApuChannel = 0 }, @import("apu/signal/Square.zig").interval); + scheduler.push(.{ .ApuChannel = 1 }, @import("apu/signal/Square.zig").interval); + scheduler.push(.{ .ApuChannel = 2 }, @import("apu/signal/Wave.zig").interval); + scheduler.push(.{ .ApuChannel = 3 }, @import("apu/signal/Lfsr.zig").interval); + scheduler.push(.FrameSequencer, FrameSequencer.interval); + } + /// Used when resetting the emulator pub fn reset(self: *Self) void { // FIXME: These reset functions are meant to emulate obscure APU behaviour. Write proper emu reset fns @@ -306,6 +310,8 @@ pub const Apu = struct { self.sampling_cycle = 0; self.fs.reset(); + + Self.initEvents(self.sched, self.interval()); } /// Emulates the reset behaviour of the APU diff --git a/src/core/ppu.zig b/src/core/ppu.zig index a6da4a9..35cb7ad 100644 --- a/src/core/ppu.zig +++ b/src/core/ppu.zig @@ -290,6 +290,26 @@ pub const Ppu = struct { }; } + pub fn reset(self: *Self) void { + self.sched.push(.Draw, 240 * 4); + + self.vram.reset(); + self.palette.reset(); + self.oam.reset(); + self.framebuf.reset(); + + self.win = Window.init(); + self.bg = [_]Background{Background.init()} ** 4; + self.aff_bg = [_]AffineBackground{AffineBackground.init()} ** 2; + self.bld = Blend.create(); + self.dispcnt = .{ .raw = 0x0000 }; + self.dispstat = .{ .raw = 0x0000 }; + self.vcount = .{ .raw = 0x0000 }; + + self.scanline.reset(); + std.mem.set(?Sprite, self.scanline_sprites, null); + } + pub fn deinit(self: *Self) void { self.allocator.destroy(self.scanline_sprites); self.framebuf.deinit(); diff --git a/src/core/ppu/Oam.zig b/src/core/ppu/Oam.zig index 2e0a78d..f09c0ff 100644 --- a/src/core/ppu/Oam.zig +++ b/src/core/ppu/Oam.zig @@ -34,6 +34,10 @@ pub fn init(allocator: Allocator) !Self { return Self{ .buf = buf, .allocator = allocator }; } +pub fn reset(self: *Self) void { + std.mem.set(u8, self.buf, 0); +} + pub fn deinit(self: *Self) void { self.allocator.free(self.buf); self.* = undefined; diff --git a/src/core/ppu/Palette.zig b/src/core/ppu/Palette.zig index d23978a..9e6f36a 100644 --- a/src/core/ppu/Palette.zig +++ b/src/core/ppu/Palette.zig @@ -37,6 +37,10 @@ pub fn init(allocator: Allocator) !Self { return Self{ .buf = buf, .allocator = allocator }; } +pub fn reset(self: *Self) void { + std.mem.set(u8, self.buf, 0); +} + pub fn deinit(self: *Self) void { self.allocator.free(self.buf); self.* = undefined; diff --git a/src/core/ppu/Vram.zig b/src/core/ppu/Vram.zig index f599212..f148dc7 100644 --- a/src/core/ppu/Vram.zig +++ b/src/core/ppu/Vram.zig @@ -45,6 +45,10 @@ pub fn init(allocator: Allocator) !Self { return Self{ .buf = buf, .allocator = allocator }; } +pub fn reset(self: *Self) void { + std.mem.set(u8, self.buf, 0); +} + pub fn deinit(self: *Self) void { self.allocator.free(self.buf); self.* = undefined; diff --git a/src/util.zig b/src/util.zig index db49131..276a658 100644 --- a/src/util.zig +++ b/src/util.zig @@ -251,7 +251,7 @@ pub const FrameBuffer = struct { layers: [2][]u8, buf: []u8, - current: u1, + current: u1 = 0, allocator: Allocator, @@ -266,12 +266,16 @@ pub const FrameBuffer = struct { // Front and Back Framebuffers .layers = [_][]u8{ buf[0..][0..len], buf[len..][0..len] }, .buf = buf, - .current = 0, .allocator = allocator, }; } + pub fn reset(self: *Self) void { + std.mem.set(u8, self.buf, 0); + self.current = 0; + } + pub fn deinit(self: *Self) void { self.allocator.free(self.buf); self.* = undefined;