use tracing::debug; bitfield::bitfield! { pub struct DutyVol(u8); impl Debug; duty, set_duty: 7, 6; r#loop, set_loop: 5; const_vol, set_const_vol: 4; volume, set_volume: 3, 0; } bitfield::bitfield! { pub struct Sweep(u8); impl Debug; enable, set_enable: 7; period, set_period: 6, 4; negate, set_negate: 3; shift, set_shift: 2, 0; } bitfield::bitfield! { pub struct LengthTimerHigh(u8); impl Debug; length, set_length: 7, 3; timer_high, set_timer_high: 2, 0; } struct PulseChannel { enabled: bool, } bitfield::bitfield! { pub struct CounterLoad(u8); impl Debug; halt, set_halt: 7; value, set_value: 6, 0; } struct TriangleChannel { enabled: bool, } struct NoiseChannel { enabled: bool, } struct DeltaChannel { enabled: bool, } pub struct APU { pulse_1: PulseChannel, pulse_2: PulseChannel, triangle: TriangleChannel, noise: NoiseChannel, dmc: DeltaChannel, frame_counter: u8, } impl std::fmt::Debug for APU { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // write!( // f, // "PPU: f {}, s {}, p {}", // self.frame_count, self.scanline, self.pixel // ) Ok(()) } } impl APU { pub fn init() -> Self { Self { pulse_1: PulseChannel { enabled: false }, pulse_2: PulseChannel { enabled: false }, triangle: TriangleChannel { enabled: false }, noise: NoiseChannel { enabled: false }, dmc: DeltaChannel { enabled: false }, frame_counter: 0, } } pub fn read_reg(&mut self, offset: u16) -> u8 { match offset { _ => panic!("No register at {:X}", offset), } } pub fn write_reg(&mut self, offset: u16, val: u8) { match offset { 0x15 => { self.dmc.enabled = val & 0b0001_0000 != 0; self.noise.enabled = val & 0b0000_1000 != 0; self.triangle.enabled = val & 0b0000_0100 != 0; self.pulse_2.enabled = val & 0b0000_0010 != 0; self.pulse_1.enabled = val & 0b0000_0001 != 0; } 0x10 => { assert_eq!(val, 0x00); // TODO: implement this value } 0x11 => { // TODO: load dmc counter with (val & 7F) } _ => panic!("No register at {:X}", offset), } } pub fn run_one_clock_cycle(&mut self) -> bool { false } pub fn peek_nmi(&self) -> bool { false } pub fn nmi_waiting(&mut self) -> bool { false } pub fn peek_irq(&self) -> bool { false } pub fn irq_waiting(&mut self) -> bool { // TODO: implement logic false } }