Topics

UTTORI ASM · IN DEVELOPMENT

Expressions and defines

Compute assembly values with defines, operators, functions, and binary directives.

On this page

Try expressions and binary data

Edit the define and arithmetic operands in this raw 6502 example. db emits bytes, while dw emits a little-endian word.

Output bytes12 23 02 01

Expected output

SNES behavior

Defines

Defines are textual values prefixed by !:

!Lives = 3
!Message = "READY"

db !Lives
db "!Message"

Supported assignment operators are:

Operator Behavior
= Store the value. Pure math-looking values may be folded
+= Append text to the current value
:= Resolve referenced defines before storing
#= Resolve and evaluate as a math expression, then store decimal text
?= Assign only if the define does not already exist

Remove a define with undef Name, undef !Name, or undef "Name".

Nested define names use braces:

!slot = 2
!value2 = $40
db !{value!slot}

In string data, \!Name emits a literal !Name, while \\ emits one backslash. Defines can expand to comma-separated data lists and can appear in include filenames.

Operators

Higher rows bind more tightly:

Precedence Operators Meaning
6 ** exponentiation
5 *, /, % multiply, divide, modulo
4 +, - add, subtract
3 <<, >>, &, |, ^ shifts and bitwise operations
2 <, >, <=, >=, ==, =, != comparisons, returning 0 or 1
1 && logical AND
0 || logical OR

Operators at the same level are left-associative. Parentheses override precedence. Division or modulo by zero is an assembly error.

Core Built-In Functions

Family Functions
Numeric sqrt, sin, cos, tan, asin/arcsin, acos/arccos, atan/arctan, log, log10, log2, ceil, floor, round
Selection min, max, clamp, safediv, select
Logical comparison not, equal, notequal, less, lessequal, greater, greaterequal, and, or, nand, nor, xor
Address helpers bank(value), offset(from,to), pc(), realbase()
Strings and symbols stringsequal, stringsequalnocase, defined, sizeof, objectsize, datasize, countof, bytesof, startof, endof
Files filesize, getfilestatus, canreadfile1...canreadfile4, canreadfile, readfile1...readfile4

File reads are little-endian. readfileN(filename, position[, default]) accepts a fallback for an unavailable range. canreadfile(filename, position, size) handles an arbitrary byte count. getfilestatus() returns the host's status code. The supported fixture treats 0 as present.

SNES Expression Functions

Function Current behavior
snestopc(address) Convert a mapped CPU address to a ROM offset
pctosnes(offset) Convert a ROM offset to a preferred mapped CPU address
canread1...canread4 Test a fixed-size range against the base/output image length
canread(position,size) Test an arbitrary range against the base/output image length
read1...read4 Map a logical SNES address and read a little-endian value

readN(position, default) returns the fallback when the mapped range is unavailable. Without a fallback, reads are disabled until check title appears, matching the plugin's selected compatibility policy:

check title
assert read1($00FFD5) == $20, "Expected LoROM header"

When patching, these functions read baseImage. On a fresh build they read the current output buffer. canread* takes range positions; mapped read* functions take logical addresses. Use the address form required by each function.

User Functions

function lowbyte(value) = value & $FF
function tilebytes(count, bpp) = count * 8 * bpp

db lowbyte($1234)
dw tilebytes(16, 4)

Definitions may continue with backslash-newline. Parameters are substituted into the expression, and a later definition with the same name replaces the earlier one. Functions return numeric expression values.

6502 family behavior

Native Defines

On 65xx.raw, defines are textual values prefixed by !:

!Lives = 3
!Message = "READY"
db !Lives

Supported assignment operators are =, +=, :=, #=, and ?=. undef Name removes a define. Nested names use !{value!slot}. See the SNES defines section for the shared engine.

ca65 Symbols

ca65 targets use := / = symbol assignment rather than ! defines for ordinary constants. .undefine ident removes a symbol. .ifdef / .ifndef test whether a name exists.

Operators

Higher rows bind more tightly:

Precedence Operators Meaning
6 ** exponentiation
5 *, /, % multiply, divide, modulo
4 +, - add, subtract
3 <<, >>, &, |, ^ shifts and bitwise operations
2 <, >, <=, >=, ==, =, !=, <> comparisons, returning 0 or 1. <> is ca65 inequality
1 && logical AND
0 || logical OR

Operators at the same level are left-associative. Parentheses override precedence. Division or modulo by zero is an assembly error.

Core Built-In Functions

Native sources have the shared numeric, selection, logical, address, string, and file helpers documented in the SNES expression section: sqrt, min, bank, defined, filesize, readfile1, and so on.

ca65 Expression Functions

Installed only on ca65-profile targets:

Function Current behavior
lobyte(value) / .lobyte(value) value & $FF
hibyte(value) / .hibyte(value) (value >> 8) & $FF
bankbyte(value) / .bankbyte(value) (value >> 16) & $FF
loword(value) / .loword(value) value & $FFFF
hiword(value) / .hiword(value) (value >> 16) & $FFFF
.defined(name) rewritten to defined(name)
.byte @17, .lobyte($1234), .hibyte($1234), .bankbyte($123456)
.word .loword($12345678), .hiword($12345678)
lda #<Label
lda #>Label

User Functions

Native function name(args) = expression is available on 65xx.raw. ca65 token-list functions (.mid, .left, .match, .xmatch, .concat, .sprintf, …) are not implemented.