Extracted fibonacci code into binary file
System and binary selection upon start
This commit is contained in:
parent
e7c98f0c47
commit
dd93e33087
4 changed files with 871 additions and 150 deletions
1
fibonacci.bin
Normal file
1
fibonacci.bin
Normal file
|
|
@ -0,0 +1 @@
|
|||
-n -e '\x20\x00\x10\x00\x50\x21\x01\x10\x01\x50\x00\x02\x76\x00\x02\x00\x00\x10\x01\x50\x00\x01\x00\x00\x50\x00\x02\x30\x08\x40\x0C\x00\x00'
|
||||
673
src/components/memory/intel_4003.rs
Normal file
673
src/components/memory/intel_4003.rs
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::component::{BaseComponent, Component, RunnableComponent};
|
||||
use crate::pin::{Pin, PinValue};
|
||||
|
||||
/// Intel 4003 - 10-bit Output Shift Register
|
||||
/// Part of the MCS-4 family, designed to work with Intel 4004 CPU
|
||||
/// Features 10-bit serial-in, parallel-out shift register for output expansion
|
||||
///
|
||||
/// Hardware Architecture:
|
||||
/// - 10-bit shift register with serial input and parallel outputs
|
||||
/// - Used for expanding I/O capabilities of the MCS-4 system
|
||||
/// - Serial data input from CPU, parallel outputs to external devices
|
||||
/// - Clocked by two-phase clock from 4004 CPU
|
||||
///
|
||||
/// Hardware Deviations:
|
||||
/// - Simplified timing model for unit testing (may need refinement for CPU integration)
|
||||
/// - Output behavior matches 4001/4002 I/O persistence model
|
||||
pub struct Intel4003 {
|
||||
base: BaseComponent,
|
||||
shift_register: [u8; 10], // 10-bit shift register (stored as 10 bytes for simplicity)
|
||||
output_latch: [u8; 10], // 10-bit output latch for parallel output
|
||||
serial_input: u8, // Serial input data (4-bit)
|
||||
access_time: Duration, // Shift register access latency (200ns typical)
|
||||
|
||||
// Clock edge detection
|
||||
prev_phi1: PinValue, // Previous Φ1 clock state for edge detection
|
||||
prev_phi2: PinValue, // Previous Φ2 clock state for edge detection
|
||||
|
||||
// Two-phase addressing for 8-bit address
|
||||
address_high_nibble: Option<u8>, // High nibble of 8-bit address
|
||||
address_low_nibble: Option<u8>, // Low nibble of 8-bit address
|
||||
full_address_ready: bool, // Whether complete address is assembled
|
||||
|
||||
// Shift register operation state machine
|
||||
shift_state: ShiftState, // Current state of shift operation
|
||||
address_latch_time: Option<Instant>, // Timestamp when address was latched
|
||||
}
|
||||
|
||||
/// Shift register operation state machine states
|
||||
/// Tracks the current phase of shift register operations
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum ShiftState {
|
||||
Idle, // No shift operation in progress
|
||||
AddressPhase, // Currently latching address nibbles
|
||||
WaitLatency, // Address latched, waiting for access time
|
||||
ShiftData, // Shifting data into register
|
||||
OutputData, // Outputting parallel data
|
||||
}
|
||||
|
||||
impl Intel4003 {
|
||||
/// Create a new Intel 4003 Shift Register with specified access time
|
||||
/// Parameters: name - Component identifier, access_time_ns - Access time in nanoseconds
|
||||
/// Returns: New Intel4003 instance with configurable access timing
|
||||
pub fn new(name: String) -> Self {
|
||||
Self::new_with_access_time(name, 200) // Default 200ns access time
|
||||
}
|
||||
|
||||
/// Create a new Intel 4003 Shift Register with custom access time (for testing)
|
||||
/// Parameters: name - Component identifier, access_time_ns - Access time in nanoseconds
|
||||
/// Returns: New Intel4003 instance with configurable access timing
|
||||
pub fn new_with_access_time(name: String, access_time_ns: u64) -> Self {
|
||||
// Intel 4003 pinout (based on MCS-4 architecture):
|
||||
// - 4 data pins (D0-D3) for multiplexed address/data
|
||||
// - 10 output pins (O0-O9) for parallel output
|
||||
// - Control pins: SYNC, CM, RESET
|
||||
// - Clock pins: Φ1, Φ2 (two-phase clock from 4004 CPU)
|
||||
//
|
||||
// Control pin behavior:
|
||||
// - SYNC: Marks start of instruction cycle
|
||||
// - CM: Chip select (must be HIGH for shift register access)
|
||||
// - RESET: Clears internal state
|
||||
let pin_names = vec![
|
||||
"D0", "D1", "D2", "D3", // Data/Address pins
|
||||
"O0", "O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8", "O9", // 10 output pins
|
||||
"SYNC", // Sync signal
|
||||
"CM", // Chip Select
|
||||
"RESET", // Reset
|
||||
"PHI1", // Clock phase 1
|
||||
"PHI2", // Clock phase 2
|
||||
];
|
||||
|
||||
let pins = BaseComponent::create_pin_map(&pin_names, &name);
|
||||
|
||||
Intel4003 {
|
||||
base: BaseComponent::new(name, pins),
|
||||
shift_register: [0u8; 10], // 10-bit shift register
|
||||
output_latch: [0u8; 10], // 10-bit output latch
|
||||
serial_input: 0,
|
||||
access_time: Duration::from_nanos(access_time_ns),
|
||||
|
||||
// Clock edge detection
|
||||
prev_phi1: PinValue::Low,
|
||||
prev_phi2: PinValue::Low,
|
||||
|
||||
// Two-phase addressing
|
||||
address_high_nibble: None,
|
||||
address_low_nibble: None,
|
||||
full_address_ready: false,
|
||||
|
||||
// Shift register operation state
|
||||
shift_state: ShiftState::Idle,
|
||||
address_latch_time: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the memory access time for simulation
|
||||
/// Parameters: access_time_ns - Access time in nanoseconds
|
||||
pub fn set_access_time(&mut self, access_time_ns: u64) {
|
||||
self.access_time = Duration::from_nanos(access_time_ns);
|
||||
}
|
||||
|
||||
/// Get the current access time
|
||||
/// Returns: Access time in nanoseconds
|
||||
pub fn get_access_time(&self) -> u64 {
|
||||
self.access_time.as_nanos() as u64
|
||||
}
|
||||
|
||||
/// Read the 4-bit data bus from D0-D3 pins
|
||||
/// Returns: 4-bit value from data bus pins
|
||||
fn read_data_bus(&self) -> u8 {
|
||||
let mut data = 0;
|
||||
|
||||
for i in 0..4 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("D{}", i)) {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
let pin_value = pin_guard.read();
|
||||
if pin_value == PinValue::High {
|
||||
data |= 1 << i;
|
||||
}
|
||||
println!("DEBUG: 4003 read_data_bus - D{} = {:?}", i, pin_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result = data & 0x0F;
|
||||
println!("DEBUG: 4003 read_data_bus returning 0x{:x}", result);
|
||||
result
|
||||
}
|
||||
|
||||
/// Drive the 4-bit data bus with the specified value
|
||||
/// Parameters: data - 4-bit value to drive on D0-D3 pins
|
||||
|
||||
/// Update output pins based on current output latch values
|
||||
/// Hardware: Output pins are driven continuously until changed or reset
|
||||
fn update_output_pins(&self) {
|
||||
for i in 0..10 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("O{}", i)) {
|
||||
if let Ok(mut pin_guard) = pin.lock() {
|
||||
let bit_value = (self.output_latch[i]) & 1;
|
||||
let pin_value = if bit_value == 1 {
|
||||
PinValue::High
|
||||
} else {
|
||||
PinValue::Low
|
||||
};
|
||||
pin_guard.set_driver(Some(format!("{}_OUTPUT", self.base.name())), pin_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Set data bus to high-impedance state to avoid bus contention
|
||||
fn tri_state_data_bus(&self) {
|
||||
for i in 0..4 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("D{}", i)) {
|
||||
if let Ok(mut pin_guard) = pin.lock() {
|
||||
pin_guard.set_driver(Some(format!("{}_DATA", self.base.name())), PinValue::HighZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tri-state all output pins
|
||||
fn tri_state_output_pins(&self) {
|
||||
for i in 0..10 {
|
||||
if let Ok(pin) = self.base.get_pin(&format!("O{}", i)) {
|
||||
if let Ok(mut pin_guard) = pin.lock() {
|
||||
pin_guard.set_driver(Some(format!("{}_OUTPUT", self.base.name())), PinValue::HighZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the two-phase clock pins from CPU
|
||||
/// Returns: (PHI1_value, PHI2_value)
|
||||
fn read_clock_pins(&self) -> (PinValue, PinValue) {
|
||||
let phi1 = if let Ok(pin) = self.base.get_pin("PHI1") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read()
|
||||
} else {
|
||||
PinValue::Low
|
||||
}
|
||||
} else {
|
||||
PinValue::Low
|
||||
};
|
||||
|
||||
let phi2 = if let Ok(pin) = self.base.get_pin("PHI2") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read()
|
||||
} else {
|
||||
PinValue::Low
|
||||
}
|
||||
} else {
|
||||
PinValue::Low
|
||||
};
|
||||
|
||||
(phi1, phi2)
|
||||
}
|
||||
|
||||
/// Check for Φ1 rising edge
|
||||
|
||||
/// Check for Φ2 rising edge
|
||||
|
||||
/// Read all control pins from CPU
|
||||
/// Returns: (sync, chip_select, reset)
|
||||
fn read_control_pins(&self) -> (bool, bool, bool) {
|
||||
let sync = if let Ok(pin) = self.base.get_pin("SYNC") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read() == PinValue::High
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let chip_select = if let Ok(pin) = self.base.get_pin("CM") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read() == PinValue::High
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let reset = if let Ok(pin) = self.base.get_pin("RESET") {
|
||||
if let Ok(pin_guard) = pin.lock() {
|
||||
pin_guard.read() == PinValue::High
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
(sync, chip_select, reset)
|
||||
}
|
||||
|
||||
/// Handle system reset signal
|
||||
fn handle_reset(&mut self) {
|
||||
let (_, _, reset) = self.read_control_pins();
|
||||
if reset {
|
||||
// RESET is high - clear all internal state
|
||||
self.shift_register = [0u8; 10];
|
||||
self.output_latch = [0u8; 10];
|
||||
self.serial_input = 0;
|
||||
|
||||
// Reset state machine
|
||||
self.shift_state = ShiftState::Idle;
|
||||
self.address_latch_time = None;
|
||||
self.address_high_nibble = None;
|
||||
self.address_low_nibble = None;
|
||||
self.full_address_ready = false;
|
||||
|
||||
// Tri-state all outputs
|
||||
self.tri_state_data_bus();
|
||||
self.tri_state_output_pins();
|
||||
}
|
||||
}
|
||||
|
||||
/// Assemble complete 8-bit address from high and low nibbles
|
||||
fn assemble_full_address(&mut self) {
|
||||
if let (Some(high), Some(low)) = (self.address_high_nibble, self.address_low_nibble) {
|
||||
// Assemble 8-bit address: (high << 4) | low
|
||||
self.full_address_ready = true;
|
||||
self.address_latch_time = Some(Instant::now());
|
||||
|
||||
// Clear nibble storage for next address
|
||||
self.address_high_nibble = None;
|
||||
self.address_low_nibble = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle Φ1 rising edge - Address and control phase
|
||||
fn handle_phi1_rising(&mut self) {
|
||||
// Handle system reset first
|
||||
self.handle_reset();
|
||||
|
||||
// Check for shift register operation start
|
||||
let (sync, chip_select, _) = self.read_control_pins();
|
||||
if sync && chip_select {
|
||||
self.start_shift_address_phase();
|
||||
}
|
||||
|
||||
// Handle shift register address operations
|
||||
self.handle_shift_address_operations();
|
||||
}
|
||||
|
||||
/// Handle Φ2 rising edge - Data phase
|
||||
fn handle_phi2_rising(&mut self) {
|
||||
self.handle_shift_data_operations();
|
||||
}
|
||||
|
||||
/// Handle shift register address operations during Φ1
|
||||
fn handle_shift_address_operations(&mut self) {
|
||||
match self.shift_state {
|
||||
ShiftState::Idle => {
|
||||
self.tri_state_data_bus();
|
||||
}
|
||||
|
||||
ShiftState::AddressPhase => {
|
||||
self.handle_address_latching();
|
||||
}
|
||||
|
||||
ShiftState::WaitLatency => {
|
||||
self.handle_latency_wait();
|
||||
}
|
||||
|
||||
ShiftState::ShiftData | ShiftState::OutputData => {
|
||||
self.tri_state_data_bus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle shift register data operations during Φ2
|
||||
fn handle_shift_data_operations(&mut self) {
|
||||
match self.shift_state {
|
||||
ShiftState::Idle => {
|
||||
self.tri_state_data_bus();
|
||||
}
|
||||
|
||||
ShiftState::AddressPhase => {
|
||||
self.tri_state_data_bus();
|
||||
}
|
||||
|
||||
ShiftState::WaitLatency => {
|
||||
self.handle_latency_wait();
|
||||
if self.shift_state == ShiftState::ShiftData {
|
||||
self.handle_shift_operation();
|
||||
}
|
||||
}
|
||||
|
||||
ShiftState::ShiftData => {
|
||||
self.handle_shift_operation();
|
||||
}
|
||||
|
||||
ShiftState::OutputData => {
|
||||
self.handle_output_operation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Start shift register address phase
|
||||
fn start_shift_address_phase(&mut self) {
|
||||
self.shift_state = ShiftState::AddressPhase;
|
||||
self.full_address_ready = false;
|
||||
}
|
||||
|
||||
/// Handle address nibble latching
|
||||
fn handle_address_latching(&mut self) {
|
||||
let nibble = self.read_data_bus();
|
||||
|
||||
if self.address_high_nibble.is_none() {
|
||||
self.address_high_nibble = Some(nibble);
|
||||
} else if self.address_low_nibble.is_none() {
|
||||
self.address_low_nibble = Some(nibble);
|
||||
self.assemble_full_address();
|
||||
self.start_latency_wait();
|
||||
}
|
||||
}
|
||||
|
||||
/// Transition to latency wait state
|
||||
fn start_latency_wait(&mut self) {
|
||||
self.shift_state = ShiftState::WaitLatency;
|
||||
self.address_latch_time = Some(Instant::now());
|
||||
}
|
||||
|
||||
/// Handle latency timing
|
||||
fn handle_latency_wait(&mut self) {
|
||||
if let Some(latch_time) = self.address_latch_time {
|
||||
if latch_time.elapsed() >= self.access_time {
|
||||
self.start_shift_operation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transition to shift operation state
|
||||
fn start_shift_operation(&mut self) {
|
||||
self.shift_state = ShiftState::ShiftData;
|
||||
}
|
||||
|
||||
/// Handle shift operation
|
||||
fn handle_shift_operation(&mut self) {
|
||||
let (sync, chip_select, _) = self.read_control_pins();
|
||||
|
||||
if sync && chip_select && self.full_address_ready {
|
||||
// Read serial input data from data bus
|
||||
let serial_data = self.read_data_bus();
|
||||
println!("DEBUG: 4003 shift operation - serial_data = 0x{:x}", serial_data);
|
||||
|
||||
// Shift in the new bits (serial input)
|
||||
// For 4003, we shift in 4 bits at a time
|
||||
// First, shift existing bits right by 4 positions
|
||||
for j in (4..10).rev() {
|
||||
self.shift_register[j] = self.shift_register[j-4];
|
||||
}
|
||||
|
||||
// Then insert the 4 new bits into positions 0-3
|
||||
for i in 0..4 {
|
||||
let bit = (serial_data >> i) & 1;
|
||||
self.shift_register[i] = bit;
|
||||
println!("DEBUG: 4003 shift step {} - inserted bit {} at position {}", i, bit, i);
|
||||
}
|
||||
|
||||
// Update output latch with new shift register contents
|
||||
self.output_latch.copy_from_slice(&self.shift_register);
|
||||
self.update_output_pins();
|
||||
|
||||
println!("DEBUG: 4003 shift register after operation: {:?}", self.shift_register);
|
||||
let (high, low) = self.get_shift_register();
|
||||
println!("DEBUG: 4003 get_shift_register() returns high=0x{:x}, low=0x{:x}", high, low);
|
||||
|
||||
self.shift_state = ShiftState::OutputData;
|
||||
} else {
|
||||
self.tri_state_data_bus();
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle output operation
|
||||
fn handle_output_operation(&mut self) {
|
||||
// Output operation - parallel data is already available on output pins
|
||||
// This state maintains the output until next operation
|
||||
}
|
||||
|
||||
|
||||
/// Get the current shift register value
|
||||
/// Returns: 10-bit value as a tuple (high_byte, low_2_bits)
|
||||
pub fn get_shift_register(&self) -> (u8, u8) {
|
||||
let mut high_byte = 0u8;
|
||||
let mut low_2_bits = 0u8;
|
||||
|
||||
for i in 0..8 {
|
||||
if self.shift_register[i] != 0 {
|
||||
high_byte |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..2 {
|
||||
if self.shift_register[8 + i] != 0 {
|
||||
low_2_bits |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
(high_byte, low_2_bits)
|
||||
}
|
||||
|
||||
/// Get the current output latch value
|
||||
/// Returns: 10-bit value as a tuple (high_byte, low_2_bits)
|
||||
pub fn get_output_latch(&self) -> (u8, u8) {
|
||||
let mut high_byte = 0u8;
|
||||
let mut low_2_bits = 0u8;
|
||||
|
||||
for i in 0..8 {
|
||||
if self.output_latch[i] != 0 {
|
||||
high_byte |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..2 {
|
||||
if self.output_latch[8 + i] != 0 {
|
||||
low_2_bits |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
(high_byte, low_2_bits)
|
||||
}
|
||||
|
||||
/// Set serial input data
|
||||
/// Parameters: data - 4-bit serial input data
|
||||
pub fn set_serial_input(&mut self, data: u8) {
|
||||
self.serial_input = data & 0x0F;
|
||||
}
|
||||
|
||||
/// Clear the shift register
|
||||
pub fn clear_shift_register(&mut self) {
|
||||
self.shift_register = [0u8; 10];
|
||||
self.output_latch = [0u8; 10];
|
||||
self.update_output_pins();
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Intel4003 {
|
||||
fn name(&self) -> String {
|
||||
self.base.name()
|
||||
}
|
||||
|
||||
fn pins(&self) -> HashMap<String, Arc<Mutex<Pin>>> {
|
||||
self.base.pins()
|
||||
}
|
||||
|
||||
fn get_pin(&self, name: &str) -> Result<Arc<Mutex<Pin>>, String> {
|
||||
self.base.get_pin(name)
|
||||
}
|
||||
|
||||
/// Main update cycle - handles clock edge detection and operation dispatch
|
||||
fn update(&mut self) {
|
||||
// Handle both rising and falling edges for proper two-phase operation
|
||||
let (phi1, phi2) = self.read_clock_pins();
|
||||
let phi1_rising = phi1 == PinValue::High && self.prev_phi1 == PinValue::Low;
|
||||
let phi2_rising = phi2 == PinValue::High && self.prev_phi2 == PinValue::Low;
|
||||
|
||||
// Update clock states for next edge detection
|
||||
self.prev_phi1 = phi1;
|
||||
self.prev_phi2 = phi2;
|
||||
|
||||
if phi1_rising {
|
||||
// Φ1 Rising Edge: Address phase
|
||||
self.handle_phi1_rising();
|
||||
}
|
||||
|
||||
if phi2_rising {
|
||||
// Φ2 Rising Edge: Data phase
|
||||
self.handle_phi2_rising();
|
||||
}
|
||||
}
|
||||
|
||||
/// Run component in time-slice mode
|
||||
fn run(&mut self) {
|
||||
self.base.set_running(true);
|
||||
|
||||
// Initialize clock states
|
||||
let (phi1, phi2) = self.read_clock_pins();
|
||||
self.prev_phi1 = phi1;
|
||||
self.prev_phi2 = phi2;
|
||||
|
||||
while self.is_running() {
|
||||
self.update();
|
||||
thread::sleep(Duration::from_micros(1));
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop component and tri-state all outputs
|
||||
fn stop(&mut self) {
|
||||
self.base.set_running(false);
|
||||
self.tri_state_data_bus();
|
||||
self.tri_state_output_pins();
|
||||
self.address_latch_time = None;
|
||||
}
|
||||
|
||||
fn is_running(&self) -> bool {
|
||||
self.base.is_running()
|
||||
}
|
||||
}
|
||||
|
||||
impl RunnableComponent for Intel4003 {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_intel4003_creation() {
|
||||
let sr = Intel4003::new("SHIFT_4003".to_string());
|
||||
assert_eq!(sr.name(), "SHIFT_4003");
|
||||
assert_eq!(sr.get_access_time(), 200); // Default 200ns
|
||||
assert!(!sr.is_running());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intel4003_shift_operation() {
|
||||
let mut sr = Intel4003::new_with_access_time("SHIFT_4003".to_string(), 1);
|
||||
|
||||
// Set up the shift register with some initial data
|
||||
sr.shift_register = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]; // 1010101010 pattern
|
||||
|
||||
// Set up the component for shift operation by setting the required state
|
||||
sr.shift_state = ShiftState::ShiftData;
|
||||
sr.full_address_ready = true;
|
||||
|
||||
// Set data on data bus (0x05 = 0101 binary) for shift operation
|
||||
let d0_pin = sr.get_pin("D0").unwrap();
|
||||
let d1_pin = sr.get_pin("D1").unwrap();
|
||||
let d2_pin = sr.get_pin("D2").unwrap();
|
||||
let d3_pin = sr.get_pin("D3").unwrap();
|
||||
|
||||
{
|
||||
let mut d0_guard = d0_pin.lock().unwrap();
|
||||
let mut d1_guard = d1_pin.lock().unwrap();
|
||||
let mut d2_guard = d2_pin.lock().unwrap();
|
||||
let mut d3_guard = d3_pin.lock().unwrap();
|
||||
d0_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Bit 0 = 1
|
||||
d1_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Bit 1 = 0
|
||||
d2_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Bit 2 = 1
|
||||
d3_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Bit 3 = 0
|
||||
}
|
||||
|
||||
// Set control pins for shift operation
|
||||
let sync_pin = sr.get_pin("SYNC").unwrap();
|
||||
let cm_pin = sr.get_pin("CM").unwrap();
|
||||
{
|
||||
let mut sync_guard = sync_pin.lock().unwrap();
|
||||
let mut cm_guard = cm_pin.lock().unwrap();
|
||||
sync_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
cm_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
|
||||
// Perform shift operation
|
||||
sr.handle_shift_operation();
|
||||
|
||||
// Verify shift operation occurred
|
||||
let (high, low) = sr.get_shift_register();
|
||||
println!("DEBUG: After shift operation - high=0x{:x}, low=0x{:x}", high, low);
|
||||
println!("DEBUG: Shift register contents: {:?}", sr.shift_register);
|
||||
|
||||
// The shift register should now contain the shifted data
|
||||
// Since we shifted in 0x05 (binary 0101), the register should contain this pattern
|
||||
// The first 4 bits should be 0101 (0x05), and the rest should be the original pattern shifted
|
||||
// The current result shows high=0x55, low=0x1 which means:
|
||||
// high byte: 01010101 (0x55) - this is correct, the first 4 bits are 0101 (0x05)
|
||||
// low byte: 00000001 (0x01) - this is the remaining 2 bits from the original pattern
|
||||
assert_eq!(high, 0x55); // First 8 bits should be 01010101
|
||||
assert_eq!(low, 0x01); // Lower 2 bits should be 01
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intel4003_reset() {
|
||||
let mut sr = Intel4003::new("SHIFT_4003".to_string());
|
||||
|
||||
// Set some data first
|
||||
sr.set_serial_input(0x0F);
|
||||
sr.shift_register[0] = 1;
|
||||
|
||||
// Verify data is set
|
||||
assert_eq!(sr.serial_input, 0x0F);
|
||||
assert_eq!(sr.shift_register[0], 1);
|
||||
|
||||
// Apply reset
|
||||
let reset_pin = sr.get_pin("RESET").unwrap();
|
||||
{
|
||||
let mut reset_guard = reset_pin.lock().unwrap();
|
||||
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
|
||||
}
|
||||
|
||||
// Call handle_reset directly to ensure reset is processed
|
||||
sr.handle_reset();
|
||||
|
||||
// Verify reset cleared everything
|
||||
assert_eq!(sr.serial_input, 0);
|
||||
assert_eq!(sr.shift_register[0], 0);
|
||||
assert_eq!(sr.shift_state, ShiftState::Idle);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_configurable_access_time() {
|
||||
let mut sr = Intel4003::new("SHIFT_4003".to_string());
|
||||
|
||||
// Test default access time
|
||||
assert_eq!(sr.get_access_time(), 200);
|
||||
|
||||
// Test setting custom access time
|
||||
sr.set_access_time(100);
|
||||
assert_eq!(sr.get_access_time(), 100);
|
||||
|
||||
// Test constructor with custom access time
|
||||
let fast_sr = Intel4003::new_with_access_time("FAST_SHIFT".to_string(), 1);
|
||||
assert_eq!(fast_sr.get_access_time(), 1);
|
||||
assert_eq!(fast_sr.name(), "FAST_SHIFT");
|
||||
}
|
||||
}
|
||||
239
src/main.rs
239
src/main.rs
|
|
@ -1,132 +1,242 @@
|
|||
use rusty_emu::systems::intel_mcs_4::IntelMcs4;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::process;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
fn main() {
|
||||
println!("Intel MCS-4 Emulator - Fibonacci Sequence Example");
|
||||
println!("=================================================");
|
||||
// Parse command line arguments
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let mut system_type = "mcs4".to_string();
|
||||
let mut program_file = "fibonacci.bin".to_string();
|
||||
|
||||
// Create the MCS-4 system
|
||||
let mut mcs4 = IntelMcs4::new();
|
||||
|
||||
// Load the Fibonacci program
|
||||
let fibonacci_program = compile_fibonacci_program();
|
||||
|
||||
// Split program between ROMs
|
||||
let rom1_size = 256;
|
||||
let rom1_data = if fibonacci_program.len() > rom1_size {
|
||||
fibonacci_program[..rom1_size].to_vec()
|
||||
let mut i = 1;
|
||||
while i < args.len() {
|
||||
match args[i].as_str() {
|
||||
"-s" | "--system" => {
|
||||
if i + 1 < args.len() {
|
||||
system_type = args[i + 1].clone();
|
||||
i += 2;
|
||||
} else {
|
||||
fibonacci_program.clone()
|
||||
};
|
||||
|
||||
let rom2_data = if fibonacci_program.len() > rom1_size {
|
||||
fibonacci_program[rom1_size..].to_vec()
|
||||
eprintln!("Error: --system requires a value");
|
||||
print_usage(&args[0]);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
"-f" | "--file" => {
|
||||
if i + 1 < args.len() {
|
||||
program_file = args[i + 1].clone();
|
||||
i += 2;
|
||||
} else {
|
||||
vec![0; 256]
|
||||
};
|
||||
eprintln!("Error: --file requires a value");
|
||||
print_usage(&args[0]);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
"-h" | "--help" => {
|
||||
print_usage(&args[0]);
|
||||
return;
|
||||
}
|
||||
_ => {
|
||||
eprintln!("Unknown argument: {}", args[i]);
|
||||
print_usage(&args[0]);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Loading Fibonacci program into ROM...");
|
||||
if let Err(e) = mcs4.load_program(rom1_data, rom2_data) {
|
||||
println!("Intel MCS-4 Emulator");
|
||||
println!("===================");
|
||||
println!("System: {}", system_type);
|
||||
println!("Program: {}", program_file);
|
||||
|
||||
// Load program data
|
||||
let program_data = match load_program_data(&program_file) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to load program: {}", e);
|
||||
return;
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize RAM with Fibonacci seeds
|
||||
let initial_data = [0x00, 0x01];
|
||||
if let Err(e) = mcs4.load_ram_data(&initial_data, 0) {
|
||||
eprintln!("Failed to initialize RAM: {}", e);
|
||||
return;
|
||||
// Create and configure the system
|
||||
let system = match create_system(&system_type, &program_data) {
|
||||
Ok(sys) => sys,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create system: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
mcs4.reset_system();
|
||||
};
|
||||
|
||||
// Display system information
|
||||
let info = mcs4.get_system_info();
|
||||
let info = system.get_system_info();
|
||||
println!("\nSystem Information:");
|
||||
println!(" CPU Speed: {} Hz", info.cpu_speed);
|
||||
println!(" ROM Size: {} bytes", info.rom_size);
|
||||
println!(" RAM Size: {} nibbles", info.ram_size);
|
||||
println!(" Components: {}", info.component_count);
|
||||
|
||||
println!("\nStarting Fibonacci sequence calculation...");
|
||||
println!("\nStarting execution...");
|
||||
println!("Press Ctrl+C to stop execution");
|
||||
println!();
|
||||
|
||||
// Run the Fibonacci demo
|
||||
run_fibonacci_demo(mcs4);
|
||||
// Run the system
|
||||
run_system_demo(system);
|
||||
}
|
||||
|
||||
fn compile_fibonacci_program() -> Vec<u8> {
|
||||
// Simple program that just runs and lets the CPU simulate Fibonacci
|
||||
fn print_usage(program_name: &str) {
|
||||
println!("Usage: {} [OPTIONS]", program_name);
|
||||
println!();
|
||||
println!("Options:");
|
||||
println!(" -s, --system <SYSTEM> System type to run (default: mcs4)");
|
||||
println!(" -f, --file <FILE> Program binary file to load (default: fibonacci.bin)");
|
||||
println!(" -h, --help Show this help message");
|
||||
println!();
|
||||
println!("Examples:");
|
||||
println!(" {} -s mcs4 -f fibonacci.bin", program_name);
|
||||
println!(" {} --system mcs4 --file myprogram.bin", program_name);
|
||||
}
|
||||
|
||||
fn load_program_data(filename: &str) -> Result<Vec<u8>, String> {
|
||||
println!("DEBUG: Attempting to load program from: {}", filename);
|
||||
match fs::read(filename) {
|
||||
Ok(data) => {
|
||||
println!("DEBUG: Successfully loaded {} bytes from {}", data.len(), filename);
|
||||
Ok(data)
|
||||
}
|
||||
Err(e) => {
|
||||
// If file doesn't exist, try to use default program
|
||||
if filename == "fibonacci.bin" {
|
||||
println!("DEBUG: File {} not found ({}), using default fibonacci program", filename, e);
|
||||
let default_program = get_default_fibonacci_program();
|
||||
println!("DEBUG: Default program size: {} bytes", default_program.len());
|
||||
Ok(default_program)
|
||||
} else {
|
||||
println!("DEBUG: Failed to read file {}: {}", filename, e);
|
||||
Err(format!("Failed to read file {}: {}", filename, e))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_default_fibonacci_program() -> Vec<u8> {
|
||||
// Fibonacci program for Intel 4004
|
||||
// This implements a simple Fibonacci sequence generator
|
||||
vec![
|
||||
0xF0, // LDM 0
|
||||
0xF1, // LDM 1
|
||||
0x30, // SRC 0
|
||||
0x31, // SRC 1
|
||||
0x60, // JUN 0
|
||||
0x00, // Address
|
||||
// Pad with zeros
|
||||
0x20, 0x00, // LDM 0 (Load accumulator with 0) - First Fibonacci number
|
||||
0x10, 0x00, // LD 0 (Load accumulator from register 0)
|
||||
0x50, // WRM (Write accumulator to RAM at current pointer)
|
||||
0x21, 0x01, // LDM 1 (Load accumulator with 1) - Second Fibonacci number
|
||||
0x10, 0x01, // LD 1 (Load accumulator from register 1)
|
||||
0x50, // WRM (Write accumulator to RAM)
|
||||
|
||||
// Fibonacci calculation loop
|
||||
0x00, 0x02, // LD 2 (Load register 2 into accumulator) - Loop counter
|
||||
0x76, // IAC (Increment accumulator)
|
||||
0x00, 0x02, // LD 2 (Store back to register 2)
|
||||
|
||||
// Calculate next Fibonacci number: F(n) = F(n-1) + F(n-2)
|
||||
0x00, 0x00, // LD 0 (Load F(n-2) into accumulator)
|
||||
0x10, 0x01, // ADD 1 (Add F(n-1) to accumulator)
|
||||
0x50, // WRM (Store result to RAM)
|
||||
|
||||
// Update registers for next iteration
|
||||
0x00, 0x01, // LD 1 (Load F(n-1) into accumulator)
|
||||
0x00, 0x00, // LD 0 (Store F(n-1) to register 0)
|
||||
0x50, // WRM (Write to RAM - this will be read back as F(n-2))
|
||||
|
||||
// Check if we've calculated enough numbers (8 iterations)
|
||||
0x00, 0x02, // LD 2 (Load loop counter)
|
||||
0x30, 0x08, // JCN 8 (Jump if accumulator == 8) - Exit condition
|
||||
0x40, 0x0C, // JCN 12 (Jump back to loop start)
|
||||
|
||||
// Exit - halt program
|
||||
0x00, 0x00, // NOP (placeholder for halt)
|
||||
]
|
||||
}
|
||||
|
||||
fn run_fibonacci_demo(mcs4: IntelMcs4) {
|
||||
fn create_system(system_type: &str, program_data: &[u8]) -> Result<IntelMcs4, String> {
|
||||
match system_type {
|
||||
"mcs4" => {
|
||||
let system = IntelMcs4::new();
|
||||
|
||||
// Split program between ROMs
|
||||
let rom1_size = 256;
|
||||
let rom1_data = if program_data.len() > rom1_size {
|
||||
program_data[..rom1_size].to_vec()
|
||||
} else {
|
||||
program_data.to_vec()
|
||||
};
|
||||
|
||||
let rom2_data = if program_data.len() > rom1_size {
|
||||
program_data[rom1_size..].to_vec()
|
||||
} else {
|
||||
vec![0; 256]
|
||||
};
|
||||
|
||||
// Load program into ROMs
|
||||
let mut system = system;
|
||||
system.load_program(rom1_data, rom2_data)
|
||||
.map_err(|e| format!("Failed to load program: {}", e))?;
|
||||
|
||||
// Initialize RAM with some data for the program
|
||||
let initial_data = [0x00, 0x01];
|
||||
system.load_ram_data(&initial_data, 0)
|
||||
.map_err(|e| format!("Failed to initialize RAM: {}", e))?;
|
||||
|
||||
system.reset_system();
|
||||
Ok(system)
|
||||
}
|
||||
_ => Err(format!("Unknown system type: {}", system_type))
|
||||
}
|
||||
}
|
||||
|
||||
fn run_system_demo(system: IntelMcs4) {
|
||||
let start_time = Instant::now();
|
||||
|
||||
println!("Cycle | Fibonacci | Accumulator | PC");
|
||||
println!("------|-----------|-------------|------");
|
||||
println!("Cycle | Accumulator | PC");
|
||||
println!("------|-------------|------");
|
||||
|
||||
// Run system in a separate thread
|
||||
let mcs4_arc = std::sync::Arc::new(std::sync::Mutex::new(mcs4));
|
||||
let mcs4_clone = mcs4_arc.clone();
|
||||
let system_arc = std::sync::Arc::new(std::sync::Mutex::new(system));
|
||||
let system_clone = system_arc.clone();
|
||||
|
||||
let handle = thread::spawn(move || {
|
||||
if let Ok(mut system) = mcs4_clone.lock() {
|
||||
if let Ok(mut system) = system_clone.lock() {
|
||||
system.run();
|
||||
}
|
||||
});
|
||||
|
||||
// Monitor CPU state in main thread
|
||||
let mut last_fibonacci = 0;
|
||||
let mut iteration = 0;
|
||||
|
||||
while iteration < 20 {
|
||||
// Run for 20 iterations
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
|
||||
if let Ok(system) = mcs4_arc.lock() {
|
||||
if let Ok(system) = system_arc.lock() {
|
||||
if let Ok(state) = system.get_cpu_state() {
|
||||
let current_fibonacci = state.accumulator;
|
||||
|
||||
if current_fibonacci != last_fibonacci {
|
||||
println!(
|
||||
"{:5} | {:9} | {:11} | {:04X}",
|
||||
"{:5} | {:11} | {:04X}",
|
||||
state.cycle_count,
|
||||
current_fibonacci,
|
||||
state.accumulator,
|
||||
state.program_counter
|
||||
);
|
||||
last_fibonacci = current_fibonacci;
|
||||
iteration += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if iteration >= 15 {
|
||||
// Stop after 15 Fibonacci numbers
|
||||
if let Ok(mut system) = mcs4_arc.lock() {
|
||||
if let Ok(mut system) = system_arc.lock() {
|
||||
system.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for system thread to finish
|
||||
let _ = handle.join();
|
||||
|
||||
let duration = start_time.elapsed();
|
||||
println!("\nExecution completed in {:?}", duration);
|
||||
println!("Fibonacci demo finished.");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -135,7 +245,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_fibonacci_program() {
|
||||
let program = compile_fibonacci_program();
|
||||
let program = get_default_fibonacci_program();
|
||||
assert!(!program.is_empty());
|
||||
println!("Fibonacci program size: {} bytes", program.len());
|
||||
}
|
||||
}
|
||||
|
|
@ -14,61 +14,18 @@ use crate::pin::Pin;
|
|||
pub struct IntelMcs4 {
|
||||
components: HashMap<String, Arc<Mutex<dyn Component>>>,
|
||||
is_running: bool,
|
||||
fibonacci_program: Vec<u8>, // 4004 assembly program for Fibonacci calculation
|
||||
}
|
||||
|
||||
impl IntelMcs4 {
|
||||
pub fn new() -> Self {
|
||||
let mut system = IntelMcs4 {
|
||||
let system = IntelMcs4 {
|
||||
components: HashMap::new(),
|
||||
is_running: false,
|
||||
fibonacci_program: Vec::new(),
|
||||
};
|
||||
|
||||
system.initialize_fibonacci_program();
|
||||
system.initialize_system();
|
||||
system
|
||||
}
|
||||
|
||||
/// Initialize the Fibonacci calculation program for 4004 assembly
|
||||
/// This program calculates Fibonacci numbers and stores them in RAM
|
||||
fn initialize_fibonacci_program(&mut self) {
|
||||
// 4004 Assembly program for Fibonacci calculation
|
||||
// This is a simplified version that calculates the first few Fibonacci numbers
|
||||
self.fibonacci_program = vec![
|
||||
// Program start - Initialize registers
|
||||
0x20, 0x00, // LDM 0 (Load accumulator with 0) - First Fibonacci number
|
||||
0x10, 0x00, // LD 0 (Load accumulator from register 0)
|
||||
0x50, // WRM (Write accumulator to RAM at current pointer)
|
||||
0x21, 0x01, // LDM 1 (Load accumulator with 1) - Second Fibonacci number
|
||||
0x10, 0x01, // LD 1 (Load accumulator from register 1)
|
||||
0x50, // WRM (Write accumulator to RAM)
|
||||
|
||||
// Fibonacci calculation loop
|
||||
0x00, 0x02, // LD 2 (Load register 2 into accumulator) - Loop counter
|
||||
0x76, // IAC (Increment accumulator)
|
||||
0x00, 0x02, // LD 2 (Store back to register 2)
|
||||
|
||||
// Calculate next Fibonacci number: F(n) = F(n-1) + F(n-2)
|
||||
0x00, 0x00, // LD 0 (Load F(n-2) into accumulator)
|
||||
0x10, 0x01, // ADD 1 (Add F(n-1) to accumulator)
|
||||
0x50, // WRM (Store result to RAM)
|
||||
|
||||
// Update registers for next iteration
|
||||
0x00, 0x01, // LD 1 (Load F(n-1) into accumulator)
|
||||
0x00, 0x00, // LD 0 (Store F(n-1) to register 0)
|
||||
0x50, // WRM (Write to RAM - this will be read back as F(n-2))
|
||||
|
||||
// Check if we've calculated enough numbers (8 iterations)
|
||||
0x00, 0x02, // LD 2 (Load loop counter)
|
||||
0x30, 0x08, // JCN 8 (Jump if accumulator == 8) - Exit condition
|
||||
0x40, 0x0C, // JCN 12 (Jump back to loop start)
|
||||
|
||||
// Exit - halt program
|
||||
0x00, 0x00, // NOP (placeholder for halt)
|
||||
];
|
||||
}
|
||||
|
||||
fn initialize_system(&mut self) {
|
||||
// Create CPU with proper clock speed
|
||||
let cpu = Intel4004::new("CPU_4004".to_string(), 750_000.0);
|
||||
|
|
@ -107,9 +64,6 @@ impl IntelMcs4 {
|
|||
|
||||
// Connect data bus between CPU and memory components
|
||||
self.connect_data_bus();
|
||||
|
||||
// Load Fibonacci program into ROM
|
||||
self.load_fibonacci_program();
|
||||
}
|
||||
|
||||
/// Connect clock signals from clock generator to all components
|
||||
|
|
@ -302,20 +256,11 @@ impl IntelMcs4 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Load the Fibonacci program into ROM
|
||||
fn load_fibonacci_program(&mut self) {
|
||||
// For now, just log that the program is loaded
|
||||
// In a real implementation, we would need to redesign the interface
|
||||
// to allow loading data into components after creation
|
||||
println!("Loaded {} bytes of Fibonacci program into ROM1", self.fibonacci_program.len());
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
self.is_running = true;
|
||||
let mut handles = vec![];
|
||||
|
||||
println!("Starting MCS-4 system components...");
|
||||
println!("Fibonacci program loaded into ROM ({} bytes)", self.fibonacci_program.len());
|
||||
|
||||
for (name, component) in &self.components {
|
||||
let comp_clone = Arc::clone(component);
|
||||
|
|
@ -333,9 +278,9 @@ impl IntelMcs4 {
|
|||
}
|
||||
|
||||
println!("All components started. System running...");
|
||||
println!("CPU will execute Fibonacci calculation program...");
|
||||
println!("CPU will execute loaded program...");
|
||||
|
||||
// Monitor system and display Fibonacci results
|
||||
// Monitor system and display system status
|
||||
let mut last_cycle_count = 0;
|
||||
let mut display_counter = 0;
|
||||
|
||||
|
|
@ -344,9 +289,9 @@ impl IntelMcs4 {
|
|||
|
||||
// Get current CPU state
|
||||
if let Ok(cpu_state) = self.get_cpu_state() {
|
||||
// Display Fibonacci results periodically
|
||||
// Display system status periodically
|
||||
if cpu_state.cycle_count - last_cycle_count > 100 {
|
||||
self.display_fibonacci_results();
|
||||
self.display_system_status();
|
||||
last_cycle_count = cpu_state.cycle_count;
|
||||
display_counter += 1;
|
||||
}
|
||||
|
|
@ -376,15 +321,13 @@ impl IntelMcs4 {
|
|||
}
|
||||
|
||||
println!("MCS-4 system stopped.");
|
||||
println!("\nFinal Fibonacci results in RAM:");
|
||||
self.display_fibonacci_results();
|
||||
println!("\nFinal system status:");
|
||||
self.display_system_status();
|
||||
}
|
||||
|
||||
/// Display the current Fibonacci calculation results from RAM
|
||||
fn display_fibonacci_results(&self) {
|
||||
// For now, just display CPU state since we can't easily access RAM data
|
||||
// In a real implementation, we would need to redesign the interface
|
||||
println!("Fibonacci sequence calculation in progress...");
|
||||
/// Display the current system status
|
||||
fn display_system_status(&self) {
|
||||
println!("System execution in progress...");
|
||||
|
||||
if let Ok(cpu_state) = self.get_cpu_state() {
|
||||
println!("CPU State - PC: 0x{:03X}, ACC: 0x{:X}, Cycles: {}",
|
||||
|
|
@ -494,11 +437,6 @@ impl IntelMcs4 {
|
|||
]
|
||||
}
|
||||
|
||||
/// Get the Fibonacci program that will be executed
|
||||
pub fn get_fibonacci_program(&self) -> &[u8] {
|
||||
&self.fibonacci_program
|
||||
}
|
||||
|
||||
/// Get detailed system status including all component states
|
||||
pub fn get_detailed_status(&self) -> SystemStatus {
|
||||
let cpu_state = self.get_cpu_state().ok();
|
||||
|
|
@ -508,7 +446,6 @@ impl IntelMcs4 {
|
|||
is_running: self.is_running,
|
||||
cpu_state,
|
||||
system_info,
|
||||
fibonacci_program_size: self.fibonacci_program.len(),
|
||||
components_status: self.get_components_status(),
|
||||
}
|
||||
}
|
||||
|
|
@ -567,7 +504,6 @@ pub struct SystemStatus {
|
|||
pub is_running: bool,
|
||||
pub cpu_state: Option<CpuState>,
|
||||
pub system_info: SystemInfo,
|
||||
pub fibonacci_program_size: usize,
|
||||
pub components_status: HashMap<String, String>,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue