| editor_syntaxes | ||
| examples | ||
| internal | ||
| lib | ||
| opencode-config | ||
| vendor | ||
| .gitignore | ||
| AGENTS.md | ||
| build_c65gm.sh | ||
| commands.md | ||
| docker-compose.yml | ||
| go.mod | ||
| go.sum | ||
| language.md | ||
| LICENSE | ||
| main.go | ||
| main_test.go | ||
| opencode-docker.sh | ||
| README.md | ||
| syntax.md | ||
c65gm
A high-level 6502 cross-compiler targeting the ACME Cross-Assembler. c65gm provides a more expressive language for writing 6502 assembly programs, with features like functions, type-checked variables, control flow structures, and compile-time optimizations.
What It Does
c65gm compiles high-level source code into ACME assembler syntax for the 6502 processor (Commodore 64 and similar platforms). It provides:
- Type system: BYTE and WORD variables with scope resolution
- Functions: Named functions with parameters and call graph analysis
- Control flow: IF/ENDIF, WHILE/WEND, FOR loops, SWITCH/CASE
- Memory operations: PEEK/POKE/PEEKW/POKEW with zero-page optimization. Access registers as variables.
- Operators: Arithmetic (ADD, SUB), bitwise (AND, OR, XOR)
- Preprocessor: File inclusion, macros, conditional compilation, Starlark scripting
- Standard library: C64 screen/kernal routines, memory management, string handling, graphics (Koala), FAT16 filesystem, and more (accessed via
#include <file>, path set byC65LIBPATHenvironment variable) - Optimizations: Constant folding, self-assignment detection
- Safety features: Compile-time detection of overlapping absolute addresses in function call chains
Prerequisites
ACME Assembler (Required for creating .prg executables)
c65gm requires the ACME Cross-Assembler to create executable .prg files. If you only need to generate assembly (.asm) files, you can use compile mode without ACME.
Installation options by platform:
- Ubuntu/Debian:
sudo apt install acme - Fedora/RHEL:
sudo dnf install acme - Arch Linux:
sudo pacman -S acme - macOS:
brew install acme - Windows: Download binary from ACME releases
If ACME is not found when running the build command, c65gm will display platform-specific installation instructions.
Go (Required for building c65gm from source)
- Go: Version 1.25.1 or higher (tested with 1.25.5)
The project uses Go modules with these dependencies:
github.com/armon/go-radix- Prefix tree for command lookupgo.starlark.net- Embedded Starlark scripting support
Building
Build the compiler binary:
go build -o c65gm
Or install to your GOPATH:
go install
Usage
Quick Start (Recommended)
Compile and assemble directly to a .prg file:
./c65gm myprogram.c65 # Creates myprogram.prg
./c65gm -i myprogram.c65 -o game.prg # Creates game.prg
Command Reference
Build (compile + assemble to .prg)
./c65gm build -i myprogram.c65 [-o output.prg] [--keep-asm] [--no-cbm]
./c65gm myprogram.c65 # Default build to myprogram.prg
./c65gm -i myprogram.c65 # Same as above
./c65gm -in myprogram.c65 # Legacy syntax, still works
Compile (to .asm only)
./c65gm compile -i myprogram.c65 [-o output.asm]
./c65gm myprogram.c65 -o output.asm # .asm extension triggers compile mode
./c65gm -i myprogram.c65 -out output.asm # Legacy syntax
Help
./c65gm help
./c65gm -h
./c65gm --help
Key Features
- Self-contained: Embedded standard library and Starlark interpreter (ACME assembler required for .prg creation)
- Flexible syntax:
-i/-inand-o/-outare equivalent - Smart defaults: Output extension determines mode (.prg = build, .asm = compile)
- ACME integration: Automatically finds and runs ACME assembler with
-f cbmby default (provides platform-specific installation instructions if missing) - Backward compatible: Legacy
-in/-outflags still work - Customizable: Use
--no-cbmto disable CBM format,--keep-asmto keep intermediate files
Compiler Options Reference
Default Behavior (Simplest Case)
The simplest way to use c65gm is to provide just the input file:
c65gm myprogram.c65
This will:
- Compile
myprogram.c65to assembly - Run ACME assembler with
-f cbmformat - Produce
myprogram.prg(C64 executable)
Input and Output Files
-i,--input(-in): Specify input.c65file (required)-o,--output(-out): Specify output file (optional)
Examples:
# Explicit input/output
c65gm -i program.c65 -o game.prg
# Input only (default output: program.prg)
c65gm program.c65
# Legacy syntax (still works)
c65gm -in program.c65 -out output.asm
Operation Modes
c65gm automatically determines the operation mode based on the output file extension:
Build Mode (.prg extension)
Compiles and assembles to create a C64 executable:
c65gm program.c65 # → program.prg (default)
c65gm program.c65 -o game.prg # → game.prg
Compile Mode (.asm extension)
Compiles only, producing ACME assembly for manual assembly:
c65gm program.c65 -o output.asm # → output.asm
c65gm compile -i program.c65 # → program.asm
Subcommands
For explicit control, use subcommands:
build - Compile + Assemble
c65gm build -i program.c65 [-o output.prg] [--keep-asm] [--no-cbm]
--keep-asm: Keep intermediate.asmfile--no-cbm: Don't add-f cbmflag to ACME (for non-CBM targets)
compile - Compile Only
c65gm compile -i program.c65 [-o output.asm]
Produces assembly file only, doesn't run ACME.
help - Show Usage
c65gm help
c65gm -h
c65gm --help
ACME Assembler Integration
c65gm automatically:
- Searches
PATHforacmeexecutable - Runs:
acme -o output.prg -f cbm temp.asm - Shows ACME output and errors
- Cleans up temporary files (unless
--keep-asm)
Error Handling: If ACME is not found, c65gm shows installation instructions and suggests using compile mode instead.
Environment Variables
C65LIBPATH: Search path for#INCLUDE <file>directivesexport C65LIBPATH=/path/to/c65gm/lib c65gm program.c65
Examples Summary
# Quick build (recommended)
c65gm program.c65
# Custom output name
c65gm -i program.c65 -o game.prg
# Keep intermediate assembly
c65gm build -i program.c65 --keep-asm
# Compile only (no ACME)
c65gm compile -i program.c65
# Legacy two-step process (still works)
c65gm -in program.c65 -out program.asm
acme -f cbm -o program.prg program.asm
Running Tests
Run all tests:
go test ./...
Run tests with verbose output:
go test -v ./...
Run tests for a specific package:
go test ./internal/compiler
go test ./internal/commands
Examples
See the examples/ directory for sample programs:
hires/- High-resolution graphics demomulticolorbm/- Multicolor bitmap demomemlib_demo/- Memory library usageswitch_demo/- SWITCH/CASE statement examples
Building Examples
cd examples/hires
c65gm hires.c65 # Creates hires.prg
c65gm -i hires.c65 -o demo.prg # Creates demo.prg
c65gm compile -i hires.c65 # Creates hires.asm only
The example directories also contain cm.sh scripts showing the old build method.
Documentation
language.md- Complete language referencesyntax.md- Syntax guidecommands.md- Command reference
Editor Syntaxes
- Kate: copy XML to ~/.local/share/org.kde.syntax-highlighting/syntax/
- Sublime: copy .sublime-syntax to Packages/User/
License
Copyright (C) 1999, 2025 Mattias Hansson
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
See LICENSE file for the full GPL v2 license text.