The Commodore 64 is the classic 8-bit home computer. Our C64 projects are written in 6502 assembly, built with the ACME cross-assembler into a .prg program file, and tested in the VICE emulator (x64sc).
ACME: https://sourceforge.net/projects/acme-crossass/ VICE: https://vice-emu.sourceforge.io Tools repository: https://git.teletype.hu/tools/c64-tools
This Makefile provides a simple, reproducible workflow for building C64 assembly projects with ACME and running them in VICE. It is designed for small projects where all
.asmfiles live in the project root and are assembled from a single entry point.
The workflow is based on four core ideas:
.asm sources are assembled through a single entry file (main.asm) that !src-includes the rest.prg file that loads and runs on a real C64 or in VICEmetadata.jsonproject-root/
├── main.asm
├── defs.asm
├── common.asm
├── ...
├── metadata.json
├── Makefile
└── README.md
main.asm is the assembler entry point; it includes the other .asm filesmetadata.json holds the catalog metadata and the version<project>.prg is generated by ACME| Variable | Description | Default |
|---|---|---|
PROJECT |
Project name (used in artifact filenames and the catalog) | — |
ASM |
Assembler binary | acme |
EMU |
Emulator binary | x64sc |
SRC |
Assembler entry point | main.asm |
TARGET |
Output program file | $(PROJECT).prg |
METADATA |
Metadata file | metadata.json |
metadata.json File{
"name": "example",
"title": "Example C64 Game",
"author": "Teletype Games",
"desc": "Short description of the game.",
"site": "https://git.teletype.hu/games/example",
"license": "MIT",
"version": "1.0.0"
}
name must match the PROJECT variable in the Makefileversion drives ci-versiontitle, author, desc, site, license) is what the update server writes into the game catalogmake deps
acme and vice via Homebrew (macOS only; on other systems install them manually).make build
main.asm (and everything it includes) with ACME<project>.prg.asm file changedmake run
x64sc)make clear # remove the .prg and CI artifacts
make rebuild # clear + build
make rebuildrun # clear + build + run
The tools repository also contains an example-tasks.json that can be copied to .vscode/tasks.json. It wraps the local make targets (deps, build, run, clear, rebuild, rebuildrun), with build set as the default build task (Cmd+Shift+B).
These targets are designed for automated continuous integration (Woodpecker CI). Each target reads the version from the .version file created by ci-version.
make ci-versionmetadata.jsonmain/master) for development builds (e.g., dev-1.0.0-feature-foo).version file for subsequent stepsmake ci-buildbuild, then creates the versioned artifacts:
<project>-<version>.prg<project>-<version>.metadata.jsonmake ci-artifact.prg and .metadata.json to the droparea using scpsshpass for SSH authenticationDROPAREA_HOST, DROPAREA_PORT, DROPAREA_USER, DROPAREA_TARGET_PATH)make ci-updatecurl with platform=c64UPDATE_SECRET) to authorize the request.prg as the release cartridge| File | Description |
|---|---|
<project>.prg |
The assembled C64 program |
<project>-<version>.prg |
Versioned copy for release |
<project>-<version>.metadata.json |
Versioned metadata for the update server |
makeacme (assembler)x64sc from VICE (only for run)sshpass and curl (for CI/CD targets)https://git.teletype.hu/tools/c64-tools/src/branch/master/example-makefile.make
This document describes the Woodpecker CI pipeline used to build, upload, and publish a C64 game project.
The pipeline logic is almost entirely encapsulated within a Makefile, which is called by each pipeline step. This approach simplifies the CI configuration and keeps the build logic centralized.
The pipeline performs the following steps:
metadata.json..prg with ACME and creates versioned artifacts..prg and metadata to a remote server.Each step corresponds to a make ci-* target.
- name: version
image: alpine
commands:
- 'apk add --no-cache make'
- 'make ci-version'
What it does:
make.make ci-version, which reads the version from metadata.json, appends the branch name on development branches, and saves it to a .version file for subsequent steps to use.- name: build
image: debian:stable-slim
commands:
- 'apt-get update && apt-get install -y --no-install-recommends make acme'
- 'make ci-build'
What it does:
apt install acme) — no custom builder image is needed.make ci-build, which assembles the .prg and creates the versioned artifacts:
<project>-<version>.prg<project>-<version>.metadata.json- name: artifact
image: alpine
environment:
DROPAREA_HOST: vps.teletype.hu
DROPAREA_PORT: 2223
DROPAREA_TARGET_PATH: /home/drop
DROPAREA_USER: drop
DROPAREA_SSH_PASSWORD:
from_secret: droparea_ssh_password
commands:
- 'apk add --no-cache make openssh-client sshpass'
- 'make ci-artifact'
What it does:
make and SSH tooling (openssh-client, sshpass).make ci-artifact, which uploads the versioned .prg and .metadata.json files to the droparea using scp.Makefile target reads the necessary environment variables.- name: update
image: alpine
environment:
UPDATE_SERVER: https://games.vps.teletype.hu
UPDATE_SECRET:
from_secret: update_secret_key
commands:
- 'apk add --no-cache make curl'
- 'make ci-update'
What it does:
make and curl.make ci-update, which sends an HTTP request to the update server with query parameters:
secret - Authorization tokenname - Project nameplatform - Platform identifier (c64)version - Version from .version file<name>-<version>.metadata.json, creates or updates the catalog entry, and registers <name>-<version>.prg as the downloadable cartridge of the release.Example request:
https://games.vps.teletype.hu/update?secret=<SECRET>&name=example&platform=c64&version=1.0.0
After a successful run:
.prg program file..prg and its metadata are uploaded to the distribution server..prg available for download.This pipeline enables fully automated C64 releases where the entire build and release logic is managed by the project's Makefile.
https://git.teletype.hu/tools/c64-tools/src/branch/master/example-woodpecker.yaml