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) 6. [Memory Operations](#memory-operations)
7. [Code Blocks](#code-blocks) 7. [Code Blocks](#code-blocks)
8. [Preprocessor](#preprocessor) 8. [Preprocessor](#preprocessor)
9. [Common Patterns](#common-patterns) 9. [Writing Libraries](#writing-libraries)
10. [Common Patterns](#common-patterns)
--- ---
## Getting Started ## 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 ```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 ### Program Structure
A typical c65gm program consists of: A typical c65gm program for C64 follows this pattern:
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
```c65 ```c65
ORIGIN $0801 #INCLUDE <c64start.c65>
#INCLUDE <c64defs.c65> // Optional: standard C64 definitions
GOTO start // Jump over your function definitions
// Variables // Variables
BYTE counter = 0 BYTE counter = 0
WORD screen = $0400 WORD screen = $0400
// Main code // Functions - must be declared before we use them.
FUNC main FUNC processData
// Do something
FEND
FUNC initialize
counter = 10 counter = 10
processData() processData()
FEND 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 ## Variables and Types
@ -120,8 +147,6 @@ value = %11111111 // Binary (% prefix)
```c65 ```c65
result = 10 + 5 // Addition result = 10 + 5 // Addition
result = 100 - 5 // Subtraction result = 100 - 5 // Subtraction
result = 4 * 10 // Multiplication
result = 100 / 5 // Division
``` ```
### Bitwise Operators ### Bitwise Operators
@ -146,27 +171,18 @@ lives--
**Expressions evaluate strictly left to right!** There is no operator precedence. **Expressions evaluate strictly left to right!** There is no operator precedence.
```c65 ```c65
result = 2 + 3 * 4 // Evaluates as (2+3)*4 = 20, NOT 2+(3*4) = 14 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 value = 100-20+5 // Evaluates as (100-20)+5 = 85
``` ```
For complex expressions, use temporary variables: For complex expressions, use temporary variables:
```c65 ```c65
// Instead of: result = a + b * c (which doesn't work as expected) // Instead of: result = (b - c) + a
temp = b * c temp = b - c
result = a + temp 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 ## 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 ## 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 ### Screen Manipulation
```c65 ```c65