ASM routines and examples for the Commodore 64
In this repository:
- lib - Reusable routines and macros written for ACME cross-assembler.
- lib-demo - Sample code (routines in action).
- programs - Illustrations of basic techniques:
- Boring Snake
- c64 rules demo
- one part in one day of Advent of Code
- a simple book reader
- and some other random experiments.
- doc - Addressing modes summary, assemblers, editor code completion, IDE and Awesome references.
- scripts - Python utility scripts:
- y-acme-fmt to format ACME source code.
Assume PAL for all VIC-II routines. Feel free to roam around the repository in no particular order but read this page first.
You should be comfortable with the following topics:
- Programming and basic algorithms, in any language, preferably in the imperative category (C, Java, but also Python, JavaScript, etc).
- Base conversion -- decimal, binary, hexadecimal. This is the bread and butter of assembly programming.
- Command line -- Understanding of
export
,source
,PATH
andmake
is required.
It is good to have these tabs opened in your browser:
- c64.org - Memory map
- c64os.com - Neat presentation of instruction set
- pagetable.com - Instruction set, KERNAL API, ROM dissasembly, memory map, PETSCII chartset
- oxyron.de - Simple table, illegal opcodes, bugs
At a minimum, keep the following reference handy:
- Memory map
- Instruction set
- Kernel tables
See also:
To use this repository, install the following tools:
- ACME - Cross-platform assembler.
- VICE - Multi-platform emulator for C64 and other Commodore products.
- dcc6502 - Disassembler. Compile it yourself or use a package manager like
brew
on macOS. - Any decent editor, preferably with syntax highlighting for ACME (vim, VSC, ...).
make
command.
ACME is the only one mandatory. There are tons of 6502/6510 cross assemblers, but our routines are written for ACME.
You can use any editor of your liking. vim
and Visual Studio Code have plugins for ACME syntax highlighting. If you prefer an IDE, consider CBM Studio or WUDSN.
VICE ships with utilities that can be launched from the command line:
c1541
disk drive utilitypetcat
ASCII/PETSCII converter (depending on the version)x64sc
to launch the emulator itself
Nothing beats the feel of real hardware, but emulators are certainly convenient.
Deploying programs to an actual C64 (or anything close like a FPGA) is an option, but convenience, we will target and work with an emulator, a macro assembler from this era and a modern editor.
By default, the Makefile
will look for tools and utilities in your PATH
:
acme
- assemblerc1541
- disk drive emulator (ships with VICE)x64sc
- VICE C64 emulator commanddcc6502
- disassembler
You can override the default values with environment variables. For instance on my macOS:
export ACME=`pwd`/c64
export C1541=/Applications/vice-gtk3-3.5/bin/c1541
export X64="open /Applications/vice-gtk3-3.5/x64sc.app"
export DCC6502=dcc6502
export PATH=`pwd`:$PATH
You must set ACME
environment variable to the root of this project to allow lib include directive to work.
NOTE If you store
export
statements in a file, remember tosource
it, not to run it.
Invoke make
from the root of the repository to assemble, create a symbol table and a default disk image.
# Assemble and package `many.a`
make TARGET=programs/sprites/many
This will create:
many.prg
- Program filemany.a.sym
- Symbol tablemany.d64
- Disk imagemany.d
- Disassembled source code
Then run the program with:
# Launch emulator and auto-load
make TARGET=programs/sprites/many run
Programs in this repository are located at $c000
by convention or use BASIC upstart for convenience.
- If the program contains a Program Counter (PC) directive, for instance
*=$c000
, typeSYS 49152
to run it from BASIC. - If the program includes
common/upstart.a
, a neat trick will cause the asm program to run withRUN
. Thanks to Vice-autostart
option, the emulator will automatically load and run the program.
NOTE The
Makefile
will automatically detect the PC directive and adjust the disassembler command accordingly.
The Makefile
will also look for a local Makefile
in the target directory. If found, it will be invoked. This allows for instance to add files to the generic disk image.