feat: rewrite device ticks
This commit is contained in:
		@@ -169,6 +169,8 @@ pub const Apu = struct {
 | 
			
		||||
 | 
			
		||||
    is_buffer_full: bool,
 | 
			
		||||
 | 
			
		||||
    pub const Tick = enum { Length, Envelope, Sweep };
 | 
			
		||||
 | 
			
		||||
    pub fn init(sched: *Scheduler) Self {
 | 
			
		||||
        const apu: Self = .{
 | 
			
		||||
            .ch1 = ToneSweep.init(sched),
 | 
			
		||||
@@ -377,12 +379,12 @@ pub const Apu = struct {
 | 
			
		||||
        self.fs.tick();
 | 
			
		||||
 | 
			
		||||
        switch (self.fs.step) {
 | 
			
		||||
            7 => self.tickEnvelopes(), // Clock Envelope
 | 
			
		||||
            0, 4 => self.tickLengths(), // Clock Length
 | 
			
		||||
            7 => self.tick(.Envelope), // Clock Envelope
 | 
			
		||||
            0, 4 => self.tick(.Length), // Clock Length
 | 
			
		||||
            2, 6 => {
 | 
			
		||||
                // Clock Length and Sweep
 | 
			
		||||
                self.tickLengths();
 | 
			
		||||
                self.ch1.tickSweep();
 | 
			
		||||
                self.tick(.Length);
 | 
			
		||||
                self.tick(.Sweep);
 | 
			
		||||
            },
 | 
			
		||||
            1, 3, 5 => {},
 | 
			
		||||
        }
 | 
			
		||||
@@ -390,17 +392,21 @@ pub const Apu = struct {
 | 
			
		||||
        self.sched.push(.FrameSequencer, ((1 << 24) / 512) -| late);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn tickLengths(self: *Self) void {
 | 
			
		||||
        self.ch1.tickLength();
 | 
			
		||||
        self.ch2.tickLength();
 | 
			
		||||
        self.ch3.tickLength();
 | 
			
		||||
        self.ch4.tickLength();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn tickEnvelopes(self: *Self) void {
 | 
			
		||||
        self.ch1.tickEnvelope();
 | 
			
		||||
        self.ch2.tickEnvelope();
 | 
			
		||||
        self.ch4.tickEnvelope();
 | 
			
		||||
    fn tick(self: *Self, comptime kind: Tick) void {
 | 
			
		||||
        switch (kind) {
 | 
			
		||||
            .Length => {
 | 
			
		||||
                self.ch1.tick(kind);
 | 
			
		||||
                self.ch2.tick(kind);
 | 
			
		||||
                self.ch3.tick(kind);
 | 
			
		||||
                self.ch4.tick(kind);
 | 
			
		||||
            },
 | 
			
		||||
            .Envelope => {
 | 
			
		||||
                self.ch1.tick(kind);
 | 
			
		||||
                self.ch2.tick(kind);
 | 
			
		||||
                self.ch4.tick(kind);
 | 
			
		||||
            },
 | 
			
		||||
            .Sweep => self.ch1.tick(kind),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn onDmaAudioSampleRequest(self: *Self, cpu: *Arm7tdmi, tim_id: u3) void {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ const util = @import("../../util.zig");
 | 
			
		||||
 | 
			
		||||
const Scheduler = @import("../scheduler.zig").Scheduler;
 | 
			
		||||
const FrameSequencer = @import("../apu.zig").FrameSequencer;
 | 
			
		||||
const Tick = @import("../apu.zig").Apu.Tick;
 | 
			
		||||
const Envelope = @import("device/Envelope.zig");
 | 
			
		||||
const Length = @import("device/Length.zig");
 | 
			
		||||
const Lfsr = @import("signal/Lfsr.zig");
 | 
			
		||||
@@ -57,12 +58,12 @@ pub fn reset(self: *Self) void {
 | 
			
		||||
    self.enabled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickLength(self: *Self) void {
 | 
			
		||||
    self.len_dev.tick(self.cnt.length_enable.read(), &self.enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickEnvelope(self: *Self) void {
 | 
			
		||||
    self.env_dev.tick(self.envelope);
 | 
			
		||||
pub fn tick(self: *Self, comptime kind: Tick) void {
 | 
			
		||||
    switch (kind) {
 | 
			
		||||
        .Length => self.len_dev.tick(self.cnt.length_enable.read(), &self.enabled),
 | 
			
		||||
        .Envelope => self.env_dev.tick(self.envelope),
 | 
			
		||||
        .Sweep => @compileError("Channel 4 does not implement Sweep"),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// NR41, NR42
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ const util = @import("../../util.zig");
 | 
			
		||||
 | 
			
		||||
const Scheduler = @import("../scheduler.zig").Scheduler;
 | 
			
		||||
const FrameSequencer = @import("../apu.zig").FrameSequencer;
 | 
			
		||||
const Tick = @import("../apu.zig").Apu.Tick;
 | 
			
		||||
const Length = @import("device/Length.zig");
 | 
			
		||||
const Envelope = @import("device/Envelope.zig");
 | 
			
		||||
const Square = @import("signal/Square.zig");
 | 
			
		||||
@@ -50,12 +51,12 @@ pub fn reset(self: *Self) void {
 | 
			
		||||
    self.enabled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickLength(self: *Self) void {
 | 
			
		||||
    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 tick(self: *Self, comptime kind: Tick) void {
 | 
			
		||||
    switch (kind) {
 | 
			
		||||
        .Length => self.len_dev.tick(self.freq.length_enable.read(), &self.enabled),
 | 
			
		||||
        .Envelope => self.env_dev.tick(self.envelope),
 | 
			
		||||
        .Sweep => @compileError("Channel 2 does not implement Sweep"),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn onToneEvent(self: *Self, late: u64) void {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@ const Envelope = @import("device/Envelope.zig");
 | 
			
		||||
const Sweep = @import("device/Sweep.zig");
 | 
			
		||||
const Square = @import("signal/Square.zig");
 | 
			
		||||
 | 
			
		||||
const Tick = @import("../apu.zig").Apu.Tick;
 | 
			
		||||
 | 
			
		||||
const Self = @This();
 | 
			
		||||
 | 
			
		||||
/// NR10
 | 
			
		||||
@@ -59,16 +61,12 @@ pub fn reset(self: *Self) void {
 | 
			
		||||
    self.enabled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickSweep(self: *Self) void {
 | 
			
		||||
    self.sweep_dev.tick(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickLength(self: *Self) void {
 | 
			
		||||
    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 tick(self: *Self, comptime kind: Tick) void {
 | 
			
		||||
    switch (kind) {
 | 
			
		||||
        .Length => self.len_dev.tick(self.freq.length_enable.read(), &self.enabled),
 | 
			
		||||
        .Envelope => self.env_dev.tick(self.envelope),
 | 
			
		||||
        .Sweep => self.sweep_dev.tick(self),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn onToneSweepEvent(self: *Self, late: u64) void {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@ const util = @import("../../util.zig");
 | 
			
		||||
 | 
			
		||||
const Scheduler = @import("../scheduler.zig").Scheduler;
 | 
			
		||||
const FrameSequencer = @import("../apu.zig").FrameSequencer;
 | 
			
		||||
const Tick = @import("../apu.zig").Apu.Tick;
 | 
			
		||||
 | 
			
		||||
const Length = @import("device/Length.zig");
 | 
			
		||||
const Wave = @import("signal/Wave.zig");
 | 
			
		||||
 | 
			
		||||
@@ -49,8 +51,12 @@ pub fn reset(self: *Self) void {
 | 
			
		||||
    self.enabled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn tickLength(self: *Self) void {
 | 
			
		||||
    self.len_dev.tick(self.freq.length_enable.read(), &self.enabled);
 | 
			
		||||
pub fn tick(self: *Self, comptime kind: Tick) void {
 | 
			
		||||
    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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user