Architecture of Regenerator 2000
Regenerator 2000 is an interactive disassembler and reverse-engineering suite for 8-bit MOS 6502/6510 Commodore computers (Commodore 64, Commodore 128, VIC-20, Plus/4, C16, PET 2001, PET 4000/8000, 1541, 1571, and 1581), written in Rust.
The system is designed with a strict unidirectional data flow and a clean separation between a headless, multi-platform core engine and its frontends. User interactions, automated analysis pipelines, external debuggers, and AI agent integrations via the Model Context Protocol (MCP) all interact through a single, deterministic action-dispatch architecture.
1. High-Level Overview
flowchart TD
subgraph bin_crate [regenerator2000 Crate - CLI Application]
Main[main.rs<br/>CLI Parsing & Terminal Init]
end
subgraph tui_crate [regenerator2000-tui Crate - TUI Frontend]
EventLoop[Event Loop & Router<br/>events.rs / input.rs]
UIState[UIState<br/>Deref to CoreViewState]
WidgetSystem[Widget Trait System<br/>Disassembly / Views / Dialogs / Menu]
Renderer[Ratatui Renderer<br/>ui.rs / render.rs]
ThemeEngine[Theme Engine<br/>theme.rs / theme_file.rs]
end
subgraph core_crate [regenerator2000-core Crate - Headless Engine]
Core[Core Hub<br/>core.rs]
ActionHandlers[Action Handlers<br/>File / Disassembly / Debug / Navigation]
AppAction[AppAction Enum<br/>actions.rs]
CommandSys[Command Pattern & UndoStack<br/>commands.rs]
AppState[AppState<br/>Memory / Labels / CrossRefs / Settings]
AnnotationMap[AnnotationManager<br/>Sparse AddressEntry Metadata]
CoreViewState[CoreViewState<br/>Cursors / Panes / Modes / History]
Analyzer[Control-Flow Analyzer<br/>analyzer.rs]
DisasmEngine[Disassembly Pipeline<br/>symbols / data_blocks / handlers / formatter]
Parsers[Parser Suite<br/>PRG / CRT / D64 / T64 / VSF / SourceGen]
Exporters[Exporter Suite & Verify<br/>ASM / HTML / Roundtrip Diff]
UnpackerSandbox[6502 Emulation Sandbox<br/>bus / cia / engine / detector / 22+ packers]
MCPServer[MCP Server Suite<br/>HTTP SSE / Stdio / handler / tools]
ViceClient[VICE Monitor Client<br/>protocol / client / state / c64_hardware]
AssetsConfig[Assets & Config<br/>system-*.toml / enum-*.toml / config.toml]
end
subgraph External [External Interfaces & Tools]
MCPClient[MCP Client / AI Agent<br/>Claude Desktop / Cursor / Custom]
VICE[VICE Emulator<br/>Binary Monitor TCP Port 6502]
AssemblerBinaries[Assembler CLIs<br/>64tass / ACME / ca65 / KickAss]
CommodoreFiles[Binary Media<br/>.prg / .crt / .d64 / .d71 / .d81 / .t64 / .vsf]
end
%% Lifecycle & Initialization
Main -->|Initializes Engine| Core
Main -->|Spawns Threads & Runs| EventLoop
Main -->|Loads Files / Media| Parsers
CommodoreFiles -->|Decoded by| Parsers
Parsers -->|Populates Initial State| AppState
%% UI Flow
EventLoop -->|Routes Input Event| WidgetSystem
WidgetSystem -->|Emits Action| AppAction
AppAction -->|apply_action| Core
Core -->|Delegates via ActionContext| ActionHandlers
ActionHandlers -->|Applies / Undoes| CommandSys
ActionHandlers -->|Mutates View State| CoreViewState
CommandSys -->|Mutates State| AppState
AppState -->|Maintains Metadata| AnnotationMap
AppState -->|Triggers Analysis| Analyzer
AppState -->|Provides Data| DisasmEngine
DisasmEngine -->|Generates Formatted Lines| AppState
%% Rendering Flow
CoreViewState -.->|Embedded via Deref| UIState
UIState -->|Supplies View State| Renderer
AppState -->|Supplies Data| Renderer
ThemeEngine -->|Supplies Styles| Renderer
EventLoop -->|Drives Render Frame| Renderer
%% Background & External Integrations
Core -->|Emits UnpackStarted Event| EventLoop
EventLoop -->|Spawns Sandbox Thread| UnpackerSandbox
UnpackerSandbox -.->|Loads Unpacked Output| AppState
MCPClient <-->|JSON-RPC via HTTP SSE or Stdio| MCPServer
MCPServer -->|Dispatches AppAction| Core
MCPServer -.->|Inspects Engine State| AppState
VICE <-->|Binary Monitor Protocol| ViceClient
ViceClient <-->|Updates Live Registers/RAM| AppState
Exporters -->|Invokes Assemblers| AssemblerBinaries
AssemblerBinaries -->|Byte-Level Diff Verification| Exporters
2. Workspace & Crate Structure
Regenerator 2000 is organized as a Cargo workspace with a strictly decoupled tripartite architecture:
regenerator2000/
├── Cargo.toml # Workspace manifest
├── src/ # Binary crate (CLI entry point)
│ └── main.rs
├── crates/
│ ├── regenerator2000-core/ # Headless reverse-engineering engine
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── core.rs # Engine central hub
│ │ ├── action_handlers/ # Modular domain action dispatchers
│ │ ├── state/ # Domain models, metadata & persistence
│ │ ├── disassembler/ # Disassembly pipeline & formatters
│ │ ├── cpu.rs # MOS 6502/6510 opcode table & modes
│ │ ├── commands.rs # Command pattern & UndoStack
│ │ ├── analyzer.rs # Control-flow & symbol heuristics
│ │ ├── parser/ # Binary container & snapshot parsers
│ │ ├── exporter/ # Multi-assembler, HTML & roundtrip verification
│ │ ├── unpacker/ # 6502 sandbox depacker engine
│ │ ├── packers/ # 22+ binary packer detection strategies
│ │ ├── mcp/ # Model Context Protocol server (HTTP & Stdio)
│ │ ├── vice/ # Live VICE binary monitor client
│ │ ├── assets.rs # Embedded ROM definitions, system TOMLs & enums
│ │ ├── config.rs # System configuration persistence
│ │ ├── error.rs # Subsystem error hierarchy (thiserror)
│ │ ├── event.rs # CoreEvent & DialogType vocabularies
│ │ ├── navigation.rs # Address jump & bookmark helpers
│ │ ├── utils.rs # Shared string & formatting utilities
│ │ ├── view_state.rs # Frontend-agnostic CoreViewState
│ │ └── bin/
│ │ └── unpacker_compare_all.rs # Depacker benchmarking & comparison tool
│ └── regenerator2000-tui/ # Terminal User Interface frontend
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs
│ ├── events.rs # Main TUI event loop & background task coordination
│ ├── events/input.rs # Input router for keyboard and mouse
│ ├── ui.rs # Top-level Ratatui layout engine
│ ├── ui_state.rs # UIState wrapping CoreViewState via Deref
│ ├── theme.rs # Runtime color theme engine
│ ├── theme_file.rs # TOML theme file parser & dumper
│ └── ui/
│ ├── widget.rs # Widget trait & WidgetResult
│ ├── statusbar.rs # Dynamic bottom status bar
│ ├── minimap_bar.rs # Memory map visualization bar
│ ├── navigable.rs # Unified navigation trait
│ ├── graphics_common.rs # Shared glyph & bit-matrix renderers
│ ├── menu/ # Menu bar model, render & actions
│ ├── view_disassembly/ # Modular disassembly view (5 submodules)
│ ├── view_hexdump.rs # Hex dump view (8/16 column)
│ ├── view_sprites.rs # Sprite visualizer (1/2 column, mono/multicolor)
│ ├── view_charset.rs # Character set visualizer (4/8 column)
│ ├── view_bitmap.rs # Full bitmap visualizer (mono/multicolor)
│ ├── view_blocks.rs # Memory block overview list
│ ├── view_debugger.rs # Live VICE monitor register & RAM view
│ └── dialog_*.rs # 35+ modal dialog implementations
3. Subsystem Deep Dives
3.1 Central Hub & Domain Action Handlers
The engine interface is centered around
Core,
which unifies persistent domain state
(AppState)
and transient view state
(CoreViewState).
The Action Dispatch Pipeline
Frontends dispatch semantic
AppAction
enum variants to
Core::apply_action().
The hub performs document safety guards, unconfirmed destructive action checks
(spawning confirmation dialogs if dirty), and delegates execution to domain
handlers via
ActionContext<'a>:
pub struct ActionContext<'a> {
pub state: &'a mut AppState,
pub view: &'a mut CoreViewState,
pub events: &'a mut Vec<CoreEvent>,
}
The context provides
preserve_cursor(),
which captures the logical memory address at the active cursor line and
re-anchors the view cursor to that address after disassembly changes or
analysis recalculations.
Modular Action Handlers (action_handlers/)
The single-responsibility handlers implement
DomainActionHandler:
file_handler.rs: Project opening, saving, export generation (ASM/HTML), VICE label import/export, and binary unpacking initialization.disassembly_handler.rs: Memory block type reclassification (Code,Byte,Word,Address,Text,Screencode,LoHi,HiLo,ExternalFile), user comments (inline side comments and preceding line comments), label assignments, immediate operand formatting overrides, routine scope creation/removal, splitter toggling, and enum usage.debug_handler.rs: VICE monitor TCP connection, execution control (Step, Step Over, Step Out, Continue, Run to Cursor), and hardware breakpoint/watchpoint management.navigation_handler.rs: Address jumps, operand target tracking, history stack navigation (Back/Forward), bookmark management, symbol searches, and cross-reference inspection.
Domain Errors & Events
error.rs: Structured hierarchy usingthiserror.CoreErroraggregates subsystem error types:UnpackError,ExportError,ViceError,ProjectError, and genericParseFailed. TheIoResultExttrait enriches raw standard I/O errors with exact file path context (with_path).event.rs: Defines frontend-agnostic event emissions:CoreEvent(StateChanged,ViewChanged,StatusMessage,DialogRequested(DialogType),DialogDismissalRequested,QuitRequested,OpenUrl,UnpackStarted,StartMcpServerRequested,StopMcpServerRequested) and 30+ modalDialogTyperequests.view_state.rs: ImplementsCoreViewStateholding active panes (ActivePane), right-pane mode (RightPane), cursor indices, visual selection boundaries, scroll offsets, navigation history stacks, and search queries.
3.2 Application State & Memory Domain (state/)
Persistent project state is encapsulated in
AppState:
pub struct AppState {
pub schema_version: u32,
pub file_path: Option<PathBuf>,
pub project_path: Option<PathBuf>,
pub raw_data: Vec<u8>,
pub disassembly: Vec<DisassemblyLine>,
pub cached_arrows: Vec<CachedArrow>,
pub origin: Addr,
pub entry_point: Option<Addr>,
pub entropy: Option<f32>,
pub block_types: Vec<BlockType>,
pub labels: BTreeMap<Addr, Vec<Label>>,
pub settings: DocumentSettings,
pub annotations: AnnotationManager,
pub cross_refs: BTreeMap<Addr, Vec<Addr>>,
pub enums: BTreeMap<String, EnumDefinition>,
pub user_global_enums: BTreeMap<String, EnumDefinition>,
pub builtin_enums: BTreeMap<String, EnumDefinition>,
pub system_config: SystemConfig,
pub undo_stack: UndoStack,
pub last_saved_pointer: usize,
pub user_excluded_addresses: BTreeSet<Addr>,
pub collapsed_blocks: Vec<(usize, usize)>,
pub splitters: BTreeSet<Addr>,
pub vice_state: ViceState,
pub vice_client: Option<ViceClient>,
pub mcp_server_running: bool,
// ...
}
Sparse Address Metadata (annotations.rs)
Rather than maintaining fragmented, parallel address-keyed tables, all
per-address metadata is consolidated into
AnnotationManager.
Each address maps to an
AddressEntry:
- system_comment: Auto-loaded ROM/system comment (transient).
- user_side_comment: Inline trailing comment (persisted).
- user_line_comment: Preceding block/line comment (persisted).
- immediate_format: Operand representation override (Hex, InvertedHex,
Decimal, NegativeDecimal, Binary, InvertedBinary, LowByte(Addr),
HighByte(Addr)).
- bookmark: User bookmark label (persisted).
- scope: Routine scope parent boundary address (persisted).
- enum_usage: Named enumeration reference (persisted).
AnnotationManager enforces automatic whitespace normalization, prunes empty
entries, and uses Serde flattening (#[serde(flatten)]) to maintain 100%
backward and forward compatibility with legacy .regen2000proj JSON project
schemas.
Domain Types (types.rs)
TargetSystem: Zero-cost machine discriminator enum (C64,C128,Vic20,Pet20,Pet40,Plus4,C16,C1541,C1571,C1581,Custom(Box<str>)). Defines architecture parameters: RAM start, default BASIC entry, screen RAM range, hardware I/O boundaries, and ROM vector locations.Addr: Transparent 16-bit address newtype (pub struct Addr(pub u16)). Implements wrapping 16-bit 6502 address bus arithmetic, hex formatting, and transparent JSON number serialization.BlockType: Classification enum (Code,DataByte,DataWord,Address,PetsciiText,ScreencodeText,LoHiAddress,HiLoAddress,LoHiWord,HiLoWord,ExternalFile,Undefined).Assembler: Supported export targets (Tass64,Acme,Ca65,Kick).
3.3 Disassembly Pipeline & Assembler Formatting Suite (disassembler/)
The disassembly engine transforms raw binary memory into structured, formatted assembly lines.
raw_data + block_types + annotations + symbols
│
▼
┌───────────────────────────┐
│ DisassemblyContext │ (Pre-computes scope ends for O(log S) checks)
└─────────────┬─────────────┘
│
▼
┌───────────────────────────┐
│ disassemble_ctx() │ (pipeline.rs decoding loop)
└─────────────┬─────────────┘
│
┌─────────────┴────────────────────────┐
▼ ▼
[Code Instruction] [Data Block Formatter]
pipeline.rs / handlers.rs data_blocks.rs
(Opcode lookup & operand format) (Bytes, Words, Text, Fill runs)
│ │
└─────────────┬────────────────────────┘
│
▼
┌───────────────────────────┐
│ Formatter Trait │ (64tass / ACME / ca65 / KickAss)
└─────────────┬─────────────┘
│
▼
Vec<DisassemblyLine> (Renderable & Exportable rows)
context.rs:DisassemblyContextbundles references to memory buffers, block types, label tables, cross-references, settings, and annotations. It pre-computes sorted scope boundaries into a vector for $O(\log S)$ binary search virtual splitter validation.pipeline.rs: Orchestrates the main disassembly iteration, emits label definition header lines, and processes instructions throughdisassemble_code_instruction.symbols.rs: Resolves symbol priority precedence (LabelKind::User>LabelKind::System>LabelKind::Auto), formats local labels (.local_label), resolves routine scope paths (compute_scope_names), and identifies instruction target addresses.data_blocks.rs: Decodes non-code regions: single/multi-byte hex tables (.byte), 16-bit words (.word), address tables, PETSCII/Screencode strings, split Lo/Hi and Hi/Lo address tables (<table, >table), external binary includes (.incbin), and fill runs (.fill).handlers.rs: Implements operand decoding across all 13 6502 addressing modes.formatter.rs& Assembler Formatters:formatter_64tass.rs: 64tass syntax (.byte,.word,.text,.fill,.binclude,* = $ADDR).formatter_acme.rs: ACME syntax (!byte, !16,!pet,!fill,!binary,* = $ADDR).formatter_ca65.rs: ca65 syntax (.byte,.word,.res,.incbin,.org $ADDR).formatter_kickasm.rs: KickAssembler syntax (.byte,.word,.text,.fill,.import binary,* = $ADDR).
3.4 MOS 6502/6510 CPU Model (cpu.rs)
The CPU model provides an exhaustive specification of all 256 opcode bytes
for the MOS 6502/6510 microprocessor:
- Opcode: Represents mnemonic, addressing mode, instruction length in
bytes (1–3), base cycle timing, descriptive metadata, and illegal/undocumented
flag.
- AddressingMode: Enum covering all 13 addressing modes: Implied,
Accumulator, Immediate, ZeroPage, ZeroPageX, ZeroPageY, Relative,
Absolute, AbsoluteX, AbsoluteY, Indirect, IndirectX, IndirectY.
- Undocumented Opcodes: Full support for undocumented/illegal 6502 opcodes
(LAX, SAX, DCP, ISC, SLO, RLA, SRE, RRA, ALR, ANC, ARR,
AXS, NOP aliases, KIL/JAM). When the document setting
use_illegal_opcodes is disabled, illegal opcodes are treated as raw data
bytes.
3.5 Command Pattern & Undo/Redo Engine (commands.rs)
All state mutations in Regenerator 2000 are modeled as atomic, reversible commands implementing the Command Pattern:
pub enum Command {
SetBlockType { range: Range<usize>, new_type: BlockType, old_types: Vec<BlockType> },
SetLabel { address: Addr, new_label: Option<Vec<Label>>, old_label: Option<Vec<Label>> },
SetAnalysisData { labels: BTreeMap<Addr, Vec<Label>>, cross_refs: BTreeMap<Addr, Vec<Addr>>, old_labels: BTreeMap<Addr, Vec<Label>>, old_cross_refs: BTreeMap<Addr, Vec<Addr>> },
SetUserSideComment { address: Addr, new_comment: Option<String>, old_comment: Option<String> },
SetUserLineComment { address: Addr, new_comment: Option<String>, old_comment: Option<String> },
ChangeOrigin { new_origin: Addr, old_origin: Addr },
SetImmediateFormat { address: Addr, new_format: Option<ImmediateFormat>, old_format: Option<ImmediateFormat> },
CollapseBlock { range: (usize, usize) },
UncollapseBlock { range: (usize, usize) },
ToggleSplitter { address: Addr },
ImportLabels { new_labels: Vec<(Addr, Label)>, old_labels: BTreeMap<Addr, Vec<Label>> },
AddScope { start: Addr, end: Addr, old_end: Option<Addr> },
RemoveScope { address: Addr, old_end: Addr },
SetBookmark { address: Addr, new_name: Option<String>, old_name: Option<String> },
SetUserExcludedAddress { address: Addr, add: bool, old_labels: BTreeMap<Addr, Vec<Label>>, old_cross_refs: BTreeMap<Addr, Vec<Addr>> },
SetEnumUsage { address: Addr, new_enum: Option<String>, old_enum: Option<String> },
SetEnumDefinition { name: String, new_definition: Option<EnumDefinition>, old_definition: Option<EnumDefinition> },
Batch(Vec<Command>),
}
UndoStack: Manages the undo/redo history, tracking a pointer relative to the last saved state (is_dirty()comparison).apply(&mut self, state: &mut AppState): Executes the mutation and invalidates downstream caches.undo(&mut self, state: &mut AppState): Reverts the modification cleanly.- Atomic Batches:
Command::Batchgroups multiple operations (such as multi-address label updates or whole-file analysis results) into a single undo step.
3.6 Control-Flow & Heuristic Analyzer (analyzer.rs)
The analyzer performs automated reverse-engineering passes over the memory buffer to discover subroutines, jump targets, data references, and consecutive fill sequences:
[Raw Program Memory]
│
▼
Recursive Control-Flow Tracing ──► JSR / Bxx / JMP / RTS / RTI graph
│
▼
Operand Symbol Classification ──► Usage count & semantic role resolution
│
▼
Auto-Label Generation ──────────► Prefix assignment (s_, j_, b_, p_, etc.)
│
▼
Cross-Reference Construction ───► Inverted index (target -> [referencing addrs])
│
▼
Fill Run Detection ─────────────► Consecutive byte sequences >= threshold
Auto-Generated Label Prefixes
Labels are generated deterministically based on instruction usage context and address width:
| Prefix | Category | Semantics |
|---|---|---|
s_ |
Subroutine | Target of a JSR instruction (e.g. s_C000). |
j_ |
Jump Target | Target of an absolute JMP instruction (e.g. j_0400). |
b_ |
Branch Target | Target of relative conditional branch instructions (BEQ, BNE, BCC, BCS, BPL, BMI, BVC, BVS). |
r_ |
Return Target | Target of a branch/jump whose first instruction is RTS or RTI (mirrors IDA Pro locret_). |
p_ |
Pointer | 16-bit address referenced by non-flow instructions (e.g. p_1000). |
zpp_ |
Zero-Page Pointer | Zero-page address used in indirect addressing modes (($zp),Y or ($zp,X)). |
f_ |
Field | Absolute memory location read or written by data instructions. |
zpf_ |
Zero-Page Field | Zero-page location read or written by data instructions. |
a_ |
Absolute Address | Target in an address table or external memory reference. |
zpa_ |
Zero-Page Absolute | Zero-page address embedded in an address table. |
e_ |
External Jump | Jump target located outside the loaded binary memory range. |
3.7 Parser Suite (parser/)
The parser suite handles importing raw files, container formats, and debug symbol files:
prg.rs: Standard Commodore PRG files (extracts 2-byte little-endian load address header and raw binary payload).basic.rs: Tokenized Commodore BASIC V2 header analyzer. EvaluatesSYSentry points, including parenthesized arguments and arithmetic expressions (e.g.,SYS 2048+16).crt.rs: C64 cartridge images (.crt). Parses cartridge hardware types, chip packet headers (CHIP), bank numbers, load addresses, and ROM sizes with bank selection dialogs.d64.rs: Unified floppy disk parser supporting D64 (35, 40, and 42-track images with error info), D71 (double-sided 70/80 tracks), and D81 (80 tracks x 40 sectors 1581 format). Traverses Track/Sector chains and extracts PRG files.t64.rs: Tape container parser (.t64). Decodes tape headers, record entries, and container metadata.dis65.rs: Imports 6502bench SourceGen project definitions (.dis65), restoring labels, comments, and block types.vice_lbl.rs: Parses VICE monitor symbol/label files (al C:0810 .label_name).vice_vsf.rs: Parses VICE snapshot files (.vsf). Auto-detects machine architecture (C64, C128, VIC-20, Plus/4, PET, C1541) and restores full RAM dumps and CPU register states.
3.8 Exporter Suite & Roundtrip Verification (exporter/)
asm.rs: Generates complete, compilable assembly files for all 4 supported assembler formats (64tass, ACME, ca65, KickAssembler). Emits build headers, origin directives, symbol scopes, local labels, external file includes (incbin), and enum value substitutions.html.rs: Exports self-contained, interactive HTML disassembly. Features full syntax highlighting, hyperlinked cross-references (jump to definition / jump to reference), dark/light theme switching, and external file sub-pages.verify.rs: Automated Roundtrip Verification Engine. Exports disassembly, invokes the actual assembler binary CLI (64tass,acme,ca65/ld65,kickass), and performs byte-for-byte binary diffing against the original input binary. Ensures zero-regression disassembly correctness.
3.9 6502 Sandbox Binary Unpacker & Packer Strategies (unpacker/ & packers/)
Many Commodore 64 executables are compressed with custom crunchers/packers.
Regenerator 2000 embeds a cycle-accurate 6502 emulation sandbox based on the
unp64 decompression algorithm:
[Packed Input PRG]
│
▼
[Packer Signature Scanner] ──► detect_packer() matches known signature
│
▼
[Phase 1: Depacker Locator] ──► Emulate 6502 from SYS entry until PC < ReturnAddr
│
▼
[Phase 2: Decompression Execution] ──► Emulate depacker stub until PC jumps back
│
▼
[Detector & Memory Diffing] ──► Snapshot diffing & trailing cluster trimming
│
▼
[Unpacked Output PRG + Entry Point]
bus.rs:C64Bus(UnpackerMemory) implements the full 64 KB memory bus, $00/$01 processor port banking, and safe checked ROM lookups.cia.rs:CiaStateprovides MOS 6526 CIA 1 and CIA 2 timer emulation for depackers that synchronize on timer interrupts.engine.rs:UnpackEnginedrives the 2-phase 6502 execution loop with step hooks and ROM trap interception.detector.rs: Compares post-execution RAM snapshots against initial memory, identifying memory boundaries and trimming trailing garbage.- Packer Strategy Pattern
(
packers/): ModularPackertrait implementations (info,pre_emulate,on_step,post_emulate) supporting 22+ commercial and demoscene packer formats: action_replay,alz64,antiram,byteboozer,card_cruncher,ccs,cruel_cruncher,dali,eagle,eca,exomizer,final_cartridge,mc_cracken,pucrunch,simple,super_cruncher,tbc,time_cruncher,tiny_crunch,triad,tscrunch,turbo_cruncher.- Benchmarking CLI
(
src/bin/unpacker_compare_all.rs): Regression test harness comparing Regenerator 2000's unpacker against referenceunp64binaries across hundreds of test samples.
3.10 Model Context Protocol (MCP) Server (mcp/)
Regenerator 2000 implements a full Model Context Protocol (MCP 2024-11-05) server, enabling AI agents (Claude Desktop, Cursor, Gemini CLI) to inspect, query, and refactor disassemblies programmatically:
- Transports:
http.rs: Streamable HTTP transport with Server-Sent Events (SSE) (default port 3000) for network or local agent connectivity.stdio.rs: Headless standard I/O loop for CLI-based subagent integration.- Request Dispatcher
(
handler.rs): Decodes JSON-RPC requests, handlinginitialize,ping,tools/list,resources/list,resources/read, andtools/call. - Tool Catalogs
(
mcp/tools/): analysis_tools.rs:get_disassembly,get_disassembly_lines,get_memory_region,get_entropy,get_cross_references,get_symbols,get_address_details,get_system_info,search_disassembly,search_memory,get_file_info.navigation_tools.rs:navigate_to_address,get_cursor_position.modification_tools.rs:set_block_type,set_label,remove_label,set_comment,set_immediate_format,toggle_splitter,add_scope,remove_scope,apply_enum,set_enum_definition.session_tools.rs:save_project,undo,redo,batch_execute,unpack_binary.common.rs: Parameter extraction, validation, and JSON-RPC error construction (make_mcp_error).
3.11 VICE Emulator Live Debugger Integration (vice/)
Provides bi-directional live debugging with the VICE emulator:
- client.rs:
Manages non-blocking TCP socket communication with the VICE binary monitor
(default port 6502) and spawns an asynchronous reader thread.
- protocol.rs:
Implements packet framing (0x02 start byte, command types, request IDs,
body lengths, and error codes). Encodes command packets (REGISTERS_GET,
REGISTERS_SET, MEMORY_GET, MEMORY_SET, CHECKPOINT_SET,
CHECKPOINT_GET, CHECKPOINT_DELETE, CHECKPOINT_LIST, CHECKPOINT_TOGGLE,
ADVANCE_INSTRUCTIONS, EXECUTE_UNTIL_RETURN, PING).
- state.rs:
Tracks connection state, CPU register snapshots (PC, A, X, Y, SP, Flags
NV-BDIZC), changed register highlights (rendered in yellow), execution
status, and active breakpoints/watchpoints (BreakpointKind::Exec, Load,
Store, LoadStore).
- c64_hardware.rs:
Decodes I/O block memory snapshots ($D000–$DFFF) into live VIC-II, SID, and
CIA register displays in the Debugger view.
3.12 Asset Management & Configuration (assets.rs, config.rs)
assets.rs: Embeds system definition files (system-c64.toml,system-c128.toml,system-vic20.toml,system-plus4.toml,system-c16.toml,system-pet2001.toml,system-pet4000.toml,system-1541.toml,system-1571.toml,system-1581.toml), theme files (theme-*.toml), and hardware register enums (enum-*.toml). Supports exporting embedded assets to user directories via CLI dump flags (--dump-system-config-files,--dump-theme-files,--dump-enum-files).config.rs: Manages persistent user preferences (config.tomlin~/.config/regenerator2000/), storing assembler preferences, default systems, theme selections, view synchronization flags, update check preferences, and recent project paths.
3.13 TUI Frontend Architecture (regenerator2000-tui)
The terminal user interface is built on ratatui and crossterm:
┌─────────────────────────────────────────────────────────────┐
│ Menu Bar (File, Edit, View, Navigate, Tools, Help) │
├──────────────────────────────┬──────────────────────────────┤
│ │ Right Pane (Toggleable) │
│ │ - Hex Dump (8/16 Col) │
│ Disassembly View │ - Sprite Matrix (1/2 Col) │
│ (Primary Left Pane) │ - Charset Matrix (4/8 Col) │
│ - Virtual Row Indexing │ - Bitmap Visualizer │
│ - Syntax Colored Tokens │ - Memory Block Overview │
│ - Control-Flow Arrows │ - Live VICE Monitor Debugger │
│ - Collapsible Code Blocks │ │
│ │ │
├──────────────────────────────┴──────────────────────────────┤
│ Minimap Bar (Memory Block Distribution Overview) │
├─────────────────────────────────────────────────────────────┤
│ Status Bar (Address, Opcodes, Mode, Progress, Status) │
└─────────────────────────────────────────────────────────────┘
[ Modal Dialog Overlay: Settings, Search, Labels, Pickers ]
WidgetTrait (ui/widget.rs): All UI views and dialogs implement the unified component trait: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; fn handle_mouse(&mut self, mouse: MouseEvent, app_state: &mut AppState, ui_state: &mut UIState) -> WidgetResult { WidgetResult::Ignored } fn handle_tick(&mut self, _app_state: &mut AppState, _ui_state: &mut UIState) -> WidgetResult { WidgetResult::Ignored } }UIStateComposition (ui_state.rs):UIStatewraps the core engine'sCoreViewStateviaDeref/DerefMut, adding TUI-specific runtime fields (active modal dialog stack, menu popup states, RatatuiListStateinstances, image pickers, and click bounding boxes).- Modular Disassembly View
(
ui/view_disassembly/): mod.rs: Widget facade implementing theWidgettrait.layout.rs: Computes visual row heights, collapsed block spans, and bidirectional mappings between visual screen lines and disassembly line indices.navigation.rs: Cursor stepping, viewport scrolling, page scrolling, visual selection, and address pinning.mouse.rs: Mouse wheel scrolling, single-click row positioning, double-click operand navigation or label editing, and drag selection.render.rs: High-performance Ratatui rendering pipeline formatting addresses, bytes, labels, mnemonics, operands, comments, and control-flow arrow glyphs.- Specialized Right-Pane Views:
view_hexdump.rs: 8-column and 16-column hex dump with PETSCII and Screencode decoding and synchronized cursor tracking.view_sprites.rs: 24x21 sprite visualizer supporting single-column and 2-column layouts in monochrome and multicolor modes.view_charset.rs: 8x8 character set visualizer supporting 4-column and 8-column layouts in monochrome and multicolor modes.view_bitmap.rs: 320x200 standard and 160x200 multicolor bitmap graphics visualizer with configurable Screen RAM mapping (AfterBitmaporBankOffset).view_blocks.rs: Structured overview of all memory blocks, their classifications, ranges, sizes, and collapsed states.view_debugger.rs: Live VICE monitor debugging console displaying CPU registers, changed flags, disassembled instructions around PC, stack page ($0100–$01FF), I/O registers, memory dump window, and active breakpoints.- Menu System
(
ui/menu/): menu_model.rs: Menu structure, shortcuts, and dynamic item enablement based on document and pane state.menu_render.rs: Renders top menu bar and active drop-down popup boxes.menu_action.rs: Converts menu activations intoAppActions and processes emittedCoreEvents (opening dialogs, launching threads).- Theme Engine
(
theme.rs,theme_file.rs): Full 24-bit TrueColor and 256-color TOML theme support with built-in presets (Default, C64 Blue, Green Monochrome, Amber Monochrome, Cyberpunk, Solarized Dark, Nord, Dracula, Monokai, Gruvbox) and user theme file loading.
4. End-to-End Data Flow & Reactive Cycles
4.1 Interactive User Action in TUI (e.g. Block Type Reclassification)
1. User Input: User presses 'C' in Disassembly View to mark bytes as Code.
2. Routing: events.rs routes KeyEvent to active DisassemblyView widget.
3. Action Creation: DisassemblyView returns
WidgetResult::Action(AppAction::Code).
4. Menu Dispatcher: dispatch_menu_action() invokes
Core::apply_action(AppAction::Code).
5. Domain Handler: Core routes action to
DisassemblyActionHandler::handle_action().
6. Context Setup: Handler captures cursor address via
ActionContext::preserve_cursor().
7. Command Execution: Handler constructs Command::SetBlockType and calls
UndoStack::apply().
8. State Mutation: AppState::block_types is updated; UndoStack records previous
types.
9. Downstream Analysis: Disassembly cache is invalidated; analyzer::analyze()
recalculates symbols.
10. Event Emission: Core emits CoreEvent::StateChanged.
11. UI Sync: TUI syncs CoreViewState to UIState; preserve_cursor() restores
visual row.
12. Render Frame: Event loop invokes ui::draw(), rendering updated disassembly
with syntax highlighting.
4.2 AI Agent / MCP Server Invocation (e.g. Setting a Label)
1. Client Request: External AI Agent sends JSON-RPC POST 'tools/call'
("set_label", {address: 0x0810, name: "init"}).
2. Transport Handling: mcp::http or mcp::stdio decodes JSON-RPC payload.
3. Handler Router: mcp::handler dispatches request to
modification_tools::handle_set_label().
4. Action Dispatch: Tool constructs AppAction::SetLabel and invokes
Core::apply_action().
5. Command Execution: DisassemblyActionHandler applies Command::SetLabel onto
AppState.
6. Reactive Invalidation: State updates labels; disassembly cache updates;
analyzer generates cross-refs.
7. Response Construction: MCP handler builds JSON-RPC success response
confirming label creation.
8. Transport Reply: Response is sent back over HTTP SSE stream or Stdio pipe.
9. TUI Coordination (if running): Event loop receives AppEvent::Mcp and
redraws TUI asynchronously.
4.3 Background Binary Unpacker Sandbox Lifecycle
1. Trigger: User loads packed binary or selects "Unpack Binary".
2. Action Dispatch: Core emits CoreEvent::UnpackStarted with binary buffer
and UnpackConfig.
3. Thread Spawn: TUI event loop spawns a background OS thread running
unpacker::unpack().
4. 6502 Emulation:
a. Signature scanner identifies packer format (e.g. Exomizer).
b. Phase 1 emulates 6502 instructions from SYS address until PC reaches
depacker loop.
c. Phase 2 emulates depacker execution until decompression finishes.
d. Periodically emits AppEvent::UnpackProgress to update the TUI status bar.
5. Completion Event: Background thread posts AppEvent::UnpackComplete(result)
to main event channel.
6. Result Handling: Event loop invokes handle_unpack_complete(), loading
unpacked bytes into AppState.
7. Context Dialog: TUI opens ImportContextDialog, allowing the user to
review origin and entry point.
4.4 Live VICE Monitor Synchronization
1. Connection: ViceClient connects to VICE binary monitor TCP socket on port
6502.
2. Background Reader: Async reader thread parses incoming binary response
frames (magic 0x02).
3. Event Bridge: Packets are converted into AppEvent::Vice and forwarded to the
TUI event channel.
4. State Update:
- Registers response (0x01) -> updates ViceState::registers (A, X, Y, SP, PC,
Flags).
- Memory response (0x02) -> updates ViceState::live_memory (disassembly
window around PC) and stack.
- Checkpoint hit (0x11/0x12) -> sets ViceState::stop_reason and triggers
debugger flash countdown.
5. UI Sync: DebuggerView renders updated registers with changed values
highlighted in yellow.
5. Persistence & Serialization Model
Projects are saved as .regen2000proj JSON documents, designed for version
stability, deterministic diffs, and small file sizes:
{
"version": 1,
"origin": 2049,
"raw_data_base64": "H4sIC...",
"blocks": [
{ "start": 0, "end": 12, "type_": "Code", "collapsed": false },
{ "start": 13, "end": 100, "type_": "DataByte", "collapsed": false }
],
"labels": {
"2049": [ { "name": "start", "label_type": "Subroutine", "kind": "User" } ]
},
"side_comments": { "2049": "Initialize VIC-II" },
"line_comments": { "2049": "Main Program Entry Point" },
"immediate_formats": { "2052": "Hex" },
"bookmarks": { "2049": "Entry" },
"scopes": { "2049": 2100 },
"enums": {},
"settings": {
"assembler": "Tass64",
"system": "Commodore 64",
"use_illegal_opcodes": true
},
"user_excluded_addresses": [ 53280, 53281 ]
}
Key Persistence Characteristics
- Gzip + Base64 Raw Data: The original binary is compressed using gzip
(
flate2) and encoded in Base64 (raw_data_base64), keeping project files compact. - Run-Length Encoded Blocks: Contiguous memory regions sharing a
BlockTypeare serialized as start/end offset ranges. - Flattened Sparse Metadata:
AnnotationManageris serialized using#[serde(flatten)]. All per-address properties (side comments, line comments, bookmarks, scopes, immediate formats) are emitted as top-level JSON objects, maintaining 100% backward compatibility with early project schemas while internally managed in a single sparse structure. - Deterministic Serialization: All address-keyed maps use
BTreeMapandBTreeSet, guaranteeing consistent, sorted JSON keys across save cycles and enabling clean Git diffs. - Version Migration: Projects declare a numeric
version. When newer formats are introduced,AppState::migrate_project()upgrades legacy schemas automatically.