diff --git a/README.md b/README.md index f24de34..7e1bb10 100644 --- a/README.md +++ b/README.md @@ -126,10 +126,14 @@ use rusty_emu::system_config::SystemFactory; // Create system from JSON configuration let factory = SystemFactory::new(); -let mut system = factory.create_from_json("configs/mcs4_basic.json") ?; +let system = factory.create_from_json("configs/mcs4_basic.json") ?; -// Run simulation -system.run(); +// Get system information +let info = system.get_system_info(); +println!("Created system: {} with {} components", info.name, info.component_count); + +// Run simulation (in a real application) +// system.run(); ``` ### Command Line Usage diff --git a/src/README.md b/src/README.md index 4aba72a..e58210f 100644 --- a/src/README.md +++ b/src/README.md @@ -148,13 +148,17 @@ rom.update(); // Process one clock cycle use rusty_emu::systems::intel_mcs_4::IntelMCS4; // Create complete MCS-4 system -let mut system = IntelMCS4::new(); +let system = IntelMCS4::new(); // Load program into ROM system.load_program(0, & program_data) ?; -// Run simulation -system.run(); +// Get system information +let info = system.get_system_info(); +println!("Loaded system: {} with {} components", info.name, info.component_count); + +// Run simulation (in a real application) +// system.run(); ``` ## Development Guidelines diff --git a/src/components/clock/generic_clock.rs b/src/components/clock/generic_clock.rs index 899e6fd..4c6e7e0 100644 --- a/src/components/clock/generic_clock.rs +++ b/src/components/clock/generic_clock.rs @@ -173,7 +173,6 @@ impl Component for GenericClock { } } - // Advanced clock features impl GenericClock {} diff --git a/src/components/clock/two_phase_clock.rs b/src/components/clock/two_phase_clock.rs index c64ab87..973f417 100644 --- a/src/components/clock/two_phase_clock.rs +++ b/src/components/clock/two_phase_clock.rs @@ -171,4 +171,4 @@ impl Component for TwoPhaseClock { fn is_running(&self) -> bool { self.base.is_running() } -} \ No newline at end of file +} diff --git a/src/components/cpu/intel_4004.rs b/src/components/cpu/intel_4004.rs index 645f419..f2b5b55 100644 --- a/src/components/cpu/intel_4004.rs +++ b/src/components/cpu/intel_4004.rs @@ -12,9 +12,7 @@ use crate::types::U12; #[derive(Debug, Clone, Copy, PartialEq)] enum InstructionPhase { Fetch, // Fetching instruction from memory - Address, // Calculating or fetching address Execute, // Executing the instruction - Wait, // Waiting for external operations } /// Memory operation state machine states @@ -32,13 +30,13 @@ enum MemoryState { #[derive(Debug, Clone, Copy, PartialEq)] enum Instruction { // Data Transfer Instructions (8) - Ldm(u8), // Load accumulator immediate (LDM #) - Ld(u8), // Load accumulator from register (LD R) - Xch(u8), // Exchange accumulator with register (XCH R) - Add(u8), // Add register to accumulator (ADD R) - Sub(u8), // Subtract register from accumulator (SUB R) - Inc(u8), // Increment register (INC R) - Bbl(u8), // Branch back and load (BBL #) + Ldm(u8), // Load accumulator immediate (LDM #) + Ld(u8), // Load accumulator from register (LD R) + Xch(u8), // Exchange accumulator with register (XCH R) + Add(u8), // Add register to accumulator (ADD R) + Sub(u8), // Subtract register from accumulator (SUB R) + Inc(u8), // Increment register (INC R) + Bbl(u8), // Branch back and load (BBL #) // Arithmetic Instructions (4) AddC(u8), // Add register with carry (ADC R) @@ -454,7 +452,7 @@ impl Intel4004 { self.address_high_nibble = None; self.address_low_nibble = None; self.full_address_ready = false; - + // Reset two-instruction format state self.pending_operand = None; self.operand_assembled = false; @@ -594,7 +592,8 @@ impl Intel4004 { let data = self.data_latch; self.write_data_bus(data); - if self.cycle_count % 1000 == 0 { // Log every 1000 cycles + if self.cycle_count % 1000 == 0 { + // Log every 1000 cycles println!("DEBUG: [{}] CPU State | PC: 0x{:03X} | Cycles: {} | ACC: 0x{:X} | SYNC: {} | CM_ROM: {} | CM_RAM: {} | RAM_Ready: {}", self.base.name(), self.program_counter.value(), self.cycle_count, self.accumulator, sync, cm_rom, cm_ram, self.full_address_ready); } @@ -928,22 +927,22 @@ impl Intel4004 { Instruction::Jcn(condition, addr) => { // Decode condition bits properly let should_jump = match condition & 0x0F { - 0x0 => !self.carry && self.accumulator != 0, // JNT (Jump if no carry and ACC != 0) - 0x1 => self.carry, // JC (Jump if carry) - 0x2 => self.accumulator == 0, // JZ (Jump if zero) - 0x3 => self.accumulator != 0, // JNZ (Jump if not zero) - 0x4 => true, // JUN (Jump unconditional) - 0x5 => false, // Always false - 0x6 => true, // Always true - 0x7 => false, // Always false - 0x8 => true, // Always true - 0x9 => false, // Always false - 0xA => true, // Always true - 0xB => false, // Always false - 0xC => true, // Always true - 0xD => false, // Always false - 0xE => true, // Always true - 0xF => false, // Always false + 0x0 => !self.carry && self.accumulator != 0, // JNT (Jump if no carry and ACC != 0) + 0x1 => self.carry, // JC (Jump if carry) + 0x2 => self.accumulator == 0, // JZ (Jump if zero) + 0x3 => self.accumulator != 0, // JNZ (Jump if not zero) + 0x4 => true, // JUN (Jump unconditional) + 0x5 => false, // Always false + 0x6 => true, // Always true + 0x7 => false, // Always false + 0x8 => true, // Always true + 0x9 => false, // Always false + 0xA => true, // Always true + 0xB => false, // Always false + 0xC => true, // Always true + 0xD => false, // Always false + 0xE => true, // Always true + 0xF => false, // Always false _ => false, }; @@ -994,15 +993,20 @@ impl Intel4004 { Instruction::Wrm => { // Write accumulator to RAM at current RAM address // This would interface with RAM chips - for now, just log - println!("DEBUG: [CPU] WRM - Write ACC 0x{:X} to RAM address 0x{:02X}", - self.accumulator, self.address_latch); + println!( + "DEBUG: [CPU] WRM - Write ACC 0x{:X} to RAM address 0x{:02X}", + self.accumulator, self.address_latch + ); self.program_counter.inc(); } Instruction::Wmp => { // Write memory pointer - set RAM address from accumulator self.address_latch = self.accumulator; - println!("DEBUG: [CPU] WMP - Set RAM address to 0x{:02X}", self.address_latch); + println!( + "DEBUG: [CPU] WMP - Set RAM address to 0x{:02X}", + self.address_latch + ); self.program_counter.inc(); } @@ -1021,19 +1025,28 @@ impl Intel4004 { Instruction::Adm => { // Add from memory - add RAM data to accumulator // This would read from RAM and add to accumulator - println!("DEBUG: [CPU] ADM - Add from RAM address 0x{:02X}", self.address_latch); + println!( + "DEBUG: [CPU] ADM - Add from RAM address 0x{:02X}", + self.address_latch + ); self.program_counter.inc(); } Instruction::Sbm => { // Subtract from memory - subtract RAM data from accumulator - println!("DEBUG: [CPU] SBM - Subtract from RAM address 0x{:02X}", self.address_latch); + println!( + "DEBUG: [CPU] SBM - Subtract from RAM address 0x{:02X}", + self.address_latch + ); self.program_counter.inc(); } Instruction::Rdm => { // Read memory - read RAM data to accumulator - println!("DEBUG: [CPU] RDM - Read from RAM address 0x{:02X}", self.address_latch); + println!( + "DEBUG: [CPU] RDM - Read from RAM address 0x{:02X}", + self.address_latch + ); self.program_counter.inc(); } @@ -1181,8 +1194,10 @@ impl Intel4004 { self.execute_instruction(); let new_pc = self.program_counter.value(); - println!("DEBUG: [TEST] Single Execute | PC: 0x{:03X} -> 0x{:03X} | ACC: 0x{:X}", - old_pc, new_pc, self.accumulator); + println!( + "DEBUG: [TEST] Single Execute | PC: 0x{:03X} -> 0x{:03X} | ACC: 0x{:X}", + old_pc, new_pc, self.accumulator + ); } } @@ -1200,7 +1215,11 @@ impl Intel4004 { } } - println!("DEBUG: [{}] Loaded test program: {:02X?}", self.base.name(), program); + println!( + "DEBUG: [{}] Loaded test program: {:02X?}", + self.base.name(), + program + ); } } @@ -1283,9 +1302,9 @@ mod tests { // Test XCH (exchange with register 1) - 0x11 = XCH 1 cpu.current_op = Instruction::Xch(1); cpu.execute_instruction(); - assert_eq!(cpu.get_accumulator(), 0x05); // ACC gets R1's value - assert_eq!(cpu.get_register(0).unwrap(), 0x0A); // R0 gets old ACC value - assert_eq!(cpu.get_register(1).unwrap(), 0x0A); // R1 gets new ACC value + assert_eq!(cpu.get_accumulator(), 0x05); // ACC gets R1's value + assert_eq!(cpu.get_register(0).unwrap(), 0x0A); // R0 gets old ACC value + assert_eq!(cpu.get_register(1).unwrap(), 0x0A); // R1 gets new ACC value println!("DEBUG: Register operations test completed successfully"); } @@ -1518,10 +1537,6 @@ impl Component for Intel4004 { } } } - - _ => { - // Other phases handled by memory operations - } } self.cycle_count += 1; diff --git a/src/components/memory/intel_4001.rs b/src/components/memory/intel_4001.rs index c1a3825..4a308ba 100644 --- a/src/components/memory/intel_4001.rs +++ b/src/components/memory/intel_4001.rs @@ -1062,18 +1062,25 @@ mod tests { } // 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()); + 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); + 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); @@ -1084,8 +1091,10 @@ mod tests { // 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); + println!( + "DEBUG: Manual edge detection - PHI1: {:?}, prev_phi1: {:?}, rising: {}", + read_phi1, rom.prev_phi1, phi1_rising + ); // Update to process Φ1 rising edge rom.update(); diff --git a/src/components/memory/intel_4002.rs b/src/components/memory/intel_4002.rs index 3c80adf..1ad6565 100644 --- a/src/components/memory/intel_4002.rs +++ b/src/components/memory/intel_4002.rs @@ -583,8 +583,13 @@ impl Intel4002 { if self.address_high_nibble.is_none() { self.address_high_nibble = Some(nibble); - println!("DEBUG: [{}] Addr Latch High | Nibble: 0x{:X} | State: {:?} | Cycles: {}", - self.base.name(), nibble, self.ram_state, self.get_cycle_count()); + println!( + "DEBUG: [{}] Addr Latch High | Nibble: 0x{:X} | State: {:?} | Cycles: {}", + self.base.name(), + nibble, + self.ram_state, + self.get_cycle_count() + ); } else if self.address_low_nibble.is_none() { self.address_low_nibble = Some(nibble); println!("DEBUG: [{}] Addr Latch Low | High: 0x{:X} | Low: 0x{:X} | State: {:?} | Cycles: {}", @@ -766,7 +771,8 @@ impl Component for Intel4002 { static mut CYCLE_COUNTER: u64 = 0; unsafe { CYCLE_COUNTER += 1; - if CYCLE_COUNTER % 5000 == 0 { // Less frequent than CPU to avoid spam + if CYCLE_COUNTER % 5000 == 0 { + // Less frequent than CPU to avoid spam println!("DEBUG: [{}] RAM State | Bank: {} | Status: {:?} | Ready: {} | LastAddr: 0x{:02X} | Cycles: {} | HighNib: {:?} | LowNib: {:?}", self.base.name(), self.bank_select, self.ram_state, self.full_address_ready, self.last_address, self.get_cycle_count(), self.address_high_nibble, self.address_low_nibble); } @@ -1161,17 +1167,27 @@ mod tests { } // 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()); + 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); + 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); + println!( + "DEBUG: Before first update - prev_phi1: {:?}", + ram.prev_phi1 + ); // High nibble phi1_pin @@ -1207,8 +1223,10 @@ mod tests { } // 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); + println!( + "DEBUG: Before low nibble - High: {:?}, Low: {:?}, Ready: {}", + ram.address_high_nibble, ram.address_low_nibble, ram.full_address_ready + ); // Low nibble phi1_pin @@ -1218,8 +1236,10 @@ mod tests { 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); + println!( + "DEBUG: After low nibble - High: {:?}, Low: {:?}, Ready: {}", + ram.address_high_nibble, ram.address_low_nibble, ram.full_address_ready + ); phi1_pin .lock() diff --git a/src/console.rs b/src/console.rs index 1049761..b68199e 100644 --- a/src/console.rs +++ b/src/console.rs @@ -414,7 +414,9 @@ impl ConsoleApp { Line::from(vec![Span::raw("Status: Running (check console output)")]), Line::from(vec![Span::raw("PC: 0x000 (see DEBUG output)")]), Line::from(vec![Span::raw("ACC: 0x0 (see DEBUG output)")]), - Line::from(vec![Span::raw("Instructions: Executing (see DEBUG output)")]), + Line::from(vec![Span::raw( + "Instructions: Executing (see DEBUG output)", + )]), ]; let register_widget = Paragraph::new(register_info) diff --git a/src/main.rs b/src/main.rs index 1af9505..deca518 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,6 @@ use std::sync::{Arc, Mutex}; use std::thread; use std::time::{Duration, Instant}; - fn main() { // Parse command line arguments let args: Vec = env::args().collect(); @@ -255,9 +254,9 @@ fn create_system(system_type: &str, program_data: &[u8]) -> Result { // Try to use provided config file directly if system_type.ends_with(".json") { - let mut system = factory - .create_from_json(system_type) - .map_err(|e| format!("Failed to create system from '{}': {}", system_type, e))?; + let mut system = factory.create_from_json(system_type).map_err(|e| { + format!("Failed to create system from '{}': {}", system_type, e) + })?; // Load program data into ROM components system.load_program_data(program_data)?; diff --git a/src/system_config.rs b/src/system_config.rs index aadd3d7..17657ea 100644 --- a/src/system_config.rs +++ b/src/system_config.rs @@ -17,10 +17,11 @@ //! //! // Create system from JSON configuration //! let factory = SystemFactory::new(); -//! let mut system = factory.create_from_json("configs/mcs4_basic.json").expect("Could not create JSON test!"); +//! let system = factory.create_from_json("configs/mcs4_basic.json").expect("Could not create system!"); //! -//! // Run the configured system -//! system.run(); +//! // Get system information +//! let info = system.get_system_info(); +//! println!("Created system: {} with {} components", info.name, info.component_count); //! ``` //! //! ## Configuration File Format @@ -174,7 +175,9 @@ impl SystemFactory { .and_then(|v| v.as_f64()) .unwrap_or(750000.0); Ok(Box::new( - crate::components::clock::two_phase_clock::TwoPhaseClock::new(name, frequency), + crate::components::clock::two_phase_clock::TwoPhaseClock::new( + name, frequency, + ), )) } else { Err("Two-phase clock must be single component".to_string()) @@ -439,9 +442,13 @@ impl ConfigurableSystem { break; } - if i % 5 == 0 { // Show header every 5 cycles + if i % 5 == 0 { + // Show header every 5 cycles println!("\n┌─────────────────────────────────────────────────────────────┐"); - println!("│ CYCLE {:2} │", i); + println!( + "│ CYCLE {:2} │", + i + ); println!("└─────────────────────────────────────────────────────────────┘"); } self.display_current_state(); @@ -494,10 +501,12 @@ impl ConfigurableSystem { if let Some(cpu_component) = self.components.get("CPU_4004") { if let Ok(_cpu) = cpu_component.lock() { println!("│ CPU State: │"); - println!("│ Accumulator: 0x{:X} Carry: {} PC: 0x{:03X} │", - 0, // Placeholder - would need CPU-specific method + println!( + "│ Accumulator: 0x{:X} Carry: {} PC: 0x{:03X} │", + 0, // Placeholder - would need CPU-specific method false, // Placeholder - would need CPU-specific method - 0); // Placeholder - would need CPU-specific method + 0 + ); // Placeholder - would need CPU-specific method } } @@ -509,11 +518,16 @@ impl ConfigurableSystem { } // Component status summary - let running_count = self.components.values() + let running_count = self + .components + .values() .filter(|comp| comp.lock().map_or(false, |c| c.is_running())) .count(); - println!("│ Components: {}/{} running │", - running_count, self.components.len()); + println!( + "│ Components: {}/{} running │", + running_count, + self.components.len() + ); println!("└─────────────────────────────────────────────────────────────┘"); } @@ -559,7 +573,10 @@ impl ConfigurableSystem { /// Parameters: program_data - Binary program data to load /// Returns: Ok(()) on success, Err(String) on failure pub fn load_program_data(&mut self, program_data: &[u8]) -> Result<(), String> { - println!("DEBUG: Loading {} bytes of program data into ROM components", program_data.len()); + println!( + "DEBUG: Loading {} bytes of program data into ROM components", + program_data.len() + ); // Load program data into ROM_4001_1 (first 256 bytes) if let Some(rom1_component) = self.components.get_mut("ROM_4001_1") { diff --git a/tests/intel_400x_tests.rs b/tests/intel_400x_tests.rs index 8d24a24..c602360 100644 --- a/tests/intel_400x_tests.rs +++ b/tests/intel_400x_tests.rs @@ -53,8 +53,8 @@ impl Intel400xAddressHandling for MockComponent { #[cfg(test)] mod tests { - use std::thread; use super::*; + use std::thread; #[test] fn test_timing_constants() {