Restore 64
A free browser-based Commodore 64 PRG disassembler
Drop any .prg file — packed, crunched, or plain. Restore 64 runs the depacker for real and delivers byte-exact KickAssembler output ready to build. No install. No server.
Open Disassembler →.pc = $0810 "Main" main: sei lda #$35 // RAM + I/O, ROMs off sta CPU_PORT lda #$7f sta CIA1_INT_CTRL // disable all CIA1 interrupts lda #<irq_0829 sta HW_IRQ_LO // set IRQ vector lda #>irq_0829 sta HW_IRQ_HI
Features
370+ Packers — Auto-Depack by Emulation
Doesn't guess the algorithm — runs the depacker as real 6502 code.
Recognizes ByteBoozer, Exomizer, PuCrunch, Time Cruncher, and hundreds more. A full 6502 CPU emulator runs the decompression stub with memory banking, VIC-II raster counter, and CIA timers. Double-crunched? No problem — the emulator keeps running through each stage until the real entry point is reached.
Multi-Phase Analysis
Multiple passes: control flow tracing, IRQ/NMI handler discovery, speculative disassembly, then a second pass to find additional handlers and jump tables in newly discovered code.
Smart Code Analysis
Traces execution from all entry points with register and flag state tracking. Discovers IRQ/NMI handlers, detects self-modifying code, finds inline data, jump tables, and RTS tricks.
Byte-Exact Output — Three Assembler Dialects
Choose your assembler: KickAssembler (v5.25+), ACME, or 64tass. Each dialect gets correct syntax, directives, and addressing mode notation. A built-in verifier reconstructs the machine code byte-by-byte — mismatches are auto-corrected to raw .byte directives. Binary accuracy guaranteed.
Hardware-Aware
Names all 250+ VIC-II, SID, CIA, and zero-page registers. Decodes bitfields in comments so you can see exactly what each hardware write does. Identifies stable raster routines, NOP slides, ROM banking, IRQ vector setup, and other C64 programming idioms.
C64 Idiom Recognition
Annotates common patterns: double IRQ stabilization, CIA interrupt disable sequences, Kernal ROM banking, and raster wait loops.
SID Player Identification
Recognizes 787 known SID player engines from the SIDID database — identifies the exact player and version used (JCH, Vibrants, GoatTracker, and hundreds more).
SID Music Detection
Finds SID music routines automatically — locates init and play addresses using IRQ vector analysis, register write patterns, and call graph tracing. Supports multi-tune programs with confidence scoring and SID data bounds detection.
Syntax Highlighting
Color-coded ASM: labels, mnemonics, registers, numbers, strings, comments, illegal opcodes.
Smart Labeling
sub_ subroutines, irq_ handlers, dat_ data, txt_ strings. Cross-references show who calls what.
PETSCII Strings
Finds text in data regions, formats as .text with correct PETSCII/screencode encoding.
Learn from the Legends
Get started with 300 top notch crack intros, fully disassembled
Ever wondered how Fairlight got those silky-smooth rasterbars? How Eagle Soft squeezed a full scroller, sprites and a SID tune into 4 KB? Now you can find out.
We ran the 300 most downloaded C64 crack intros through the disassembler and published every single line of source code — syntax-highlighted, with label navigation, and ready to learn from.
Free. No login. Just pure 6502 wizardry.
// Rasterbar IRQ handler irq_raster: ldx #$00 raster_loop: lda color_table,x // load rasterbar color sta $d020 // border sta $d021 // background ldy #$09 waste: dey bne waste // 45 cycles delay nop inx cpx #$20 // 32 lines bne raster_loop lda #$00 sta $d020 // restore black sta $d021
How It Works
Every .prg file goes through a five-stage pipeline. Each stage feeds the next, producing fully annotated, reassemblable output in your assembler dialect of choice.
Stage Details
Load — Parses the two-byte PRG load address header and extracts the binary data. Detects BASIC SYS stubs to find the entry point automatically.
Emulator — When a packer is detected, the decompression stub runs as genuine 6502 machine code — no static algorithm analysis, just execution. The emulator tracks every memory write and detects when the real program appears, even through multiple depack stages. Full Kernal and BASIC ROM support, memory banking, VIC-II raster counter, and CIA timers are all included.
Analyzer — Runs in multiple passes. First pass: traces code execution from all entry points (main, IRQ, NMI), discovers interrupt handlers, detects jump tables, RTS tricks, and self-modifying code. Then speculative disassembly scans untraced regions for hidden code blocks. A second pass re-scans for additional IRQ handlers, jump tables, and RTS tricks in newly discovered code. SID music routines are detected and matched against 787 known player signatures. Finally: PETSCII strings, sine tables, charsets, sprite data, and data patterns are classified.
Formatter — Generates KickAssembler-compatible ASM with .pc directives, .const definitions, labeled subroutines, hardware register names, bitfield comments, and C64 idiom annotations.
Verifier — Walks every emitted line, reconstructs the expected bytes, and compares against the original PRG. Any mismatch is auto-corrected to .byte directives, guaranteeing binary accuracy.
Supported Packers 370+ signatures
Restore 64 recognizes 370+ C64 packing, crunching, linking, and protection signatures. When a packed PRG is detected, the built-in 6502 emulator runs the decompression stub and captures the depacked binary for analysis. Multi-stage packing — files crunched twice or more — is handled automatically: the emulator simply keeps going until the original program surfaces.
Packers & Crunchers 284
Intro Coders 46
Tools that pack a PRG and prepend an intro/cracktro screen. The depacker handles these like any other packed format.
Linkers 16
File joiners that combine multiple parts into a single PRG, often with compression.
Protectors 12
Code protection and encryption wrappers.
Freeze Cartridge Saves 9
Memory snapshots from Action Replay, Final Cartridge, and other freeze cartridges. Identified but not depacked.
Virus Signatures 5
Known C64 virus signatures. Detected and flagged during analysis.
Documentation
Getting Started
- Open the disassembler in any modern browser.
- Load a file — drag a
.prgfile onto the drop zone, or click Load Preset to pick a built-in C64 scene release. - Adjust options (optional) — set entry point, data/code ranges, or comment verbosity in the sidebar.
- Click Disassemble — the Analysis Log streams results in real time: packer detection, entry points, IRQ handlers, statistics.
- View the output — switch to the Assembly Output tab to see the full KickAssembler ASM with syntax highlighting.
- Export — copy to clipboard or download the
.asmfile.
Options Reference
| Option | Default | Description |
|---|---|---|
| Entry point | auto | Override the detected start address (hex). Auto-detected from BASIC SYS stub or first code byte. |
| Data ranges | none | Force address ranges to be treated as data. Example: C000-CFFF. Comma-separated. |
| Code ranges | none | Force address ranges to be treated as code. Example: 1E00-1EFF. |
| Comments | Normal | Minimal: SMC refs only. Normal: + hardware names, bitfields, idioms. Verbose: + everything. |
| Decode illegal opcodes | On | Recognize undocumented 6502 opcodes. Always emitted as .byte for KickAssembler compatibility. |
| Detect PETSCII strings | On | Find and format printable text sequences in data regions as .text directives. |
| Verbose warnings | On | Show detailed warnings in the analysis log. |
| Auto-depack | On | Automatically detect and depack crunched/packed PRGs via 6502 emulation. |
| Data blocks at end | On | Group data sections after code in the output for cleaner layout. |
Understanding the Output
The ASM output uses standard KickAssembler v5.25+ syntax. Here's what to look for:
// ── Constants ──────────────────────────────────────── .const CPU_PORT = $01 // CPU port: memory config .const RASTER = $d012 // VIC: raster line low byte .const BORDER_COLOR = $d020 // VIC: border color // ── Code $0810-$0860 ───────────────────────────────── .pc = $0810 "Main" main: // Referenced by: jmp from $0870 sei lda #$35 // RAM + I/O, ROMs off sta CPU_PORT jsr sub_0840 sub_0840: // Referenced by: jsr from $0818 lda RASTER // VIC: current raster line cmp #$ff bne sub_0840 // wait for raster line $ff rts // ── Data $0870-$087F ───────────────────────────────── .pc = $0870 "Data" txt_0870: .text "HELLO WORLD" .byte $00 dat_087C: .fill 4, $ff
Labels are auto-generated by type: sub_ (subroutines), irq_ (IRQ handlers), nmi_ (NMI handlers), lbl_ (branch targets), dat_ (data blocks), txt_ (text strings).
Comments include hardware register descriptions, bitfield decoding (e.g. "$D011 bit 3 = 25-row mode"), cross-references ("Referenced by: jsr from $0820"), C64 idiom annotations, and self-modifying code warnings ("!SMC: modified by $0900").
.byte is used for raw data, illegal opcodes (KickAssembler uses different bytes for some), and absolute instructions targeting zero-page addresses (to prevent KickAssembler from optimizing to 2-byte ZP mode).
FAQ
Why are illegal opcodes emitted as .byte instead of mnemonics?
.byte guarantees the output assembles to the exact same binary.Why are some absolute instructions emitted as .byte?
.byte preserves the original 3-byte encoding.The packer isn't detected. What can I do?
Can I use the output with other assemblers?
.pc → *=, .const → =, etc.).