Syntax cleanup, fixed never-ending test suite (console in doc-test)
This commit is contained in:
parent
f46cde7ef0
commit
3d4de8b268
11 changed files with 161 additions and 92 deletions
|
|
@ -173,7 +173,6 @@ impl Component for GenericClock {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Advanced clock features
|
||||
impl GenericClock {}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,4 +171,4 @@ impl Component for TwoPhaseClock {
|
|||
fn is_running(&self) -> bool {
|
||||
self.base.is_running()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue