aboutsummaryrefslogtreecommitdiff
path: root/src/memory_tracker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory_tracker.rs')
-rw-r--r--src/memory_tracker.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/memory_tracker.rs b/src/memory_tracker.rs
new file mode 100644
index 0000000..e35bf2d
--- /dev/null
+++ b/src/memory_tracker.rs
@@ -0,0 +1,85 @@
+use rustv::isa;
+use rustv::memory::{Memory, MemoryInterface, Result};
+
+pub struct MemoryTracker {
+ memory: Memory,
+ program1_byte: u8,
+ program2_byte: u8,
+ program1: i64,
+ program2: i64,
+}
+
+impl MemoryTracker {
+ pub fn new(memory: Memory, program1: u8, program2: u8) -> MemoryTracker {
+ MemoryTracker {
+ memory: memory,
+ program1_byte: program1,
+ program2_byte: program2,
+ program1: 0,
+ program2: 0,
+ }
+ }
+
+ pub fn score(&self) -> (i64, i64) {
+ (self.program1, self.program2)
+ }
+}
+
+impl MemoryInterface for MemoryTracker {
+ fn latency(&self) -> u32 {
+ self.memory.latency()
+ }
+
+ fn step(&mut self) {
+ self.memory.step();
+ }
+
+ fn is_address_accessible(&self, address: isa::Address) -> bool {
+ self.memory.is_address_accessible(address)
+ }
+
+ fn read_word(&mut self, address: isa::Address) -> Result<isa::Word> {
+ self.memory.read_word(address)
+ }
+
+ fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> {
+ let original = self.memory.read_word(address);
+ let result = self.memory.write_word(address, value);
+
+ if let Ok(original) = original {
+ if let Ok(()) = result {
+ let p1b = self.program1_byte as u32;
+ let mut p1orig = 0;
+ let mut p1new = 0;
+ if original & 0xFF == p1b { p1orig += 1; }
+ if (original >> 8) & 0xFF == p1b { p1orig += 1; }
+ if (original >> 16) & 0xFF == p1b { p1orig += 1; }
+ if (original >> 24) & 0xFF == p1b { p1orig += 1; }
+
+ if value & 0xFF == p1b { p1new += 1; }
+ if (value >> 8) & 0xFF == p1b { p1new += 1; }
+ if (value >> 16) & 0xFF == p1b { p1new += 1; }
+ if (value >> 24) & 0xFF == p1b { p1new += 1; }
+
+ self.program1 += p1new - p1orig;
+
+ let p2b = self.program2_byte as u32;
+ let mut p2orig = 0;
+ let mut p2new = 0;
+ if original & 0xFF == p2b { p2orig += 1; }
+ if (original >> 8) & 0xFF == p2b { p2orig += 1; }
+ if (original >> 16) & 0xFF == p2b { p2orig += 1; }
+ if (original >> 24) & 0xFF == p2b { p2orig += 1; }
+
+ if value & 0xFF == p2b { p2new += 1; }
+ if (value >> 8) & 0xFF == p2b { p2new += 1; }
+ if (value >> 16) & 0xFF == p2b { p2new += 1; }
+ if (value >> 24) & 0xFF == p2b { p2new += 1; }
+
+ self.program2 += p2new - p2orig;
+ }
+ }
+
+ result
+ }
+}