A browser-based Commodore 64 PRG disassembler
Drop any .prg file. Get byte-exact KickAssembler output, ready to build right away. No installation, no upload, 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
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. Two-stage loaders (depacker-in-depacker) are handled automatically.
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.
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.
Generates reassemblable ASM with proper KickAssembler v5.25+ syntax. A built-in verifier walks every line, reconstructs the machine code, and compares byte-by-byte. Mismatches are auto-corrected to .byte directives — binary accuracy guaranteed.
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.
Annotates common patterns: double IRQ stabilization, CIA interrupt disable sequences, Kernal ROM banking, and raster wait loops.
Color-coded ASM: labels, mnemonics, registers, numbers, strings, comments, illegal opcodes.
sub_ subroutines, irq_ handlers, dat_ data, txt_ strings. Cross-references show who calls what.
Finds text in data regions, formats as .text with correct PETSCII/screencode encoding.
Every .prg file goes through a five-stage pipeline. Each stage feeds the next, producing fully annotated, reassemblable KickAssembler output.
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 — If a packer signature is found, a full 6502 CPU emulator runs the decompression stub. The emulator includes memory banking, VIC-II raster counter, CIA timers, and page write tracking to capture the depacked result. Two-stage loaders (a depacker that unpacks another depacker) are detected and handled automatically.
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. 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.
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.
Tools that pack a PRG and prepend an intro/cracktro screen. The depacker handles these like any other packed format.
File joiners that combine multiple parts into a single PRG, often with compression.
Code protection and encryption wrappers.
Memory snapshots from Action Replay, Final Cartridge, and other freeze cartridges. Identified but not depacked.
Known C64 virus signatures. Detected and flagged during analysis.
.prg file onto the drop zone, or click Load Preset to pick a built-in C64 scene release..asm file.| 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. |
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).
.byte guarantees the output assembles to the exact same binary..byte preserves the original 3-byte encoding..pc → *=, .const → =, etc.).