c65gm/commands.md

863 lines
No EOL
12 KiB
Markdown

# 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>
<funcname>()
<funcname>(<param1>[,<param2>,...])
```
**Arguments can be:**
- Variables: `myvar`
- Constants or literals: `42`, `$FF`
- String literals: `"hello"` (passed as pointer to WORD parameter)
- Label addresses: `@spriteData` (passed as pointer to WORD parameter)
**Examples:**
```
initialize
initialize()
setColor(1,14)
drawSprite(xpos,ypos,@spriteData)
process("hello",42,myvar)
```
---
## CASE
Defines a case branch within SWITCH statement.
**Syntax:**
```
See SWITCH
```
---
## DEC
Decrements a variable or memory location by 1.
**Syntax:**
```
<var>--
DEC <target>
DECREMENT <target>
```
**Examples:**
```
counter--
lives--
index--
DEC $D020
DECREMENT screenColor
```
---
## DEFAULT
Defines the default branch in SWITCH statement.
**Syntax:**
```
See SWITCH
```
---
## ELSE
Alternative branch in IF statement.
**Syntax:**
```
See IF
```
---
## ENDIF
Terminates IF block.
**Syntax:**
```
See IF
```
---
## ENDSWITCH
Terminates SWITCH block.
**Syntax:**
```
See SWITCH
```
---
## FEND
Ends a function definition.
**Syntax:**
```
See FUNC
```
---
## FOR
Loop with automatic counter increment.
**Syntax:**
```
FOR <iterator> = <start_value> TO <end_value>
```
**Examples:**
```
FOR i = 0 TO 10
screen = i
NEXT
FOR counter = start TO finish
process(counter)
NEXT
```
---
## FUNC
Defines a function with optional parameters. Functions must be terminated with `FEND`.
**Modern syntax (recommended):** Use implicit declarations with curly braces for self-contained functions with local parameters.
**Legacy syntax:** Can use pre-declared global variables for direct memory access.
Parameter passing modes: `in:` (default, read-only), `out:` (write-only), `io:` (read-write)
**Syntax:**
```
FUNC name # void function
FUNC name ( {BYTE param} ) # single parameter (modern)
FUNC name ( {BYTE a} {BYTE b} ) # multiple parameters (modern)
FUNC name ( in:{BYTE x} out:{BYTE y} io:{BYTE z} ) # all direction modifiers
FUNC name ( {BYTE param @ $fa} ) # parameter at absolute address
FUNC name ( param ) # single pre-declared variable (legacy)
FUNC name ( a b ) # multiple pre-declared vars (legacy)
FUNC name ( in:x out:y io:z ) # direction with pre-declared (legacy)
```
**Examples:**
```
// Modern: self-contained function with local parameters
FUNC add({BYTE a} {BYTE b} out:{BYTE result})
result = a + b
FEND
// Modern: with direction modifiers
FUNC process(in:{BYTE input} out:{BYTE output})
output = input + 1
FEND
// Modern: io parameter (read-write)
FUNC increment(io:{BYTE counter})
counter = counter + 1
FEND
// Modern: absolute address parameter
FUNC read_byte({BYTE data @ $fa})
BYTE temp
temp = data // Reads from $fa
FEND
// Legacy: uses global variables directly
BYTE x
BYTE y
FUNC swap_legacy ( x y )
BYTE temp
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 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.
For operating with offsets the address parameter must be an absolute WORD variable in the zero page.
**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 at address.
For operating with offsets the address parameter must be an absolute WORD variable in the zero page.
**Syntax:**
```
<dest> = PEEKW <address>[<offset>]
```
**Examples:**
```
reset_addr = PEEKW $FFFE
WORD buffer @ $fd
offset_val = PEEKW buff_ptr[10]
WORD pointer
val = PEEKW pointer
```
---
## POINT
Sets pointer variable to address of target.
**Syntax:**
```
POINTER <ptrvar> TO <target>
```
**Examples:**
```
POINTER screenPtr TO $0400
POINTER buff_ptr TO buffer // buffer might be a label to some data
POINTER funcPtr TO myFunction
```
---
## POKE
Writes byte to memory location.
For operating with offsets the address parameter must be an absolute WORD variable in the zero page.
**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.
For operating with offsets the address parameter must be an absolute WORD variable in the zero page.
**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
```
---
## SHIFTL
Logical shift left operation.
**Syntax:**
```
SHIFTL <source> BY <amount> GIVING <dest>
SHIFTL <source> << <amount> -> <dest>
<dest> = <source> << <amount>
```
**Parameters:**
- `source`: BYTE or WORD variable or constant expression
- `amount`: BYTE variable or constant expression (0-255)
- `dest`: BYTE or WORD variable (cannot be constant)
**Notes:**
- Logical shift only (no sign extension)
- Shift amount of 0 copies source to dest unchanged
- Shift amount ≥ bit-width yields zero (≥8 for BYTE, ≥16 for WORD)
- BYTE→WORD conversion zero-extends before shifting
- WORD→BYTE conversion truncates low byte only
**Examples:**
```
result = value << 3
SHIFTL mask BY bits GIVING shifted
SHIFTR flags >> 2 -> masked
```
---
## SHIFTR
Logical shift right operation.
**Syntax:**
```
SHIFTR <source> BY <amount> GIVING <dest>
SHIFTR <source> >> <amount> -> <dest>
<dest> = <source> >> <amount>
```
**Parameters:**
- `source`: BYTE or WORD variable or constant expression
- `amount`: BYTE variable or constant expression (0-255)
- `dest`: BYTE or WORD variable (cannot be constant)
**Notes:**
- Logical shift only (no sign extension)
- Shift amount of 0 copies source to dest unchanged
- Shift amount ≥ bit-width yields zero (≥8 for BYTE, ≥16 for WORD)
- BYTE→WORD conversion zero-extends before shifting
- WORD→BYTE conversion truncates low byte only
**Examples:**
```
mask = flags >> 2
SHIFTR value BY shift GIVING result
SHIFTR data >> 4 -> nibble
```
---
## SUBTR
Subtracts second value from first.
**Syntax:**
```
<dest> = <param1> - <param2>
```
**Examples:**
```
result = 100 - 5
difference = end - start
remaining = total - used
```
---
## SWITCH
Multi-way branching based on variable value comparison.
Features implicit breaks (automatic jump to ENDSWITCH after each case), supports nesting, and works with BYTE and WORD types.
**Syntax:**
```
SWITCH <variable>
CASE <value>
[statements]
[CASE <value>
[statements]]
[DEFAULT
[statements]]
ENDSWITCH
```
**Notes:**
- Each CASE automatically breaks (jumps to ENDSWITCH) after execution
- CASE values can be literals, constants, or variables
- DEFAULT branch is optional and executes when no CASE matches
- DEFAULT must come after all CASE statements
- Only one DEFAULT per SWITCH
- BYTE variables can only be compared with values 0-255
- Can use `#PRAGMA _P_USE_LONG_JUMP 1` for large switch statements
- Nested SWITCH statements are supported
**Examples:**
```
// Basic switch with default
SWITCH status
CASE 1
result = 10
CASE 2
result = 20
DEFAULT
result = 0
ENDSWITCH
// Switch with constants
BYTE CONST MAX = 100
SWITCH value
CASE MAX
overflow = 1
CASE 50
halfway = 1
ENDSWITCH
// WORD switch
WORD big_val
SWITCH big_val
CASE 1000
mode = 1
CASE 5000
mode = 2
DEFAULT
mode = 0
ENDSWITCH
// Nested switch
SWITCH outer
CASE 1
result = 1
CASE 2
SWITCH inner
CASE 10
result = 20
CASE 20
result = 40
ENDSWITCH
DEFAULT
result = 0
ENDSWITCH
// Using variables in CASE
BYTE threshold1
BYTE threshold2
LET threshold1 = 50
LET threshold2 = 100
SWITCH temperature
CASE threshold1
fan_speed = 1
CASE threshold2
fan_speed = 2
DEFAULT
fan_speed = 0
ENDSWITCH
```
---
## 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> = @<label>
WORD <varname> @ <address>
WORD CONST <varname> = <value>
```
**Examples:**
```
WORD counter
WORD address = $C000
WORD message = "Hello"
WORD spritePtr = @spriteData
WORD irqVector @ $0314
WORD CONST SCREEN = $0400
```
The `@<label>` syntax initializes a WORD variable with the address of a label. This is useful for pointers to data blocks or code labels. The label can be a forward reference (declared later in the source) or an existing variable name. For local variables, the name is automatically expanded to the full scoped name.
---
## XOR
Bitwise XOR operation between two values.
**Syntax:**
```
<dest> = <param1> ^ <param2>
```
**Examples:**
```
result = value ^ $FF
output = byte1 ^ byte2
toggleBits = flags ^ mask
```