rusty_emu/plans/codebase_analysis.md

17 KiB

MCS-4 Emulator Codebase Analysis

Executive Summary

This document provides a comprehensive analysis of the MCS-4 emulator codebase structure, focusing on GUI, console output, configuration systems, and entry points. The analysis identifies specific locations for implementing ROM/RAM/CPU register display and Ctrl-Q keyboard handling.


1. GUI Structure Analysis

1.1 Framework and Architecture

Location: src/gui/mod.rs

The GUI is built using eframe/egui (Rust immediate mode GUI framework):

use eframe::egui;

Key Structure:

  • GuiApp - Main GUI application struct
    • system: Option<Arc<Mutex<ConfigurableSystem>>> - Thread-safe system reference
    • gui_state: state::GuiState - GUI state management
    • components: components::GuiComponents - Component container

Entry Point: run_gui() function launches the GUI

1.2 State Management

Location: src/gui/state.rs

Key Structures:

Structure Purpose Location
GuiState Main UI state container Lines 12-29
SystemInfo System metadata display Lines 32-40
ComponentStates Component running states Lines 43-49
MemoryState RAM contents display Lines 52-57
RegisterState CPU register display Lines 60-67

Current State Fields:

pub struct MemoryState {
    pub ram_contents: Vec<[u8; 4]>,  // 4 banks of RAM data
    pub selected_bank: usize,
    pub selected_address: usize,
}

pub struct RegisterState {
    pub accumulator: u8,
    pub carry_flag: bool,
    pub program_counter: u16,
    pub index_registers: [u8; 16],  // R0-R15
    pub stack_pointer: u8,
}

State Update Method: update_from_system()

1.3 GUI Components

Location: src/gui/components.rs

Component Purpose Location
GuiComponents Component container Lines 72-84
ControlPanel Start/Stop/Reset buttons Lines 180-303
MemoryViewer RAM display Lines 305-428
RegisterViewer CPU registers display Lines 430-574
RomLoader ROM file loading Lines 576-671
StatusBar System status Lines 673-804

Where to Add ROM Display:

1.4 Current Display Gaps

Missing ROM Display:

  • No ROM content viewer exists
  • Need to add ROM data retrieval from Intel4001 components

RAM Display Status:

CPU Register Status:


2. Console Output Analysis

2.1 Console Interface

Location: src/gui/console.rs

Framework: ratatui + crossterm (Terminal UI)

Key Structure:

pub struct ConsoleApp {
    system: Arc<Mutex<ConfigurableSystem>>,
    config: ConsoleConfig,
    running: bool,
    command_buffer: String,
    show_help: bool,
    selected_pane: usize,
}

2.2 Console Configuration

Location: src/gui/console.rs:35-58

pub struct ConsoleConfig {
    pub enabled: bool,
    pub refresh_rate_ms: u64,
    pub show_ram: bool,
    pub show_registers: bool,
    pub show_system_info: bool,
    pub ram_banks_per_row: usize,
    pub max_ram_rows: usize,
}

XML Config File: configs/console_config.xml

2.3 Current Console Display

RAM Display: draw_ram_contents()

  • Currently shows placeholder data (00 values)
  • Does NOT read actual RAM from Intel4002

CPU Register Display: draw_system_info()

  • Shows placeholder text: "see DEBUG output"
  • Does NOT read actual registers from Intel4004

ROM Display:

  • NOT implemented in console
  • Would need new draw_rom_contents() method

2.4 Input Handling

Location: handle_key_event()

Current key bindings:

  • q/Q/Esc - Quit
  • r/R - Run/Stop toggle
  • s/S - Stop
  • h/H - Help
  • Tab - Switch panes
  • Enter - Execute command

Ctrl-Q NOT currently handled - Need to add KeyCode::Char('q') with Ctrl modifier check


3. Configuration System Analysis

3.1 System Configuration

Location: src/system_config.rs

Key Structures:

Structure Purpose Location
SystemConfig JSON system definition Lines 58-67
ComponentConfig Component configuration enum Lines 70-75
ConfigurableSystem Runtime system instance Lines 362-428

Configuration Files:

3.2 Existing Configuration Options

JSON Configuration Structure:

{
  "name": "IntelMcs4",
  "description": "Basic MCS-4 System",
  "version": "1.0",
  "metadata": {
    "cpu_speed": 750000,
    "rom_count": 2,
    "ram_count": 1
  },
  "components": { ... },
  "connections": { ... }
}

3.3 Where Display Configuration Fits

Option 1: Extend ConsoleConfig in src/gui/console.rs:35-58

pub struct ConsoleConfig {
    // Existing fields...
    pub show_rom: bool,           // NEW: ROM display toggle
    pub rom_address_range: String, // NEW: ROM address range to display
    pub display_format: String,    // NEW: hex/decimal/ascii
}

Option 2: Extend XML Config configs/console_config.xml

<interface>
    <!-- Existing options -->
    <show_rom>true</show_rom>
    <rom_bytes_per_row>16</rom_bytes_per_row>
    <display_format>hex</display_format>
</interface>

Option 3: Create New DisplayConfig structure for unified GUI/Console settings


4. Main Entry Point Analysis

4.1 Application Flow

Location: src/main.rs

flowchart TD
    A[main] --> B[Parse CLI Args]
    B --> C{Mode?}
    C -->|--console| D[Launch Console]
    C -->|--gui| E[Launch GUI]
    C -->|default| F[Traditional Mode]
    D --> G[run_console]
    E --> H[run_gui]
    F --> I[run_system_demo]

4.2 Mode Selection

Location: main()

// Interface mode selection and launch
if use_console {
    // Launch interactive console interface
    let console_config = ConsoleConfig::default();
    run_console(system_arc, console_config)
} else if use_gui {
    // Launch graphical user interface
    run_gui(Some(system_arc))
} else {
    // Traditional mode
    run_system_demo(system)
}

4.3 System Start/Stop

ConfigurableSystem Methods:

4.4 Keyboard Input Handling

Console: handle_key_event()

GUI: Uses egui event system - no explicit keyboard handler

Traditional Mode: No keyboard handling (Ctrl+C only)

Where Ctrl-Q Fits:

Mode Location Implementation
Console handle_key_event() Add Ctrl-Q detection
GUI GuiApp update loop Add keyboard shortcut
Traditional run_system_demo() Add terminal input thread

5. Component Data Access Analysis

5.1 Intel 4004 CPU

Location: src/components/cpu/intel_4004.rs

Register Access Methods:

Method Returns Location
get_accumulator() u8 Line 1142
get_carry() bool Line 1154
get_program_counter() u16 Line 1130
get_register(index) Option<u8> Line 1191
get_stack_pointer() u8 Line 1160
get_cycle_count() u64 Line 1166

5.2 Intel 4002 RAM

Location: src/components/memory/intel_4002.rs

Memory Access Methods:

Method Returns Location
read_ram_direct(addr) Option<u8> Line 818
get_io_port(port) Option<u8> Line 842
get_ram_size() usize Line 810

5.3 Intel 4001 ROM

Location: src/components/memory/intel_4001.rs

Expected Methods (need verification):

  • ROM data read/access
  • I/O port access

5.4 Component Access Pattern

From ConfigurableSystem:

// Access components HashMap
let components = system.get_components();

// Get CPU
if let Some(cpu_component) = components.get("CPU_4004") {
    if let Ok(cpu) = cpu_component.lock() {
        // Access CPU methods - but need downcast to Intel4004
    }
}

Challenge: Components are stored as Box<dyn Component> - need downcasting to access type-specific methods.


6. Fibonacci Example Analysis

6.1 Program Files

Location: programs/

File Size Purpose
fibonacci.bin 33 bytes Basic Fibonacci (RAM only)
fibonacci_output.bin 55 bytes Fibonacci with output ports

6.2 Expected Behavior

From programs/README.md:

  • Calculates first 8 Fibonacci numbers
  • Results stored in RAM locations 0-7
  • fibonacci_output.bin also outputs to ports for visibility

6.3 Where Results Appear

RAM Locations: 0x00-0x07 (first 8 Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, 13)

Output Ports: Port values visible during execution with fibonacci_output.bin


7. Implementation Recommendations

7.1 ROM/RAM/CPU Display - Console

File: src/gui/console.rs

Changes Required:

  1. Add ROM display method (new ~50 lines after line 505):
fn draw_rom_contents(&self, f: &mut Frame, area: Rect) {
    // Access ROM components and display contents
}
  1. Update RAM display draw_ram_contents():

    • Add actual RAM data retrieval from Intel4002
    • Use read_ram_direct() method
  2. Update CPU display draw_system_info():

    • Add actual register retrieval from Intel4004
    • Use getter methods: get_accumulator(), get_program_counter(), etc.
  3. Add component downcasting helper (new method):

fn get_cpu_state(&self) -> Option<CpuState> { ... }
fn get_ram_state(&self) -> Option<RamState> { ... }
fn get_rom_state(&self) -> Option<RomState> { ... }

7.2 ROM/RAM/CPU Display - GUI

File: src/gui/state.rs

Changes Required:

  1. Extend MemoryState (line 52-57):
pub struct MemoryState {
    pub ram_contents: Vec<[u8; 4]>,
    pub rom_contents: Vec<u8>,  // NEW: ROM data
    pub rom_address_range: (u16, u16),  // NEW: Address range
    // ...existing fields
}
  1. Update update_from_system() (line 100-118):
    • Add actual CPU register retrieval
    • Add actual RAM data retrieval
    • Add ROM data retrieval

File: src/gui/components.rs

  1. Add RomViewer component (new ~100 lines after line 428):
    • Similar to MemoryViewer
    • Display ROM contents in hex grid

7.3 Display Configuration

File: src/gui/console.rs

Extend ConsoleConfig:

pub struct ConsoleConfig {
    // Existing...
    pub show_rom: bool,           // NEW
    pub display_refresh_rate: u64, // NEW
    pub address_format: String,    // NEW: hex/decimal
}

File: configs/console_config.xml

Add display options:

<display>
    <show_rom>true</show_rom>
    <show_rom_addresses>true</show_rom_addresses>
</display>

7.4 Ctrl-Q Keyboard Handling

Console - File: src/gui/console.rs

Add in handle_key_event():

KeyCode::Char('q') if key.modifiers.contains(KeyModifiers::CONTROL) => {
    self.running = false;
    if let Ok(mut system) = self.system.lock() {
        system.stop();
    }
}

GUI - File: src/gui/mod.rs

Add in update() method:

// Check for Ctrl-Q shortcut
if ui.input(|i| i.key_pressed(egui::Key::Q) && i.modifiers.ctrl) {
    ctx.send_viewport_cmd(egui::ViewportCommand::Close);
}

Traditional Mode - File: src/main.rs

Add terminal input thread in run_system_demo():

thread::spawn(move || {
    let stdin = std::io::stdin();
    for line in stdin.lock().lines() {
        if line.unwrap() == "\x11" { // Ctrl-Q
            *running.lock().unwrap() = false;
            break;
        }
    }
});

8. Summary of Required Changes

Task File Location Type
Console RAM display src/gui/console.rs draw_ram_contents() Modify
Console CPU display src/gui/console.rs draw_system_info() Modify
Console ROM display src/gui/console.rs New method Add
GUI state update src/gui/state.rs update_from_system() Modify
GUI ROM viewer src/gui/components.rs New component Add
Console config src/gui/console.rs ConsoleConfig Extend
XML config configs/console_config.xml Add display options Extend
Console Ctrl-Q src/gui/console.rs handle_key_event() Modify
GUI Ctrl-Q src/gui/mod.rs update() Modify
Traditional Ctrl-Q src/main.rs run_system_demo() Modify

9. Architecture Diagram

graph TB
    subgraph Entry
        main[main.rs]
    end
    
    subgraph Modes
        console[Console Mode]
        gui[GUI Mode]
        traditional[Traditional Mode]
    end
    
    subgraph Console Components
        console_app[ConsoleApp]
        console_config[ConsoleConfig]
        draw_ram[draw_ram_contents]
        draw_cpu[draw_system_info]
        handle_keys[handle_key_event]
    end
    
    subgraph GUI Components
        gui_app[GuiApp]
        gui_state[GuiState]
        gui_components[GuiComponents]
        mem_viewer[MemoryViewer]
        reg_viewer[RegisterViewer]
    end
    
    subgraph System
        config_sys[ConfigurableSystem]
        components[Component HashMap]
    end
    
    subgraph Hardware Components
        cpu[Intel4004 CPU]
        ram[Intel4002 RAM]
        rom[Intel4001 ROM]
    end
    
    main --> console
    main --> gui
    main --> traditional
    
    console --> console_app
    console_app --> draw_ram
    console_app --> draw_cpu
    console_app --> handle_keys
    
    gui --> gui_app
    gui_app --> gui_state
    gui_app --> gui_components
    gui_components --> mem_viewer
    gui_components --> reg_viewer
    
    console_app --> config_sys
    gui_state --> config_sys
    config_sys --> components
    components --> cpu
    components --> ram
    components --> rom

10. Key Code Locations Reference

Component File Key Lines
GUI Entry src/gui/mod.rs 234-259
GUI State src/gui/state.rs 12-176
GUI Components src/gui/components.rs 72-804
Console Entry src/gui/console.rs 509-515
Console Config src/gui/console.rs 35-58
Console Keys src/gui/console.rs 142-202
System Config src/system_config.rs 58-629
Main Entry src/main.rs 102-279
CPU Getters src/components/cpu/intel_4004.rs 1130-1197
RAM Getters src/components/memory/intel_4002.rs 810-866