From c7b7a99cf9da9a351d9576787fb841091327edc8 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Mon, 24 Apr 2023 11:35:38 +1000 Subject: [PATCH] cgb pcm registers --- lib/src/processor/memory.rs | 4 ++-- lib/src/processor/memory/mmio/apu.rs | 8 ++++++++ lib/src/processor/memory/mmio/apu/channels.rs | 19 ++++++++++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index de7e5c6..ed04761 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -372,8 +372,8 @@ where CgbIoAddress::Palette(address) => self.gpu.get_cgb_palette(address), CgbIoAddress::ObjPriority => self.gpu.get_obj_priority(), CgbIoAddress::WramBank => ((*selected) & 0b111) as u8, - CgbIoAddress::Pcm12 => todo!(), - CgbIoAddress::Pcm34 => todo!(), + CgbIoAddress::Pcm12 => self.apu.get_pcm_1_2(), + CgbIoAddress::Pcm34 => self.apu.get_pcm_3_4(), CgbIoAddress::Unused(v) => { println!("attempt to get 0x{v:0>4X}"); todo!() diff --git a/lib/src/processor/memory/mmio/apu.rs b/lib/src/processor/memory/mmio/apu.rs index c865716..b039a79 100644 --- a/lib/src/processor/memory/mmio/apu.rs +++ b/lib/src/processor/memory/mmio/apu.rs @@ -153,6 +153,14 @@ impl Apu { } } + pub(crate) fn get_pcm_1_2(&self) -> u8 { + (self.channels.one.last & 0xF) | ((self.channels.two.last & 0xF0) << 4) + } + + pub(crate) fn get_pcm_3_4(&self) -> u8 { + (self.channels.one.last & 0xF) | ((self.channels.two.last & 0xF0) << 4) + } + fn next_audio(&mut self) { self.out_buffer.append( &mut self.converter.process( diff --git a/lib/src/processor/memory/mmio/apu/channels.rs b/lib/src/processor/memory/mmio/apu/channels.rs index c4d7b6c..8e18045 100644 --- a/lib/src/processor/memory/mmio/apu/channels.rs +++ b/lib/src/processor/memory/mmio/apu/channels.rs @@ -127,6 +127,7 @@ impl DutyCycle { #[derive(Serialize, Deserialize, Clone, Copy)] pub(super) struct PwmChannel { pub(super) enabled: bool, + pub(super) last: u8, sweep: Sweep, duty_cycle: DutyCycle, length_enable: bool, @@ -143,6 +144,7 @@ impl PwmChannel { let wavelength = 0x7FF; Self { enabled, + last: 0, sweep: Sweep::default(), duty_cycle: DutyCycle::Fifty, length_enable: false, @@ -181,11 +183,13 @@ impl PwmChannel { }) .collect() } else { + self.last = 0; vec![0.; steps] } } - fn dac(&self, digital: u8) -> f32 { + fn dac(&mut self, digital: u8) -> f32 { + self.last = digital; (((digital as f32) * (-2.)) + 1.) * ((self.envelope.current_volume as f32) / 15.) } @@ -339,6 +343,7 @@ impl WaveRam { #[derive(Serialize, Deserialize, Clone, Copy)] pub(super) struct WaveChannel { pub(super) enabled: bool, + pub(super) last: u8, dac_enabled: bool, length_enable: bool, length_timer: u8, @@ -354,6 +359,7 @@ impl WaveChannel { let wavelength = 0x7FF; Self { enabled, + last: 0, dac_enabled: false, length_enable: false, length_timer: 0, @@ -390,14 +396,17 @@ impl WaveChannel { }) .collect() } else { + self.last = 0; vec![0.; steps] } } - fn dac(&self, digital: u8) -> f32 { + fn dac(&mut self, digital: u8) -> f32 { if self.dac_enabled && self.volume != ShiftVolumePercent::Zero { + self.last = digital; ((((digital >> self.volume.as_shift_amount()) as f32) * (-2.)) + 1.) / 15. } else { + self.last = 0; 0. } } @@ -545,6 +554,7 @@ impl Default for Lfsr { #[derive(Serialize, Deserialize, Clone, Copy)] pub(super) struct NoiseChannel { pub(super) enabled: bool, + pub(super) last: u8, length_enable: bool, length_timer: u8, envelope: Envelope, @@ -556,6 +566,7 @@ impl NoiseChannel { pub(super) fn new(enabled: bool) -> Self { Self { enabled, + last: 0, length_enable: false, length_timer: 0, envelope: Envelope::default(), @@ -582,11 +593,13 @@ impl NoiseChannel { }) .collect() } else { + self.last = 0; vec![0.; steps] } } - fn dac(&self, digital: u8) -> f32 { + fn dac(&mut self, digital: u8) -> f32 { + self.last = digital; (((digital as f32) * (-2.)) + 1.) * ((self.envelope.current_volume as f32) / 15.) }