Toolchain: DASM & Stella#

Two tools cover the entire development loop for this book: DASM assembles your .asm source into a cartridge image, and Stella runs that image as if it were a real console.

Installing#

On macOS with Homebrew:

brew install dasm
brew install --cask stella

DASM is the de-facto assembler for the VCS; Stella is the reference emulator and an excellent debugger.

Assembling a ROM#

The canonical build command (from the repository’s xmas/Makefile) is:

dasm xmas.asm -I../include -f3 -v0 -oxmas.bin -sxmas.sym -lxmas.lst
FlagMeaning
-IInclude path: a directory to search for include files.
-f3Output format 3: a raw cartridge image with no header — what the VCS expects.
-v0Verbosity 0: quiet unless there’s an error.
-oOutput binary (.bin).
-sEmit a symbol table (.sym) — every label and its address.
-lEmit a listing (.lst) — source interleaved with the bytes and addresses it produced.

DASM looks for an include "vcs.h" first in the source file’s own directory, then in any -I directory. So you can keep vcs.h/macro.h right next to your .asm and drop the -I entirely — but this repository keeps them in one shared top-level include/ directory, hence -I../include.

The .sym and .lst files are your primary debugging aids: the listing shows exactly what each line assembled to, and the symbol table lets Stella’s debugger show your label names.

Running#

stella xmas.bin

In this repository each project directory has a Makefile wrapping these two commands:

cd xmas
make        # assemble -> xmas.bin
make run    # launch Stella on the .bin

There is no separate “lint” or “test” step. On the VCS, assembling cleanly is the first check and watching the picture in Stella is the second. The .lst file is where you confirm a routine fits its cycle budget.

In Practice#

If a change makes the screen roll, tear, or go black, the cause is almost always timing — a scanline region with the wrong number of WSYNCs — not a syntax error. Stella’s TV mode and its debugger’s scanline counter are the fastest way to find which region drifted. See The Frame Structure for the line counts every frame must hit.