Skip to content

Commit

Permalink
Ignore APU registers write when it is off and fix some APU div details
Browse files Browse the repository at this point in the history
  • Loading branch information
Kanabenki committed Sep 13, 2023
1 parent 02f48e1 commit 1d42d49
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 32 deletions.
51 changes: 20 additions & 31 deletions src/gameboy/apu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,36 +374,40 @@ impl Apu {
}

pub(crate) fn inc_div(&mut self) {
self.div = self.div.wrapping_add(1);
// Tick sound length.
if self.div & 0b10 == 0 {
let tick_len = |len_timer: &mut u8, len_enable, ch_enable: &mut bool| {
*len_timer = u8::min(*len_timer + 1, 64);
if *len_timer == 64 && len_enable {
if self.div & 0b1 == 0 {
let tick_len = |len_timer: &mut u8, len_enable, ch_enable: &mut bool, limit| {
*len_timer = u8::min(*len_timer + 1, limit);
if *len_timer == limit && len_enable {
*ch_enable = false;
}
};
tick_len(
&mut self.ch_1.wave_duty_len_timer.len_timer,
self.ch_1.wavelen_ctrl.len_enable,
&mut self.sound_enable.channels.ch_1,
0b11_1111,
);
tick_len(
&mut self.ch_2.wave_duty_len_timer.len_timer,
self.ch_2.wavelen_ctrl.len_enable,
&mut self.sound_enable.channels.ch_2,
0b11_1111,
);
tick_len(
&mut self.ch_3.len_timer,
self.ch_3.wavelen_ctrl.len_enable,
&mut self.sound_enable.channels.ch_3,
u8::MAX,
);
tick_len(
&mut self.ch_4.len_timer,
self.ch_4.len_enable,
&mut self.sound_enable.channels.ch_4,
0b11_1111,
);
}

// Tick channel 1 frequency sweep.
if self.div & 0b11 == 0
&& self.ch_1.sweep.pace != 0
Expand All @@ -429,6 +433,7 @@ impl Apu {
}
}
}

// Tick enveloppe sweep.
if self.div & 0b111 == 0 {
let tick_enveloppe = |vol_env: &VolumeEnvelope, volume: &mut u8| {
Expand All @@ -446,33 +451,9 @@ impl Apu {
tick_enveloppe(&self.ch_1.vol_env, &mut self.ch_1.volume);
tick_enveloppe(&self.ch_2.vol_env, &mut self.ch_2.volume);
tick_enveloppe(&self.ch_4.vol_env, &mut self.ch_4.volume);

if self.ch_1.vol_env.pace != 0 && (self.div % self.ch_1.vol_env.pace) == 0 {
match self.ch_1.vol_env.direction {
EnvelopeDir::Increase => {
self.ch_1.volume = u8::max(self.ch_1.volume + 1, 0b1111)
}
EnvelopeDir::Decrease => {
if self.ch_1.volume > 0 {
self.ch_1.volume -= 1;
}
}
}
}

if self.ch_2.vol_env.pace != 0 && (self.div % self.ch_2.vol_env.pace) == 0 {
match self.ch_2.vol_env.direction {
EnvelopeDir::Increase => {
self.ch_2.volume = u8::max(self.ch_2.volume + 1, 0b1111)
}
EnvelopeDir::Decrease => {
if self.ch_2.volume > 0 {
self.ch_2.volume -= 1;
}
}
}
}
}

self.div = self.div.wrapping_add(1);
}

pub(crate) fn tick(&mut self) {
Expand Down Expand Up @@ -644,6 +625,14 @@ impl Apu {
}

pub(crate) fn write(&mut self, address: u16, value: u8) {
// Ignore register writes when APU is turned off.
if !self.sound_enable.all
&& address != Self::SOUND_ENABLE_ADDRESS
&& !(Self::CH3_WAVE_PATTERN_START_ADDRESS..=Self::CH3_WAVE_PATTERN_END_ADDRESS)
.contains(&address)
{
return;
}
match address {
Self::CH1_SWEEP_ADDRESS => self.ch_1.sweep.set_value(value),
Self::CH1_VOLUME_ENVELOPPE_ADDRESS => self.ch_1.vol_env.set_value(value),
Expand Down
3 changes: 2 additions & 1 deletion src/gameboy/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ impl Timer {
self.divider = self.divider.wrapping_add(4);

// Bit 4 high to low
let apu_inc_div = self.divider == 0b10_0000 || self.apu_inc_div;
let apu_inc_div =
(old_divider & 0b1_0000) != 0 && (self.divider & 0b1_0000) == 0 || self.apu_inc_div;
self.apu_inc_div = false;

if !self.enabled {
Expand Down

0 comments on commit 1d42d49

Please sign in to comment.