Commodore 64: emulator, BASIC, assembler and debugger
A Commodore 64 in your browser — the cycle-stepped chips emulator in WebAssembly, booting the free MEGA65 Open ROMs (or your own). Run PRG, D64, T64 and TAP files; type and save BASIC; write 6502 assembly and run it, or call it from BASIC with SYS; and debug anything that runs with breakpoints beside the code, stepping, registers, memory, and the VIC-II, SID and CIA registers.
Added · updated 13 October 2026
Works with
- Retro disk and tape images Retro computingopens D64, T64 and TAP images (or files) here
- Retro image converter Retro computingshows the converted C64 pictures (drop the downloaded file here)
- C64 BASIC and PETSCII Retro computingruns the .prg programs saved there, and shares its BASIC listing code
- C64 disk images (D64) Retro computingruns the D64 disk images built there
How to use it
Press Power on (about 0.15 MB downloads once), or just press Assemble & run in the Assembly tab — the C64 starts by itself. Click the screen to give it the keyboard. The page has five tabs: Run (programs, disks, tapes, joystick, firmware), BASIC, Assembly, Debugger and References.
Assembly
Write 6502 assembly in the editor, or pick one of the examples — hello world with the KERNAL’s
CHROUT, border and background colours, a raster interrupt that splits the screen, a sprite
moved with the joystick, a tune on the SID, a custom character set, and a machine-code routine
called from BASIC. Assemble & run (Ctrl+Enter) resets the C64, waits for READY., puts the
program in memory and types SYS with its start address (or RUN, for a program at $0801
with its own BASIC line). Code you start with SYS usually goes at *= $C000 (49152), free
RAM that BASIC doesn’t use.
If the source ends with a ; BASIC: comment block, those lines are a BASIC program: the code
is loaded, then the BASIC lines are typed and run — see Called from BASIC (SYS).
Download .PRG saves the program with its load address; .PRG with a SYS line adds a
10 SYS … line at $0801 in front of it, so LOAD + RUN starts it on a real C64.
Debugging
The Assembly tab is a split view: the editor on one side, and the screen with the debugger on the other — registers and flags (click to edit), the stack with JSR return addresses marked, the code around the program counter, and watches.
-
Click a line number beside the code to set a breakpoint (a red dot); click the dot to clear it; right-click a number for Run to here. F9 toggles the line with the cursor. Breakpoints follow their lines when you edit and re-assemble, and the list under the editor has a ✕ for each and Clear all.
-
When the program stops, ▶ and a highlight mark the line, and the status says
Stopped at $C00B — line 12, or not in your source when the CPU is in the KERNAL or BASIC ROM (the disassembly then shows where). -
Keys: F5 continue, F6 pause, F11 step, F10 step over, Shift+F11 step out, Ctrl+F10 run to the cursor line. On the C64 screen itself F1–F8 are the C64’s function keys; F10 and F11 still step.
Pause stops the CPU at the next instruction, in the middle of a frame; the red line on the
screen shows where the beam had got to. The Debugger tab adds a memory viewer and editor,
the breakpoint list, and decoded chips: the VIC-II (graphics mode, screen and character or
bitmap address in the current bank, raster line and interrupt, border and background colours,
all eight sprites), the SID (each voice’s frequency in Hz, waveform, pulse width and ADSR,
the filter and volume) and the CIAs (ports, timers, interrupts, the joystick on port 2, the
VIC bank, and what the CPU port $01 maps in). It works on whatever is running — your code, a
loaded program, or BASIC.
BASIC
Type it types a listing key by key. Load as a program tokenises the numbered lines and puts
them straight into memory, then types the rest (such as RUN). Save as .PRG and List it as
text work on the program in memory (TXTTAB to VARTAB).
The Open ROMs' BASIC is unfinished: PRINT of text, LIST, RUN and SYS work, but
variables, arithmetic and most commands report ?NOT IMPLEMENTED ERROR. For full BASIC, load
your own ROM dumps (see Firmware).
Running programs
Drop a file on the screen or the Programs, disks and tapes box:
-
.PRG — loaded straight into memory at its load address. With Start programs automatically on, BASIC programs (load address
$0801) areRUNand machine code getsSYSto its load address. -
.D64 — the disk’s directory is listed; the first program loads, and clicking any other
PRGloads that one instead. -
.T64 / .P00 — the programs inside are extracted and loaded the same way.
-
.TAP — inserted in the datasette; the page types
LOAD, presses Play, and you wait (or turn on Warp).
There’s no 1541 drive emulation, because the drive’s own DOS ROM is still under copyright and isn’t bundled. Programs that are one file work; games and demos that load more parts from disk while running don’t. Cartridges (.CRT) aren’t supported by this emulator core. Files you open are remembered under Recently used (in IndexedDB, in this browser only).
Keys and joysticks
Esc |
RUN/STOP (Shift+Esc is RUN) |
Page Up |
RESTORE |
Tab |
CTRL |
Alt / Option |
C= (the Commodore key) |
Backspace |
DEL (Shift+Backspace is INST) |
Home |
HOME (Shift+Home is CLR) |
F1–F8 |
Function keys (Shift+F1 is F2, as on the C64) |
Letters are capitals, as on a C64 at power-on; Shift+letter gives the graphics character (or lower case after Shift+C=). Most games read joystick port 2: choose Arrows = joystick and the arrow keys plus Space are the stick. A gamepad drives the selected port whenever one is connected.
Firmware
The MEGA65 Open ROMs are a KERNAL, BASIC and character
set written from scratch and released under the LGPL. The KERNAL is solid, so machine-code
programs — most games and demos, including those started by a 10 SYS 2061 line — and the
KERNAL routines your own code calls (CHROUT, GETIN …) work well. Software that jumps into
undocumented Commodore ROM routines (including many fast loaders) needs the original ROMs. Load
ROM dumps you own with Load my ROM files… — pick your kernal, basic and chargen files;
they’re identified by size and content and stay in this browser.
Presenting
⛶ Present (or F) shows just the C64 screen, filling the window — for a talk or a classroom. The keyboard and joystick keep working; Esc closes it.
Sharing
Share link copies a URL with your controller settings, the tab, and the assembly source (or
the example you picked) — never programs from disk, or ROMs. Under Link options, Open in
presentation mode and Start automatically make the link open full screen and run the program
straight away (the BASIC listing, if you share from the BASIC tab). Browsers only allow sound
after a click, so such a link first shows a Click to start button. By hand: mode (the tab:
run, basic, asm, debug, refs), example (hello, colours, raster, sprite,
sid, charset, basic-sys), present=1, autostart=1, arrows (cursor, joystick),
port (1, 2) — for example
?mode=asm&example=sprite&arrows=joystick&present=1&autostart=1.
Software to load
The Software panel (on the Run tab) has two parts:
-
Library — programs this site can share: open-source and public-domain releases, freeware whose author allows it to be passed on, and this site’s own examples. Each shows its licence, why it may be shared, and where it came from; Copy link gives a link (
?lib=<id>) that opens this page and loads it. -
Open URL / archive.org — paste a link to a file, or an archive.org item (its URL or identifier). For an archive.org item the panel lists the files the C64 can open, with the item’s licence as the uploader set it. Sites that allow it load straight into the emulator; archive.org doesn’t let other sites read its files, so for those you get a download link and drop the file onto the emulator.
There are no links to "complete ROM set" archives: most are copies of commercial software that is still under copyright, whatever the upload’s licence field says. Files you own you can always load — drop them onto the emulator or paste a link.
How it’s built
The emulator is the C64 from Andre Weissflog’s chips
(zlib licence) — a cycle-stepped 6510, VIC-II, SID and two CIAs — compiled with Emscripten
behind a small wrapper that adds the debugger: breakpoints are checked at every instruction
fetch, and a stop just ends the frame early, so it costs no speed (about 1.1 ms per emulated
frame either way). The assembler is this site’s 6502 assembler.
Licences, sources and the build script are under /wasm/c64/ and in this site’s repository
(tools/wasm/c64/).
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.