UTTORI ASM · IN DEVELOPMENT
Macros
Define and call reusable source macros with local labels and arguments.
On this page
SNES behavior
Macros emit commands, not values:
macro SetBrightness(level)
lda #<level>
sta $2100
endmacro
%SetBrightness($0F)
Headers use macro Name(arg, arg) and calls use %Name(value, value). Arguments are comma-split with quoted text preserved. Inside the body, <parameter> inserts the supplied source text. !<parameter> treats the argument as a define name.
Variadic macros put ... or the single-character ellipsis … last:
macro EmitBytes(required, ...)
db <required>
if sizeof(...) > 0
db <...[0]>
endif
endmacro
%EmitBytes($10, $20, $30)
sizeof(...) is the extra-argument count and <...[expression]> selects one extra argument. The expression can use defines. Out-of-range indices are errors. The older <!a> form for alphabetic variadic positions is accepted but deprecated.
Macro bodies can contain conditionals, while, for, define assignments, and macro-local labels. Duplicate macro definitions are rejected. See variadic_syntax.asm, macrolabels.asm, and macro-engine.ts.
6502 family behavior
Native macros emit commands, not values:
macro SetByte(addr, value)
lda #<value>
sta <addr>
endmacro
%SetByte($10, $42)
ca65 macros use dotted headers, \parameter substitution, and bare invocation:
.macro emit value
.byte \value
.endmacro
emit $22
Variadic native macros, sizeof(...), and macro-local ? labels follow the shared SNES macro engine. ca65 .local and .exitmacro are rejected with a macro-compatibility diagnostic. Token-list/string macros are not implemented.