diff --git a/src/main.rs b/src/main.rs index 236523a..d214f35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,7 +75,7 @@ fn main() { let system = match args.system { SystemArg::Basic => BasicSystemBuilder::build(romfile.unwrap(), (), platform.provider()), SystemArg::Easy => Easy6502SystemBuilder::build(romfile.unwrap(), (), platform.provider()), - SystemArg::Klaus => KlausSystemBuilder::build(romfile.unwrap(), (), platform.provider()), + SystemArg::Klaus => KlausSystemBuilder::build(romfile.unwrap(), None, platform.provider()), SystemArg::Pet => PetSystemBuilder::build( PetSystemRoms::from_disk(), PetSystemConfig { mapping }, diff --git a/src/systems/klaus.rs b/src/systems/klaus.rs index 3f90f47..7388b93 100644 --- a/src/systems/klaus.rs +++ b/src/systems/klaus.rs @@ -1,10 +1,12 @@ -use instant::{Duration, Instant}; +use instant::Duration; use crate::cpu::Mos6502; use crate::memory::BlockMemory; use crate::platform::{PlatformProvider, WindowConfig}; use crate::roms::RomFile; use crate::systems::System; +use std::cell::Cell; +use std::rc::Rc; use std::sync::Arc; use super::SystemBuilder; @@ -12,33 +14,34 @@ use super::SystemBuilder; /// A factory for creating a system that runs Klaus Dormann's 6502 CPU test suite. pub struct KlausSystemBuilder; -impl SystemBuilder for KlausSystemBuilder { - fn build(rom: RomFile, _config: (), _platform: Arc) -> Box { +impl SystemBuilder>>> for KlausSystemBuilder { + fn build( + rom: RomFile, + config: Option>>, + _platform: Arc, + ) -> Box { let rom = BlockMemory::from_file(0x10000, rom); let mut cpu = Mos6502::new(Box::new(rom)); cpu.registers.pc.load(0x0400); - Box::new(KlausSystem { - cpu, - last_report: Instant::now(), - }) + Box::new(KlausSystem { cpu, pc: config }) } } /// A system used to run Klaus Dormann's 6502 CPU test suite. pub struct KlausSystem { cpu: Mos6502, - last_report: Instant, + pc: Option>>, } impl System for KlausSystem { fn tick(&mut self) -> Duration { - if self.last_report.elapsed().as_secs() > 1 { - println!("PC: {:04x}", self.cpu.registers.pc.address()); - self.last_report = Instant::now(); - }; - Duration::from_secs_f64(1.0 / 1_000_000.0) * self.cpu.tick().into() + self.cpu.tick(); + if let Some(pc) = &self.pc { + pc.set(self.cpu.registers.pc.address()); + } + Duration::ZERO } fn reset(&mut self) { @@ -47,3 +50,27 @@ impl System for KlausSystem { fn render(&mut self, _framebuffer: &mut [u8], _window: WindowConfig) {} } + +#[cfg(test)] +mod tests { + use crate::{ + platform::{Platform, TextPlatform}, + roms::DiskLoadable, + }; + + use super::*; + + #[test] + fn test_klaus() { + let roms = RomFile::from_file("bin/klaus.bin"); + let platform = TextPlatform::new(); + let pc = Rc::new(Cell::new(0)); + let mut system = KlausSystemBuilder::build(roms, Some(pc.clone()), platform.provider()); + + for _ in 0..=100000000 { + system.tick(); + } + + assert_eq!(pc.get(), 0x3469); + } +}