c65gm/commands.md

15 KiB

Compiler Commands Reference

Index

  • ADD - Adds two values
  • AND - Bitwise AND operation
  • BREAK - Exits current loop
  • BYTE - Declares 8-bit variable or constant
  • CALL - Calls function with parameters
  • CASE - Case branch in SWITCH statement
  • DEC - Decrements variable or memory location
  • DEFAULT - Default branch in SWITCH statement
  • ELSE - Alternative branch in IF statement
  • ENDIF - Terminates IF block
  • ENDSWITCH - Terminates SWITCH block
  • FEND - Ends function definition
  • FOR - Loop with automatic counter increment
  • FUNC - Defines function with parameters
  • GOSUB - Calls subroutine with register passing
  • GOTO - Unconditional jump to label
  • IF - Conditional execution
  • INC - Increments variable or memory location
  • LABEL - Creates named assembly label
  • LET - Assigns value to variable
  • NEXT - Terminates FOR loop
  • OR - Bitwise OR operation
  • ORIGIN - Sets assembly origin address
  • PEEK - Reads byte from memory
  • PEEKW - Reads word from memory
  • POINTER - Sets pointer to address
  • POKE - Writes byte to memory
  • POKEW - Writes word to memory
  • SUBEND - Returns from subroutine
  • SHIFTL - Logical shift left
  • SHIFTR - Logical shift right
  • SUBTR - Subtracts values
  • SWITCH - Multi-way branching
  • WEND - Terminates WHILE loop
  • WHILE - Loop while condition true
  • WORD - Declares 16-bit variable or constant
  • XOR - Bitwise XOR operation

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:

// BREAK in FOR loop
FOR i = 0 TO 100
    IF i = 50
        BREAK
    ENDIF
NEXT
// BREAK in WHILE loop
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.

See SWITCH for syntax and examples.


DEC

Decrements a variable or memory location by 1.

Syntax:

<var>--
DEC <target>
DECREMENT <target>

Examples:

// Modern: decrement variables
counter--
lives--
index--
// Alternative: decrement memory location
DEC $D020
// Legacy: DECREMENT form
DECREMENT screenColor

DEFAULT

Defines the default branch in SWITCH statement.

See SWITCH for syntax and examples.


ELSE

Alternative branch in IF statement.

See IF for syntax and examples.


ENDIF

Terminates IF block.

See IF for syntax and examples.


ENDSWITCH

Terminates SWITCH block.

See SWITCH for syntax and examples.


FEND

Ends a function definition.

See FUNC for syntax and examples.


FOR

Loop with automatic counter increment.

Syntax:

FOR <iterator> = <start_value> TO <end_value>

Examples:

// FOR loop with literal values
FOR i = 0 TO 10
    screen = i
NEXT
// FOR loop with variables
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:

// Simple IF statement
IF count == 10
    result = 1
ENDIF
// IF with ELSE branch
IF value > threshold
    process(value)
ELSE
    skip(value)
ENDIF
// IF-ELSE with actions
IF x < 100
    x++
ELSE
    x = 0
ENDIF

INC

Increments a variable or memory location by 1.

Syntax:

<var>++
INC <target>
INCREMENT <target>

Examples:

// Modern: increment variables
counter++
index++
frameCount++
// Alternative: increment memory location
INC $D020
// Legacy: INCREMENT form
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.

See FOR for syntax and examples.


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:

// Read from absolute address
reset_addr = PEEKW $FFFE
// Read with offset (requires WORD variable in zero page)
WORD buffer @ $fd
offset_val = PEEKW buffer[10]
// Read through pointer
WORD pointer
val = PEEKW pointer

POINTER

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:

// Simple subroutine with SUBEND
LABEL subroutine
    counter = counter + 1
    SUBEND
// Subroutine with early EXIT
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:

// Modern: assignment form
result = value << 3
// Alternative: arrow form
SHIFTL flags << 2 -> masked
// Legacy: verbose form
SHIFTL mask BY bits GIVING shifted

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:

// Modern: assignment form
mask = flags >> 2
// Alternative: arrow form
SHIFTR data >> 4 -> nibble
// Legacy: verbose form
SHIFTR value BY shift GIVING result

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.

See WHILE for syntax and examples.


WHILE

Loop that continues while condition is true.

When single parameter: 0 = false, non-zero = true

Syntax:

WHILE <param1> [<operator> <param2>]

Operators: = == <> != > < >= <=

Examples:

// WHILE with numeric comparison
WHILE counter < 100
    counter++
    result = result + counter
WEND
// WHILE with boolean condition
WHILE running
    processFrame
    checkInput
WEND
// WHILE with inequality
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