feat: rewrite device ticks

This commit is contained in:
Rekai Nyangadzayi Musuka 2022-10-21 05:13:04 -03:00
parent 739d38533a
commit 3c5b30dece
5 changed files with 51 additions and 39 deletions

View File

@ -169,6 +169,8 @@ pub const Apu = struct {
is_buffer_full: bool, is_buffer_full: bool,
pub const Tick = enum { Length, Envelope, Sweep };
pub fn init(sched: *Scheduler) Self { pub fn init(sched: *Scheduler) Self {
const apu: Self = .{ const apu: Self = .{
.ch1 = ToneSweep.init(sched), .ch1 = ToneSweep.init(sched),
@ -377,12 +379,12 @@ pub const Apu = struct {
self.fs.tick(); self.fs.tick();
switch (self.fs.step) { switch (self.fs.step) {
7 => self.tickEnvelopes(), // Clock Envelope 7 => self.tick(.Envelope), // Clock Envelope
0, 4 => self.tickLengths(), // Clock Length 0, 4 => self.tick(.Length), // Clock Length
2, 6 => { 2, 6 => {
// Clock Length and Sweep // Clock Length and Sweep
self.tickLengths(); self.tick(.Length);
self.ch1.tickSweep(); self.tick(.Sweep);
}, },
1, 3, 5 => {}, 1, 3, 5 => {},
} }
@ -390,17 +392,21 @@ pub const Apu = struct {
self.sched.push(.FrameSequencer, ((1 << 24) / 512) -| late); self.sched.push(.FrameSequencer, ((1 << 24) / 512) -| late);
} }
fn tickLengths(self: *Self) void { fn tick(self: *Self, comptime kind: Tick) void {
self.ch1.tickLength(); switch (kind) {
self.ch2.tickLength(); .Length => {
self.ch3.tickLength(); self.ch1.tick(kind);
self.ch4.tickLength(); self.ch2.tick(kind);
} self.ch3.tick(kind);
self.ch4.tick(kind);
fn tickEnvelopes(self: *Self) void { },
self.ch1.tickEnvelope(); .Envelope => {
self.ch2.tickEnvelope(); self.ch1.tick(kind);
self.ch4.tickEnvelope(); self.ch2.tick(kind);
self.ch4.tick(kind);
},
.Sweep => self.ch1.tick(kind),
}
} }
pub fn onDmaAudioSampleRequest(self: *Self, cpu: *Arm7tdmi, tim_id: u3) void { pub fn onDmaAudioSampleRequest(self: *Self, cpu: *Arm7tdmi, tim_id: u3) void {

View File

@ -3,6 +3,7 @@ const util = @import("../../util.zig");
const Scheduler = @import("../scheduler.zig").Scheduler; const Scheduler = @import("../scheduler.zig").Scheduler;
const FrameSequencer = @import("../apu.zig").FrameSequencer; const FrameSequencer = @import("../apu.zig").FrameSequencer;
const Tick = @import("../apu.zig").Apu.Tick;
const Envelope = @import("device/Envelope.zig"); const Envelope = @import("device/Envelope.zig");
const Length = @import("device/Length.zig"); const Length = @import("device/Length.zig");
const Lfsr = @import("signal/Lfsr.zig"); const Lfsr = @import("signal/Lfsr.zig");
@ -57,12 +58,12 @@ pub fn reset(self: *Self) void {
self.enabled = false; self.enabled = false;
} }
pub fn tickLength(self: *Self) void { pub fn tick(self: *Self, comptime kind: Tick) void {
self.len_dev.tick(self.cnt.length_enable.read(), &self.enabled); switch (kind) {
} .Length => self.len_dev.tick(self.cnt.length_enable.read(), &self.enabled),
.Envelope => self.env_dev.tick(self.envelope),
pub fn tickEnvelope(self: *Self) void { .Sweep => @compileError("Channel 4 does not implement Sweep"),
self.env_dev.tick(self.envelope); }
} }
/// NR41, NR42 /// NR41, NR42

View File

@ -3,6 +3,7 @@ const util = @import("../../util.zig");
const Scheduler = @import("../scheduler.zig").Scheduler; const Scheduler = @import("../scheduler.zig").Scheduler;
const FrameSequencer = @import("../apu.zig").FrameSequencer; const FrameSequencer = @import("../apu.zig").FrameSequencer;
const Tick = @import("../apu.zig").Apu.Tick;
const Length = @import("device/Length.zig"); const Length = @import("device/Length.zig");
const Envelope = @import("device/Envelope.zig"); const Envelope = @import("device/Envelope.zig");
const Square = @import("signal/Square.zig"); const Square = @import("signal/Square.zig");
@ -50,12 +51,12 @@ pub fn reset(self: *Self) void {
self.enabled = false; self.enabled = false;
} }
pub fn tickLength(self: *Self) void { pub fn tick(self: *Self, comptime kind: Tick) void {
self.len_dev.tick(self.freq.length_enable.read(), &self.enabled); switch (kind) {
} .Length => self.len_dev.tick(self.freq.length_enable.read(), &self.enabled),
.Envelope => self.env_dev.tick(self.envelope),
pub fn tickEnvelope(self: *Self) void { .Sweep => @compileError("Channel 2 does not implement Sweep"),
self.env_dev.tick(self.envelope); }
} }
pub fn onToneEvent(self: *Self, late: u64) void { pub fn onToneEvent(self: *Self, late: u64) void {

View File

@ -8,6 +8,8 @@ const Envelope = @import("device/Envelope.zig");
const Sweep = @import("device/Sweep.zig"); const Sweep = @import("device/Sweep.zig");
const Square = @import("signal/Square.zig"); const Square = @import("signal/Square.zig");
const Tick = @import("../apu.zig").Apu.Tick;
const Self = @This(); const Self = @This();
/// NR10 /// NR10
@ -59,16 +61,12 @@ pub fn reset(self: *Self) void {
self.enabled = false; self.enabled = false;
} }
pub fn tickSweep(self: *Self) void { pub fn tick(self: *Self, comptime kind: Tick) void {
self.sweep_dev.tick(self); switch (kind) {
} .Length => self.len_dev.tick(self.freq.length_enable.read(), &self.enabled),
.Envelope => self.env_dev.tick(self.envelope),
pub fn tickLength(self: *Self) void { .Sweep => self.sweep_dev.tick(self),
self.len_dev.tick(self.freq.length_enable.read(), &self.enabled); }
}
pub fn tickEnvelope(self: *Self) void {
self.env_dev.tick(self.envelope);
} }
pub fn onToneSweepEvent(self: *Self, late: u64) void { pub fn onToneSweepEvent(self: *Self, late: u64) void {

View File

@ -3,6 +3,8 @@ const util = @import("../../util.zig");
const Scheduler = @import("../scheduler.zig").Scheduler; const Scheduler = @import("../scheduler.zig").Scheduler;
const FrameSequencer = @import("../apu.zig").FrameSequencer; const FrameSequencer = @import("../apu.zig").FrameSequencer;
const Tick = @import("../apu.zig").Apu.Tick;
const Length = @import("device/Length.zig"); const Length = @import("device/Length.zig");
const Wave = @import("signal/Wave.zig"); const Wave = @import("signal/Wave.zig");
@ -49,8 +51,12 @@ pub fn reset(self: *Self) void {
self.enabled = false; self.enabled = false;
} }
pub fn tickLength(self: *Self) void { pub fn tick(self: *Self, comptime kind: Tick) void {
self.len_dev.tick(self.freq.length_enable.read(), &self.enabled); switch (kind) {
.Length => self.len_dev.tick(self.freq.length_enable.read(), &self.enabled),
.Envelope => @compileError("Channel 3 does not implement Envelope"),
.Sweep => @compileError("Channel 3 does not implement Sweep"),
}
} }
/// NR30, NR31, NR32 /// NR30, NR31, NR32