feat: Add real-time data display for CPU registers, RAM, and ROM

This commit is contained in:
Jan-Peter von Hunnius 2026-02-26 19:36:59 +01:00
parent 3530ea5f28
commit 6636417d18
22 changed files with 1233 additions and 188 deletions

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -171,6 +172,10 @@ impl Component for GenericClock {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
// Advanced clock features

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -182,4 +183,8 @@ impl Component for TwoPhaseClock {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}

View file

@ -592,7 +592,12 @@ pub enum Intel400xEvent {
///
/// # Example
///
/// ```rust
/// ```rust,ignore
/// use std::time::Duration;
/// use rusty_emu::components::common::intel_400x::{
/// Intel400xComponentBehavior, Intel400xComponentType, Intel400xUnifiedState
/// };
///
/// struct MyCustomComponent {
/// // Component fields...
/// }
@ -641,7 +646,7 @@ pub trait Intel400xComponentBehavior {
///
/// # Example
///
/// ```rust
/// ```rust,ignore
/// fn on_state_entry(&mut self, state: Intel400xUnifiedState) {
/// match state {
/// Intel400xUnifiedState::AddressPhase => {
@ -699,7 +704,7 @@ pub trait Intel400xComponentBehavior {
///
/// # Example
///
/// ```rust
/// ```rust,ignore
/// fn execute_state_logic(&mut self, state: Intel400xUnifiedState) {
/// match state {
/// Intel400xUnifiedState::AddressPhase => {
@ -769,6 +774,12 @@ pub trait Intel400xComponentBehavior {
/// # Example
///
/// ```rust
/// use std::time::Duration;
/// use rusty_emu::components::common::intel_400x::{
/// Intel400xStateMachine, Intel400xComponentType, Intel400xEvent,
/// Intel400xUnifiedState, process_event_direct
/// };
///
/// // Create a state machine for an Intel 4001 ROM chip
/// let mut state_machine = Intel400xStateMachine::new(
/// Intel400xComponentType::Intel4001,
@ -826,6 +837,11 @@ impl Intel400xStateMachine {
/// # Example
///
/// ```rust
/// use std::time::Duration;
/// use rusty_emu::components::common::intel_400x::{
/// Intel400xStateMachine, Intel400xComponentType, Intel400xUnifiedState
/// };
///
/// // Create a state machine for an Intel 4002 RAM chip with 500ns access time
/// let state_machine = Intel400xStateMachine::new(
/// Intel400xComponentType::Intel4002,
@ -1092,21 +1108,28 @@ impl Intel400xComponentBehavior for NoOpBehavior {
/// # Example
///
/// ```rust
/// use std::time::Duration;
/// use rusty_emu::components::common::intel_400x::{
/// Intel400xStateMachine, Intel400xComponentType, Intel400xEvent,
/// Intel400xUnifiedState, process_event
/// };
///
/// let mut state_machine = Intel400xStateMachine::new(
/// Intel400xComponentType::Intel4001,
/// Duration::from_nanos(500)
/// );
/// let mut component = Intel4001Component::new();
/// // Note: Intel4001Component would be imported from its module
/// // let mut component = Intel4001Component::new();
///
/// // Process a chip select event
/// let handled = process_event(
/// &mut state_machine,
/// Intel400xEvent::ChipSelect,
/// &mut component
/// );
/// // let handled = process_event(
/// // &mut state_machine,
/// // Intel400xEvent::ChipSelect,
/// // &mut component
/// // );
///
/// assert!(handled);
/// assert_eq!(state_machine.get_state(), Intel400xUnifiedState::AddressPhase);
/// // assert!(handled);
/// // assert_eq!(state_machine.get_state(), Intel400xUnifiedState::AddressPhase);
/// ```
pub fn process_event<T: Intel400xComponentBehavior>(
state_machine: &mut Intel400xStateMachine,
@ -1163,6 +1186,12 @@ pub fn process_event<T: Intel400xComponentBehavior>(
/// # Example
///
/// ```rust
/// use std::time::Duration;
/// use rusty_emu::components::common::intel_400x::{
/// Intel400xStateMachine, Intel400xComponentType, Intel400xEvent,
/// Intel400xUnifiedState, process_event_direct
/// };
///
/// let mut state_machine = Intel400xStateMachine::new(
/// Intel400xComponentType::Intel4001,
/// Duration::from_nanos(500)

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -1577,6 +1578,10 @@ impl Component for Intel4004 {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl RunnableComponent for Intel4004 {

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -231,6 +232,10 @@ impl Component for MOS6502 {
fn is_running(&self) -> bool {
self.is_running
}
fn as_any(&self) -> &dyn Any {
self
}
}
// 6502-specific methods

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
@ -107,6 +108,10 @@ impl Component for WDC65C02 {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
// 65C02-specific enhancements

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -924,6 +925,10 @@ impl Component for Intel4001 {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl RunnableComponent for Intel4001 {}

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -47,22 +48,6 @@ pub struct Intel4002 {
pending_operation: PendingOperation,
}
/// RAM register operations (for WRM/WRR instructions)
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RamOperation {
Read, // Read from RAM register
Write, // Write to RAM register
WriteOr, // Write to RAM register with OR operation
WriteAnd, // Write to RAM register with AND operation
}
/// RAM access modes (for SRC/SRC instructions)
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RamAccessMode {
Direct, // Direct access to RAM
Indirect, // Indirect access via register pair
}
impl Intel400xClockHandling for Intel4002 {
fn get_base(&self) -> &BaseComponent {
&self.base
@ -403,17 +388,6 @@ impl Intel4002 {
}
}
/// Read from a specific I/O port
/// Parameters: port - I/O port number (0-3)
/// Returns: 4-bit value from I/O port
pub fn read_io_port(&self, port: usize) -> u8 {
if port < 4 {
self.io_ports[port]
} else {
0
}
}
/// Write to a specific I/O port
/// Parameters: port - I/O port number (0-3), data - 4-bit data to write
/// Returns: Ok(()) on success, Err(String) on failure
@ -453,25 +427,6 @@ impl Intel4002 {
}
}
/// Drive status character on status pins
fn drive_status_character(&self) {
let status = self.status_character & 0x7F; // Ensure only 7 bits
for i in 0..4 {
if let Ok(pin) = self.base.get_pin(&format!("S{}", i)) {
if let Ok(mut pin_guard) = pin.lock() {
let bit_value = (status >> i) & 1;
let pin_value = if bit_value == 1 {
PinValue::High
} else {
PinValue::Low
};
pin_guard.set_driver(Some(self.base.name()), pin_value);
}
}
}
}
/// Handle Φ1 rising edge - Address and control phase
/// Hardware: Φ1 high = CPU drives bus with address/control information
/// Memory operations start when SYNC goes high during Φ1 rising edge
@ -699,13 +654,6 @@ impl Intel4002 {
self.on_state_entry(new_state);
}
}
/// Helper function to execute unified state machine logic
fn execute_state_machine(&mut self) {
// Execute the current state logic using the unified state machine
let current_state = self.state_machine.get_state();
self.execute_state_logic(current_state);
}
}
impl Component for Intel4002 {
@ -800,6 +748,10 @@ impl Component for Intel4002 {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl RunnableComponent for Intel4002 {}

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
@ -619,6 +620,10 @@ impl Component for Intel4003 {
fn is_running(&self) -> bool {
self.base.is_running()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl RunnableComponent for Intel4003 {}