Skip to content

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

sh
brew install cc65
sh
sudo apt-get install cc65
sh
# 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 --version

The 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 supported

Which matters, and which doesn't:

What you're building2.19Newer
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 haveWhat it prints
A build from current sourcecl65 V2.19 - Git 547d92358
The 2.19 release, built from its tarballcl65 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/stdin

Silence 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:

sh
brew install --HEAD cc65

Anywhere else, from source. It takes about a minute:

sh
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/local

Two parts of that look redundant and are not:

  • bin and none are separate builds. bin is the tools; none is a target library — the one cl65 -t none hands 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/lib is 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

CommandWhat it does
ca65Assembler — source in, object file out
ld65Linker — object files plus a config, image out
cl65Both of the above in one command. This is the one you'll use.
da65Disassembler
od65Object 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.

Written for BIOS v1.5. Released under the MIT License.