Updated language guide slightly

This commit is contained in:
Mattias Hansson 2025-12-19 19:44:13 +01:00
parent b54183aab4
commit 4319373828

View file

@ -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 <c64start.c65>
#INCLUDE <c64defs.c65>
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 <c64start.c65>
```
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 <c64start.c65>
#INCLUDE <c64defs.c65> // 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 <mylib.c65>`, 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 <c64start.c65>
#INCLUDE <c64defs.c65>
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