Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Klaus functional test to CI #35

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/target
/bin
/flamegraph.svg
/.idea
.DS_Store
Binary file added bin/easy.bin
Binary file not shown.
Binary file added bin/guessing.bin
Binary file not shown.
Binary file added bin/klaus.bin
Binary file not shown.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
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()),

Check warning on line 78 in src/main.rs

View check run for this annotation

Codecov / codecov/patch

src/main.rs#L78

Added line #L78 was not covered by tests
SystemArg::Pet => PetSystemBuilder::build(
PetSystemRoms::from_disk(),
PetSystemConfig { mapping },
Expand Down
7 changes: 7 additions & 0 deletions src/memory/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ impl BlockMemory {
writeable: false,
}
}

/// Change whether this BlockMemory is writable.
pub fn set_writeable(mut self, writeable: bool) -> Self {
self.writeable = writeable;

self
}
}

impl Memory for BlockMemory {
Expand Down
55 changes: 41 additions & 14 deletions src/systems/klaus.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
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;

/// A factory for creating a system that runs Klaus Dormann's 6502 CPU test suite.
pub struct KlausSystemBuilder;

impl SystemBuilder<KlausSystem, RomFile, ()> for KlausSystemBuilder {
fn build(rom: RomFile, _config: (), _platform: Arc<dyn PlatformProvider>) -> Box<dyn System> {
let rom = BlockMemory::from_file(0x10000, rom);
impl SystemBuilder<KlausSystem, RomFile, Option<Rc<Cell<u16>>>> for KlausSystemBuilder {
fn build(
rom: RomFile,
config: Option<Rc<Cell<u16>>>,
_platform: Arc<dyn PlatformProvider>,
) -> Box<dyn System> {
let rom = BlockMemory::from_file(0x10000, rom).set_writeable(true);
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<Rc<Cell<u16>>>,
}

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) {
Expand All @@ -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);
}
}
Loading