Skip to content

Architecture

Regenerator 2000 is an interactive disassembler for 8-bit Commodore computers (C64, C128, VIC-20, Plus/4, PET, 1541), written in Rust. It follows a unidirectional data flow architecture where user events modify the application state through commands, triggering re-analysis and re-rendering of the view.

High-Level Overview

flowchart TD
    subgraph bin [regenerator2000 Crate - CLI]
        Main[main.rs]
    end

    subgraph tui_crate [regenerator2000-tui Crate - TUI]
        Input[User Input]
        EventLoop[Event Loop]
        Widget[Active Widget<br/>View/Dialog]
        Renderer[TUI Renderer]
        UIState[UI State]
    end

    subgraph core_crate [regenerator2000-core Crate - Engine]
        Core[Core Hub]
        Action[AppAction]
        CommandSys[Command System]
        AppState[Application State]
        CoreViewState[Core View State]
        Analyzer[Code Analyzer]
        DisasmEngine[Disassembly Engine]
        ViceClient[VICE Client]
        MCPServer[MCP Server<br/>HTTP/Stdio]
        Unpacker[Binary Unpacker]
    end

    subgraph External [External Interface]
        MCPClient[MCP Client / AI Agent]
        VICE[VICE Emulator]
    end

    Main -->|Initializes| Core
    Main -->|Initializes| EventLoop
    Input -->|Handled by| Widget
    EventLoop -->|Drives| Renderer
    Widget -->|AppAction| Action
    Action -->|apply_action| Core

    MCPClient -->|Tools/Resources| MCPServer
    MCPServer -->|AppAction| Core
    MCPServer -.->|Read State| AppState

    Core -->|Dispatch| CommandSys
    Core -->|Direct Mutate| CoreViewState
    Core -->|UnpackStarted Event| EventLoop
    EventLoop -->|Spawns background| Unpacker
    Unpacker -.->|Loads unpacked PRG| AppState

    CommandSys -->|Apply/Undo| AppState

    AppState -->|Requests| DisasmEngine
    AppState -->|Triggers| Analyzer

    CoreViewState -.->|Embedded via Deref| UIState
    UIState -->|Provides Context| Renderer
    AppState -->|Provides Data| Renderer
    DisasmEngine -->|Generates Lines| Renderer

    VICE <-->|Binary Protocol| ViceClient
    ViceClient -.-> AppState

Workspace Structure

The project is organized as a Cargo workspace with three primary components:

  1. regenerator2000-core : The head-less engine. Contains all memory management, disassembly logic, CPU tables, analysis heuristics, cross-frontend view state, and the MCP server.
  2. regenerator2000-tui: The TUI library. Implements the ratatui widgets, event loop coordination, and theme system.
  3. regenerator2000 (root): The binary crate. Provides the CLI entry point, initializes the terminal, and links the core engine with the TUI frontend.

Core Components

1. Application State & Logic (regenerator2000-core/src/state/)

The core engine state, organized across multiple modules:

  • core.rs: The central Core hub. Orchestrates persistent state (AppState) and transient view state (CoreViewState). Frontends interact with it via apply_action().
  • app_state.rs : The main AppState struct that holds the runtime data hub. Contains the Undo Stack, Disassembly Cache, scopes, and connection state for VICE.
  • view_state.rs : Defines CoreViewState — the frontend-agnostic representation of cursor positions, selections, and active panes.
  • actions.rs : Defines the AppAction enum — semantic actions that any frontend (TUI, GUI, Web, MCP) can produce.
  • blocks.rs : Block management logic (Code, Data, Text, etc.) and memory layout queries.
  • disassembly.rs : Disassembly orchestration and line-index lookups.
  • file_io.rs : Loading and importing of various formats into AppState.
  • navigation.rs : Pure navigation helpers (jumping to addresses, creating save contexts) that operate on AppState + CoreViewState.
  • project.rs : The ProjectState struct — the persistent part of the state saved to .regen2000proj files (includes labels, comments, blocks, scopes, and enums).
  • settings.rs : Document-level settings (assembler, system, display preferences, fill run threshold).
  • search.rs : Centralized search logic (hex, text, PETSCII).
  • types.rs : Core type definitions used across the workspace (Addr, System, BlockType, Assembler, LabelType, etc.).
  • event.rs : Defines CoreEvent (state changes, dialog requests, status messages) and DialogType — the frontend-agnostic event vocabulary returned by Core::apply_action().

2. Disassembly Engine (regenerator2000-core/src/disassembler/)

Responsible for converting raw bytes into human-readable assembly code based on the state.

  • disassembler.rs : The main driver. It iterates through the raw data, respecting BlockType definitions, and produces a list of DisassemblyLines.
  • context.rs : The DisassemblyContext struct that bundles all data needed for a disassembly pass (binary data, block types, labels, comments, cross-refs, analysis hints, etc.).
  • handlers.rs : Helper functions for disassembling specific block types (e.g., data bytes, words, addresses, text, screencodes).
  • formatter.rs : A trait abstracting the differences between assembler syntaxes.
  • formatter_acme.rs : ACME assembler implementation.
  • formatter_64tass.rs : 64tass assembler implementation.
  • formatter_ca65.rs : ca65 (cc65 suite) assembler implementation.
  • formatter_kickasm.rs : KickAssembler implementation.

3. CPU Model (regenerator2000-core/src/cpu.rs)

Provides the domain model for the MOS 6502/6510 CPU.

  • Opcode: Definitions of all supported opcodes, including cycle counts, addressing modes, and descriptions.
  • AddressingMode: Enum defining the different addressing modes (Absolute, ZeroPage, Immediate, etc.). Used by both the Disassembler (to decode instructions) and the Analyzer (to understand control flow).

4. Command System (regenerator2000-core/src/commands.rs)

Implements the Command Pattern. Granular actions (e.g., SetBlockType, SetLabel) are encapsulated as Structs that know how to:

  • Apply: Execute the change on AppState.
  • Undo: Revert the change. This enables robust Undo/Redo functionality and ensures state consistency.

5. Analyzer (regenerator2000-core/src/analyzer.rs)

A heuristic engine that runs after state changes. It:

  • Traces code paths (following JMPs and branches).
  • Identifies referenced addresses.
  • Identifies and marks fill sequences based on the "Fill run threshold" setting.
  • Auto-generates labels (e.g., s_C000, j_0400, zpf_A0) based on usage context (subroutine, branch, jump, pointer, field). See Analysis — Label Prefixes for the complete prefix reference.

6. Parser (regenerator2000-core/src/parser/)

Handles importing various Commodore file formats and label files.

  • parser.rs : Module re-exports for all parser sub-modules.
  • prg.rs : Parser for standard Commodore PRG files (2-byte load address header). Also parses embedded BASIC SYS addresses to suggest entry points.
  • crt.rs : Parser for Commodore 64 cartridge (.crt) files with multi-bank chip selection.
  • d64.rs : Unified parser for D64 (35/40/42-track), D71 (70/80-track), and D81 disk image files. Supports file extraction from 1541/1571/1581 disk images.
  • t64.rs : Parser for T64 tape archive files.
  • dis65.rs : Parser for 6502bench SourceGen (.dis65) project files.
  • vice_lbl.rs : Parser for VICE label files (.lbl) for importing debug symbols.
  • vice_vsf.rs : Parser for VICE snapshot files (.vsf). Auto-detects the system from the VSF header.

These parsers allow Regenerator 2000 to load programs from multiple source formats (PRG, CRT, D64/D71/D81, T64, VSF, DIS65) and import debugging symbols from VICE emulator sessions.

7. Exporter (regenerator2000-core/src/exporter/)

Handles generation of complete, compilable source code and browsable HTML disassembly files.

  • asm.rs : Exports disassembly as a compilable assembly source file. Supports all four assembler formats (ACME, 64tass, ca65, KickAssembler) via the Formatter trait, and handles external-file (incbin) regions.
  • html.rs : Exports disassembly as a self-contained, syntax-highlighted HTML file with clickable cross-reference hyperlinks, light/dark theme toggle, and assembler-specific build instructions in the header. ExternalFile regions are written to separate linked HTML files.
  • verify.rs : Export→assemble→diff roundtrip verification. Exports ASM, invokes the real assembler binary, and byte-compares the output against the original binary to confirm disassembly correctness. Supports all four assemblers.

8. Binary Unpacker (regenerator2000-core/src/unpacker.rs)

Provides a accurate 6502 emulation sandbox to automatically decompress packed Commodore 64 programs.

  • Two-Phase Emulation: Simulates the packer's decryption stub (Phase 1) and runs the main decompression routine ( Phase 2), tracking memory writes to extract clean, decompressed program data.
  • Advanced Sandboxing: Intercepts Kernal and BASIC ROM vectors (such as GETIN, CHROUT, CLRSCR) to bypass I/O calls, prevent infinite loops, and handle sophisticated decompression stubs natively.
  • Background Execution: Runs asynchronously on a separate thread with real-time instruction counters sent to the TUI status bar for responsiveness during heavy unpacking jobs.

9. UI Architecture

The UI is built on crossterm and ratatui with a custom Widget trait abstraction.

pub trait Widget {
    fn render(&self, f: &mut Frame, area: Rect, app_state: &AppState, ui_state: &mut UIState);
    fn handle_input(&mut self, key: KeyEvent, app_state: &mut AppState, ui_state: &mut UIState) -> WidgetResult;
    // Default implementation returns WidgetResult::Ignored
    fn handle_mouse(&mut self, mouse: MouseEvent, app_state: &mut AppState, ui_state: &mut UIState) -> WidgetResult;
}

10. Theme System (regenerator2000-tui/src/theme.rs & [

theme_file.rs](https://github.com/ricardoquesada/regenerator2000/blob/main/crates/regenerator2000-tui/src/theme_file.rs))

Provides customizable color schemes for the UI.

  • theme.rs: Defines color palettes for different UI elements (dialogs, menus, status bar, syntax highlighting). Loads themes by name.
  • theme_file.rs : Parses TOML-based theme definition files (theme-*.toml). Built-in themes are embedded as assets; users can override or create custom themes by placing TOML files in the config directory.
  • Supports multiple built-in themes (Dracula, Nord, Catppuccin, Gruvbox, etc.).

11. Configuration (regenerator2000-core/src/config.rs)

Manages application-level configuration that persists across sessions.

  • SystemConfig: User preferences including:
  • Theme selection
  • View synchronization settings (sync hex dump, sprites, charset, bitmap, blocks with disassembly)
  • Auto-analyze toggle
  • Entropy threshold for analysis
  • Recent projects list
  • Update checking preference
  • Stored as config.toml in the OS-specific config directory (migrated from JSON in v0.9.13). Stored separately from project state to maintain user preferences across different projects.

12. Assets (regenerator2000-core/src/assets.rs)

Manages embedded system definition files (system-*.toml) and theme files (theme-*.toml). System files provide labels, comments, and exclude-address lists for each supported machine. Theme files define color palettes for the TUI. Both support user overrides from the config directory.

13. MCP Server (regenerator2000-core/src/mcp/)

Implements the Model Context Protocol (MCP) server for programmatic access to Regenerator 2000.

  • mod.rs : Module definition.
  • handler.rs : Core request handler implementing all MCP tools and resources. Routes tool calls to the appropriate AppState commands.
  • http.rs : HTTP transport using Server-Sent Events (SSE) on port 3000 for real-time communication.
  • stdio.rs : Stdio transport mode for headless subprocess MCP communication (e.g., Claude Desktop, Gemini CLI).
  • types.rs : Shared type definitions for MCP request/response structures.

The MCP server exposes tools and resources allowing AI agents to:

  • Tools: Manipulate disassembly (set labels, comments, block types), search memory, manage cross-references, save projects, and perform undo/redo operations.
  • Resources: Access binary data, disassembly views, hexdump views, and selected regions.

This enables collaborative human-AI workflows where both can work on the same project simultaneously (HTTP mode) or fully automated analysis sessions (stdio mode).

14. VICE Integration (regenerator2000-core/src/vice/)

Provides live debugging integration with the VICE emulator.

  • client.rs : ViceClient that manages the TCP connection to VICE's remote monitor, sending commands and receiving events.
  • protocol.rs : Defines ViceCommand and ViceMessage types for the VICE binary monitor protocol.
  • state.rs : ViceState tracking the debugger connection status, CPU registers, breakpoints, and run/stop state.
  • c64_hardware.rs : Vic2State and CiaState structs for reading and displaying C64 hardware register values during debugging.

15. Utilities (regenerator2000-tui/src/utils.rs & regenerator2000-core/src/utils.rs)

Contains shared helper functions and utilities used across the application, split between TUI and core logic.

Data Flow

  1. Input: User presses a key (e.g., C) or interacts with the mouse.
  2. Dispatch: regenerator2000-tui/src/events/input.rs routes the input to the active Widget.
  3. Action: The Widget processes the input and returns an AppAction (e.g., AppAction::Code).
  4. Core Application: The TUI calls Core::apply_action(action).
  5. Execution: Core converts the action into a Command (e.g., SetBlockType), pushes to the UndoStack, and applies it to AppState.
  6. Side Effects: Core executes the logic, potentially triggering analyzer.rs or regenerating the disassembly.
  7. Events: Core::apply_action returns a list of CoreEvents (e.g., StateChanged, DialogRequested).
  8. UI Sync: The TUI processes these events, updating UIState (opening dialogs, syncing cursors, setting status messages).
  9. Render: The main loop calls ui::draw(), which renders the TUI from the updated AppState and UIState.

Persistence

Projects are saved as JSON files (.regen2000proj).

  • Structure: Serializes the ProjectState struct.
  • Efficiency:
  • Raw data is gzip-compressed and base64-encoded to reduce file size.
  • Block types use run-length encoding to compress long sequences of the same type.
  • Scopes: Saved as start/end address pairs to represent named memory regions (.proc, .block, .namespace, etc).
  • Portability: Designed to be portable across different machines, storing relative paths where possible.
  • Session State: Cursor positions and view settings are saved with the project for seamless session restoration.