6.3 KiB
c65gm Agent Instructions
Project Overview
c65gm is a high-level 6502 cross-compiler targeting the ACME Cross-Assembler for Commodore 64 and similar 6502-based platforms. It provides a more expressive language for writing 6502 assembly programs with modern programming constructs.
Key Documentation Locations
Primary Documentation
- README.md - Project overview, building, usage, and requirements
- language.md - Complete language reference with examples (1091 lines)
- syntax.md - Syntax rules and preprocessor directives (646 lines)
- commands.md - Complete command reference (776 lines)
Code Structure
- main.go - Entry point and command-line interface
- internal/compiler/ - Core compiler implementation
- internal/preproc/ - Preprocessor implementation
- internal/commands/ - Individual command implementations
- internal/utils/ - Utility functions
- lib/ - Standard library files for C64 development
- examples/ - Example programs demonstrating language features
Standard Library (lib/)
- c64start.c65 - Required for C64 executables (BASIC loader setup)
- c64defs.c65 - C64 hardware definitions (colors, addresses, etc.)
- c64kernal.c65 - Kernal routine wrappers
- c64scr.c65 - Screen manipulation functions
- string.c65 - String handling functions
- memlib.c65 - Memory management functions
- fat16/ - FAT16 filesystem support
- koalalib.c65 - Koala graphics support
Language Features to Note
Key Concepts
- Type system: BYTE (8-bit) and WORD (16-bit) 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
- Preprocessor: File inclusion, macros, conditional compilation, Starlark scripting
- Optimizations: Constant folding, self-assignment detection
- Safety features: Compile-time detection of overlapping absolute addresses
Important Syntax Rules
- No operator precedence: Expressions evaluate strictly left-to-right
- Memory-mapped variables: Use
@to place variables at specific addresses - Constants: Prefer
BYTE CONST/WORD CONSTover#DEFINE - Zero-page optimization: Place frequently accessed pointers in zero page ($00-$FF)
- Include guards: Always use
#IFNDEFin library files
Special Blocks
- ASM blocks: Inline assembly code
- SCRIPT blocks: Starlark code for compile-time code generation
- SCRIPT LIBRARY blocks: Reusable Starlark functions
- SCRIPT MACRO blocks: Parameterized macros for inline expansion
Common Patterns
Program Structure
#INCLUDE <c64start.c65>
#INCLUDE <c64defs.c65>
GOTO start // Jump over function definitions
// Variables and functions here
LABEL start // Program entry point
main()
Library Structure
#IFNDEF __MY_LIBRARY
#DEFINE __MY_LIBRARY = 1
GOTO lib_mylib_skip
// Library code here
LABEL lib_mylib_skip
#IFEND
Memory Operations
- Use
PEEK/POKEfor byte access - Use
PEEKW/POKEWfor word (16-bit) access - For indexed access, address must be a WORD variable in zero page
Development Guidelines
Environment Constraints
IMPORTANT: The agent runs in a Docker container without access to compilers, testing tools, or external build systems. All compilation and testing must be performed by the user. The agent can only:
- Read and analyze source code
- Make code changes
- Provide instructions for the user to compile and test
File Access Restrictions
CRITICAL: The agent must only access normal project files within the current working directory. The agent must NEVER:
- Look at files outside the project directory (e.g.,
/tmp/,/etc/,/home/, etc.) - Read or attempt to access system files, environment files (
.env), or configuration files outside the project - Search for or read files containing secrets, credentials, or sensitive information
- Attempt to access files in parent directories or unrelated paths
All file operations must be restricted to the project's source code and documentation files only.
When Modifying the Compiler
- Check
internal/commands/for command implementations - Check
internal/compiler/for core compiler logic - Check
internal/preproc/for preprocessor functionality - DO NOT run tests - provide instructions for the user to run tests
When Adding New Features
- Follow existing patterns in command implementations
- Add comprehensive tests
- Update documentation in appropriate .md files
- Consider adding examples in
examples/directory
Testing
IMPORTANT: The agent cannot run tests. Provide these instructions to the user:
- Run all tests:
go test ./... - Run specific package tests:
go test ./internal/compiler - Test with verbose output:
go test -v ./...
Common Pitfalls
- Expression evaluation: Remember no operator precedence
- Zero-page requirements: Indexed memory operations require zero-page addresses
- Include guards: Essential for library files to prevent multiple inclusion
- Program structure: Always use
GOTO startto jump over function definitions - String handling: Strings are passed as pointers to WORD parameters
Quick Reference
Compilation
IMPORTANT: The agent cannot compile code. Provide these instructions to the user:
./c65gm -in input.c65 -out output.asm
acme -f cbm -o output.prg output.asm
Environment Variables
C65LIBPATH: Library search path for#INCLUDE <file>
Editor Support
- Kate syntax:
editor_syntaxes/kate/ - Sublime syntax:
editor_syntaxes/sublime/
Where to Look for Specifics
Language Syntax
language.md: Sections 1-10 cover all language featuressyntax.md: Detailed syntax rules and preprocessor directivescommands.md: Complete command reference with examples
Implementation Details
internal/compiler/compiler.go: Main compiler logicinternal/commands/*.go: Individual command implementationsinternal/preproc/preproc.go: Preprocessor implementation
Examples
examples/: Working example programslib/: Standard library usage examples
Testing
*_test.gofiles throughout the codebaseexamples/: Functional test programs