From 196336b5f7f65c7a616a7673639df7b3cde3b49b Mon Sep 17 00:00:00 2001
From: Brooke Chalmers <breq@breq.dev>
Date: Wed, 22 Nov 2023 18:44:11 -0500
Subject: [PATCH 1/3] Add (failing) Klaus test

---
 src/main.rs          |  2 +-
 src/systems/klaus.rs | 53 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 236523a0..d214f350 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 3f90f47c..7388b93c 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<KlausSystem, RomFile, ()> for KlausSystemBuilder {
-  fn build(rom: RomFile, _config: (), _platform: Arc<dyn PlatformProvider>) -> Box<dyn System> {
+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);
     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) {
@@ -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);
+  }
+}

From f030d541aa2861521536e7fe435ddbb9832edddb Mon Sep 17 00:00:00 2001
From: Brooke Chalmers <breq@breq.dev>
Date: Wed, 22 Nov 2023 19:27:47 -0500
Subject: [PATCH 2/3] Make Klaus ROM writeable

---
 src/memory/block.rs  | 7 +++++++
 src/systems/klaus.rs | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/memory/block.rs b/src/memory/block.rs
index efc3e3b2..95e90353 100644
--- a/src/memory/block.rs
+++ b/src/memory/block.rs
@@ -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 {
diff --git a/src/systems/klaus.rs b/src/systems/klaus.rs
index 7388b93c..3a26a000 100644
--- a/src/systems/klaus.rs
+++ b/src/systems/klaus.rs
@@ -20,7 +20,7 @@ impl SystemBuilder<KlausSystem, RomFile, Option<Rc<Cell<u16>>>> for KlausSystemB
     config: Option<Rc<Cell<u16>>>,
     _platform: Arc<dyn PlatformProvider>,
   ) -> Box<dyn System> {
-    let rom = BlockMemory::from_file(0x10000, rom);
+    let rom = BlockMemory::from_file(0x10000, rom).set_writeable(true);
     let mut cpu = Mos6502::new(Box::new(rom));
 
     cpu.registers.pc.load(0x0400);

From cb4c86a96c1f6a8950e52808b2b004efd9f20acc Mon Sep 17 00:00:00 2001
From: Brooke Chalmers <breq@breq.dev>
Date: Wed, 22 Nov 2023 19:43:58 -0500
Subject: [PATCH 3/3] Add .bin's to version control

---
 .gitignore       |   1 -
 bin/easy.bin     | Bin 0 -> 32768 bytes
 bin/guessing.bin | Bin 0 -> 32768 bytes
 bin/klaus.bin    | Bin 0 -> 65536 bytes
 4 files changed, 1 deletion(-)
 create mode 100644 bin/easy.bin
 create mode 100644 bin/guessing.bin
 create mode 100644 bin/klaus.bin

diff --git a/.gitignore b/.gitignore
index 0193ec54..d8ccb15b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 /target
-/bin
 /flamegraph.svg
 /.idea
 .DS_Store
diff --git a/bin/easy.bin b/bin/easy.bin
new file mode 100644
index 0000000000000000000000000000000000000000..adf5a7f067c8b0c5f4fe5e66e41c2cdf11a102cf
GIT binary patch
literal 32768
zcmeIuKT88K9LDk7omLALbN&Iv;ev=*L7arHf>WuJgKJjbMQ+F<2nxDOA!3|v=_`;H
zu2Wxx9O{%+1T}pd^3C)lKX{USRLiKIQ5~ZWjrOTc{esPWZl#xY&9B;xxX<mn-PG>K
z3is2^wysi}XmxJXjZv>gZI?=w>Zly_jQg!GL#I9q8}&ulsZYbM_6vLIY~Lp~)qXj~
zo%tQwCo#%c9b+2fqF;_tt9zrKjdo%zXC0S}^Vw39HQD@W!*nF$X={{^^U!{Of6GE^
z@L~ohrGCn$*CY9`HkDs4?N{x7wcW3Zes%0*??YL6o9IdIV_P`Tjr7Hy425=b>nhHw
zL^ru_#o3CUNGH2RU4%r(+Q<0WI}yvhDCJQ2q?CFnK0l|k@A+7;5I_I{1Q0*~0R#|0
z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{
z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL
wKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009L4kAM;44_GsHYXATM

literal 0
HcmV?d00001

diff --git a/bin/guessing.bin b/bin/guessing.bin
new file mode 100644
index 0000000000000000000000000000000000000000..be00b1fe1640c06e01733dbdfcd6f5353cb2f6cf
GIT binary patch
literal 32768
zcmeIuF=_%)5C-4}iimgsE7=@C@CbH_Y;S3rpf*~B5bR!KY2^*<w(uA>Rvsls&{-jS
z0=w@O{~Kmt2EM9&NayzLZ&-}-B~7kr+`adUeJ%&NnCG&Si)Eds=v32VYf}A0d_{ae
zBmUkqKC3dyUBqwGoJF~bSVgRx$>M*qjq0PBG>hWE>r{Orc?1X$AV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
e5FkK+009C72oNAZfB*pk1PBlyK;R7mIi&~fUp&VE

literal 0
HcmV?d00001

diff --git a/bin/klaus.bin b/bin/klaus.bin
new file mode 100644
index 0000000000000000000000000000000000000000..c9a35e1d6bd2e7d85844da2abf7034d5ed820e6e
GIT binary patch
literal 65536
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
E3ya{&@Bjb+

literal 0
HcmV?d00001