# 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`](src/gui/mod.rs:1-259) The GUI is built using **eframe/egui** (Rust immediate mode GUI framework): ```rust use eframe::egui; ``` **Key Structure:** - [`GuiApp`](src/gui/mod.rs:21-29) - Main GUI application struct - `system: Option>>` - Thread-safe system reference - `gui_state: state::GuiState` - GUI state management - `components: components::GuiComponents` - Component container **Entry Point:** [`run_gui()`](src/gui/mod.rs:234-259) function launches the GUI ### 1.2 State Management **Location:** [`src/gui/state.rs`](src/gui/state.rs:1-176) **Key Structures:** | Structure | Purpose | Location | |-----------|---------|----------| | [`GuiState`](src/gui/state.rs:12-29) | Main UI state container | Lines 12-29 | | [`SystemInfo`](src/gui/state.rs:32-40) | System metadata display | Lines 32-40 | | [`ComponentStates`](src/gui/state.rs:43-49) | Component running states | Lines 43-49 | | [`MemoryState`](src/gui/state.rs:52-57) | RAM contents display | Lines 52-57 | | [`RegisterState`](src/gui/state.rs:60-67) | CPU register display | Lines 60-67 | **Current State Fields:** ```rust 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()`](src/gui/state.rs:100-118) ### 1.3 GUI Components **Location:** [`src/gui/components.rs`](src/gui/components.rs:1-804) | Component | Purpose | Location | |-----------|---------|----------| | [`GuiComponents`](src/gui/components.rs:72-84) | Component container | Lines 72-84 | | [`ControlPanel`](src/gui/components.rs:180-303) | Start/Stop/Reset buttons | Lines 180-303 | | [`MemoryViewer`](src/gui/components.rs:305-428) | RAM display | Lines 305-428 | | [`RegisterViewer`](src/gui/components.rs:430-574) | CPU registers display | Lines 430-574 | | [`RomLoader`](src/gui/components.rs:576-671) | ROM file loading | Lines 576-671 | | [`StatusBar`](src/gui/components.rs:673-804) | System status | Lines 673-804 | **Where to Add ROM Display:** - Create new `RomViewer` component similar to `MemoryViewer` - Add to [`GuiComponents`](src/gui/components.rs:72-84) struct - Render in [`render_gui()`](src/gui/mod.rs:171-185) ### 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:** - [`MemoryState.ram_contents`](src/gui/state.rs:54) exists but uses placeholder data - [`update_from_system()`](src/gui/state.rs:100-118) does NOT populate actual RAM data - Need to add RAM data extraction from Intel4002 components **CPU Register Status:** - [`RegisterState`](src/gui/state.rs:60-67) exists with all needed fields - [`update_from_system()`](src/gui/state.rs:100-118) does NOT populate actual CPU data - Need to add CPU data extraction from Intel4004 component --- ## 2. Console Output Analysis ### 2.1 Console Interface **Location:** [`src/gui/console.rs`](src/gui/console.rs:1-515) **Framework:** ratatui + crossterm (Terminal UI) **Key Structure:** ```rust pub struct ConsoleApp { system: Arc>, config: ConsoleConfig, running: bool, command_buffer: String, show_help: bool, selected_pane: usize, } ``` ### 2.2 Console Configuration **Location:** [`src/gui/console.rs:35-58`](src/gui/console.rs:35-58) ```rust 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`](configs/console_config.xml:1-45) ### 2.3 Current Console Display **RAM Display:** [`draw_ram_contents()`](src/gui/console.rs:472-505) - Currently shows placeholder data (`00` values) - Does NOT read actual RAM from Intel4002 **CPU Register Display:** [`draw_system_info()`](src/gui/console.rs:401-470) - 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()`](src/gui/console.rs:142-202) 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`](src/system_config.rs:1-629) **Key Structures:** | Structure | Purpose | Location | |-----------|---------|----------| | [`SystemConfig`](src/system_config.rs:58-67) | JSON system definition | Lines 58-67 | | [`ComponentConfig`](src/system_config.rs:70-75) | Component configuration enum | Lines 70-75 | | [`ConfigurableSystem`](src/system_config.rs:362-363) | Runtime system instance | Lines 362-428 | **Configuration Files:** - [`configs/mcs4_basic.json`](configs/mcs4_basic.json:1-167) - Basic MCS-4 system - [`configs/mcs4_max.json`](configs/mcs4_max.json) - Maximum configuration - [`configs/mcs4_io_demo.json`](configs/mcs4_io_demo.json) - I/O demonstration ### 3.2 Existing Configuration Options **JSON Configuration Structure:** ```json { "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`](src/gui/console.rs:35-58) ```rust 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`](configs/console_config.xml:1-45) ```xml true 16 hex ``` **Option 3: Create New DisplayConfig** structure for unified GUI/Console settings --- ## 4. Main Entry Point Analysis ### 4.1 Application Flow **Location:** [`src/main.rs`](src/main.rs:1-676) ```mermaid 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()`](src/main.rs:102-279) ```rust // 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:** - [`run()`](src/system_config.rs:380-428) - Start system - [`stop()`](src/system_config.rs:538-540) - Stop system - [`is_running()`](src/system_config.rs:542-544) - Check running state ### 4.4 Keyboard Input Handling **Console:** [`handle_key_event()`](src/gui/console.rs:142-202) **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()`](src/gui/console.rs:142) | Add Ctrl-Q detection | | GUI | [`GuiApp`](src/gui/mod.rs:21) update loop | Add keyboard shortcut | | Traditional | [`run_system_demo()`](src/main.rs:460) | Add terminal input thread | --- ## 5. Component Data Access Analysis ### 5.1 Intel 4004 CPU **Location:** [`src/components/cpu/intel_4004.rs`](src/components/cpu/intel_4004.rs:1-1602) **Register Access Methods:** | Method | Returns | Location | |--------|---------|----------| | [`get_accumulator()`](src/components/cpu/intel_4004.rs:1142-1144) | `u8` | Line 1142 | | [`get_carry()`](src/components/cpu/intel_4004.rs:1154-1156) | `bool` | Line 1154 | | [`get_program_counter()`](src/components/cpu/intel_4004.rs:1130-1132) | `u16` | Line 1130 | | [`get_register(index)`](src/components/cpu/intel_4004.rs:1191-1197) | `Option` | Line 1191 | | [`get_stack_pointer()`](src/components/cpu/intel_4004.rs:1160-1162) | `u8` | Line 1160 | | [`get_cycle_count()`](src/components/cpu/intel_4004.rs:1166-1168) | `u64` | Line 1166 | ### 5.2 Intel 4002 RAM **Location:** [`src/components/memory/intel_4002.rs`](src/components/memory/intel_4002.rs:1-1140) **Memory Access Methods:** | Method | Returns | Location | |--------|---------|----------| | [`read_ram_direct(addr)`](src/components/memory/intel_4002.rs:818-824) | `Option` | Line 818 | | [`get_io_port(port)`](src/components/memory/intel_4002.rs:842-848) | `Option` | Line 842 | | [`get_ram_size()`](src/components/memory/intel_4002.rs:810-813) | `usize` | Line 810 | ### 5.3 Intel 4001 ROM **Location:** [`src/components/memory/intel_4001.rs`](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:** ```rust // 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` - need downcasting to access type-specific methods. --- ## 6. Fibonacci Example Analysis ### 6.1 Program Files **Location:** [`programs/`](programs/) | File | Size | Purpose | |------|------|---------| | [`fibonacci.bin`](programs/fibonacci.bin) | 33 bytes | Basic Fibonacci (RAM only) | | [`fibonacci_output.bin`](programs/fibonacci_output.bin) | 55 bytes | Fibonacci with output ports | ### 6.2 Expected Behavior **From [`programs/README.md`](programs/README.md:7-13):** - 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`](src/gui/console.rs) **Changes Required:** 1. **Add ROM display method** (new ~50 lines after line 505): ```rust fn draw_rom_contents(&self, f: &mut Frame, area: Rect) { // Access ROM components and display contents } ``` 2. **Update RAM display** [`draw_ram_contents()`](src/gui/console.rs:472-505): - Add actual RAM data retrieval from Intel4002 - Use `read_ram_direct()` method 3. **Update CPU display** [`draw_system_info()`](src/gui/console.rs:401-470): - Add actual register retrieval from Intel4004 - Use getter methods: `get_accumulator()`, `get_program_counter()`, etc. 4. **Add component downcasting helper** (new method): ```rust fn get_cpu_state(&self) -> Option { ... } fn get_ram_state(&self) -> Option { ... } fn get_rom_state(&self) -> Option { ... } ``` ### 7.2 ROM/RAM/CPU Display - GUI **File:** [`src/gui/state.rs`](src/gui/state.rs) **Changes Required:** 1. **Extend `MemoryState`** (line 52-57): ```rust pub struct MemoryState { pub ram_contents: Vec<[u8; 4]>, pub rom_contents: Vec, // NEW: ROM data pub rom_address_range: (u16, u16), // NEW: Address range // ...existing fields } ``` 2. **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`](src/gui/components.rs) 3. **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`](src/gui/console.rs:35-58) **Extend `ConsoleConfig`:** ```rust 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`](configs/console_config.xml) **Add display options:** ```xml true true ``` ### 7.4 Ctrl-Q Keyboard Handling **Console - File:** [`src/gui/console.rs`](src/gui/console.rs:142) **Add in `handle_key_event()`:** ```rust 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`](src/gui/mod.rs:141) **Add in `update()` method:** ```rust // 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`](src/main.rs:460) **Add terminal input thread in `run_system_demo()`**: ```rust 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`](src/gui/console.rs:472) | `draw_ram_contents()` | Modify | | Console CPU display | [`src/gui/console.rs`](src/gui/console.rs:401) | `draw_system_info()` | Modify | | Console ROM display | [`src/gui/console.rs`](src/gui/console.rs:505) | New method | Add | | GUI state update | [`src/gui/state.rs`](src/gui/state.rs:100) | `update_from_system()` | Modify | | GUI ROM viewer | [`src/gui/components.rs`](src/gui/components.rs:428) | New component | Add | | Console config | [`src/gui/console.rs`](src/gui/console.rs:35) | `ConsoleConfig` | Extend | | XML config | [`configs/console_config.xml`](configs/console_config.xml) | Add display options | Extend | | Console Ctrl-Q | [`src/gui/console.rs`](src/gui/console.rs:142) | `handle_key_event()` | Modify | | GUI Ctrl-Q | [`src/gui/mod.rs`](src/gui/mod.rs:141) | `update()` | Modify | | Traditional Ctrl-Q | [`src/main.rs`](src/main.rs:460) | `run_system_demo()` | Modify | --- ## 9. Architecture Diagram ```mermaid 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`](src/gui/mod.rs:234) | 234-259 | | GUI State | [`src/gui/state.rs`](src/gui/state.rs:12) | 12-176 | | GUI Components | [`src/gui/components.rs`](src/gui/components.rs:72) | 72-804 | | Console Entry | [`src/gui/console.rs`](src/gui/console.rs:509) | 509-515 | | Console Config | [`src/gui/console.rs`](src/gui/console.rs:35) | 35-58 | | Console Keys | [`src/gui/console.rs`](src/gui/console.rs:142) | 142-202 | | System Config | [`src/system_config.rs`](src/system_config.rs:58) | 58-629 | | Main Entry | [`src/main.rs`](src/main.rs:102) | 102-279 | | CPU Getters | [`src/components/cpu/intel_4004.rs`](src/components/cpu/intel_4004.rs:1130) | 1130-1197 | | RAM Getters | [`src/components/memory/intel_4002.rs`](src/components/memory/intel_4002.rs:810) | 810-866 |