Installing cc65
cc65 is the assembler and linker this ecosystem builds with. It is a mature, well-documented toolchain that has been aimed at 6502 machines for thirty years, and it is the only required install in this whole section.
Install it
brew install cc65sudo apt-get install cc65# Two options, both fine:
# 1. Download the Windows snapshot from https://cc65.github.io/ and put
# its bin\ folder on your PATH.
# 2. Work inside WSL and use the Debian line.Then check it runs at all:
cl65 --versionThe one trap
Every package manager still ships cc65 2.19, released in 2020. That version builds everything in this guide. It does not build the BIOS.
The reason is one directive. The ROM targets the WDC 65C02S specifically, and sets:
.setcpu "W65C02"cc65 only learned that CPU name in July 2025 — five and a half years after 2.19 went out. On 2.19 the assembler stops on that line:
BIOS.asm(22): Error: CPU not supportedWhich matters, and which doesn't:
| What you're building | 2.19 | Newer |
|---|---|---|
A program from the 6502-PRG template | ✅ | ✅ |
A cartridge from 6502-CRT | ✅ | ✅ |
| Anything in this guide | ✅ | ✅ |
| The BIOS itself, from source | ❌ | ✅ |
So: install the packaged version, write programs, and only go and get a newer toolchain on the day you want to rebuild the ROM. The templates and everything here set .setcpu "65C02", which 2.19 has supported since long before it was released.
How much does that cost you?
Nothing, byte for byte. The worked program in Build, run, repeat, assembled with the 2.19 release and again with a build from the current source, produces two identical files — same size, same bytes. The newer toolchain adds instructions the 65C02S has and the plain 65C02 doesn't (WAI, STP, and Rockwell's bit operations). Until your program uses one of those, the two are the same assembler.
Don't trust the version string
This is worth ten minutes of your life, so: --version cannot answer the question above.
| What you have | What it prints |
|---|---|
| A build from current source | cl65 V2.19 - Git 547d92358 |
| The 2.19 release, built from its tarball | cl65 V2.18 - N/A |
The newer one claims 2.19. The older one claims 2.18. Ask the assembler something only the newer one can answer instead:
printf '.setcpu "W65C02"\n wai\n' | ca65 -o /dev/null /dev/stdinSilence means you have a toolchain new enough to build the ROM. Error: CPU not supported means you have 2.19, which — see the table — is almost certainly fine.
Getting a newer one
Only needed if you plan to build the BIOS.
macOS:
brew install --HEAD cc65Anywhere else, from source. It takes about a minute:
git clone https://github.com/cc65/cc65.git
make -C cc65 -j"$(nproc)" bin PREFIX=/usr/local
mkdir -p cc65/lib
make -C cc65 -j"$(nproc)" none PREFIX=/usr/local
sudo make -C cc65/src install PREFIX=/usr/local
sudo make -C cc65/libsrc install PREFIX=/usr/localTwo parts of that look redundant and are not:
binandnoneare separate builds.binis the tools;noneis a target library — the onecl65 -t nonehands to the linker. cc65 has thirty or so targets for other machines, and not building those is what keeps this to a minute.mkdir -p cc65/libis there because asking cc65 for a single target by name skips the pass that would have created that directory.
Both halves get installed because the tools alone are not enough: the ROM's BASIC uses .macpack longbranch, which is read from cc65's asminc directory and travels with the libraries rather than the binaries.
What you actually installed
| Command | What it does |
|---|---|
ca65 | Assembler — source in, object file out |
ld65 | Linker — object files plus a config, image out |
cl65 | Both of the above in one command. This is the one you'll use. |
da65 | Disassembler |
od65 | Object file dumper |
The ca65 manual and the ld65 manual are good, and worth knowing exist before you need them.
Next: the rest of the tool belt.

