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