nesfuzz/src/apu/mod.rs

85 lines
2.5 KiB
Rust
Raw Normal View History

2019-11-27 01:11:51 +00:00
mod noise;
mod square;
mod triangle;
mod dmc;
pub struct Apu {
square1: Square,
square2: Square,
triangle: Triangle,
noise: Noise,
dmc: DMC,
}
struct Square {
duty_cycle: usize,
length_counter_halt: bool, // (this bit is also the envelope's loop flag)
constant_volume_flag: bool, // (0: use volume from envelope; 1: use constant volume)
timer: usize,
length_counter: usize,
envelope: usize,
sweep: usize,
}
// $4008 Hlll.llll Triangle channel length counter halt and linear counter load (write)
// bit 7 H--- ---- Halt length counter (this bit is also the linear counter's control flag)
struct Triangle {
timer: usize,
length_counter: usize, // (this bit is also the linear counter's control flag)
linear_counter: usize,
}
// $400E M---.PPPP Mode and period (write)
// bit 7 M--- ---- Mode flag
struct Noise {
timer: usize,
length_counter: usize,
envelope: usize,
linear_feedback_sr: u16,
mode: bool, // also called loop noise, bit 7 of $400E
}
struct DMC {
}
impl Apu {
fn new() -> Self {
Apu {
square1: Square::new(),
square2: Square::new(),
triangle: Triangle::new(),
noise: Noise::new(),
dmc: DMC::new(),
}
}
fn write_reg(&mut self, address: usize, value: u8) {
match address {
0x4000 => self.square1.duty(value),
0x4001 => self.square1.sweep(value),
0x4002 => self.square1.timer_low(value),
0x4003 => self.square1.timer_high(value),
0x4004 => self.square2.duty(value),
0x4005 => self.square2.sweep(value),
0x4006 => self.square2.timer_low(value),
0x4007 => self.square2.timer_high(value),
0x4008 => self.triangle.counter(value),
0x400A => self.triangle.timer_low(value),
0x400B => self.triangle.timer_high(value),
0x400C => self.noise.envelope(value),
0x400D => (),
0x400E => self.noise.loop_noise(value),
0x400F => self.noise.load_length_counter(value),
0x4010 => self.dmc.control(value),
0x4011 => self.dmc.direct_load(value),
0x4012 => self.dmc.sample_address(value),
0x4013 => self.dmc.sample_length(value),
0x4014 => (),
0x4015 => self.control(value),
0x4016 => (),
0x4017 => self.frame_counter(value),
}
}
}