mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Reword docs now that SET is deprecated (#946)
- '=' constants are "variables" (not "mutable constants") - EQU constants are "numeric constants" (not "immutable constants") - EQUS constants are "string constants" (not "string equates") - DS declarations are "static allocations" (not "variables")
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
enum SymbolType {
|
enum SymbolType {
|
||||||
SYM_LABEL,
|
SYM_LABEL,
|
||||||
SYM_EQU,
|
SYM_EQU,
|
||||||
SYM_SET,
|
SYM_VAR,
|
||||||
SYM_MACRO,
|
SYM_MACRO,
|
||||||
SYM_EQUS,
|
SYM_EQUS,
|
||||||
SYM_REF // Forward reference to a label
|
SYM_REF // Forward reference to a label
|
||||||
@@ -75,12 +75,12 @@ static inline bool sym_IsConstant(struct Symbol const *sym)
|
|||||||
|
|
||||||
return sect && sect->org != (uint32_t)-1;
|
return sect && sect->org != (uint32_t)-1;
|
||||||
}
|
}
|
||||||
return sym->type == SYM_EQU || sym->type == SYM_SET;
|
return sym->type == SYM_EQU || sym->type == SYM_VAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool sym_IsNumeric(struct Symbol const *sym)
|
static inline bool sym_IsNumeric(struct Symbol const *sym)
|
||||||
{
|
{
|
||||||
return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_SET;
|
return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_VAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool sym_IsLabel(struct Symbol const *sym)
|
static inline bool sym_IsLabel(struct Symbol const *sym)
|
||||||
@@ -119,7 +119,7 @@ void sym_WriteAnonLabelName(char buf[MIN_NB_ELMS(MAXSYMLEN + 1)], uint32_t ofs,
|
|||||||
void sym_Export(char const *symName);
|
void sym_Export(char const *symName);
|
||||||
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
|
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
|
||||||
struct Symbol *sym_RedefEqu(char const *symName, int32_t value);
|
struct Symbol *sym_RedefEqu(char const *symName, int32_t value);
|
||||||
struct Symbol *sym_AddSet(char const *symName, int32_t value);
|
struct Symbol *sym_AddVar(char const *symName, int32_t value);
|
||||||
uint32_t sym_GetPCValue(void);
|
uint32_t sym_GetPCValue(void);
|
||||||
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
|
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
|
||||||
uint32_t sym_GetConstantValue(char const *symName);
|
uint32_t sym_GetConstantValue(char const *symName);
|
||||||
|
|||||||
@@ -241,11 +241,11 @@ bool yywrap(void)
|
|||||||
/* If this is a FOR, update the symbol value */
|
/* If this is a FOR, update the symbol value */
|
||||||
if (contextStack->forName && fileInfo->iters[0] <= contextStack->nbReptIters) {
|
if (contextStack->forName && fileInfo->iters[0] <= contextStack->nbReptIters) {
|
||||||
contextStack->forValue += contextStack->forStep;
|
contextStack->forValue += contextStack->forStep;
|
||||||
struct Symbol *sym = sym_AddSet(contextStack->forName,
|
struct Symbol *sym = sym_AddVar(contextStack->forName,
|
||||||
contextStack->forValue);
|
contextStack->forValue);
|
||||||
|
|
||||||
/* This error message will refer to the current iteration */
|
/* This error message will refer to the current iteration */
|
||||||
if (sym->type != SYM_SET)
|
if (sym->type != SYM_VAR)
|
||||||
fatalerror("Failed to update FOR symbol value\n");
|
fatalerror("Failed to update FOR symbol value\n");
|
||||||
}
|
}
|
||||||
/* Advance to the next iteration */
|
/* Advance to the next iteration */
|
||||||
@@ -478,9 +478,9 @@ void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
|||||||
dbgPrint("Running FOR(\"%s\", %" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
|
dbgPrint("Running FOR(\"%s\", %" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
|
||||||
symName, start, stop, step);
|
symName, start, stop, step);
|
||||||
|
|
||||||
struct Symbol *sym = sym_AddSet(symName, start);
|
struct Symbol *sym = sym_AddVar(symName, start);
|
||||||
|
|
||||||
if (sym->type != SYM_SET)
|
if (sym->type != SYM_VAR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ static void compoundAssignment(const char *symName, enum RPNCommand op, int32_t
|
|||||||
rpn_Number(&constExpr, constValue);
|
rpn_Number(&constExpr, constValue);
|
||||||
rpn_BinaryOp(op, &newExpr, &oldExpr, &constExpr);
|
rpn_BinaryOp(op, &newExpr, &oldExpr, &constExpr);
|
||||||
newValue = rpn_GetConstVal(&newExpr);
|
newValue = rpn_GetConstVal(&newExpr);
|
||||||
sym_AddSet(symName, newValue);
|
sym_AddVar(symName, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initDsArgList(struct DsArgList *args)
|
static void initDsArgList(struct DsArgList *args)
|
||||||
@@ -927,11 +927,11 @@ compoundeq : T_POP_ADDEQ { $$ = RPN_ADD; }
|
|||||||
equ : T_LABEL T_POP_EQU const { sym_AddEqu($1, $3); }
|
equ : T_LABEL T_POP_EQU const { sym_AddEqu($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
set : T_LABEL T_POP_EQUAL const { sym_AddSet($1, $3); }
|
set : T_LABEL T_POP_EQUAL const { sym_AddVar($1, $3); }
|
||||||
| T_LABEL compoundeq const { compoundAssignment($1, $2, $3); }
|
| T_LABEL compoundeq const { compoundAssignment($1, $2, $3); }
|
||||||
| T_LABEL T_POP_SET const {
|
| T_LABEL T_POP_SET const {
|
||||||
warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
|
warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
|
||||||
sym_AddSet($1, $3);
|
sym_AddVar($1, $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -940,19 +940,19 @@ equs : T_LABEL T_POP_EQUS string { sym_AddString($1, $3); }
|
|||||||
|
|
||||||
rb : T_LABEL T_POP_RB rs_uconst {
|
rb : T_LABEL T_POP_RB rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rw : T_LABEL T_POP_RW rs_uconst {
|
rw : T_LABEL T_POP_RW rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + 2 * $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rl : T_LABEL T_Z80_RL rs_uconst {
|
rl : T_LABEL T_Z80_RL rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + 4 * $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1116,10 +1116,10 @@ macrodef : T_POP_MACRO {
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rsset : T_POP_RSSET uconst { sym_AddSet("_RS", $2); }
|
rsset : T_POP_RSSET uconst { sym_AddVar("_RS", $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rsreset : T_POP_RSRESET { sym_AddSet("_RS", 0); }
|
rsreset : T_POP_RSRESET { sym_AddVar("_RS", 0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rs_uconst : %empty { $$ = 1; }
|
rs_uconst : %empty { $$ = 1; }
|
||||||
@@ -1174,35 +1174,35 @@ def_equ : def_id T_POP_EQU const { sym_AddEqu($1, $3); }
|
|||||||
redef_equ : redef_id T_POP_EQU const { sym_RedefEqu($1, $3); }
|
redef_equ : redef_id T_POP_EQU const { sym_RedefEqu($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
def_set : def_id T_POP_EQUAL const { sym_AddSet($1, $3); }
|
def_set : def_id T_POP_EQUAL const { sym_AddVar($1, $3); }
|
||||||
| redef_id T_POP_EQUAL const { sym_AddSet($1, $3); }
|
| redef_id T_POP_EQUAL const { sym_AddVar($1, $3); }
|
||||||
| def_id compoundeq const { compoundAssignment($1, $2, $3); }
|
| def_id compoundeq const { compoundAssignment($1, $2, $3); }
|
||||||
| redef_id compoundeq const { compoundAssignment($1, $2, $3); }
|
| redef_id compoundeq const { compoundAssignment($1, $2, $3); }
|
||||||
| def_id T_POP_SET const {
|
| def_id T_POP_SET const {
|
||||||
warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
|
warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
|
||||||
sym_AddSet($1, $3);
|
sym_AddVar($1, $3);
|
||||||
}
|
}
|
||||||
| redef_id T_POP_SET const {
|
| redef_id T_POP_SET const {
|
||||||
warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
|
warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
|
||||||
sym_AddSet($1, $3);
|
sym_AddVar($1, $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
def_rb : def_id T_POP_RB rs_uconst {
|
def_rb : def_id T_POP_RB rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
def_rw : def_id T_POP_RW rs_uconst {
|
def_rw : def_id T_POP_RW rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + 2 * $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
def_rl : def_id T_Z80_RL rs_uconst {
|
def_rl : def_id T_Z80_RL rs_uconst {
|
||||||
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
sym_AddEqu($1, sym_GetConstantValue("_RS"));
|
||||||
sym_AddSet("_RS", sym_GetConstantValue("_RS") + 4 * $3);
|
sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1312,13 +1312,13 @@ printv : T_POP_PRINTV const {
|
|||||||
;
|
;
|
||||||
|
|
||||||
printi : T_POP_PRINTI const {
|
printi : T_POP_PRINTI const {
|
||||||
warning(WARNING_OBSOLETE, "`PRINTI` is deprecated; use `PRINT` with `STRFMT`\n");
|
warning(WARNING_OBSOLETE, "`PRINTI` is deprecated; use `PRINT` with `STRFMT` \"%%d\"\n");
|
||||||
printf("%" PRId32, $2);
|
printf("%" PRId32, $2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
printf : T_POP_PRINTF const {
|
printf : T_POP_PRINTF const {
|
||||||
warning(WARNING_OBSOLETE, "`PRINTF` is deprecated; use `PRINT` with `STRFMT`\n");
|
warning(WARNING_OBSOLETE, "`PRINTF` is deprecated; use `PRINT` with `STRFMT` \"%%f\"\n");
|
||||||
fix_Print($2);
|
fix_Print($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|||||||
183
src/asm/rgbasm.5
183
src/asm/rgbasm.5
@@ -77,8 +77,8 @@ within a string, called
|
|||||||
This will paste the contents of
|
This will paste the contents of
|
||||||
.Ql symbol
|
.Ql symbol
|
||||||
as if they were part of the source file.
|
as if they were part of the source file.
|
||||||
If it is a string equate, its characters are simply inserted as-is.
|
If it is a string symbol, its characters are simply inserted as-is.
|
||||||
If it is a numerical symbol, its value is converted to hexadecimal notation with a dollar sign
|
If it is a numeric symbol, its value is converted to hexadecimal notation with a dollar sign
|
||||||
.Sq $
|
.Sq $
|
||||||
prepended.
|
prepended.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -97,7 +97,7 @@ Symbols can be
|
|||||||
.Em interpolated
|
.Em interpolated
|
||||||
even in the contexts that disable automatic
|
even in the contexts that disable automatic
|
||||||
.Em expansion
|
.Em expansion
|
||||||
of string equates:
|
of string constants:
|
||||||
.Ql name
|
.Ql name
|
||||||
will be expanded in all of
|
will be expanded in all of
|
||||||
.Ql DEF({name}) ,
|
.Ql DEF({name}) ,
|
||||||
@@ -170,8 +170,8 @@ Examples:
|
|||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
SECTION "Test", ROM0[2]
|
SECTION "Test", ROM0[2]
|
||||||
X: ;\ This works with labels **whose address is known**
|
X: ;\ This works with labels **whose address is known**
|
||||||
Y = 3 ;\ This also works with mutable constants
|
Y = 3 ;\ This also works with variables
|
||||||
SUM equ X + Y ;\ Likewise with immutable constants
|
SUM equ X + Y ;\ And likewise with numeric constants
|
||||||
; Prints "%0010 + $3 == 5"
|
; Prints "%0010 + $3 == 5"
|
||||||
PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}"
|
PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}"
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ would be more approriate; see
|
|||||||
further below.
|
further below.
|
||||||
.Sh EXPRESSIONS
|
.Sh EXPRESSIONS
|
||||||
An expression can be composed of many things.
|
An expression can be composed of many things.
|
||||||
Numerical expressions are always evaluated using signed 32-bit math.
|
Numeric expressions are always evaluated using signed 32-bit math.
|
||||||
Zero is considered to be the only "false" number, all non-zero numbers (including negative) are "true".
|
Zero is considered to be the only "false" number, all non-zero numbers (including negative) are "true".
|
||||||
.Pp
|
.Pp
|
||||||
An expression is said to be "constant" if
|
An expression is said to be "constant" if
|
||||||
@@ -468,7 +468,7 @@ The result is not constant, since only RGBLINK can compute its value.
|
|||||||
.It Fn DEF symbol Ta Returns TRUE (1) if
|
.It Fn DEF symbol Ta Returns TRUE (1) if
|
||||||
.Ar symbol
|
.Ar symbol
|
||||||
has been defined, FALSE (0) otherwise.
|
has been defined, FALSE (0) otherwise.
|
||||||
String equates are not expanded within the parentheses.
|
String constants are not expanded within the parentheses.
|
||||||
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register.
|
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register.
|
||||||
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
|
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
|
||||||
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ap s value is known by RGBASM (e.g. if it can be an argument to
|
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ap s value is known by RGBASM (e.g. if it can be an argument to
|
||||||
@@ -756,12 +756,12 @@ or
|
|||||||
.Ic FRAGMENT
|
.Ic FRAGMENT
|
||||||
modifiers, as described below.
|
modifiers, as described below.
|
||||||
.Ss Unionized Sections
|
.Ss Unionized Sections
|
||||||
When you're tight on RAM, you may want to define overlapping blocks of variables, as explained in the
|
When you're tight on RAM, you may want to define overlapping static memory allocations, as explained in the
|
||||||
.Sx Unions
|
.Sx Unions
|
||||||
section.
|
section.
|
||||||
However, the
|
However, a
|
||||||
.Ic UNION
|
.Ic UNION
|
||||||
keyword only works within a single file, which prevents e.g. defining temporary variables on a single memory area across several files.
|
only works within a single file, so it can't be used e.g. to define temporary variables across several files, all of which use the same statically allocated memory.
|
||||||
Unionized sections solve this problem.
|
Unionized sections solve this problem.
|
||||||
To declare an unionized section, add a
|
To declare an unionized section, add a
|
||||||
.Ic UNION
|
.Ic UNION
|
||||||
@@ -771,7 +771,7 @@ one; the declaration is otherwise not different.
|
|||||||
Unionized sections follow some different rules from normal sections:
|
Unionized sections follow some different rules from normal sections:
|
||||||
.Bl -bullet -offset indent
|
.Bl -bullet -offset indent
|
||||||
.It
|
.It
|
||||||
The same unionized section (= having the same name) can be declared several times per
|
The same unionized section (i.e. having the same name) can be declared several times per
|
||||||
.Nm
|
.Nm
|
||||||
invocation, and across several invocations.
|
invocation, and across several invocations.
|
||||||
Different declarations are treated and merged identically whether within the same invocation, or different ones.
|
Different declarations are treated and merged identically whether within the same invocation, or different ones.
|
||||||
@@ -852,15 +852,15 @@ last.
|
|||||||
RGBDS supports several types of symbols:
|
RGBDS supports several types of symbols:
|
||||||
.Bl -hang
|
.Bl -hang
|
||||||
.It Sy Label
|
.It Sy Label
|
||||||
Numerical symbol designating a memory location.
|
Numeric symbol designating a memory location.
|
||||||
May or may not have a value known at assembly time.
|
May or may not have a value known at assembly time.
|
||||||
.It Sy Constant
|
.It Sy Constant
|
||||||
Numerical symbol whose value has to be known at assembly time.
|
Numeric symbol whose value has to be known at assembly time.
|
||||||
.It Sy Macro
|
.It Sy Macro
|
||||||
A block of
|
A block of
|
||||||
.Nm
|
.Nm
|
||||||
code that can be invoked later.
|
code that can be invoked later.
|
||||||
.It Sy String equate
|
.It Sy String
|
||||||
A text string that can be expanded later, similarly to a macro.
|
A text string that can be expanded later, similarly to a macro.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
@@ -987,52 +987,17 @@ and so on.
|
|||||||
: ; referenced by "ld hl"
|
: ; referenced by "ld hl"
|
||||||
dw $7FFF, $1061, $03E0, $58A5
|
dw $7FFF, $1061, $03E0, $58A5
|
||||||
.Ed
|
.Ed
|
||||||
.Ss Immutable constants
|
.Ss Variables
|
||||||
.Ic EQU
|
An equal sign
|
||||||
is used to define numerical constant symbols.
|
|
||||||
Unlike
|
|
||||||
.Ic =
|
.Ic =
|
||||||
below, constants defined this way cannot be redefined.
|
is used to define mutable numeric symbols.
|
||||||
These constants can be used for unchanging values such as properties of the hardware.
|
Unlike the other symbols described below, variables can be redefined.
|
||||||
.Bd -literal -offset indent
|
This is useful for internal symbols in macros, for counters, etc.
|
||||||
def SCREEN_WIDTH equ 160 ;\ In pixels
|
|
||||||
def SCREEN_HEIGHT equ 144
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
Note that colons
|
|
||||||
.Ql \&:
|
|
||||||
following the name are not allowed.
|
|
||||||
.Pp
|
|
||||||
If you
|
|
||||||
.Em really
|
|
||||||
need to, the
|
|
||||||
.Ic REDEF
|
|
||||||
keyword will define or redefine a constant symbol.
|
|
||||||
This can be used, for example, to update a constant using a macro, without making it mutable in general.
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
def NUM_ITEMS equ 0
|
|
||||||
MACRO add_item
|
|
||||||
redef NUM_ITEMS equ NUM_ITEMS + 1
|
|
||||||
def ITEM_{02x:NUM_ITEMS} equ \[rs]1
|
|
||||||
ENDM
|
|
||||||
add_item 1
|
|
||||||
add_item 4
|
|
||||||
add_item 9
|
|
||||||
add_item 16
|
|
||||||
assert NUM_ITEMS == 4
|
|
||||||
assert ITEM_04 == 16
|
|
||||||
.Ed
|
|
||||||
.Ss Mutable constants
|
|
||||||
.Ic =
|
|
||||||
is used to define numerical symbols like
|
|
||||||
.Ic EQU ,
|
|
||||||
but these symbols can be redefined.
|
|
||||||
This is useful for variables in macros, for counters, etc.
|
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DEF ARRAY_SIZE EQU 4
|
DEF ARRAY_SIZE EQU 4
|
||||||
DEF COUNT = 2
|
DEF COUNT = 2
|
||||||
DEF COUNT = 3
|
DEF COUNT = 3
|
||||||
REDEF COUNT = ARRAY_SIZE + COUNT
|
DEF COUNT = ARRAY_SIZE + COUNT
|
||||||
COUNT = COUNT*2
|
COUNT = COUNT*2
|
||||||
;\ COUNT now has the value 14
|
;\ COUNT now has the value 14
|
||||||
.Ed
|
.Ed
|
||||||
@@ -1041,7 +1006,7 @@ Note that colons
|
|||||||
.Ql \&:
|
.Ql \&:
|
||||||
following the name are not allowed.
|
following the name are not allowed.
|
||||||
.Pp
|
.Pp
|
||||||
Mutable constants can be conveniently redefined by compound assignment operators like in C:
|
Variables can be conveniently redefined by compound assignment operators like in C:
|
||||||
.Bl -column -offset indent "*= /= %="
|
.Bl -column -offset indent "*= /= %="
|
||||||
.It Sy Operator Ta Sy Meaning
|
.It Sy Operator Ta Sy Meaning
|
||||||
.It Li += -= Ta Compound plus/minus
|
.It Li += -= Ta Compound plus/minus
|
||||||
@@ -1059,6 +1024,42 @@ DEF y *= 2 ; y == 20
|
|||||||
DEF y >>= 1 ; y == 10
|
DEF y >>= 1 ; y == 10
|
||||||
DEF x ^= y ; x == 1
|
DEF x ^= y ; x == 1
|
||||||
.Ed
|
.Ed
|
||||||
|
.Ss Numeric constants
|
||||||
|
.Ic EQU
|
||||||
|
is used to define immutable numeric symbols.
|
||||||
|
Unlike
|
||||||
|
.Ic =
|
||||||
|
above, constants defined this way cannot be redefined.
|
||||||
|
These constants can be used for unchanging values such as properties of the hardware.
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
def SCREEN_WIDTH equ 160 ;\ In pixels
|
||||||
|
def SCREEN_HEIGHT equ 144
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Note that colons
|
||||||
|
.Ql \&:
|
||||||
|
following the name are not allowed.
|
||||||
|
.Pp
|
||||||
|
If you
|
||||||
|
.Em really
|
||||||
|
need to, the
|
||||||
|
.Ic REDEF
|
||||||
|
keyword will define or redefine a numeric constant symbol.
|
||||||
|
(It can also be used for variables, although it's not necessary since they are mutable.)
|
||||||
|
This can be used, for example, to update a constant using a macro, without making it mutable in general.
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
def NUM_ITEMS equ 0
|
||||||
|
MACRO add_item
|
||||||
|
redef NUM_ITEMS equ NUM_ITEMS + 1
|
||||||
|
def ITEM_{02x:NUM_ITEMS} equ \[rs]1
|
||||||
|
ENDM
|
||||||
|
add_item 1
|
||||||
|
add_item 4
|
||||||
|
add_item 9
|
||||||
|
add_item 16
|
||||||
|
assert NUM_ITEMS == 4
|
||||||
|
assert ITEM_04 == 16
|
||||||
|
.Ed
|
||||||
.Ss Offset constants
|
.Ss Offset constants
|
||||||
The RS group of commands is a handy way of defining structure offsets:
|
The RS group of commands is a handy way of defining structure offsets:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
@@ -1096,10 +1097,10 @@ is omitted, it's assumed to be 1.
|
|||||||
Note that colons
|
Note that colons
|
||||||
.Ql \&:
|
.Ql \&:
|
||||||
following the name are not allowed.
|
following the name are not allowed.
|
||||||
.Ss String equates
|
.Ss String constants
|
||||||
.Ic EQUS
|
.Ic EQUS
|
||||||
is used to define string equate symbols.
|
is used to define string constant symbols.
|
||||||
Wherever the assembler reads a string equate, it gets
|
Wherever the assembler reads a string constant, it gets
|
||||||
.Em expanded :
|
.Em expanded :
|
||||||
the symbol's name is replaced with its contents.
|
the symbol's name is replaced with its contents.
|
||||||
If you are familiar with C, you can think of it as similar to
|
If you are familiar with C, you can think of it as similar to
|
||||||
@@ -1110,7 +1111,7 @@ This expansion is disabled in a few contexts:
|
|||||||
.Ql PURGE name ,
|
.Ql PURGE name ,
|
||||||
and
|
and
|
||||||
.Ql MACRO name
|
.Ql MACRO name
|
||||||
will not expand string equates in their names.
|
will not expand string constants in their names.
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DEF COUNTREG EQUS "[hl+]"
|
DEF COUNTREG EQUS "[hl+]"
|
||||||
ld a,COUNTREG
|
ld a,COUNTREG
|
||||||
@@ -1125,7 +1126,7 @@ This will be interpreted as:
|
|||||||
db "John"
|
db "John"
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
String equates can also be used to define small one-line macros:
|
String constants can also be used to define small one-line macros:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DEF pusha EQUS "push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n"
|
DEF pusha EQUS "push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n"
|
||||||
.Ed
|
.Ed
|
||||||
@@ -1134,14 +1135,12 @@ Note that colons
|
|||||||
.Ql \&:
|
.Ql \&:
|
||||||
following the name are not allowed.
|
following the name are not allowed.
|
||||||
.Pp
|
.Pp
|
||||||
String equates can't be exported or imported.
|
String constants can't be exported or imported.
|
||||||
.Pp
|
.Pp
|
||||||
String equates, like
|
String constants, like numeric constants, cannot be redefined.
|
||||||
.Ic EQU
|
|
||||||
constants, cannot be redefined.
|
|
||||||
However, the
|
However, the
|
||||||
.Ic REDEF
|
.Ic REDEF
|
||||||
keyword will define or redefine a string symbol.
|
keyword will define or redefine a string constant symbol.
|
||||||
For example:
|
For example:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DEF s EQUS "Hello, "
|
DEF s EQUS "Hello, "
|
||||||
@@ -1151,11 +1150,7 @@ PRINTLN "{s}\n"
|
|||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
.Sy Important note :
|
.Sy Important note :
|
||||||
An
|
When a string constant is expanded, its expansion may contain another string constant, which will be expanded as well.
|
||||||
.Ic EQUS
|
|
||||||
can be expanded to a string that contains another
|
|
||||||
.Ic EQUS
|
|
||||||
and it will be expanded as well.
|
|
||||||
If this creates an infinite loop,
|
If this creates an infinite loop,
|
||||||
.Nm
|
.Nm
|
||||||
will error out once a certain depth is
|
will error out once a certain depth is
|
||||||
@@ -1164,9 +1159,7 @@ See the
|
|||||||
.Fl r
|
.Fl r
|
||||||
command-line option in
|
command-line option in
|
||||||
.Xr rgbasm 1 .
|
.Xr rgbasm 1 .
|
||||||
Also, a macro can contain an
|
The same problem can occur if the expansion of a macro invokes another macro, recursively.
|
||||||
.Ic EQUS
|
|
||||||
which calls the same macro, which causes the same problem.
|
|
||||||
.Pp
|
.Pp
|
||||||
The examples above for
|
The examples above for
|
||||||
.Ql EQU ,
|
.Ql EQU ,
|
||||||
@@ -1178,9 +1171,7 @@ and
|
|||||||
.Ql EQUS
|
.Ql EQUS
|
||||||
all start with
|
all start with
|
||||||
.Ql DEF .
|
.Ql DEF .
|
||||||
(An
|
(A variable definition may start with
|
||||||
.Ql =
|
|
||||||
definition may start with
|
|
||||||
.Ql REDEF
|
.Ql REDEF
|
||||||
instead, since they are redefinable.)
|
instead, since they are redefinable.)
|
||||||
You may use the older syntax without
|
You may use the older syntax without
|
||||||
@@ -1194,7 +1185,7 @@ will treat it as a macro invocation.
|
|||||||
Furthermore, without the
|
Furthermore, without the
|
||||||
.Ql DEF
|
.Ql DEF
|
||||||
keyword,
|
keyword,
|
||||||
string equates may be expanded for the name.
|
string constants may be expanded for the name.
|
||||||
This can lead to surprising results:
|
This can lead to surprising results:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
X EQUS "Y"
|
X EQUS "Y"
|
||||||
@@ -1218,7 +1209,7 @@ ENDM
|
|||||||
The example above defines
|
The example above defines
|
||||||
.Ql MyMacro
|
.Ql MyMacro
|
||||||
as a new macro.
|
as a new macro.
|
||||||
String equates are not expanded within the name of the macro.
|
String constants are not expanded within the name of the macro.
|
||||||
You may use the older syntax
|
You may use the older syntax
|
||||||
.Ql MyMacro: MACRO
|
.Ql MyMacro: MACRO
|
||||||
instead of
|
instead of
|
||||||
@@ -1226,7 +1217,7 @@ instead of
|
|||||||
with a single colon
|
with a single colon
|
||||||
.Ql \&:
|
.Ql \&:
|
||||||
following the macro's name.
|
following the macro's name.
|
||||||
With the older syntax, string equates may be expanded for the name.
|
With the older syntax, string constants may be expanded for the name.
|
||||||
.Pp
|
.Pp
|
||||||
Macros can't be exported or imported.
|
Macros can't be exported or imported.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -1320,14 +1311,14 @@ allows you to completely remove a symbol from the symbol table as if it had neve
|
|||||||
I can't stress this enough,
|
I can't stress this enough,
|
||||||
.Sy you seriously need to know what you are doing .
|
.Sy you seriously need to know what you are doing .
|
||||||
DON'T purge a symbol that you use in expressions the linker needs to calculate.
|
DON'T purge a symbol that you use in expressions the linker needs to calculate.
|
||||||
When not sure, it's probably not safe to purge anything other than string symbols, macros, and constants.
|
When not sure, it's probably not safe to purge anything other than variables, numeric or string constants, or macros.
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DEF Kamikaze EQUS "I don't want to live anymore"
|
DEF Kamikaze EQUS "I don't want to live anymore"
|
||||||
DEF AOLer EQUS "Me too"
|
DEF AOLer EQUS "Me too"
|
||||||
PURGE Kamikaze, AOLer
|
PURGE Kamikaze, AOLer
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
String equates are not expanded within the symbol names.
|
String constants are not expanded within the symbol names.
|
||||||
.Ss Predeclared Symbols
|
.Ss Predeclared Symbols
|
||||||
The following symbols are defined by the assembler:
|
The following symbols are defined by the assembler:
|
||||||
.Bl -column -offset indent "EQUS" "__ISO_8601_LOCAL__"
|
.Bl -column -offset indent "EQUS" "__ISO_8601_LOCAL__"
|
||||||
@@ -1360,16 +1351,16 @@ environment variable if that is defined as a UNIX timestamp.
|
|||||||
Refer to the spec at
|
Refer to the spec at
|
||||||
.Lk https://reproducible-builds.org/docs/source-date-epoch/ .
|
.Lk https://reproducible-builds.org/docs/source-date-epoch/ .
|
||||||
.Sh DEFINING DATA
|
.Sh DEFINING DATA
|
||||||
.Ss Declaring variables in a RAM section
|
.Ss Statically allocating space in RAM
|
||||||
.Ic DS
|
.Ic DS
|
||||||
allocates a number of empty bytes.
|
statically allocates a number of empty bytes.
|
||||||
This is the preferred method of allocating space in a RAM section.
|
This is the preferred method of allocating space in a RAM section.
|
||||||
You can also use
|
You can also use
|
||||||
.Ic DB , DW
|
.Ic DB , DW
|
||||||
and
|
and
|
||||||
.Ic DL
|
.Ic DL
|
||||||
without any arguments instead (see
|
without any arguments instead (see
|
||||||
.Sx Defining constant data
|
.Sx Defining constant data in ROM
|
||||||
below).
|
below).
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
DS 42 ;\ Allocates 42 bytes
|
DS 42 ;\ Allocates 42 bytes
|
||||||
@@ -1380,7 +1371,7 @@ In ROM sections, it will be filled with the value passed to the
|
|||||||
.Fl p
|
.Fl p
|
||||||
command-line option, except when using overlays with
|
command-line option, except when using overlays with
|
||||||
.Fl O .
|
.Fl O .
|
||||||
.Ss Defining constant data
|
.Ss Defining constant data in ROM
|
||||||
.Ic DB
|
.Ic DB
|
||||||
defines a list of bytes that will be stored in the final image.
|
defines a list of bytes that will be stored in the final image.
|
||||||
Ideal for tables and text.
|
Ideal for tables and text.
|
||||||
@@ -1465,7 +1456,7 @@ INCBIN "data.bin",78,256
|
|||||||
The length argument is optional.
|
The length argument is optional.
|
||||||
If only the start position is specified, the bytes from the start position until the end of the file will be included.
|
If only the start position is specified, the bytes from the start position until the end of the file will be included.
|
||||||
.Ss Unions
|
.Ss Unions
|
||||||
Unions allow multiple memory allocations to overlap, like unions in C.
|
Unions allow multiple static memory allocations to overlap, like unions in C.
|
||||||
This does not increase the amount of memory available, but allows re-using the same memory region for different purposes.
|
This does not increase the amount of memory available, but allows re-using the same memory region for different purposes.
|
||||||
.Pp
|
.Pp
|
||||||
A union starts with a
|
A union starts with a
|
||||||
@@ -1513,7 +1504,7 @@ Nesting unions is possible, with each inner union's size being considered as des
|
|||||||
Unions may be used in any section, but inside them may only be
|
Unions may be used in any section, but inside them may only be
|
||||||
.Ic DS -
|
.Ic DS -
|
||||||
like commands (see
|
like commands (see
|
||||||
.Sx Declaring variables in a RAM section ) .
|
.Sx Statically allocating space in RAM ) .
|
||||||
.Sh THE MACRO LANGUAGE
|
.Sh THE MACRO LANGUAGE
|
||||||
.Ss Invoking macros
|
.Ss Invoking macros
|
||||||
You execute the macro by inserting its name.
|
You execute the macro by inserting its name.
|
||||||
@@ -1600,7 +1591,7 @@ The generated code will then reset all bytes in this range.
|
|||||||
LoopyMacro MyVars,54
|
LoopyMacro MyVars,54
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
Arguments are passed as string equates, although there's no need to enclose them in quotes.
|
Arguments are passed as string constants, although there's no need to enclose them in quotes.
|
||||||
Thus, an expression will not be evaluated first but kind of copy-pasted.
|
Thus, an expression will not be evaluated first but kind of copy-pasted.
|
||||||
This means that it's probably a very good idea to use brackets around
|
This means that it's probably a very good idea to use brackets around
|
||||||
.Ic \[rs]1
|
.Ic \[rs]1
|
||||||
@@ -1649,7 +1640,7 @@ also does not need escaping because string literals work as usual inside macro a
|
|||||||
Since there are only nine digits, you can only access the first nine macro arguments like this.
|
Since there are only nine digits, you can only access the first nine macro arguments like this.
|
||||||
To use the rest, you need to put the multi-digit argument number in angle brackets, like
|
To use the rest, you need to put the multi-digit argument number in angle brackets, like
|
||||||
.Ql \[rs]<10> .
|
.Ql \[rs]<10> .
|
||||||
This bracketed syntax supports decimal numbers and numeric symbol names.
|
This bracketed syntax supports decimal numbers and numeric constant symbols.
|
||||||
For example,
|
For example,
|
||||||
.Ql \[rs]<_NARG>
|
.Ql \[rs]<_NARG>
|
||||||
will get the last argument.
|
will get the last argument.
|
||||||
@@ -1765,7 +1756,7 @@ Everything between
|
|||||||
and the matching
|
and the matching
|
||||||
.Ic ENDR
|
.Ic ENDR
|
||||||
will be repeated for each value of a given symbol.
|
will be repeated for each value of a given symbol.
|
||||||
String equates are not expanded within the symbol name.
|
String constants are not expanded within the symbol name.
|
||||||
For example, this code will produce a table of squared values from 0 to 255:
|
For example, this code will produce a table of squared values from 0 to 255:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
FOR N, 256
|
FOR N, 256
|
||||||
@@ -1879,16 +1870,18 @@ Syntax examples are given below:
|
|||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
Function:
|
Function:
|
||||||
xor a
|
xor a
|
||||||
ASSERT LOW(Variable) == 0
|
ASSERT LOW(MyByte) == 0
|
||||||
ld h, HIGH(Variable)
|
ld h, HIGH(MyByte)
|
||||||
ld l, a
|
ld l, a
|
||||||
ld a, [hli]
|
ld a, [hli]
|
||||||
; You can also indent this!
|
; You can also indent this!
|
||||||
ASSERT BANK(OtherFunction) == BANK(Function)
|
ASSERT BANK(OtherFunction) == BANK(Function)
|
||||||
call OtherFunction
|
call OtherFunction
|
||||||
; Lowercase also works
|
; Lowercase also works
|
||||||
assert Variable + 1 == OtherVariable
|
ld hl, FirstByte
|
||||||
ld c, [hl]
|
ld a, [hli]
|
||||||
|
assert FirstByte + 1 == SecondByte
|
||||||
|
ld b, [hl]
|
||||||
ret
|
ret
|
||||||
\&.end
|
\&.end
|
||||||
; If you specify one, a message will be printed
|
; If you specify one, a message will be printed
|
||||||
|
|||||||
@@ -477,13 +477,13 @@ struct Symbol *sym_RedefString(char const *symName, char const *value)
|
|||||||
/*
|
/*
|
||||||
* Alter a mutable symbol's value
|
* Alter a mutable symbol's value
|
||||||
*/
|
*/
|
||||||
struct Symbol *sym_AddSet(char const *symName, int32_t value)
|
struct Symbol *sym_AddVar(char const *symName, int32_t value)
|
||||||
{
|
{
|
||||||
struct Symbol *sym = sym_FindExactSymbol(symName);
|
struct Symbol *sym = sym_FindExactSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = createsymbol(symName);
|
sym = createsymbol(symName);
|
||||||
} else if (sym_IsDefined(sym) && sym->type != SYM_SET) {
|
} else if (sym_IsDefined(sym) && sym->type != SYM_VAR) {
|
||||||
error("'%s' already defined as %s at ",
|
error("'%s' already defined as %s at ",
|
||||||
symName, sym->type == SYM_LABEL ? "label" : "constant");
|
symName, sym->type == SYM_LABEL ? "label" : "constant");
|
||||||
dumpFilename(sym);
|
dumpFilename(sym);
|
||||||
@@ -493,7 +493,7 @@ struct Symbol *sym_AddSet(char const *symName, int32_t value)
|
|||||||
updateSymbolFilename(sym);
|
updateSymbolFilename(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
sym->type = SYM_SET;
|
sym->type = SYM_VAR;
|
||||||
sym->value = value;
|
sym->value = value;
|
||||||
|
|
||||||
return sym;
|
return sym;
|
||||||
@@ -741,7 +741,7 @@ void sym_Init(time_t now)
|
|||||||
__FILE__Symbol->type = SYM_EQUS;
|
__FILE__Symbol->type = SYM_EQUS;
|
||||||
__FILE__Symbol->strCallback = Callback__FILE__;
|
__FILE__Symbol->strCallback = Callback__FILE__;
|
||||||
|
|
||||||
sym_AddSet("_RS", 0)->isBuiltin = true;
|
sym_AddVar("_RS", 0)->isBuiltin = true;
|
||||||
|
|
||||||
#define addNumber(name, val) sym_AddEqu(name, val)->isBuiltin = true
|
#define addNumber(name, val) sym_AddEqu(name, val)->isBuiltin = true
|
||||||
#define addString(name, val) sym_AddString(name, val)->isBuiltin = true
|
#define addString(name, val) sym_AddString(name, val)->isBuiltin = true
|
||||||
|
|||||||
Reference in New Issue
Block a user