implement apu ticks from div

This commit is contained in:
Alex Janka 2023-02-15 08:44:56 +11:00
parent 75a9396b57
commit 28fb90c8d6
3 changed files with 41 additions and 3 deletions

View file

@ -186,6 +186,10 @@ impl Memory {
self.joypad.update_pressed_keys(keys, gamepads) self.joypad.update_pressed_keys(keys, gamepads)
} }
pub fn div_apu_tick(&mut self) {
self.apu.div_apu_tick();
}
pub(super) fn cpu_ram_init(&mut self) { pub(super) fn cpu_ram_init(&mut self) {
self.set(0xFF04, 0xAD); self.set(0xFF04, 0xAD);
self.set(0xFF10, 0x80); self.set(0xFF10, 0x80);

View file

@ -45,6 +45,7 @@ pub struct Apu {
vin: VinEnable, vin: VinEnable,
vol_left: u8, vol_left: u8,
vol_right: u8, vol_right: u8,
div_apu: u8,
} }
impl Default for Apu { impl Default for Apu {
@ -56,11 +57,25 @@ impl Default for Apu {
vin: VinEnable::default(), vin: VinEnable::default(),
vol_left: 7, vol_left: 7,
vol_right: 7, vol_right: 7,
div_apu: 0,
} }
} }
} }
impl Apu { impl Apu {
pub fn div_apu_tick(&mut self) {
self.div_apu = self.div_apu.wrapping_add(1);
if self.div_apu % 8 == 0 {
// envelope sweep
}
if self.div_apu % 4 == 0 {
// ch1 frequency sweep
}
if self.div_apu % 2 == 0 {
// tick sound length timers
}
}
pub fn get_register(&self, addr: Address) -> u8 { pub fn get_register(&self, addr: Address) -> u8 {
if addr == 0xFF26 if addr == 0xFF26
|| addr == 0xFF11 || addr == 0xFF11

View file

@ -19,6 +19,10 @@ impl Timers {
} }
} }
// this will need to change when cgb mode is implemented
// as it uses bit 5 in double speed mode
const AUDIO_BIT: u8 = 4;
impl Cpu { impl Cpu {
pub(super) fn increment_timers(&mut self, machine_cycles: u8) { pub(super) fn increment_timers(&mut self, machine_cycles: u8) {
let clock_cycles = (machine_cycles as usize) * 4; let clock_cycles = (machine_cycles as usize) * 4;
@ -26,10 +30,25 @@ impl Cpu {
self.advance_gpu_clock(clock_cycles); self.advance_gpu_clock(clock_cycles);
self.timers.div_counter += clock_cycles; self.timers.div_counter += clock_cycles;
let div_diff = (self.timers.div_counter / 256) as u8; let mut div_diff = (self.timers.div_counter / 256) as u8;
let mut last_div = self.memory.get(0xFF04);
let mut new_div = None;
while div_diff > 0 {
let div = last_div.wrapping_add(1);
if (div & (1 << AUDIO_BIT)) < (last_div & (1 << AUDIO_BIT)) {
// trigger DIV-APU
self.memory.div_apu_tick();
}
new_div = Some(div);
last_div = div;
div_diff -= 1;
}
self.timers.div_counter %= 256; self.timers.div_counter %= 256;
self.memory if let Some(div) = new_div {
.set(0xFF04, self.memory.get(0xFF04).wrapping_add(div_diff)); self.memory.set(0xFF04, div)
};
let (timer_enabled, timer_rate) = self.timer_scale(); let (timer_enabled, timer_rate) = self.timer_scale();
if timer_enabled { if timer_enabled {