c65gm/AGENTS.md

8.2 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

  1. README.md - Project overview, building, usage, and requirements
  2. language.md - Complete language reference with examples (1091 lines)
  3. syntax.md - Syntax rules and preprocessor directives (646 lines)
  4. 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

  1. Type system: BYTE (8-bit) and WORD (16-bit) variables with scope resolution
  2. Functions: Named functions with parameters and call graph analysis
  3. Control flow: IF/ENDIF, WHILE/WEND, FOR loops, SWITCH/CASE
  4. Memory operations: PEEK/POKE/PEEKW/POKEW with zero-page optimization
  5. Preprocessor: File inclusion, macros, conditional compilation, Starlark scripting
  6. Optimizations: Constant folding, self-assignment detection
  7. Safety features: Compile-time detection of overlapping absolute addresses

Important Syntax Rules

  1. No operator precedence: Expressions evaluate strictly left-to-right
  2. Memory-mapped variables: Use @ to place variables at specific addresses
  3. Constants: Prefer BYTE CONST/WORD CONST over #DEFINE
  4. Zero-page optimization: Place frequently accessed pointers in zero page ($00-$FF)
  5. Include guards: Always use #IFNDEF in library files

Special Blocks

  1. ASM blocks: Inline assembly code
  2. SCRIPT blocks: Starlark code for compile-time code generation
  3. SCRIPT LIBRARY blocks: Reusable Starlark functions
  4. 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/POKE for byte access
  • Use PEEKW/POKEW for word (16-bit) access
  • For indexed access, address must be a WORD variable in zero page

Development Guidelines

Environment Constraints

CRITICAL - NO GO TOOLS AVAILABLE: The agent runs in a Docker container without access to compilers, testing tools, or external build systems. The container does NOT have Go installed (go command not found). All compilation and testing must be performed by the user. The agent can only:

  1. Read and analyze source code
  2. Make code changes
  3. Provide instructions for the user to compile and test

NEVER attempt to run go build, go test, or any Go commands - they will fail with "go: not found".

File Access Restrictions

CRITICAL: The agent must only access normal project files within the current working directory. The agent must NEVER:

  1. Look at files outside the project directory (e.g., /tmp/, /etc/, /home/, etc.)
  2. Read or attempt to access system files, environment files (.env), or configuration files outside the project
  3. Search for or read files containing secrets, credentials, or sensitive information
  4. 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

  1. Check internal/commands/ for command implementations
  2. Check internal/compiler/ for core compiler logic
  3. Check internal/preproc/ for preprocessor functionality
  4. DO NOT run tests - provide instructions for the user to run tests

When Adding New Features

  1. Follow existing patterns in command implementations
  2. Add comprehensive tests
  3. Update documentation in appropriate .md files
  4. Consider adding examples in examples/ directory

Testing and Rebuilding

CRITICAL: The agent cannot run tests or compile code. The container has no Go installation. Provide these instructions to the user:

Testing:

  • Run all tests: go test ./...
  • Run specific package tests: go test ./internal/compiler
  • Test with verbose output: go test -v ./...

Rebuilding c65gm:

When making changes to the compiler, ask the user to rebuild c65gm:

go build -o c65gm

This creates a fresh binary with your changes. The agent should:

  1. Make code changes
  2. Ask the user to rebuild c65gm: go build -o c65gm
  3. Check file datetime: Verify the c65gm binary was recently updated (use ls -la c65gm or similar)
  4. Ask the user to run tests: go test ./...
  5. Test the changes with example .c65 files

IMPORTANT: Always check the file datetime of the c65gm binary after asking for a rebuild. If the timestamp hasn't changed, the user may have forgotten to rebuild, or the build may have failed. Testing with an old version is wasteful and can lead to incorrect conclusions.

Compiling .c65 files:

C65LIBPATH=/app/lib ./c65gm -in input.c65 -out output.asm

Common Pitfalls

  1. Expression evaluation: Remember no operator precedence
  2. Zero-page requirements: Indexed memory operations require zero-page addresses
  3. Include guards: Essential for library files to prevent multiple inclusion
  4. Program structure: Always use GOTO start to jump over function definitions
  5. 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 features
  • syntax.md: Detailed syntax rules and preprocessor directives
  • commands.md: Complete command reference with examples

Implementation Details

  • internal/compiler/compiler.go: Main compiler logic
  • internal/commands/*.go: Individual command implementations
  • internal/preproc/preproc.go: Preprocessor implementation

Examples

  • examples/: Working example programs
  • lib/: Standard library usage examples

Testing

  • *_test.go files throughout the codebase
  • examples/: Functional test programs

Tool Notes

Shell Environment

  • Shell: Only /bin/sh (BusyBox) is available, not bash
  • The bash tool in the interface runs commands through /bin/sh (BusyBox)
  • BusyBox limitations: Many GNU extensions are not available

grep Limitations

The environment uses BusyBox grep which doesn't support GNU grep extensions:

  • NOT supported: --include="*.go", --exclude="*.md", etc.
  • Use instead: find /app -name "*.go" -type f -exec grep -l "pattern" {} \;
  • Example: Instead of grep -r "CheckUnusedFunctions" /app --include="*.go", use:
    find /app -name "*.go" -type f -exec grep -l "CheckUnusedFunctions" {} \;
    

File Operations

  • Use find with -exec for pattern-based file searches
  • Use grep without GNU extensions for simple pattern matching
  • Prefer the bash tool with proper BusyBox-compatible commands