diff --git a/language.md b/language.md index cf9740d..a73a1d3 100644 --- a/language.md +++ b/language.md @@ -12,46 +12,73 @@ c65gm is a high-level language for 6502 assembly programming that combines moder 6. [Memory Operations](#memory-operations) 7. [Code Blocks](#code-blocks) 8. [Preprocessor](#preprocessor) -9. [Common Patterns](#common-patterns) +9. [Writing Libraries](#writing-libraries) +10. [Common Patterns](#common-patterns) --- ## Getting Started -### Your First Program +### Your First C64 Program -Here's a simple program that changes the screen border color on a Commodore 64: +Here's a simple complete program that changes the screen border color: ```c65 -ORIGIN $0801 +#INCLUDE +#INCLUDE -BYTE borderColor @ $D020 +GOTO start -borderColor = 5 // Set border to green +FUNC main + BYTE borderColor @ $D020 + borderColor = color_green +FEND + +LABEL start +main() ``` +### Creating a C64 Executable + +To create a runnable C64 program, always start with: + +```c65 +#INCLUDE +``` + +This creates a valid C64 executable with a BASIC loader (`0 SYS 2064`) and sets up the proper memory layout. + ### Program Structure -A typical c65gm program consists of: - -1. **ORIGIN directive** - Sets where code will be placed in memory -2. **Variable declarations** - Define your data -3. **Code** - Functions and statements that do the work +A typical c65gm program for C64 follows this pattern: ```c65 -ORIGIN $0801 +#INCLUDE +#INCLUDE // Optional: standard C64 definitions + +GOTO start // Jump over your function definitions // Variables BYTE counter = 0 WORD screen = $0400 -// Main code -FUNC main +// Functions - must be declared before we use them. +FUNC processData + // Do something +FEND + +FUNC initialize counter = 10 processData() FEND + +// Entry point - execution starts here +LABEL start +initialize() ``` +**Important:** The `GOTO start` jumps over your function definitions. Without it, the CPU would try to execute directly into your function code, causing a crash. Always put `GOTO start` before your functions, and `LABEL start` before your actual program entry point. + --- ## Variables and Types @@ -120,8 +147,6 @@ value = %11111111 // Binary (% prefix) ```c65 result = 10 + 5 // Addition result = 100 - 5 // Subtraction -result = 4 * 10 // Multiplication -result = 100 / 5 // Division ``` ### Bitwise Operators @@ -146,27 +171,18 @@ lives-- **Expressions evaluate strictly left to right!** There is no operator precedence. ```c65 -result = 2 + 3 * 4 // Evaluates as (2+3)*4 = 20, NOT 2+(3*4) = 14 -value = 100 - 20 + 5 // Evaluates as (100-20)+5 = 85 +result = 2+3*4 // Evaluates as (2+3)*4 = 20, NOT 2+(3*4) = 14 +value = 100-20+5 // Evaluates as (100-20)+5 = 85 ``` For complex expressions, use temporary variables: ```c65 -// Instead of: result = a + b * c (which doesn't work as expected) -temp = b * c +// Instead of: result = (b - c) + a +temp = b - c result = a + temp ``` -### Constant Expressions - -Expressions without spaces are treated as compile-time constants: - -```c65 -value = 100+50 // OK - constant expression, evaluated at compile time -value = 100 + 50 // ERROR - spaces make it a runtime expression -``` - --- ## Control Flow @@ -581,8 +597,84 @@ Control compiler behavior: --- +## Writing Libraries + +When creating a library file to be included by other programs, use this structure: + +```c65 +#IFNDEF __MY_LIBRARY +#DEFINE __MY_LIBRARY = 1 + +GOTO lib_mylib_skip // Jump over library code + +// Library variables +WORD lib_mylib_buffer + +// Library functions +FUNC lib_mylib_initialize + lib_mylib_buffer = $C000 +FEND + +FUNC lib_mylib_process(value) + // Do something +FEND + +// Skip label - execution continues here after GOTO +LABEL lib_mylib_skip + +#IFEND +``` + +**Key points for libraries:** + +1. **Include guard** - Use `#IFNDEF` to prevent multiple inclusion +2. **GOTO skip** - Jump over all library code immediately +3. **LABEL skip** - Place at the end so GOTO jumps past everything +4. **Naming convention** - Prefix all names with `lib_yourlib_` to avoid conflicts + +This ensures when someone does `#INCLUDE `, the library functions are defined but not executed. + +--- + ## Common Patterns +### Complete Working Example + +Here's a complete C64 program showing all the pieces together: + +```c65 +#INCLUDE +#INCLUDE + +GOTO start + +// Variables +BYTE frameCount = 0 +WORD screenPtr @ $FB + +// Functions +FUNC initialize + BYTE borderColor @ $D020 + borderColor = color_black + POINTER screenPtr TO $0400 +FEND + +FUNC updateScreen + BYTE color + color = frameCount & $0F + POKE screenPtr[0] WITH color + frameCount++ +FEND + +// Entry point +LABEL start +initialize() + +WHILE 1 + updateScreen() +WEND +``` + ### Screen Manipulation ```c65