style: code refactoring
This commit is contained in:
parent
dc7cad9691
commit
bcacac64df
|
@ -306,15 +306,15 @@ pub const Apu = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add all PSG channels together
|
// Add all PSG channels together
|
||||||
left += if (ch_left & 1 == 1) self.ch1.amplitude() else 0;
|
left += if (ch_left & 1 == 1) @as(i16, self.ch1.sample) else 0;
|
||||||
left += if (ch_left >> 1 & 1 == 1) self.ch2.amplitude() else 0;
|
left += if (ch_left >> 1 & 1 == 1) @as(i16, self.ch2.sample) else 0;
|
||||||
left += if (ch_left >> 2 & 1 == 1) self.ch3.amplitude() else 0;
|
left += if (ch_left >> 2 & 1 == 1) @as(i16, self.ch3.sample) else 0;
|
||||||
left += if (ch_left >> 3 == 1) self.ch4.amplitude() else 0;
|
left += if (ch_left >> 3 == 1) @as(i16, self.ch4.sample) else 0;
|
||||||
|
|
||||||
right += if (ch_right & 1 == 1) self.ch1.amplitude() else 0;
|
right += if (ch_right & 1 == 1) @as(i16, self.ch1.sample) else 0;
|
||||||
right += if (ch_right >> 1 & 1 == 1) self.ch2.amplitude() else 0;
|
right += if (ch_right >> 1 & 1 == 1) @as(i16, self.ch2.sample) else 0;
|
||||||
right += if (ch_right >> 2 & 1 == 1) self.ch3.amplitude() else 0;
|
right += if (ch_right >> 2 & 1 == 1) @as(i16, self.ch3.sample) else 0;
|
||||||
right += if (ch_right >> 3 == 1) self.ch4.amplitude() else 0;
|
right += if (ch_right >> 3 == 1) @as(i16, self.ch4.sample) else 0;
|
||||||
|
|
||||||
// Multiply by master channel volume
|
// Multiply by master channel volume
|
||||||
left *= 1 + @as(i16, self.psg_cnt.left_vol.read());
|
left *= 1 + @as(i16, self.psg_cnt.left_vol.read());
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const io = @import("../bus/io.zig");
|
const io = @import("../bus/io.zig");
|
||||||
|
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;
|
||||||
|
@ -123,7 +124,7 @@ pub fn setNr44(self: *Self, fs: *const FrameSequencer, byte: u8) void {
|
||||||
self.enabled = self.isDacEnabled();
|
self.enabled = self.isDacEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lfsr.updateLength(fs, self, new);
|
util.audio.length.ch4.update(self, fs, new);
|
||||||
self.cnt = new;
|
self.cnt = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,10 +136,6 @@ pub fn channelTimerOverflow(self: *Self, late: u64) void {
|
||||||
self.sample = if (self.enabled) self.lfsr.sample() * @as(i8, self.env_dev.vol) else 0;
|
self.sample = if (self.enabled) self.lfsr.sample() * @as(i8, self.env_dev.vol) else 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn amplitude(self: *const Self) i16 {
|
|
||||||
return @as(i16, self.sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn isDacEnabled(self: *const Self) bool {
|
fn isDacEnabled(self: *const Self) bool {
|
||||||
return self.envelope.raw & 0xF8 != 0x00;
|
return self.envelope.raw & 0xF8 != 0x00;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const io = @import("../bus/io.zig");
|
const io = @import("../bus/io.zig");
|
||||||
|
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;
|
||||||
|
@ -65,10 +66,6 @@ pub fn channelTimerOverflow(self: *Self, late: u64) void {
|
||||||
self.sample = if (self.enabled) self.square.sample(self.duty) * @as(i8, self.env_dev.vol) else 0;
|
self.sample = if (self.enabled) self.square.sample(self.duty) * @as(i8, self.env_dev.vol) else 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn amplitude(self: *const Self) i16 {
|
|
||||||
return @as(i16, self.sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NR21, NR22
|
/// NR21, NR22
|
||||||
pub fn getSoundCntL(self: *const Self) u16 {
|
pub fn getSoundCntL(self: *const Self) u16 {
|
||||||
return @as(u16, self.envelope.raw) << 8 | (self.duty.raw & 0xC0);
|
return @as(u16, self.envelope.raw) << 8 | (self.duty.raw & 0xC0);
|
||||||
|
@ -131,7 +128,7 @@ pub fn setNr24(self: *Self, fs: *const FrameSequencer, byte: u8) void {
|
||||||
self.enabled = self.isDacEnabled();
|
self.enabled = self.isDacEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.square.updateLength(Self, fs, self, new);
|
util.audio.length.update(Self, self, fs, new);
|
||||||
self.freq = new;
|
self.freq = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// const std = @import("std");
|
|
||||||
const io = @import("../bus/io.zig");
|
const io = @import("../bus/io.zig");
|
||||||
|
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;
|
||||||
|
@ -79,10 +79,6 @@ pub fn channelTimerOverflow(self: *Self, late: u64) void {
|
||||||
self.sample = if (self.enabled) self.square.sample(self.duty) * @as(i8, self.env_dev.vol) else 0;
|
self.sample = if (self.enabled) self.square.sample(self.duty) * @as(i8, self.env_dev.vol) else 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn amplitude(self: *const Self) i16 {
|
|
||||||
return @as(i16, self.sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NR10, NR11, NR12
|
/// NR10, NR11, NR12
|
||||||
pub fn setSoundCnt(self: *Self, value: u32) void {
|
pub fn setSoundCnt(self: *Self, value: u32) void {
|
||||||
self.setSoundCntL(@truncate(u8, value));
|
self.setSoundCntL(@truncate(u8, value));
|
||||||
|
@ -181,7 +177,7 @@ pub fn setNr14(self: *Self, fs: *const FrameSequencer, byte: u8) void {
|
||||||
self.enabled = self.isDacEnabled();
|
self.enabled = self.isDacEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.square.updateLength(Self, fs, self, new);
|
util.audio.length.update(Self, self, fs, new);
|
||||||
self.freq = new;
|
self.freq = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const io = @import("../bus/io.zig");
|
const io = @import("../bus/io.zig");
|
||||||
|
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;
|
||||||
|
@ -111,7 +112,7 @@ pub fn setNr34(self: *Self, fs: *const FrameSequencer, byte: u8) void {
|
||||||
self.enabled = self.select.enabled.read();
|
self.enabled = self.select.enabled.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.wave_dev.updateLength(fs, self, new);
|
util.audio.length.update(Self, self, fs, new);
|
||||||
self.freq = new;
|
self.freq = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +124,3 @@ pub fn channelTimerOverflow(self: *Self, late: u64) void {
|
||||||
// Convert unsigned 4-bit wave sample to signed 8-bit sample
|
// Convert unsigned 4-bit wave sample to signed 8-bit sample
|
||||||
self.sample = (2 * @as(i8, self.wave_dev.sample(self.select)) - 15) >> self.wave_dev.shift(self.vol);
|
self.sample = (2 * @as(i8, self.wave_dev.sample(self.select)) - 15) >> self.wave_dev.shift(self.vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn amplitude(self: *const Self) i16 {
|
|
||||||
return @as(i16, self.sample);
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,22 +25,6 @@ pub fn sample(self: *const Self) i8 {
|
||||||
return if ((~self.shift & 1) == 1) 1 else -1;
|
return if ((~self.shift & 1) == 1) 1 else -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the sate of the Channel Length TImer
|
|
||||||
pub fn updateLength(_: *Self, fs: *const FrameSequencer, ch4: *Noise, nr44: io.NoiseControl) void {
|
|
||||||
// Write to NRx4 when FS's next step is not one that clocks the length counter
|
|
||||||
if (!fs.isLengthNext()) {
|
|
||||||
// If length_enable was disabled but is now enabled and length timer is not 0 already,
|
|
||||||
// decrement the length timer
|
|
||||||
|
|
||||||
if (!ch4.cnt.length_enable.read() and nr44.length_enable.read() and ch4.len_dev.timer != 0) {
|
|
||||||
ch4.len_dev.timer -= 1;
|
|
||||||
|
|
||||||
// If Length Timer is now 0 and trigger is clear, disable the channel
|
|
||||||
if (ch4.len_dev.timer == 0 and !nr44.trigger.read()) ch4.enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reload LFSR Timer
|
/// Reload LFSR Timer
|
||||||
pub fn reload(self: *Self, poly: io.PolyCounter) void {
|
pub fn reload(self: *Self, poly: io.PolyCounter) void {
|
||||||
self.sched.removeScheduledEvent(.{ .ApuChannel = 3 });
|
self.sched.removeScheduledEvent(.{ .ApuChannel = 3 });
|
||||||
|
|
|
@ -21,23 +21,6 @@ pub fn init(sched: *Scheduler) Self {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the State of either Ch1 or Ch2's Length Timer
|
|
||||||
pub fn updateLength(_: *const Self, comptime T: type, fs: *const FrameSequencer, ch: *T, nrx34: io.Frequency) void {
|
|
||||||
comptime std.debug.assert(T == ToneSweep or T == Tone);
|
|
||||||
// Write to NRx4 when FS's next step is not one that clocks the length counter
|
|
||||||
if (!fs.isLengthNext()) {
|
|
||||||
// If length_enable was disabled but is now enabled and length timer is not 0 already,
|
|
||||||
// decrement the length timer
|
|
||||||
|
|
||||||
if (!ch.freq.length_enable.read() and nrx34.length_enable.read() and ch.len_dev.timer != 0) {
|
|
||||||
ch.len_dev.timer -= 1;
|
|
||||||
|
|
||||||
// If Length Timer is now 0 and trigger is clear, disable the channel
|
|
||||||
if (ch.len_dev.timer == 0 and !nrx34.trigger.read()) ch.enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Scheduler Event Handler for Square Synth Timer Expire
|
/// Scheduler Event Handler for Square Synth Timer Expire
|
||||||
pub fn onSquareTimerExpire(self: *Self, comptime T: type, nrx34: io.Frequency, late: u64) void {
|
pub fn onSquareTimerExpire(self: *Self, comptime T: type, nrx34: io.Frequency, late: u64) void {
|
||||||
comptime std.debug.assert(T == ToneSweep or T == Tone);
|
comptime std.debug.assert(T == ToneSweep or T == Tone);
|
||||||
|
|
|
@ -77,19 +77,3 @@ pub fn shift(_: *const Self, nr32: io.WaveVolume) u2 {
|
||||||
0b11 => 2, // 25% Volume
|
0b11 => 2, // 25% Volume
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update state of Channel 3 Length Device
|
|
||||||
pub fn updateLength(_: *Self, fs: *const FrameSequencer, ch3: *Wave, nrx34: io.Frequency) void {
|
|
||||||
// Write to NRx4 when FS's next step is not one that clocks the length counter
|
|
||||||
if (!fs.isLengthNext()) {
|
|
||||||
// If length_enable was disabled but is now enabled and length timer is not 0 already,
|
|
||||||
// decrement the length timer
|
|
||||||
|
|
||||||
if (!ch3.freq.length_enable.read() and nrx34.length_enable.read() and ch3.len_dev.timer != 0) {
|
|
||||||
ch3.len_dev.timer -= 1;
|
|
||||||
|
|
||||||
// If Length Timer is now 0 and trigger is clear, disable the channel
|
|
||||||
if (ch3.len_dev.timer == 0 and !nrx34.trigger.read()) ch3.enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
60
src/util.zig
60
src/util.zig
|
@ -158,17 +158,6 @@ pub const io = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
pub fn readUndefined(log: anytype, comptime format: []const u8, args: anytype) u8 {
|
|
||||||
log.warn(format, args);
|
|
||||||
if (builtin.mode == .Debug) std.debug.panic("TODO: Implement I/O Register", .{});
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn writeUndefined(log: anytype, comptime format: []const u8, args: anytype) void {
|
|
||||||
log.warn(format, args);
|
|
||||||
if (builtin.mode == .Debug) std.debug.panic("TODO: Implement I/O Register", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Logger = struct {
|
pub const Logger = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
@ -230,3 +219,52 @@ pub const Logger = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const FmtArgTuple = std.meta.Tuple(&.{ u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32 });
|
const FmtArgTuple = std.meta.Tuple(&.{ u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32 });
|
||||||
|
|
||||||
|
pub const audio = struct {
|
||||||
|
const _io = @import("core/bus/io.zig");
|
||||||
|
|
||||||
|
const ToneSweep = @import("core/apu/ToneSweep.zig");
|
||||||
|
const Tone = @import("core/apu/Tone.zig");
|
||||||
|
const Wave = @import("core/apu/Wave.zig");
|
||||||
|
const Noise = @import("core/apu/Noise.zig");
|
||||||
|
|
||||||
|
pub const length = struct {
|
||||||
|
const FrameSequencer = @import("core/apu.zig").FrameSequencer;
|
||||||
|
|
||||||
|
/// Update State of Ch1, Ch2 and Ch3 length timer
|
||||||
|
pub fn update(comptime T: type, self: *T, fs: *const FrameSequencer, nrx34: _io.Frequency) void {
|
||||||
|
comptime std.debug.assert(T == ToneSweep or T == Tone or T == Wave);
|
||||||
|
|
||||||
|
// Write to NRx4 when FS's next step is not one that clocks the length counter
|
||||||
|
if (!fs.isLengthNext()) {
|
||||||
|
// If length_enable was disabled but is now enabled and length timer is not 0 already,
|
||||||
|
// decrement the length timer
|
||||||
|
|
||||||
|
if (!self.freq.length_enable.read() and nrx34.length_enable.read() and self.len_dev.timer != 0) {
|
||||||
|
self.len_dev.timer -= 1;
|
||||||
|
|
||||||
|
// If Length Timer is now 0 and trigger is clear, disable the channel
|
||||||
|
if (self.len_dev.timer == 0 and !nrx34.trigger.read()) self.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ch4 = struct {
|
||||||
|
/// update state of ch4 length timer
|
||||||
|
pub fn update(self: *Noise, fs: *const FrameSequencer, nr44: _io.NoiseControl) void {
|
||||||
|
// Write to NRx4 when FS's next step is not one that clocks the length counter
|
||||||
|
if (!fs.isLengthNext()) {
|
||||||
|
// If length_enable was disabled but is now enabled and length timer is not 0 already,
|
||||||
|
// decrement the length timer
|
||||||
|
|
||||||
|
if (!self.cnt.length_enable.read() and nr44.length_enable.read() and self.len_dev.timer != 0) {
|
||||||
|
self.len_dev.timer -= 1;
|
||||||
|
|
||||||
|
// If Length Timer is now 0 and trigger is clear, disable the channel
|
||||||
|
if (self.len_dev.timer == 0 and !nr44.trigger.read()) self.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue