This is the description of the RGB object file format that is output by rgbasm(1) and read by rgblink(1).
The following types are used:
LONG is a 32-bit integer stored in
little-endian format. BYTE is an 8-bit integer.
STRING is a 0-terminated string of
BYTE. Brackets after a type (e.g.
LONG[n]) indicate
n consecutive elements (here,
LONGs). All items are contiguous, with no padding
anywhere—this also means that they may not be aligned in the
file!
REPT n indicates
that the fields between the REPT and corresponding
ENDR are repeated n times.
All IDs refer to objects within the file; for example, symbol ID $0001 refers to the second symbol defined in this object file's Symbols array. The only exception is the Source file info nodes, whose IDs are backwards, i.e. source node ID $0000 refers to the last node in the array, not the first one. References to other object files are made by imports (symbols), by name (sections), etc.—but never by ID.
LONG
NumberOfNodesREPT
NumberOfNodesLONG
ParentIDImportant: the nodes are actually written in reverse order, meaning the node with ID 0 is the last one in the list!
LONG
ParentLineNoBYTE
Type| Value | Meaning |
| 0 | REPT node |
| 1 | File node |
| 2 | Macro node |
Bit 7 being set means that the node is "quieted" (see “Excluding locations from backtraces” in rgbasm(5)).
IF
Type ≠ 0STRING
Namesrc/includes/defines.asm::error’).ELSEENDCENDRREPT
NumberOfSymbolsSTRING
NameScope.symbol’).BYTE
Type| Value | Meaning |
| 0 | Local symbol only used in this file. |
| 1 | Import of an exported symbol (by name) from another object file. |
| 2 | Exported symbol visible from other object files. |
IF
Type ≠ 1LONG
NodeIDLONG
LineNoLONG
SectionIDLONG
ValueENDCENDRREPT
NumberOfSectionsSTRING
NameLONG
NodeIDLONG
LineNoLONG
SizeBYTE
Type| Value | Meaning |
| 0 | WRAM0 |
| 1 | VRAM |
| 2 | ROMX |
| 3 | ROM0 |
| 4 | HRAM |
| 5 | WRAMX |
| 6 | SRAM |
| 7 | OAM |
Bit 7 being set means that the section is a "union" (see “Unionized sections” in rgbasm(5)). Bit 6 being set means that the section is a "fragment" (see “Section fragments” in rgbasm(5)). These two bits are mutually exclusive.
LONG
Address-t or -d in
rgblink(1)), or -1 to indicate that the linker
should automatically decide (the section is
“floating”).LONG
BankBYTE
AlignmentLONG
AlignOfs1 <<
Alignment’.IF
Type = 2 ||
Type = 3BYTE
Data[Size]LONG
NumberOfPatchesREPT
NumberOfPatchesLONG
NodeIDLONG
LineNoLONG
OffsetLONG
PCSectionIDLOAD’ blocks, see
“RAM code” in rgbasm(5).)LONG
PCOffsetjp @’
must be an infinite loop), and to the patch's first byte
otherwise (‘db’,
‘dw’,
‘dl’).BYTE
Type| Value | Meaning |
| 0 | Single-byte patch |
| 1 | Little-endian two-byte patch |
| 2 | Little-endian four-byte patch |
| 3 | Single-byte ‘jr’
patch; the patch's value will be subtracted to PC + 2
(i.e. ‘jr @’ must be
the infinite loop ‘18
FE’). |
LONG
RPNSizeBYTE
RPNExpr[RPNSize]ENDRENDCLONG
NumberOfAssertionsREPT
NumberOfAssertionsLONG
NodeIDLONG
LineNoLONG
OffsetLONG
PCSectionIDLONG
PCOffsetBYTE
Type| Value | Meaning |
| 0 | Print a warning message, and continue linking normally. |
| 1 | Print an error message, so linking will fail, but allow other assertions to be evaluated. |
| 2 | Print a fatal error message, and abort immediately. |
LONG
RPNSizeBYTE
RPNExpr[RPNSize]STRING
MessageENDRExpressions in the object file are stored as RPN, or
“Reverse Polish Notation”, which is a notation that allows
computing arbitrary expressions with just a simple stack. For example, the
expression ‘2 5 -’ will first push the
value “2” to the stack, then “5”. The
‘-’ operator pops two arguments from
the stack, subtracts them, and then pushes back the result
(“3”) on the stack. A well-formed RPN expression never tries
to pop from an empty stack, and leaves exactly one value in it at the
end.
RGBDS encodes RPN expressions as an array of
BYTEs. The first byte encodes either an operator, or
a literal, which consumes more BYTEs after it:
| Value | Meaning |
$00 |
Addition operator (‘+’) |
$01 |
Subtraction operator (‘-’) |
$02 |
Multiplication operator (‘*’) |
$03 |
Division operator (‘/’) |
$04 |
Modulo operator (‘%’) |
$05 |
Negation (unary ‘-’) |
$06 |
Exponent operator (‘**’) |
$10 |
Bitwise OR operator (‘|’) |
$11 |
Bitwise AND operator
(‘&’) |
$12 |
Bitwise XOR operator (‘^’) |
$13 |
Bitwise complement operator (unary
‘~’) |
$21 |
Logical AND operator
(‘&&’) |
$22 |
Logical OR operator (‘||’) |
$23 |
Logical complement operator (unary
‘!’) |
$30 |
Equality operator (‘==’) |
$31 |
Non-equality operator (‘!=’) |
$32 |
Greater-than operator
(‘>’) |
$33 |
Less-than operator (‘<’) |
$34 |
Greater-than-or-equal operator
(‘>=’) |
$35 |
Less-than-or-equal operator
(‘<=’) |
$40 |
Left shift operator
(‘<<’) |
$41 |
Arithmetic/signed right shift operator
(‘>>’) |
$42 |
Logical/unsigned right shift operator
(‘>>>’) |
$50 |
BANK(symbol);
followed by the symbol's
LONG ID. |
$51 |
BANK(section); followed by
the section's STRING
name. |
$52 |
PC's BANK() (i.e.
‘BANK(@)’). |
$53 |
SIZEOF(section);
followed by the section's
STRING name. |
$54 |
STARTOF(section);
followed by the section's
STRING name. |
$55 |
SIZEOF(sectiontype);
followed by the sectiontype's
BYTE value (see the Type
values in
Sections). |
$56 |
STARTOF(sectiontype);
followed by the sectiontype's
BYTE value (see the Type
values in
Sections). |
$60 |
‘ldh’ check. Checks if the value
is a valid ‘ldh’ operand (see
“Load Instructions” in gbz80(7)), i.e.
that it is between either $00 and $FF, or $FF00 and $FFFF, both inclusive.
The value is then ANDed with $00FF (‘&
$FF’). |
$61 |
‘rst’ check. Checks if the value
is a valid ‘rst’ vector (see
“RST vec” in gbz80(7)), that is, one of
$00, $08, $10, $18, $20, $28, $30, or $38. The value is then ORed with $C7
(‘| $C7’). |
$62 |
‘bit/res/set’ check; followed by
the instruction's BYTE mask. Checks if the value
is a valid bit index (see e.g. “BIT u3, r8” in
gbz80(7)), that is, from 0 to 7. The value is then ORed
with the instruction's mask. |
$70 |
HIGH
byte. |
$71 |
LOW
byte. |
$72 |
BITWIDTH
value. |
$73 |
TZCOUNT
value. |
$80 |
Integer literal; followed by the LONG
integer. |
$81 |
A symbol's value; followed by the symbol's LONG
ID. |
rgbasm(1), rgbasm(5), rgblink(1), rgblink(5), rgbfix(1), rgbgfx(1), gbz80(7), rgbds(7)
rgbasm(1) and rgblink(1) were originally written by Carsten Sørensen as part of the ASMotor package, and was later repackaged in RGBDS by Justin Lloyd. It is now maintained by a number of contributors at https://github.com/gbdev/rgbds.