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,6 +1,7 @@
|
|||
use parking_lot::Mutex;
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
|
|
@ -382,10 +383,9 @@ impl Intel4001 {
|
|||
|
||||
for i in 0..4 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("IO{}", i)) {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
if pin_guard.read() == PinValue::High {
|
||||
data |= 1 << i;
|
||||
}
|
||||
let pin_guard = pin.lock();
|
||||
if pin_guard.read() == PinValue::High {
|
||||
data |= 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -499,9 +499,8 @@ impl Intel4001 {
|
|||
fn tri_state_io_pins(&self) {
|
||||
for i in 0..4 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("IO{}", i)) {
|
||||
if let Ok(mut pin_guard) = pin.lock() {
|
||||
pin_guard.set_driver(Some(self.base.name()), PinValue::HighZ);
|
||||
}
|
||||
let mut pin_guard = pin.lock();
|
||||
pin_guard.set_driver(Some(self.base.name()), PinValue::HighZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -575,11 +574,8 @@ impl Intel4001 {
|
|||
/// Hardware: CI pin distinguishes I/O vs ROM access when chip selected (CM=1)
|
||||
fn read_ci_pin(&self) -> bool {
|
||||
if let Ok(pin) = self.base.get_pin("CI") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read() == PinValue::High
|
||||
} else {
|
||||
false
|
||||
}
|
||||
let pin_guard = pin.lock();
|
||||
pin_guard.read() == PinValue::High
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -620,22 +616,21 @@ impl Intel4001 {
|
|||
fn update_io_pins(&self) {
|
||||
for i in 0..4 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("IO{}", i)) {
|
||||
if let Ok(mut pin_guard) = pin.lock() {
|
||||
match self.io_direction[i] {
|
||||
IoDirection::Output => {
|
||||
// Drive pin with output port value
|
||||
let bit_value = (self.io_ports[i]) & 1;
|
||||
let pin_value = if bit_value == 1 {
|
||||
PinValue::High
|
||||
} else {
|
||||
PinValue::Low
|
||||
};
|
||||
pin_guard.set_driver(Some(self.base.name()), pin_value);
|
||||
}
|
||||
IoDirection::Input => {
|
||||
// Input mode - tri-state pin
|
||||
pin_guard.set_driver(Some(self.base.name()), PinValue::HighZ);
|
||||
}
|
||||
let mut pin_guard = pin.lock();
|
||||
match self.io_direction[i] {
|
||||
IoDirection::Output => {
|
||||
// Drive pin with output port value
|
||||
let bit_value = (self.io_ports[i]) & 1;
|
||||
let pin_value = if bit_value == 1 {
|
||||
PinValue::High
|
||||
} else {
|
||||
PinValue::Low
|
||||
};
|
||||
pin_guard.set_driver(Some(self.base.name()), pin_value);
|
||||
}
|
||||
IoDirection::Input => {
|
||||
// Input mode - tri-state pin
|
||||
pin_guard.set_driver(Some(self.base.name()), PinValue::HighZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -926,9 +921,17 @@ impl Component for Intel4001 {
|
|||
self.base.is_running()
|
||||
}
|
||||
|
||||
fn set_running(&mut self, running: bool) {
|
||||
self.base.set_running(running);
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RunnableComponent for Intel4001 {}
|
||||
|
|
@ -1159,15 +1162,15 @@ mod tests {
|
|||
|
||||
// Initialize PHI1 to Low first
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// Set up memory read operation: SYNC=1, CM=1, CI=0 (memory access)
|
||||
{
|
||||
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); // Memory access
|
||||
|
|
@ -1175,7 +1178,7 @@ mod tests {
|
|||
|
||||
// Set Φ1 high (creating rising edge)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -1224,9 +1227,9 @@ mod tests {
|
|||
|
||||
// Set up memory read operation: SYNC=1, chip_select=1, io_select=0 (memory access)
|
||||
{
|
||||
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); // Memory access, not I/O
|
||||
|
|
@ -1259,9 +1262,9 @@ mod tests {
|
|||
|
||||
// Set memory operation active
|
||||
{
|
||||
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); // Memory access, not I/O
|
||||
|
|
@ -1272,7 +1275,7 @@ mod tests {
|
|||
|
||||
// Now assert 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::High);
|
||||
}
|
||||
|
||||
|
|
@ -1290,10 +1293,10 @@ mod tests {
|
|||
let d3_pin = rom.get_pin("D3").unwrap();
|
||||
|
||||
// After reset, all pins should be HighZ (tri-stated)
|
||||
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]
|
||||
|
|
@ -1310,19 +1313,19 @@ mod tests {
|
|||
let d3_pin = rom.get_pin("D3").unwrap();
|
||||
|
||||
// Initially, no operation - should be tri-stated
|
||||
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);
|
||||
|
||||
// Set up memory operation but don't complete address phase
|
||||
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 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); // Memory access, not I/O
|
||||
|
|
@ -1331,20 +1334,20 @@ mod tests {
|
|||
rom.update();
|
||||
|
||||
// Should still be tri-stated during address phase
|
||||
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);
|
||||
|
||||
// Complete address phase but don't wait for latency
|
||||
// Should still be tri-stated
|
||||
rom.update();
|
||||
|
||||
// Should still be tri-stated (waiting for latency)
|
||||
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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue