feat: migrate to parking_lot mutex and add system control architecture
This commit is contained in:
parent
14060e15e5
commit
54144d10e9
29 changed files with 2387 additions and 1130 deletions
|
|
@ -1,10 +1,11 @@
|
|||
use parking_lot::Mutex;
|
||||
use rusty_emu::component::{BaseComponent, Component};
|
||||
use rusty_emu::components::common::intel_400x::*;
|
||||
use rusty_emu::components::memory::intel_4001::{Intel4001, IoDirection, IoMode};
|
||||
use rusty_emu::pin::{Pin, PinValue};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
// Mock component for testing trait implementations
|
||||
|
|
@ -47,9 +48,17 @@ impl Component for MockComponent {
|
|||
false
|
||||
}
|
||||
|
||||
fn set_running(&mut self, _running: bool) {
|
||||
// No-op for mock
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Intel400xAddressHandling for MockComponent {
|
||||
|
|
@ -354,57 +363,29 @@ mod tests {
|
|||
let d3_pin = rom.get_pin("D3").unwrap();
|
||||
|
||||
// Set settlement time to 0 for immediate testing
|
||||
sync_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
cm_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
ci_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
sync_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
cm_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
ci_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
reset_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi1_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi2_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d0_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d1_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d2_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d3_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi1_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
phi2_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d0_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d1_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d2_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d3_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
|
||||
// Initially, all data pins should be HighZ
|
||||
assert_eq!(d0_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d1_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d2_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d3_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d0_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d1_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d2_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d3_pin.lock().read(), PinValue::HighZ);
|
||||
|
||||
// Test reset (RESET is active LOW)
|
||||
println!("=== Testing Reset ===");
|
||||
{
|
||||
let mut reset_guard = reset_pin.lock().unwrap();
|
||||
let mut reset_guard = reset_pin.lock();
|
||||
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -413,7 +394,7 @@ mod tests {
|
|||
|
||||
// Release reset (set HIGH for normal operation)
|
||||
{
|
||||
let mut reset_guard = reset_pin.lock().unwrap();
|
||||
let mut reset_guard = reset_pin.lock();
|
||||
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -466,11 +447,11 @@ mod tests {
|
|||
// Pin state snapshots
|
||||
println!(
|
||||
"Pin states: SYNC: {:?}, CM: {:?}, CI: {:?}, PHI1: {:?}, PHI2: {:?}",
|
||||
sync_pin.lock().unwrap().read(),
|
||||
cm_pin.lock().unwrap().read(),
|
||||
ci_pin.lock().unwrap().read(),
|
||||
phi1_pin.lock().unwrap().read(),
|
||||
phi2_pin.lock().unwrap().read()
|
||||
sync_pin.lock().read(),
|
||||
cm_pin.lock().read(),
|
||||
ci_pin.lock().read(),
|
||||
phi1_pin.lock().read(),
|
||||
phi2_pin.lock().read()
|
||||
);
|
||||
|
||||
println!("Test completed successfully!");
|
||||
|
|
@ -493,22 +474,22 @@ mod tests {
|
|||
// Reset to known state first (RESET is active LOW)
|
||||
{
|
||||
let reset_pin = rom.get_pin("RESET").unwrap();
|
||||
let mut reset_guard = reset_pin.lock().unwrap();
|
||||
let mut reset_guard = reset_pin.lock();
|
||||
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
|
||||
}
|
||||
rom.update();
|
||||
{
|
||||
let reset_pin = rom.get_pin("RESET").unwrap();
|
||||
let mut reset_guard = reset_pin.lock().unwrap();
|
||||
let mut reset_guard = reset_pin.lock();
|
||||
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
|
||||
}
|
||||
rom.update();
|
||||
|
||||
// Set SYNC=1, CM=1, CI=0 for memory read
|
||||
{
|
||||
let mut sync_guard = sync_pin.lock().unwrap();
|
||||
let mut cm_guard = cm_pin.lock().unwrap();
|
||||
let mut ci_guard = ci_pin.lock().unwrap();
|
||||
let mut sync_guard = sync_pin.lock();
|
||||
let mut cm_guard = cm_pin.lock();
|
||||
let mut ci_guard = ci_pin.lock();
|
||||
sync_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
cm_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
|
|
@ -517,14 +498,14 @@ mod tests {
|
|||
|
||||
// Ensure PHI2 is low initially
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
rom.update();
|
||||
|
||||
// Ensure PHI1 is low initially
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -534,7 +515,7 @@ mod tests {
|
|||
|
||||
// PHI1 low to high: Address phase for high nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -546,14 +527,14 @@ mod tests {
|
|||
|
||||
// PHI1 high to low: Complete address phase for high nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
rom.update();
|
||||
|
||||
// PHI1 low to high again: Address phase for low nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -564,7 +545,7 @@ mod tests {
|
|||
|
||||
// PHI1 high to low: Complete address phase
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -589,14 +570,14 @@ mod tests {
|
|||
// Release data bus from test control to allow ROM to drive it
|
||||
for i in 0..4 {
|
||||
let pin = rom.get_pin(&format!("D{}", i)).unwrap();
|
||||
let mut pin_guard = pin.lock().unwrap();
|
||||
let mut pin_guard = pin.lock();
|
||||
pin_guard.set_driver(Some("TEST".to_string()), PinValue::HighZ);
|
||||
}
|
||||
rom.update();
|
||||
|
||||
// PHI2 low to high: Data phase
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
rom.update();
|
||||
|
|
@ -612,17 +593,17 @@ mod tests {
|
|||
|
||||
// PHI2 high to low: Cleanup
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
rom.update();
|
||||
assert_eq!(rom.get_timing_state(), TimingState::Idle);
|
||||
|
||||
// Tri-state pins
|
||||
assert_eq!(d0_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d1_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d2_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d3_pin.lock().unwrap().read(), PinValue::HighZ);
|
||||
assert_eq!(d0_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d1_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d2_pin.lock().read(), PinValue::HighZ);
|
||||
assert_eq!(d3_pin.lock().read(), PinValue::HighZ);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -644,46 +625,18 @@ mod tests {
|
|||
let d3_pin = chip.get_pin("D3").unwrap();
|
||||
|
||||
// Set settlement time to 0 for immediate testing
|
||||
sync_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
cm_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
ci_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
sync_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
cm_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
ci_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
reset_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi1_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi2_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d0_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d1_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d2_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
d3_pin
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
phi1_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
phi2_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d0_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d1_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d2_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
d3_pin.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
|
||||
// Test memory read at minimum timing
|
||||
// Note: Intel 4004 has a 4-bit data bus, so we can only read 4 bits at a time
|
||||
|
|
@ -861,28 +814,19 @@ mod tests {
|
|||
// Set settlement times to 0
|
||||
test_sync
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
test_cm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
test_ci
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
test_cm.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
test_ci.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
test_phi1
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
test_phi2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
|
||||
// Initialize PHI2 to Low to ensure proper edge detection
|
||||
{
|
||||
let mut phi2_guard = test_phi2.lock().unwrap();
|
||||
let mut phi2_guard = test_phi2.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -890,9 +834,9 @@ mod tests {
|
|||
// Manually step through the state machine to verify timing
|
||||
// Set control pins for memory read
|
||||
{
|
||||
let mut sync_guard = test_sync.lock().unwrap();
|
||||
let mut cm_guard = test_cm.lock().unwrap();
|
||||
let mut ci_guard = test_ci.lock().unwrap();
|
||||
let mut sync_guard = test_sync.lock();
|
||||
let mut cm_guard = test_cm.lock();
|
||||
let mut ci_guard = test_ci.lock();
|
||||
sync_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
cm_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
|
|
@ -902,14 +846,14 @@ mod tests {
|
|||
|
||||
// Ensure PHI1 is low initially
|
||||
{
|
||||
let mut phi1_guard = test_phi1.lock().unwrap();
|
||||
let mut phi1_guard = test_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
test_chip.update();
|
||||
|
||||
// Start address phase - first PHI1 cycle for high nibble
|
||||
{
|
||||
let mut phi1_guard = test_phi1.lock().unwrap();
|
||||
let mut phi1_guard = test_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -921,7 +865,7 @@ mod tests {
|
|||
|
||||
// PHI1 falling edge - latch high nibble
|
||||
{
|
||||
let mut phi1_guard = test_phi1.lock().unwrap();
|
||||
let mut phi1_guard = test_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -929,7 +873,7 @@ mod tests {
|
|||
|
||||
// Second PHI1 cycle for low nibble
|
||||
{
|
||||
let mut phi1_guard = test_phi1.lock().unwrap();
|
||||
let mut phi1_guard = test_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -940,7 +884,7 @@ mod tests {
|
|||
|
||||
// PHI1 falling edge - latch low nibble and complete address
|
||||
{
|
||||
let mut phi1_guard = test_phi1.lock().unwrap();
|
||||
let mut phi1_guard = test_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -951,7 +895,7 @@ mod tests {
|
|||
|
||||
// PHI2 high: Data phase
|
||||
{
|
||||
let mut phi2_guard = test_phi2.lock().unwrap();
|
||||
let mut phi2_guard = test_phi2.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -963,7 +907,7 @@ mod tests {
|
|||
|
||||
// Complete cycle
|
||||
{
|
||||
let mut phi2_guard = test_phi2.lock().unwrap();
|
||||
let mut phi2_guard = test_phi2.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
test_chip.update();
|
||||
|
|
@ -984,37 +928,28 @@ mod tests {
|
|||
// Set settlement times to 0
|
||||
fast_sync
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
fast_cm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
fast_ci
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
fast_cm.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
fast_ci.lock().set_settlement_time(Duration::from_nanos(0));
|
||||
fast_phi1
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
fast_phi2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_settlement_time(Duration::from_nanos(0));
|
||||
|
||||
// Initialize PHI2 to Low to ensure proper edge detection
|
||||
{
|
||||
let mut phi2_guard = fast_phi2.lock().unwrap();
|
||||
let mut phi2_guard = fast_phi2.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
||||
// Set up for memory read
|
||||
{
|
||||
let mut sync_guard = fast_sync.lock().unwrap();
|
||||
let mut cm_guard = fast_cm.lock().unwrap();
|
||||
let mut ci_guard = fast_ci.lock().unwrap();
|
||||
let mut sync_guard = fast_sync.lock();
|
||||
let mut cm_guard = fast_cm.lock();
|
||||
let mut ci_guard = fast_ci.lock();
|
||||
sync_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
cm_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
|
|
@ -1023,14 +958,14 @@ mod tests {
|
|||
|
||||
// Ensure PHI1 is low initially
|
||||
{
|
||||
let mut phi1_guard = fast_phi1.lock().unwrap();
|
||||
let mut phi1_guard = fast_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
||||
// First PHI1 cycle - latch high nibble
|
||||
{
|
||||
let mut phi1_guard = fast_phi1.lock().unwrap();
|
||||
let mut phi1_guard = fast_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
|
@ -1041,14 +976,14 @@ mod tests {
|
|||
|
||||
// PHI1 falling edge - latch high nibble
|
||||
{
|
||||
let mut phi1_guard = fast_phi1.lock().unwrap();
|
||||
let mut phi1_guard = fast_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
||||
// Second PHI1 cycle - latch low nibble
|
||||
{
|
||||
let mut phi1_guard = fast_phi1.lock().unwrap();
|
||||
let mut phi1_guard = fast_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
|
@ -1059,7 +994,7 @@ mod tests {
|
|||
|
||||
// PHI1 falling edge - latch low nibble and complete address
|
||||
{
|
||||
let mut phi1_guard = fast_phi1.lock().unwrap();
|
||||
let mut phi1_guard = fast_phi1.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
|
@ -1075,14 +1010,14 @@ mod tests {
|
|||
// Release data bus from test control to allow ROM to drive it
|
||||
for i in 0..4 {
|
||||
let pin = fast_chip.get_pin(&format!("D{}", i)).unwrap();
|
||||
let mut pin_guard = pin.lock().unwrap();
|
||||
let mut pin_guard = pin.lock();
|
||||
pin_guard.set_driver(Some("TEST".to_string()), PinValue::HighZ);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
||||
// Try to read data - PHI2 rising edge triggers data driving if latency elapsed
|
||||
{
|
||||
let mut phi2_guard = fast_phi2.lock().unwrap();
|
||||
let mut phi2_guard = fast_phi2.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
fast_chip.update();
|
||||
|
|
@ -1124,9 +1059,9 @@ mod tests {
|
|||
|
||||
// Set control pins for memory read
|
||||
{
|
||||
let mut sync_guard = sync_pin.lock().unwrap();
|
||||
let mut cm_guard = cm_pin.lock().unwrap();
|
||||
let mut ci_guard = ci_pin.lock().unwrap();
|
||||
let mut sync_guard = sync_pin.lock();
|
||||
let mut cm_guard = cm_pin.lock();
|
||||
let mut ci_guard = ci_pin.lock();
|
||||
sync_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
cm_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
|
|
@ -1135,21 +1070,21 @@ mod tests {
|
|||
|
||||
// Ensure PHI2 is low initially
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
chip.update();
|
||||
|
||||
// Ensure PHI1 is low initially
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
chip.update();
|
||||
|
||||
// PHI1 low to high: Address phase for high nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
chip.update();
|
||||
|
|
@ -1160,14 +1095,14 @@ mod tests {
|
|||
|
||||
// PHI1 high to low: Complete address phase for high nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
chip.update();
|
||||
|
||||
// PHI1 low to high again: Address phase for low nibble
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
chip.update();
|
||||
|
|
@ -1178,7 +1113,7 @@ mod tests {
|
|||
|
||||
// PHI1 high to low: Complete address phase
|
||||
{
|
||||
let mut phi1_guard = phi1_pin.lock().unwrap();
|
||||
let mut phi1_guard = phi1_pin.lock();
|
||||
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
chip.update();
|
||||
|
|
@ -1208,14 +1143,14 @@ mod tests {
|
|||
// Release data bus from test control to allow ROM to drive it
|
||||
for i in 0..4 {
|
||||
let pin = chip.get_pin(&format!("D{}", i)).unwrap();
|
||||
let mut pin_guard = pin.lock().unwrap();
|
||||
let mut pin_guard = pin.lock();
|
||||
pin_guard.set_driver(Some("TEST".to_string()), PinValue::HighZ);
|
||||
}
|
||||
chip.update();
|
||||
|
||||
// PHI2 low to high: Data phase
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
chip.update();
|
||||
|
|
@ -1230,7 +1165,7 @@ mod tests {
|
|||
|
||||
// PHI2 high to low: Cleanup
|
||||
{
|
||||
let mut phi2_guard = phi2_pin.lock().unwrap();
|
||||
let mut phi2_guard = phi2_pin.lock();
|
||||
phi2_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
|
||||
}
|
||||
chip.update();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue