diff --git a/README.md b/README.md index 93ef8d9..e5c3384 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Test status of [Blargg's Gameboy hardware test ROMs](https://github.com/retrio/g Test status of [Same Suite](https://github.com/YushiOMOTE/SameSuite/tree/430ab7f68fc612e005ed5586990dfec0ea7a9ce5) * [x] `apu/div_write_trigger.gb` -* [ ] `apu/div_write_trigger_10.gb` +* [x] `apu/div_write_trigger_10.gb` ## Projects diff --git a/core/src/apu/envelope.rs b/core/src/apu/envelope.rs index 9930cba..5f9470c 100644 --- a/core/src/apu/envelope.rs +++ b/core/src/apu/envelope.rs @@ -1,5 +1,7 @@ use crate::clock::Timer; +use super::frame_sequencer::Frame; + #[derive(Debug, Clone)] pub struct Envelope { amp: usize, @@ -23,8 +25,8 @@ impl Envelope { self.timer.set_interval(count); } - pub fn step(&mut self, frame: Option) { - match frame { + pub fn step(&mut self, frame: Frame) { + match frame.switched() { Some(7) => {} _ => return, } diff --git a/core/src/apu/frame_sequencer.rs b/core/src/apu/frame_sequencer.rs index cb6e086..db96bb2 100644 --- a/core/src/apu/frame_sequencer.rs +++ b/core/src/apu/frame_sequencer.rs @@ -1,7 +1,3 @@ -use crate::clock::ClockDivider; - -const FRAME_SEQUENCER_FREQ_HZ: usize = 512; - /// The frame sequencer generates low frequency clocks for the modulation units. It is clocked by a 512 Hz timer. /// /// Step Length Ctr Vol Env Sweep @@ -19,56 +15,173 @@ const FRAME_SEQUENCER_FREQ_HZ: usize = 512; /// #[derive(Debug, Clone)] pub struct FrameSequencer { - divider: ClockDivider, - step: usize, + frame: Frame, resetting: usize, + last_div: usize, +} + +#[derive(Debug, Clone, Copy)] +pub struct Frame { + pub step: usize, + pub cycles: usize, +} + +impl Frame { + pub fn switched(&self) -> Option { + if self.cycles == 0 { + Some(self.step) + } else { + None + } + } +} + +impl Frame { + fn new() -> Self { + Self { step: 7, cycles: 0 } + } } impl FrameSequencer { pub fn new() -> Self { Self { - divider: ClockDivider::new(FRAME_SEQUENCER_FREQ_HZ), - step: 0, + frame: Frame::new(), resetting: 0, + last_div: 0, } } pub fn reset_step(&mut self) { - self.step = 0; + self.frame = Frame::new(); + // This is to prevent updaating step immediately to 1 after reset // when reset and div-apu happens in the same machine cycle, self.resetting = 4; - self.divider.reset(); } - pub fn step(&mut self, cycles: usize, div_apu: bool) -> Option { - if div_apu && self.resetting == 0 { - return Some(self.update()); + fn bit_down(&mut self, div: usize) -> bool { + let bit4_old = bit4(self.last_div); + let bit4_new = bit4(div); + + self.last_div = div; + + bit4_old && !bit4_new + } + + pub fn step(&mut self, cycles: usize, div: usize) -> Frame { + if self.resetting > 0 && div & 0x10 > 0 { + // If reset with bit 4 set, skip the first frame + self.update(); } + + self.frame.cycles = self.frame.cycles.wrapping_add(cycles); + + if self.bit_down(div) && self.resetting == 0 { + self.update(); + } + self.resetting = self.resetting.saturating_sub(cycles); - None + + self.frame } - fn update(&mut self) -> usize { - let current_step = self.step; - self.step = (self.step + 1) % 8; - current_step + fn update(&mut self) { + let new_step = (self.frame.step + 1) % 8; + self.frame.step = new_step; + self.frame.cycles = 0; } } +fn bit4(value: usize) -> bool { + value & 0x10 != 0 +} + +#[test] +fn test_frame_sequencer_step() { + let mut seq = FrameSequencer::new(); + + assert_eq!(seq.step(1, 0x10).step, 7); + assert_eq!(seq.step(1, 0x00).step, 0); + assert_eq!(seq.step(1, 0x10).step, 0); + assert_eq!(seq.step(1, 0x00).step, 1); + assert_eq!(seq.step(1, 0x10).step, 1); + assert_eq!(seq.step(1, 0x00).step, 2); + assert_eq!(seq.step(1, 0x10).step, 2); + assert_eq!(seq.step(1, 0x00).step, 3); + assert_eq!(seq.step(1, 0x10).step, 3); + assert_eq!(seq.step(1, 0x00).step, 4); + assert_eq!(seq.step(1, 0x10).step, 4); + assert_eq!(seq.step(1, 0x00).step, 5); + assert_eq!(seq.step(1, 0x10).step, 5); + assert_eq!(seq.step(1, 0x00).step, 6); + assert_eq!(seq.step(1, 0x10).step, 6); + assert_eq!(seq.step(1, 0x00).step, 7); + assert_eq!(seq.step(1, 0x10).step, 7); + assert_eq!(seq.step(1, 0x00).step, 0); + assert_eq!(seq.step(1, 0x10).step, 0); + assert_eq!(seq.step(1, 0x00).step, 1); + assert_eq!(seq.step(1, 0x10).step, 1); + assert_eq!(seq.step(1, 0x00).step, 2); +} + +#[test] +fn test_frame_sequencer_cycles() { + let mut seq = FrameSequencer::new(); + + assert_eq!(seq.step(1, 0x10).cycles, 1); + assert_eq!(seq.step(2, 0x10).cycles, 3); + assert_eq!(seq.step(3, 0x10).cycles, 6); + assert_eq!(seq.step(4, 0x10).cycles, 10); + assert_eq!(seq.step(5, 0x10).cycles, 15); + assert_eq!(seq.step(6, 0x00).step, 0); + assert_eq!(seq.step(7, 0x10).cycles, 7); + assert_eq!(seq.step(8, 0x10).cycles, 15); + assert_eq!(seq.step(9, 0x10).cycles, 24); + assert_eq!(seq.step(10, 0x10).cycles, 34); + assert_eq!(seq.step(11, 0x10).cycles, 45); + assert_eq!(seq.step(12, 0x00).step, 1); + assert_eq!(seq.step(13, 0x10).cycles, 13); + assert_eq!(seq.step(14, 0x10).cycles, 27); + assert_eq!(seq.step(15, 0x10).cycles, 42); + assert_eq!(seq.step(16, 0x10).cycles, 58); + assert_eq!(seq.step(17, 0x10).cycles, 75); +} + #[test] -fn test_frame_sequencer() { +fn test_frame_sequencer_switch() { let mut seq = FrameSequencer::new(); - assert_eq!(seq.step(1, true), Some(0)); - assert_eq!(seq.step(1, true), Some(1)); - assert_eq!(seq.step(1, true), Some(2)); - assert_eq!(seq.step(1, true), Some(3)); - assert_eq!(seq.step(1, true), Some(4)); - assert_eq!(seq.step(1, true), Some(5)); - assert_eq!(seq.step(1, true), Some(6)); - assert_eq!(seq.step(1, true), Some(7)); - assert_eq!(seq.step(1, true), Some(0)); - assert_eq!(seq.step(1, true), Some(1)); - assert_eq!(seq.step(1, true), Some(2)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(0)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(1)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(2)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(3)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(4)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(5)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(6)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(7)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(0)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(1)); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x10).switched(), None); + assert_eq!(seq.step(1, 0x00).switched(), Some(2)); } diff --git a/core/src/apu/length_counter.rs b/core/src/apu/length_counter.rs index 392d07d..937d9bb 100644 --- a/core/src/apu/length_counter.rs +++ b/core/src/apu/length_counter.rs @@ -1,5 +1,7 @@ use log::*; +use super::frame_sequencer::Frame; + #[derive(Clone, Debug)] pub struct LengthCounter { enable: bool, @@ -87,16 +89,15 @@ impl LengthCounter { self.length = self.base - value; } - pub fn step(&mut self, step: Option) { - match step { - Some(0) | Some(2) | Some(4) | Some(6) => { - self.first_half = true; - } - Some(1) | Some(3) | Some(5) | Some(7) => { - self.first_half = false; - return; - } - _ => return, + pub fn step(&mut self, frame: Frame) { + self.first_half = match frame.step { + 0 | 2 | 4 | 6 => true, + 1 | 3 | 5 | 7 => false, + _ => unreachable!(), + }; + + if frame.cycles != 0 || !self.first_half { + return; } if self.enable { diff --git a/core/src/apu/mixer.rs b/core/src/apu/mixer.rs index 9259b6d..5638e5d 100644 --- a/core/src/apu/mixer.rs +++ b/core/src/apu/mixer.rs @@ -1,4 +1,9 @@ -use super::{frame_sequencer::FrameSequencer, noise::Noise, tone::Tone, wave::Wave}; +use super::{ + frame_sequencer::{Frame, FrameSequencer}, + noise::Noise, + tone::Tone, + wave::Wave, +}; use crate::{cpu::CPU_FREQ_HZ, divider::Divider, hardware::Stream}; use alloc::sync::Arc; use bitfield_struct::bitfield; @@ -146,8 +151,8 @@ impl Shared { } } - fn step(&mut self, cycles: usize, step: Option) { - self.channel.lock().step(cycles, step); + fn step(&mut self, cycles: usize, frame: Frame) { + self.channel.lock().step(cycles, frame); } fn sync_channel(&self, channel: T) { @@ -166,7 +171,7 @@ impl Shared { trait VolumeUnit { fn amp(&self) -> isize; - fn step(&mut self, rate: usize, step: Option); + fn step(&mut self, rate: usize, frame: Frame); } impl VolumeUnit for Tone { @@ -174,8 +179,8 @@ impl VolumeUnit for Tone { self.amp() } - fn step(&mut self, cycles: usize, step: Option) { - self.step(cycles, step); + fn step(&mut self, cycles: usize, frame: Frame) { + self.step(cycles, frame); } } @@ -184,8 +189,8 @@ impl VolumeUnit for Wave { self.amp() } - fn step(&mut self, cycles: usize, step: Option) { - self.step(cycles, step); + fn step(&mut self, cycles: usize, frame: Frame) { + self.step(cycles, frame); } } @@ -194,8 +199,8 @@ impl VolumeUnit for Noise { self.amp() } - fn step(&mut self, cycles: usize, step: Option) { - self.step(cycles, step); + fn step(&mut self, cycles: usize, frame: Frame) { + self.step(cycles, frame); } } @@ -249,8 +254,8 @@ impl MixerStream { while cycles > 0 { let sub_cycles = cycles.max(4); - let div_apu = self.divider.step(sub_cycles); - let step = self.frame_sequencer.step(cycles, div_apu); + let div = self.divider.step(sub_cycles); + let step = self.frame_sequencer.step(cycles, div); self.state.tones[0].step(sub_cycles, step); self.state.tones[1].step(sub_cycles, step); diff --git a/core/src/apu/mod.rs b/core/src/apu/mod.rs index 7d3a32d..3737859 100644 --- a/core/src/apu/mod.rs +++ b/core/src/apu/mod.rs @@ -292,8 +292,8 @@ impl Apu { self.mixer.sync_noise(self.noise.clone()); } - pub fn step(&mut self, cycles: usize, div_apu: bool) { - let frame = self.frame_sequencer.step(cycles, div_apu); + pub fn step(&mut self, cycles: usize, div: usize) { + let frame = self.frame_sequencer.step(cycles, div); for tone in &mut self.tones { tone.step(cycles, frame); diff --git a/core/src/apu/noise.rs b/core/src/apu/noise.rs index 3efb043..20b40a7 100644 --- a/core/src/apu/noise.rs +++ b/core/src/apu/noise.rs @@ -1,4 +1,4 @@ -use super::{dac::Dac, envelope::Envelope, length_counter::LengthCounter}; +use super::{dac::Dac, envelope::Envelope, frame_sequencer::Frame, length_counter::LengthCounter}; use crate::clock::{ClockDivider, Timer}; use bitfield_struct::bitfield; @@ -150,7 +150,7 @@ impl Noise { self.nr44.trigger() } - pub fn step(&mut self, cycles: usize, frame: Option) { + pub fn step(&mut self, cycles: usize, frame: Frame) { self.length_counter.step(frame); self.envelope.step(frame); diff --git a/core/src/apu/sweep.rs b/core/src/apu/sweep.rs index 976a0e4..ec57826 100644 --- a/core/src/apu/sweep.rs +++ b/core/src/apu/sweep.rs @@ -2,6 +2,8 @@ use crate::clock::Timer; use log::*; +use super::frame_sequencer::Frame; + #[derive(Clone, Debug)] pub struct Sweep { disabling_channel: bool, @@ -69,8 +71,8 @@ impl Sweep { self.subtract = subtract; } - pub fn step(&mut self, frame: Option) -> Option { - match frame { + pub fn step(&mut self, frame: Frame) -> Option { + match frame.switched() { Some(2) | Some(6) => {} _ => return None, } diff --git a/core/src/apu/tone.rs b/core/src/apu/tone.rs index dd2bf6e..40088d8 100644 --- a/core/src/apu/tone.rs +++ b/core/src/apu/tone.rs @@ -1,4 +1,7 @@ -use super::{dac::Dac, envelope::Envelope, length_counter::LengthCounter, sweep::Sweep}; +use super::{ + dac::Dac, envelope::Envelope, frame_sequencer::Frame, length_counter::LengthCounter, + sweep::Sweep, +}; use crate::clock::{ClockDivider, Timer}; use bitfield_struct::bitfield; @@ -245,7 +248,7 @@ impl Tone { self.dac.power_off(); } - pub fn step(&mut self, cycles: usize, frame: Option) { + pub fn step(&mut self, cycles: usize, frame: Frame) { if let Some(sweep) = self.sweep.as_mut() { if let Some(new_freq) = sweep.step(frame) { self.freq = Freq::from_value(new_freq); diff --git a/core/src/apu/wave.rs b/core/src/apu/wave.rs index 1ff7202..ca489ee 100644 --- a/core/src/apu/wave.rs +++ b/core/src/apu/wave.rs @@ -2,7 +2,7 @@ use log::*; use bitfield_struct::bitfield; -use super::{dac::Dac, length_counter::LengthCounter}; +use super::{dac::Dac, frame_sequencer::Frame, length_counter::LengthCounter}; use crate::clock::{ClockDivider, Timer}; const RAM_SIZE: usize = 16; @@ -246,7 +246,7 @@ impl Wave { } } - pub fn step(&mut self, cycles: usize, frame: Option) { + pub fn step(&mut self, cycles: usize, frame: Frame) { self.length_counter.step(frame); let times = self.divider.step(cycles); diff --git a/core/src/divider.rs b/core/src/divider.rs index 6198242..a2e3e76 100644 --- a/core/src/divider.rs +++ b/core/src/divider.rs @@ -2,7 +2,6 @@ use crate::clock::PrescaledTimer; pub struct Divider { timer: PrescaledTimer, - last_counter: usize, } impl Divider { @@ -13,23 +12,12 @@ impl Divider { .frequency(16384) .interval(256) .build(), - last_counter: 0, } } - pub fn step(&mut self, cycles: usize) -> bool { + pub fn step(&mut self, cycles: usize) -> usize { self.timer.step(cycles); - - self.check_div_apu() - } - - fn check_div_apu(&mut self) -> bool { - let bit4_old = self.last_counter & 0x10 > 0; - let bit4_new = self.timer.counter() & 0x10 > 0; - - self.last_counter = self.timer.counter(); - - bit4_old && !bit4_new + self.timer.counter() } // TODO: To be used for STOP emulation where DIV doesn't ticks diff --git a/core/tests/expects/same_suite_div_write_trigger_10.txt b/core/tests/expects/same_suite_div_write_trigger_10.txt new file mode 100644 index 0000000..c7f20ce --- /dev/null +++ b/core/tests/expects/same_suite_div_write_trigger_10.txt @@ -0,0 +1,144 @@ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##..##..##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##..##..##..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##..##..##..##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##..##..##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##..##..##..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##..##..##..######....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######...###....######....#####..##.......#####..##.......#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..####....##..##....#.....###.......#.....###.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..####....##..##....#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##....##....##..##....####....#.......####....#.......####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##....##....##..##....#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##....##....##..##....#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######...###....######....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..####....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..####....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##....##....######....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##....##....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##....##....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..##..##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##......##..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##.....##...##..##....####....#.......####....#.......####....#.......####....#.......####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##....##....##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##...##.....##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..##..##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##......##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##.....##...######....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##....##....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##...##.....##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####.#####.....#####.#####.. +.##..##..##..##..##..##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....#...#.....#.....#...#.. +.##......##..##......##..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.. +.##......##..##....####..##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####..#...#.....####..#...#.. +.##......##..##......##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.. +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..##..##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##......##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##....####..######....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##......##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##..##..##..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######....###...######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##...####...##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##...####...##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##..#####...##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##..##.##...##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##..######..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######.....##...######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######....###...######....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##...####...##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##...####...##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..#####...######....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##..##.##...##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##..######..##..##....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######.....##...######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##..###.....##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##..######..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##......##..##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##......##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..###.....##..##....#.....###.......#.....###.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..######..##..##....#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##......##..######....####....#.......####....#.......####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##......##..##..##....#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..#####...######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##..##......##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##..######..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##..##..##..##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..#####...######....#####..##.......#####..##.......#####..##.......#####..##.......#####.#####.....#####.#####.....#####.#####.....#####.#####.. +.##..##..##..##..##......##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..######..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##......##..##..##..##..######....####....#.......####....#.......####....#.......####....#.......####..#...#.....####..#...#.....####..#...#.....####..#...#.. +.##......##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.##..##..##..##..##..##..##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.....#.....#...#.....#.....#...#.. +.######..######..######..######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.... +.##..##..##..##..#...##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.... +.##......##..##.....###..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.... +.##......##..##.....##...##..##....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####....#.... +.##......##..##....###...##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.##..##..##..##....###...##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.... +.######..######....##....######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +.######..######..######..######....#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####..##.......#####.#####.....#####.#####.. +.##..##..##..##..#...##..##..##....#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....###.......#.....#...#.....#.....#...#.. +.##......##..##.....###..##..##....#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#.#.......#.....#...#.....#.....#...#.. +.##......##..##.....##...######....####....#.......####....#.......####....#.......####....#.......####....#.......####....#.......####..#...#.....####..#...#.. +.##......##..##....###...##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.. +.##..##..##..##....###...##..##....#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.......#.....#...#.....#.....#...#.. +.######..######....##....######....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.....#.....#####.. +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ +................................................................................................................................................................ diff --git a/core/tests/test_roms.rs b/core/tests/test_roms.rs index bed4f60..e2ca853 100644 --- a/core/tests/test_roms.rs +++ b/core/tests/test_roms.rs @@ -303,3 +303,11 @@ fn same_suite_div_write_trigger() { "../roms/same_suite/apu/div_write_trigger.gb", ); } + +#[test] +fn same_suite_div_write_trigger_10() { + test_rom( + Expected::from_file("tests/expects/same_suite_div_write_trigger_10.txt"), + "../roms/same_suite/apu/div_write_trigger_10.gb", + ); +}