Added initial documentation

This commit is contained in:
Mattias Hansson 2025-11-20 21:43:34 +01:00
parent 1617297067
commit fe3d122258
2 changed files with 1112 additions and 0 deletions

631
commands.md Normal file
View file

@ -0,0 +1,631 @@
# Compiler Commands Reference
## ADD
Adds two values and stores result in destination.
**Syntax:**
```
<dest> = <param1> + <param2>
```
**Examples:**
```
result = 10 + 5
total = count + offset
sum = var1 + 100
```
---
## AND
Bitwise AND operation between two values.
**Syntax:**
```
<dest> = <param1> & <param2>
```
**Examples:**
```
mask = value & $FF
result = byte1 & byte2
flags = status & $80
```
---
## BREAK
Exits current loop immediately.
**Syntax:**
```
BREAK
```
**Examples:**
```
FOR i = 0 TO 100
IF i = 50
BREAK
ENDIF
NEXT
WHILE counter < 1000
counter++
IF error
BREAK
ENDIF
WEND
```
---
## BYTE
Declares an 8-bit variable or constant.
**Syntax:**
```
BYTE <varname>
BYTE <varname> = <value>
BYTE <varname> @ <address>
BYTE CONST <varname> = <value>
```
**Examples:**
```
BYTE counter
BYTE speed = 5
BYTE screen @ $D020
BYTE CONST MAX_SPEED = 10
```
---
## CALL
Calls a function with optional arguments.
**Syntax:**
```
<funcname>([<param1>,[<param2>,...]])
```
**Examples:**
```
initialize
setColor(1,14)
drawSprite(xpos,ypos,@spriteData)
process("hello",42,myvar)
```
---
## DEC
Decrements a variable or memory location by 1.
**Syntax:**
```
<var>--
DEC <target>
DECREMENT <target>
```
**Examples:**
```
counter--
lives--
index--
DEC $D020
DECREMENT screenColor
```
---
## ELSE
Alternative branch in IF statement.
**Syntax:**
```
See IF
```
---
## ENDIF
Terminates IF block.
**Syntax:**
```
See IF
```
---
## FEND
Ends a function definition.
**Syntax:**
```
See FUNC
```
---
## FOR
Loop with automatic counter increment.
**Syntax:**
```
FOR <iterator> = <start_value> TO <end_value> [STEP <increment>]
```
**Examples:**
```
FOR i = 0 TO 10
screen = i
NEXT
FOR x = 0 TO 255 STEP 2
result = result + x
NEXT
FOR counter = start TO finish
process(counter)
NEXT
```
---
## FUNC
Defines a function with optional parameters.
Parameter passing modes: `in:` (default, read-only), `out:` (write-only), `io:` (read-write)
**Syntax:**
```
FUNC <n>
FUNC <n>(<param1>[,<param2>,...])
```
**Examples:**
```
FUNC initialize
BYTE temp = 0
screen = temp
FEND
FUNC add(in:a,in:b,out:result)
result = a + b
FEND
FUNC process(value,{BYTE temp})
temp = value + 1
FEND
FUNC swap(io:x,io:y)
BYTE temp = x
x = y
y = temp
FEND
```
---
## GOSUB
Calls subroutine with optional register passing.
**Syntax:**
```
GOSUB <target>
GOSUB <target> PASSING <var> AS ACC|XREG|YREG [<var> AS XREG|YREG [<var> AS YREG]]
```
**Examples:**
```
GOSUB myRoutine
GOSUB clearScreen
GOSUB processData PASSING value AS ACC
GOSUB multiply PASSING a AS ACC b AS XREG result AS ACC
```
---
## GOTO
Unconditional jump to label or address.
**Syntax:**
```
GOTO <target>
```
**Examples:**
```
GOTO mainLoop
GOTO error
GOTO endProgram
GOTO $9000
GOTO (startAddress+$100)
```
---
## IF
Conditional execution based on comparison.
When single parameter: 0 = false, non-zero = true
**Syntax:**
```
IF <param1> [<operator> <param2>]
```
Operators: `=` `==` `<>` `!=` `>` `<` `>=` `<=`
**Examples:**
```
IF count = 10
result = 1
ENDIF
IF value > threshold
process(value)
ELSE
skip(value)
ENDIF
IF status & $80
errorFlag = 1
ENDIF
IF x < 100
x++
ELSE
x = 0
ENDIF
```
---
## INC
Increments a variable or memory location by 1.
**Syntax:**
```
<var>++
INC <target>
INCREMENT <target>
```
**Examples:**
```
counter++
index++
frameCount++
INC $D020
INCREMENT screenColor
```
---
## LABEL
Creates a named assembly label.
**Syntax:**
```
LABEL <n>
```
**Examples:**
```
LABEL mainLoop
LABEL skipSection
LABEL errorHandler
```
---
## LET
Assigns value to variable.
Note: expressions not allowed (except constant expressions without spaces)
**Syntax:**
```
<dest> = <source>
```
**Examples:**
```
counter = 0
speed = maxSpeed
result = temp
value = 100+50
```
---
## NEXT
Loop terminator for FOR.
**Syntax:**
```
See FOR
```
---
## OR
Bitwise OR operation between two values.
**Syntax:**
```
<dest> = <param1> | <param2>
```
**Examples:**
```
flags = flags | $01
result = byte1 | byte2
status = status | errorBit
```
---
## ORIGIN
Sets assembly origin address.
**Syntax:**
```
ORIGIN <address>
```
**Examples:**
```
ORIGIN $0801
ORIGIN $C000
ORIGIN startAddress
```
---
## PEEK
Reads byte from memory location.
**Syntax:**
```
<dest> = PEEK <address>[<offset>]
```
**Examples:**
```
value = PEEK $D020
char = PEEK screenPtr[index]
data = PEEK buffer[5]
byte = PEEK pointer
```
---
## PEEKW
Reads word (16-bit) from memory location.
**Syntax:**
```
<dest> = PEEKW <address>[<offset>]
```
**Examples:**
```
addr = PEEKW $FFFE
value = PEEKW dataPtr[0]
word = PEEKW buffer[10]
address = PEEKW pointer
```
---
## POINT
Sets pointer variable to address of target.
**Syntax:**
```
POINTER <ptrvar> TO <target>
```
**Examples:**
```
POINTER screenPtr TO $0400
POINTER dataPtr TO buffer
POINTER funcPtr TO myFunction
```
---
## POKE
Writes byte to memory location.
**Syntax:**
```
POKE <address>[<offset>] WITH <value>
```
**Examples:**
```
POKE $D020 WITH 0
POKE screenPtr[index] WITH char
POKE buffer[5] WITH data
POKE pointer WITH value
```
---
## POKEW
Writes word (16-bit) to memory location.
**Syntax:**
```
POKEW <address>[<offset>] WITH <value>
```
**Examples:**
```
POKEW $0314 WITH handler
POKEW dataPtr[0] WITH value
POKEW buffer[10] WITH address
```
---
## SUBEND
Returns from subroutine.
**Syntax:**
```
SUBEND
```
or
```
EXIT
```
**Examples:**
```
LABEL subroutine
counter = counter + 1
SUBEND
LABEL checkValue
IF value = 0
EXIT
ENDIF
process(value)
SUBEND
```
---
## SUBTR
Subtracts second value from first.
**Syntax:**
```
<dest> = <param1> - <param2>
```
**Examples:**
```
result = 100 - 5
difference = end - start
remaining = total - used
```
---
## WEND
Terminates WHILE loop.
**Syntax:**
```
See WHILE
```
---
## WHILE
Loop that continues while condition is true.
When single parameter: 0 = false, non-zero = true
**Syntax:**
```
WHILE <param1> [<operator> <param2>]
```
Operators: `=` `==` `<>` `!=` `>` `<` `>=` `<=`
**Examples:**
```
WHILE counter < 100
counter++
result = result + counter
WEND
WHILE running
processFrame
checkInput
WEND
WHILE x != y
x++
WEND
```
---
## WORD
Declares a 16-bit variable or constant.
**Syntax:**
```
WORD <varname>
WORD <varname> = <value>
WORD <varname> = "<string>"
WORD <varname> @ <address>
WORD CONST <varname> = <value>
```
**Examples:**
```
WORD counter
WORD address = $C000
WORD message = "Hello"
WORD irqVector @ $0314
WORD CONST SCREEN = $0400
```
---
## XOR
Bitwise XOR operation between two values.
**Syntax:**
```
<dest> = <param1> ^ <param2>
```
**Examples:**
```
result = value ^ $FF
output = byte1 ^ byte2
toggleBits = flags ^ mask
```

481
syntax.md Normal file
View file

@ -0,0 +1,481 @@
# Syntax Reference
## Comments
C65GM uses C-style line comments.
**Syntax:**
```
// <comment text>
```
**Examples:**
```
BYTE counter = 0 // Initialize counter
// This is a full line comment
FOR i = 0 TO 10 // Loop through values
counter++ // Increment
NEXT
```
**Notes:**
- Comments start with `//` and continue to end of line
- Comments in ASM blocks use assembly syntax: `;`
- Comments in SCRIPT blocks use Starlark syntax: `#`
---
## Preprocessor Directives
### #DEFINE
Defines a text substitution macro.
**Syntax:**
```
#DEFINE <n> [= <value>]
```
**Examples:**
```
#DEFINE MAX_SPEED = 10
#DEFINE SCREEN = $0400
#DEFINE OFFSET = 255
#DEFINE BASE+DELTA = $D000+32
```
**Notes:**
- Optional `=` separator
- Value can contain previously defined macros
- Macros are expanded in source lines
- Case sensitive
---
### #UNDEF
Undefines a previously defined macro.
**Syntax:**
```
#UNDEF <n>
```
**Examples:**
```
#DEFINE DEBUG = 1
#UNDEF DEBUG
```
---
### #IFDEF
Conditional compilation if macro is defined.
**Syntax:**
```
#IFDEF <n>
```
**Examples:**
```
#IFDEF DEBUG
BYTE debugFlag = 1
#IFEND
#IFDEF PAL
BYTE scanlines = 312
#IFEND
```
---
### #IFNDEF
Conditional compilation if macro is not defined.
**Syntax:**
```
#IFNDEF <n>
```
**Examples:**
```
#IFNDEF __INCLUDED_SPRITE_LIB
#DEFINE __INCLUDED_SPRITE_LIB = 1
FUNC drawSprite
; sprite code
FEND
#IFEND
```
**Notes:**
- Common pattern for include guards
- Prevents multiple inclusion
---
### #IFEND
Ends conditional compilation block.
**Syntax:**
```
#IFEND
```
**Examples:**
```
See #IFDEF and #IFNDEF
```
---
### #INCLUDE
Includes another source file.
**Syntax:**
```
#INCLUDE <filename>
#INCLUDE <libfile>
```
**Examples:**
```
#INCLUDE sprites.c65
#INCLUDE lib/math.c65
#INCLUDE "constants.c65"
#INCLUDE <stdlib.c65>
```
**Notes:**
- Relative path: resolves relative to current file
- Angle brackets `<file>`: searches in library path defined by C65LIBPATH environment variable
- Supports nested includes
- Use with #IFNDEF for include guards
---
### #PRINT
Prints message during compilation.
**Syntax:**
```
#PRINT <message>
```
**Examples:**
```
#PRINT Compiling main module
#PRINT MAX_VALUE
#PRINT Debug build enabled
```
**Notes:**
- Useful for debugging preprocessor
- Macros expanded before printing
---
### #HALT
Stops compilation immediately.
**Syntax:**
```
#HALT
```
**Examples:**
```
#IFDEF INCOMPLETE
#PRINT Feature not implemented
#HALT
#IFEND
```
**Notes:**
- Halts entire compilation process, not just preprocessing
- Returns exit code 2
---
### #PRAGMA
Sets compiler pragmas (options).
**Syntax:**
```
#PRAGMA <n> [<value>]
```
**Available Pragmas:**
**_P_USE_LONG_JUMP**
- Uses JMP instead of branch instructions for IF/WHILE/FOR
- Needed when branch targets exceed 127 byte range
- Value: any non-zero value enables
**_P_USE_IMMUTABLE_CODE**
- Prevents self-modifying code generation
- Required for ROM-based code
- Errors on PEEK/POKE/GOSUB with variable addresses
**_P_USE_CBM_STRINGS**
- Encodes strings in CBM PETSCII format
- Default: ASCII encoding
- Value: any non-empty value enables
**Examples:**
```
#PRAGMA _P_USE_LONG_JUMP 1
#PRAGMA _P_USE_IMMUTABLE_CODE 1
#PRAGMA _P_USE_CBM_STRINGS 1
```
---
## Code Blocks
### ASM...ENDASM
Inline assembly code block.
**Syntax:**
```
ASM
<assembly code>
ENDASM
```
**Examples:**
```
ASM
lda #$00
sta $d020
jsr $ffd2
ENDASM
BYTE temp = 5
ASM
lda temp
clc
adc #10
sta temp
ENDASM
FUNC calculate(value)
BYTE local = 10
ASM
lda |local| ; Reference local variable
clc
adc value
sta |local|
ENDASM
FEND
```
**Notes:**
- Assembly code passed through to ACME assembler unchanged
- Can reference global variables by name
- Local variables inside FUNC must use `|varname|` syntax
- Comments in ASM blocks use `;` (assembly syntax)
- No macro expansion inside ASM blocks
---
### SCRIPT...ENDSCRIPT
Starlark script code block for generating assembly code.
Scripts are written in Starlark (Python-like language) and executed at compile time. Output from `print()` statements is fed directly into the assembler.
**Syntax:**
```
SCRIPT
<starlark code>
ENDSCRIPT
```
**Examples:**
**Simple data generation:**
```
SCRIPT
for i in range(256):
print(" !byte %d" % i)
ENDSCRIPT
```
**Sine table generation:**
```
SCRIPT
import math
print("sintable:")
for i in range(256):
angle = (i * 2.0 * math.pi) / 256.0
sine = math.sin(angle)
value = int((sine + 1.0) * 127.5)
print(" !byte %d" % value)
ENDSCRIPT
```
**Using compiler variables:**
```
BYTE tableSize = 64
SCRIPT
# Reference variables in generated assembly
print("lookup:")
for i in range(64):
print(" !byte %d" % (i * 2))
print(" ; Table size is stored in |tableSize|")
ENDSCRIPT
```
**Notes:**
- Scripts use Starlark language (Python-like subset)
- Comments in SCRIPT blocks use `#` (Python syntax)
- Output from `print()` goes directly to assembler
- Can reference compiler variables using `|varname|` syntax
- Math module available: `import math`
- Maximum 1 million execution steps (prevents infinite loops)
- Executed at compile time, not runtime
---
## Expression Syntax
Expressions evaluate left to right with no operator precedence.
### Number Formats
**Decimal:**
```
123
0
255
65535
```
**Hexadecimal ($-prefix):**
```
$FF
$D020
$C000
$00
```
**Binary (%-prefix):**
```
%11111111
%10000000
%00000001
%11110000
```
### Operators
Evaluated strictly left to right:
- `+` Addition
- `-` Subtraction
- `*` Multiplication
- `/` Division
- `|` Bitwise OR
- `&` Bitwise AND
### Constants
Named constants defined with BYTE CONST or WORD CONST:
```
BYTE CONST MAX_SPEED = 10
WORD CONST SCREEN = $0400
speed = MAX_SPEED
pointer = SCREEN
```
### Expression Examples
```
value = 100+50
result = $FF-10
address = $D000+32
mask = %11110000&$0F
combined = base|offset
calculated = start+length*2
```
**Critical:** No operator precedence. Evaluation is strictly left to right:
```
result = 2+3*4 ; evaluates as (2+3)*4 = 20, not 2+(3*4) = 14
value = $10|$20&$0F ; evaluates as ($10|$20)&$0F, not $10|($20&$0F)
```
### Usage Contexts
Expressions accepted anywhere a numeric literal is expected:
**Variable initialization:**
```
BYTE count = 10+5
WORD addr = $C000+$100
```
**Absolute addresses:**
```
BYTE screen @ $0400+40*10
INC $D000+20
```
**Command parameters:**
```
FOR i = 0 TO MAX_VALUE-1
IF x > THRESHOLD+10
POKE $D020+offset WITH value
result = PEEK $0400+index
```
**Arithmetic operations:**
```
sum = value1+value2
product = base*factor
adjusted = original+OFFSET
```
### Limitations
**No parentheses for grouping:**
```
; NOT SUPPORTED:
result = (a+b)*c
value = base+(offset*2)
```
**No nested expressions in assignments:**
```
; NOT SUPPORTED:
x = y + z ; only single value or constant expression
x = a+b ; constant expression (no spaces) OK if a,b are constants
```
**Workaround for complex expressions:**
Use temporary variables:
```
temp = a + b
result = temp * c
```
### Constant Expressions
Expressions without spaces are treated as constant expressions:
```
value = 100+50 ; OK - constant expression
value = 100 + 50 ; ERROR - not a simple assignment
value = MAX+10 ; OK if MAX is constant
```