Built with: go version go1.26.3 linux/amd64 Build date: 2026-05-24T11:45:55Z SHA256 checksums: 5ef2aa7ee40195d5d46ed8087b4640f443fa0ef8ffd6d60307e836de91999569 c65gm_v1.4_darwin_amd64.tar.gz e7ce4a66762ce81e12e2e1784dab0bb26608233b650f56d922b0fb5a910fcd77 c65gm_v1.4_darwin_arm64.tar.gz 57f7db207cf279eb9858b7644b4184408180611347307e8a13539c82b55c9f8c c65gm_v1.4_linux_amd64.tar.gz 6ff833f2e09d3b7372d19353597e62fc392551cd4dfeb89b56901d65293a3bd1 c65gm_v1.4_linux_arm64.tar.gz 89bfb0925107f7555a2f0af341f78f6a00550bdeebced8e43e44bc6b2eeadcab c65gm_v1.4_windows_amd64.zip |
||
|---|---|---|
| editor_syntaxes | ||
| examples | ||
| internal | ||
| lib | ||
| opencode-config | ||
| scripts | ||
| vendor | ||
| .gitignore | ||
| AGENTS.md | ||
| build_c65gm.sh | ||
| BUILDNUM | ||
| commands.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| 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.
Download
Pre-built binaries are available from siders.techserio.com/downloads. Each release follows the naming pattern c65gm_v{MAJOR}.{BUILD}_os_arch:
| File | Platform |
|---|---|
c65gm_v1.1_linux_amd64.tar.gz |
Linux (x86_64) |
c65gm_v1.1_linux_arm64.tar.gz |
Linux (ARM64) |
c65gm_v1.1_darwin_amd64.tar.gz |
macOS (Intel) |
c65gm_v1.1_darwin_arm64.tar.gz |
macOS (Apple Silicon) |
c65gm_v1.1_windows_amd64.zip |
Windows (x86_64) |
Each release includes a checksums.txt file for verifying download integrity:
sha256sum -c checksums.txt
Verify with the annotated tag
Every release is created from an annotated git tag containing the Go compiler version and SHA256 checksums. To inspect:
git fetch --tags
git tag -l v1.1
The tag message shows the exact checksums. You can reproduce the build from the tag and verify your binary matches:
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/
Release Process
This section documents how to create a new release for maintainers.
Prerequisites
- Go 1.25.1+ installed
sha256sum(Linux) orshasum(macOS)- Git with write access to the repository
Steps
The release script does everything automatically. Just run it:
bash scripts/release.sh
This performs the following sequence:
- Verify git clean — fails if uncommitted changes exist
- Read BUILDNUM — e.g.,
42→ version1.42 - Verify tag available — fails if tag
v1.42already exists - Bump BUILDNUM — writes
43toBUILDNUM - Build all targets — 5 platform binaries with version injected via ldflags
- Generate SHA256 checksums — written to
dist/checksums.txt - Commit BUILDNUM —
git commitwith checksums in the commit body - Create annotated tag —
git tag -a v1.42pointing at the pre-bump commit, with checksums and Go version in the tag message
Publish
git push --follow-tags origin
--follow-tags is critical. Without it, only the commit is pushed — the annotated tag (with checksums) stays local. The release is incomplete until the tag is on the remote.
Forgot to use --follow-tags?
If you already ran git push without it, push just the tag:
git push origin v1.1
The tag is the source of truth for verification. Without it on the remote, nobody can verify.
Verify a release
git checkout v1.42
# You now have the exact source (BUILDNUM=42)
go build -trimpath -ldflags="-s -w -X main.version=1.42"
sha256sum c65gm
# Compare with the checksum in: git tag -l v1.42
Reproducible builds
The release script uses these flags for deterministic builds:
go build -trimpath -ldflags="-s -w -X main.version=${VERSION}"
-trimpathstrips local filesystem paths-s -wstrips symbol table and DWARF debug info-X main.versioninjects the versionCGO_ENABLED=0ensures fully static binaries
Binaries built from the same source with the same Go version produce identical hashes. The tag message captures the Go version and expected checksums for verification.
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.