No description
Find a file
Mattias Hansson 59b53fb5f0 v1.4
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
2026-05-24 13:45:57 +02:00
editor_syntaxes Updated new c65gm keywords to editor syntaxes. LIBRARY and MACRO 2026-02-17 07:54:09 +01:00
examples build_all script for examples and fixed warnings in examples about unused functions. 2026-05-17 16:29:54 +02:00
internal Fix pragma auto-removal for multi-FUNC groups sharing one FEND 2026-05-17 16:23:14 +02:00
lib Added decimal output lib and used it in new multdivlib demo. 2026-05-17 15:04:05 +02:00
opencode-config Added release building script 2026-05-24 13:25:26 +02:00
scripts Improvement on the release script 2026-05-24 13:38:45 +02:00
vendor Added Starlark scripting language for SCRIPT blocks. 2025-11-06 06:57:06 +01:00
.gitignore Added release building script 2026-05-24 13:25:26 +02:00
AGENTS.md Fix pragma auto-removal for multi-FUNC groups sharing one FEND 2026-05-17 16:23:14 +02:00
build_c65gm.sh Added c65cm stdlib as embedded into the c65gm exe so it's completely self contained, for easy distribution. 2026-04-17 11:53:20 +02:00
BUILDNUM v1.4 2026-05-24 13:45:57 +02:00
commands.md Improved commands reference 2026-04-16 07:02:59 +02:00
docker-compose.yml Fix pragma auto-removal for multi-FUNC groups sharing one FEND 2026-05-17 16:23:14 +02:00
Dockerfile Added release building script 2026-05-24 13:25:26 +02:00
go.mod Added Starlark scripting language for SCRIPT blocks. 2025-11-06 06:57:06 +01:00
go.sum Added Starlark scripting language for SCRIPT blocks. 2025-11-06 06:57:06 +01:00
language.md Added pragma _P_ASM_AFTER_VARS to control is ASM blocks should be generated after everything else (vars and string constants) 2026-04-17 23:01:42 +02:00
LICENSE Added license. Docs updated to explain the command line options. 2026-04-17 15:08:53 +02:00
main.go Added release building script 2026-05-24 13:25:26 +02:00
main_test.go Added license. Docs updated to explain the command line options. 2026-04-17 15:08:53 +02:00
opencode-docker.sh First commit refactoring and centralizing constant handling all over 2026-04-13 12:21:11 +02:00
README.md Fixed download path for the actual release place at siders site. 2026-05-24 13:45:42 +02:00
syntax.md Added pragma _P_ASM_AFTER_VARS to control is ASM blocks should be generated after everything else (vars and string constants) 2026-04-17 23:01:42 +02:00

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 by C65LIBPATH environment 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 lookup
  • go.starlark.net - Embedded Starlark scripting support

Building

Build the compiler binary:

go build -o c65gm

Or install to your GOPATH:

go install

Usage

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/-in and -o/-out are equivalent
  • Smart defaults: Output extension determines mode (.prg = build, .asm = compile)
  • ACME integration: Automatically finds and runs ACME assembler with -f cbm by default (provides platform-specific installation instructions if missing)
  • Backward compatible: Legacy -in/-out flags still work
  • Customizable: Use --no-cbm to disable CBM format, --keep-asm to 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:

  1. Compile myprogram.c65 to assembly
  2. Run ACME assembler with -f cbm format
  3. Produce myprogram.prg (C64 executable)

Input and Output Files

  • -i, --input (-in): Specify input .c65 file (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 .asm file
  • --no-cbm: Don't add -f cbm flag 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:

  1. Searches PATH for acme executable
  2. Runs: acme -o output.prg -f cbm temp.asm
  3. Shows ACME output and errors
  4. 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> directives
    export 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 demo
  • multicolorbm/ - Multicolor bitmap demo
  • memlib_demo/ - Memory library usage
  • switch_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 reference
  • syntax.md - Syntax guide
  • commands.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) or shasum (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:

  1. Verify git clean — fails if uncommitted changes exist
  2. Read BUILDNUM — e.g., 42 → version 1.42
  3. Verify tag available — fails if tag v1.42 already exists
  4. Bump BUILDNUM — writes 43 to BUILDNUM
  5. Build all targets — 5 platform binaries with version injected via ldflags
  6. Generate SHA256 checksums — written to dist/checksums.txt
  7. Commit BUILDNUMgit commit with checksums in the commit body
  8. Create annotated taggit tag -a v1.42 pointing 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}"
  • -trimpath strips local filesystem paths
  • -s -w strips symbol table and DWARF debug info
  • -X main.version injects the version
  • CGO_ENABLED=0 ensures 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.