From 0e0713c3a078646879995d962ba50080f0b158b3 Mon Sep 17 00:00:00 2001 From: Jan-Peter von Hunnius Date: Tue, 30 Sep 2025 10:23:17 +0200 Subject: [PATCH] Fixed test failures --- src/components/memory/intel_4001.rs | 43 ++++++++++++++++++++++++++- src/components/memory/intel_4002.rs | 45 ++++++++++++++++++++++++----- src/main.rs | 2 -- tests/intel_400x_tests.rs | 3 ++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/components/memory/intel_4001.rs b/src/components/memory/intel_4001.rs index f8f19cf..50fadc7 100644 --- a/src/components/memory/intel_4001.rs +++ b/src/components/memory/intel_4001.rs @@ -742,7 +742,9 @@ impl Component for Intel4001 { /// Main update cycle - handles clock edge detection and operation dispatch /// Hardware: Responds to Φ1 and Φ2 clock edges from CPU fn update(&mut self) { + println!("DEBUG: update() method called for {}", self.base.name()); if !self.is_running() { + println!("DEBUG: Component not running, returning"); return; } // Handle both rising and falling edges for proper two-phase operation @@ -1028,12 +1030,22 @@ mod tests { // Initially should be in idle state assert_eq!(rom.memory_state, MemoryState::Idle); + // Start the component so it can process updates + rom.base.set_running(true); + assert!(rom.is_running()); + // Get pin references let sync_pin = rom.get_pin("SYNC").unwrap(); let cm_pin = rom.get_pin("CM").unwrap(); let ci_pin = rom.get_pin("CI").unwrap(); let phi1_pin = rom.get_pin("PHI1").unwrap(); + // Initialize PHI1 to Low first + { + let mut phi1_guard = phi1_pin.lock().unwrap(); + phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low); + } + // Set up memory read operation: SYNC=1, CM=1, CI=0 (memory access) { let mut sync_guard = sync_pin.lock().unwrap(); @@ -1044,15 +1056,44 @@ mod tests { ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Memory access } - // Set Φ1 high + // Set Φ1 high (creating rising edge) { let mut phi1_guard = phi1_pin.lock().unwrap(); phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High); } + // Debug: Check pin states before update + println!("DEBUG: Before update - SYNC: {:?}, CM: {:?}, CI: {:?}, PHI1: {:?}", + sync_pin.lock().unwrap().read(), + cm_pin.lock().unwrap().read(), + ci_pin.lock().unwrap().read(), + phi1_pin.lock().unwrap().read()); + + // Debug: Check conditions that would trigger memory operation + let sync = rom.read_sync_pin(); + let chip_select = rom.read_cm_rom_pin(); + let io_select = rom.read_ci_pin(); + println!("DEBUG: Conditions - sync: {}, chip_select: {}, io_select: {}, combined: {}", + sync, chip_select, io_select, sync && chip_select && !io_select); + + // Debug: Check edge detection + println!("DEBUG: Before update - prev_phi1: {:?}", rom.prev_phi1); + + // Debug: Check what read_clock_pins returns + let (read_phi1, _) = rom.read_clock_pins(); + println!("DEBUG: read_clock_pins() returns PHI1: {:?}", read_phi1); + + // Debug: Check edge detection logic manually + let phi1_rising = read_phi1 == PinValue::High && rom.prev_phi1 == PinValue::Low; + println!("DEBUG: Manual edge detection - PHI1: {:?}, prev_phi1: {:?}, rising: {}", + read_phi1, rom.prev_phi1, phi1_rising); + // Update to process Φ1 rising edge rom.update(); + // Debug: Check edge detection results + println!("DEBUG: After update - prev_phi1: {:?}", rom.prev_phi1); + // Should have started memory operation and transitioned to AddressPhase assert_eq!(rom.memory_state, MemoryState::AddressPhase); println!("Memory state after Φ1 rising: {:?}", rom.memory_state); diff --git a/src/components/memory/intel_4002.rs b/src/components/memory/intel_4002.rs index d13a84e..3c80adf 100644 --- a/src/components/memory/intel_4002.rs +++ b/src/components/memory/intel_4002.rs @@ -476,8 +476,8 @@ impl Intel4002 { // Check for RAM operation start on Φ1 rising edge with SYNC high let (sync, _cm, p0, _) = self.read_control_pins(); - if sync && p0 { - // Start RAM address phase on Φ1 rising edge + if sync && p0 && self.ram_state == RamState::Idle { + // Start RAM address phase on Φ1 rising edge (only when idle) self.start_ram_address_phase(); } @@ -1121,6 +1121,10 @@ mod tests { fn test_address_latching() { let mut ram = Intel4002::new_with_access_time("RAM_4002".to_string(), 1); + // Start the component so it can process updates + ram.base.set_running(true); + assert!(ram.is_running()); + // Get pin references let sync_pin = ram.get_pin("SYNC").unwrap(); let p0_pin = ram.get_pin("P0").unwrap(); @@ -1156,40 +1160,67 @@ mod tests { d3_guard.set_driver(Some("TEST".to_string()), PinValue::Low); } + // Debug: Check pin states before first update + println!("DEBUG: Before first update - SYNC: {:?}, P0: {:?}, PHI1: {:?}", + sync_pin.lock().unwrap().read(), + p0_pin.lock().unwrap().read(), + phi1_pin.lock().unwrap().read()); + + // Debug: Check conditions that would trigger RAM operation + let (sync, _cm, p0, _) = ram.read_control_pins(); + println!("DEBUG: Control pins - sync: {}, p0: {}, combined: {}", sync, p0, sync && p0); + + // Debug: Check initial clock state + println!("DEBUG: Before first update - prev_phi1: {:?}", ram.prev_phi1); + // High nibble phi1_pin .lock() .unwrap() .set_driver(Some("TEST".into()), PinValue::High); ram.update(); // rising edge -> latch high nibble + + // Debug: Check clock state after first update + println!("DEBUG: After first update - prev_phi1: {:?}", ram.prev_phi1); + phi1_pin .lock() .unwrap() .set_driver(Some("TEST".into()), PinValue::Low); ram.update(); // falling edge - // Should have transitioned to AddressPhase + // Should have transitioned to AddressPhase and latched high nibble assert_eq!(ram.ram_state, RamState::AddressPhase); assert_eq!(ram.address_high_nibble, Some(0x0)); + // Note: full_address_ready should be false until both nibbles are assembled - // Set address low nibble (0x0) on data bus + // Set address low nibble (0x1) on data bus - different from high nibble { let mut d0_guard = d0_pin.lock().unwrap(); let mut d1_guard = d1_pin.lock().unwrap(); let mut d2_guard = d2_pin.lock().unwrap(); let mut d3_guard = d3_pin.lock().unwrap(); - d0_guard.set_driver(Some("TEST".into()), PinValue::Low); + d0_guard.set_driver(Some("TEST".into()), PinValue::High); // Bit 0 = 1 d1_guard.set_driver(Some("TEST".into()), PinValue::Low); d2_guard.set_driver(Some("TEST".into()), PinValue::Low); d3_guard.set_driver(Some("TEST".into()), PinValue::Low); } + // Debug: Check state before low nibble + println!("DEBUG: Before low nibble - High: {:?}, Low: {:?}, Ready: {}", + ram.address_high_nibble, ram.address_low_nibble, ram.full_address_ready); + // Low nibble phi1_pin .lock() .unwrap() .set_driver(Some("TEST".into()), PinValue::High); ram.update(); // rising edge -> latch low nibble + + // Debug: Check state after low nibble + println!("DEBUG: After low nibble - High: {:?}, Low: {:?}, Ready: {}", + ram.address_high_nibble, ram.address_low_nibble, ram.full_address_ready); + phi1_pin .lock() .unwrap() @@ -1197,8 +1228,8 @@ mod tests { ram.update(); // falling edge // Should have assembled full address and transitioned to WaitLatency - assert_eq!(ram.last_address, 0x00); - assert_eq!(ram.full_address_ready, true); + assert_eq!(ram.last_address, 0x01); // High nibble 0x0, low nibble 0x1 = 0x01 + assert_eq!(ram.full_address_ready, true); // Now both nibbles are assembled assert_eq!(ram.ram_state, RamState::WaitLatency); } diff --git a/src/main.rs b/src/main.rs index 8a2dab8..1af9505 100644 --- a/src/main.rs +++ b/src/main.rs @@ -271,8 +271,6 @@ fn create_system(system_type: &str, program_data: &[u8]) -> Result