1.\" 2.\" This file is part of RGBDS. 3.\" 4.\" Copyright (c) 2017-2021, Antonio Nino Diaz and RGBDS contributors. 5.\" 6.\" SPDX-License-Identifier: MIT 7.\" 8.Dd March 28, 2021 9.Dt RGBASM 5 10.Os 11.Sh NAME 12.Nm rgbasm 13.Nd language documentation 14.Sh DESCRIPTION 15This is the full description of the language used by 16.Xr rgbasm 1 . 17The description of the instructions supported by the Game Boy CPU is in 18.Xr gbz80 7 . 19.Pp 20It is strongly recommended to have some familiarity with the Game Boy hardware before reading this document. 21RGBDS is specifically targeted at the Game Boy, and thus a lot of its features tie directly to its concepts. 22This document is not intended to be a Game Boy hardware reference. 23.Pp 24Generally, 25.Dq the linker 26will refer to 27.Xr rgblink 1 , 28but any program that processes RGBDS object files (described in 29.Xr rgbds 5 ) 30can be used in its place. 31.Sh SYNTAX 32The syntax is line-based, just as in any other assembler, meaning that you do one instruction or directive per line: 33.Pp 34.Dl Oo Ar label Oc Oo Ar instruction Oc Oo Ar ;\ comment Oc 35.Pp 36Example: 37.Bd -literal -offset indent 38John: ld a,87 ;Weee 39.Ed 40.Pp 41All reserved keywords (directives, mnemonics, registers, etc.) are case-insensitive; 42all identifiers (symbol names) are case-sensitive. 43.Pp 44Comments are used to give humans information about the code, such as explanations. 45The assembler 46.Em always 47ignores comments and their contents. 48.Pp 49There are two syntaxes for comments. 50The most common is that anything that follows a semicolon 51.Ql \&; 52not inside a string, is a comment until the end of the line. 53The second is a block comment, beginning with 54.Ql /* 55and ending with 56.Ql */ . 57It can be split across multiple lines, or occur in the middle of an expression: 58.Bd -literal -offset indent 59X = /* the value of x 60 should be 3 */ 3 61.Ed 62.Pp 63Sometimes lines can be too long and it may be necessary to split them. 64To do so, put a backslash at the end of the line: 65.Bd -literal -offset indent 66 DB 1, 2, 3,\ \[rs] 67 4, 5, 6,\ \[rs]\ ;\ Put it before any comments 68 7, 8, 9 69 DB "Hello,\ \[rs]\ \ ;\ Space before the \[rs] is included 70world!"\ \ \ \ \ \ \ \ \ \ \ ;\ Any leading space is included 71.Ed 72.Ss Symbol interpolation 73A funky feature is 74.Ql {symbol} 75within a string, called 76.Dq symbol interpolation . 77This will paste the contents of 78.Ql symbol 79as if they were part of the source file. 80If it is a string symbol, its characters are simply inserted as-is. 81If it is a numeric symbol, its value is converted to hexadecimal notation with a dollar sign 82.Sq $ 83prepended. 84.Pp 85Symbol interpolations can be nested, too! 86.Bd -literal -offset indent 87DEF topic EQUS "life, the universe, and \[rs]"everything\[rs]"" 88DEF meaning EQUS "answer" 89;\ Defines answer = 42 90DEF {meaning} = 42 91;\ Prints "The answer to life, the universe, and "everything" is $2A" 92PRINTLN "The {meaning} to {topic} is {{meaning}}" 93PURGE topic, meaning, {meaning} 94.Ed 95.Pp 96Symbols can be 97.Em interpolated 98even in the contexts that disable automatic 99.Em expansion 100of string constants: 101.Ql name 102will be expanded in all of 103.Ql DEF({name}) , 104.Ql DEF {name} EQU/=/EQUS/etc ... , 105.Ql PURGE {name} , 106and 107.Ql MACRO {name} , 108but, for example, won't be in 109.Ql DEF(name) . 110.Pp 111It's possible to change the way symbols are printed by specifying a print format like so: 112.Ql {fmt:symbol} . 113The 114.Ql fmt 115specifier consists of these parts: 116.Ql <sign><prefix><align><pad><width><frac><type> . 117These parts are: 118.Bl -column "<prefix>" 119.It Sy Part Ta Sy Meaning 120.It Ql <sign> Ta May be 121.Ql + 122or 123.Ql \ . 124If specified, prints this character in front of non-negative numbers. 125.It Ql <prefix> Ta May be 126.Ql # . 127If specified, prints the appropriate prefix for numbers, 128.Ql $ , 129.Ql & , 130or 131.Ql % . 132.It Ql <align> Ta May be 133.Ql - . 134If specified, aligns left instead of right. 135.It Ql <pad> Ta May be 136.Ql 0 . 137If specified, pads right-aligned numbers with zeros instead of spaces. 138.It Ql <width> Ta May be one or more 139.Ql 0 140\[en] 141.Ql 9 . 142If specified, pads the value to this width, right-aligned with spaces by default. 143.It Ql <frac> Ta May be 144.Ql \&. 145followed by one or more 146.Ql 0 147\[en] 148.Ql 9 . 149If specified, prints this many digits of a fixed-point fraction. 150Defaults to 5 digits, maximum 255 digits. 151.It Ql <type> Ta Specifies the type of value. 152.El 153.Pp 154All the format specifier parts are optional except the 155.Ql <type> . 156Valid print types are: 157.Bl -column -offset indent "Print type" "Lowercase hexadecimal" "Example" 158.It Sy Print type Ta Sy Format Ta Sy Example 159.It Ql d Ta Signed decimal Ta -42 160.It Ql u Ta Unsigned decimal Ta 42 161.It Ql x Ta Lowercase hexadecimal Ta 2a 162.It Ql X Ta Uppercase hexadecimal Ta 2A 163.It Ql b Ta Binary Ta 101010 164.It Ql o Ta Octal Ta 52 165.It Ql f Ta Fixed-point Ta 1234.56789 166.It Ql s Ta String Ta \&"example\&" 167.El 168.Pp 169Examples: 170.Bd -literal -offset indent 171SECTION "Test", ROM0[2] 172X: ;\ This works with labels **whose address is known** 173Y = 3 ;\ This also works with variables 174SUM equ X + Y ;\ And likewise with numeric constants 175; Prints "%0010 + $3 == 5" 176PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}" 177 178rsset 32 179PERCENT rb 1 ;\ Same with offset constants 180VALUE = 20 181RESULT = MUL(20.0, 0.32) 182; Prints "32% of 20 = 6.40" 183PRINTLN "{d:PERCENT}% of {d:VALUE} = {f:RESULT}" 184 185WHO equs STRLWR("WORLD") 186; Prints "Hello world!" 187PRINTLN "Hello {s:WHO}!" 188.Ed 189.Pp 190Although, for these examples, 191.Ic STRFMT 192would be more approriate; see 193.Sx String expressions 194further below. 195.Sh EXPRESSIONS 196An expression can be composed of many things. 197Numeric expressions are always evaluated using signed 32-bit math. 198Zero is considered to be the only "false" number, all non-zero numbers (including negative) are "true". 199.Pp 200An expression is said to be "constant" if 201.Nm 202knows its value. 203This is generally always the case, unless a label is involved, as explained in the 204.Sx SYMBOLS 205section. 206.Pp 207The instructions in the macro-language generally require constant expressions. 208.Ss Numeric formats 209There are a number of numeric formats. 210.Bl -column -offset indent "Fixed point (Q16.16)" "Prefix" 211.It Sy Format type Ta Sy Prefix Ta Sy Accepted characters 212.It Hexadecimal Ta $ Ta 0123456789ABCDEF 213.It Decimal Ta none Ta 0123456789 214.It Octal Ta & Ta 01234567 215.It Binary Ta % Ta 01 216.It Fixed point (Q16.16) Ta none Ta 01234.56789 217.It Character constant Ta none Ta \(dqABYZ\(dq 218.It Gameboy graphics Ta \` Ta 0123 219.El 220.Pp 221Underscores are also accepted in numbers, except at the beginning of one. 222This can be useful for grouping digits, like 223.Ql 123_456 224or 225.Ql %1100_1001 . 226.Pp 227The "character constant" form yields the value the character maps to in the current charmap. 228For example, by default 229.Pq refer to Xr ascii 7 230.Sq \(dqA\(dq 231yields 65. 232See 233.Sx Character maps 234for information on charmaps. 235.Pp 236The last one, Gameboy graphics, is quite interesting and useful. 237After the backtick, 8 digits between 0 and 3 are expected, corresponding to pixel values. 238The resulting value is the two bytes of tile data that would produce that row of pixels. 239For example, 240.Sq \`01012323 241is equivalent to 242.Sq $0F55 . 243.Pp 244You can also use symbols, which are implicitly replaced with their value. 245.Ss Operators 246A great number of operators you can use in expressions are available (listed from highest to lowest precedence): 247.Bl -column -offset indent "!= == <= >= < >" 248.It Sy Operator Ta Sy Meaning 249.It Li \&( \&) Ta Precedence override 250.It Li FUNC() Ta Built-in function call 251.It Li ** Ta Exponent 252.It Li ~ + - Ta Unary complement/plus/minus 253.It Li * / % Ta Multiply/divide/modulo 254.It Li << >> Ta Shift left/right 255.It Li & \&| ^ Ta Binary and/or/xor 256.It Li + - Ta Add/subtract 257.It Li != == <= >= < > Ta Comparison 258.It Li && || Ta Boolean and/or 259.It Li \&! Ta Unary not 260.El 261.Pp 262.Ic ~ 263complements a value by inverting all its bits. 264.Pp 265.Ic % 266is used to get the remainder of the corresponding division, so that 267.Sq a / b * b + a % b == a 268is always true. 269The result has the same sign as the divisor. 270This makes 271.Sq a % b . 272equal to 273.Sq (a + b) % b 274or 275.Sq (a - b) % b . 276.Pp 277Shifting works by shifting all bits in the left operand either left 278.Pq Sq << 279or right 280.Pq Sq >> 281by the right operand's amount. 282When shifting left, all newly-inserted bits are reset; when shifting right, they are copies of the original most significant bit instead. 283This makes 284.Sq a << b 285and 286.Sq a >> b 287equivalent to multiplying and dividing by 2 to the power of b, respectively. 288.Pp 289Comparison operators return 0 if the comparison is false, and 1 otherwise. 290.Pp 291Unlike in a lot of languages, and for technical reasons, 292.Nm 293still evaluates both operands of 294.Sq && 295and 296.Sq || . 297.Pp 298.Ic \&! 299returns 1 if the operand was 0, and 0 otherwise. 300.Ss Fixed-point expressions 301Fixed-point numbers are basically normal (32-bit) integers, which count 65536ths instead of entire units, offering better precision than integers but limiting the range of values. 302The upper 16 bits are used for the integer part and the lower 16 bits are used for the fraction (65536ths). 303Since they are still akin to integers, you can use them in normal integer expressions, and some integer operators like 304.Sq + 305and 306.Sq - 307don't care whether the operands are integers or fixed-point. 308You can easily truncate a fixed-point number into an integer by shifting it right by 16 bits. 309It follows that you can convert an integer to a fixed-point number by shifting it left. 310.Pp 311The following functions are designed to operate with fixed-point numbers: 312.EQ 313delim $$ 314.EN 315.Bl -column -offset indent "ATAN2(x, y)" 316.It Sy Name Ta Sy Operation 317.It Fn DIV x y Ta $x \[di] y$ 318.It Fn MUL x y Ta $x \[mu] y$ 319.It Fn POW x y Ta $x$ to the $y$ power 320.It Fn LOG x y Ta Logarithm of $x$ to the base $y$ 321.It Fn ROUND x Ta Round $x$ to the nearest integer 322.It Fn CEIL x Ta Round $x$ up to an integer 323.It Fn FLOOR x Ta Round $x$ down to an integer 324.It Fn SIN x Ta Sine of $x$ 325.It Fn COS x Ta Cosine of $x$ 326.It Fn TAN x Ta Tangent of $x$ 327.It Fn ASIN x Ta Inverse sine of $x$ 328.It Fn ACOS x Ta Inverse cosine of $x$ 329.It Fn ATAN x Ta Inverse tangent of $x$ 330.It Fn ATAN2 x y Ta Angle between $( x , y )$ and $( 1 , 0 )$ 331.El 332.EQ 333delim off 334.EN 335.Pp 336The trigonometry functions ( 337.Ic SIN , 338.Ic COS , 339.Ic TAN , 340etc) are defined in terms of a circle divided into 65535.0 degrees. 341.Pp 342These functions are useful for automatic generation of various tables. 343For example: 344.Bd -literal -offset indent 345; Generate a 256-byte sine table with values in the range [0, 128] 346; (shifted and scaled from the range [-1.0, 1.0]) 347ANGLE = 0.0 348 REPT 256 349 db (MUL(64.0, SIN(ANGLE)) + 64.0) >> 16 350ANGLE = ANGLE + 256.0 ; 256.0 = 65536 degrees / 256 entries 351 ENDR 352.Ed 353.Ss String expressions 354The most basic string expression is any number of characters contained in double quotes 355.Pq Ql \&"for instance" . 356The backslash character 357.Ql \[rs] 358is special in that it causes the character following it to be 359.Dq escaped , 360meaning that it is treated differently from normal. 361There are a number of escape sequences you can use within a string: 362.Bl -column -offset indent "Qo \[rs]1 Qc \[en] Qo \[rs]9 Qc" 363.It Sy String Ta Sy Meaning 364.It Ql \[rs]\[rs] Ta Produces a backslash 365.It Ql \[rs]" Ta Produces a double quote without terminating 366.It Ql \[rs]{ Ta Curly bracket left 367.It Ql \[rs]} Ta Curly bracket right 368.It Ql \[rs]n Ta Newline ($0A) 369.It Ql \[rs]r Ta Carriage return ($0D) 370.It Ql \[rs]t Ta Tab ($09) 371.It Qo \[rs]1 Qc \[en] Qo \[rs]9 Qc Ta Macro argument (Only in the body of a macro; see Sx Invoking macros ) 372.It Ql \[rs]# Ta All Dv _NARG No macro arguments, separated by commas (Only in the body of a macro) 373.It Ql \[rs]@ Ta Label name suffix (Only in the body of a macro or a Ic REPT No block) 374.El 375(Note that some of those can be used outside of strings, when noted further in this document.) 376.Pp 377Multi-line strings are contained in triple quotes 378.Pq Ql \&"\&"\&"for instance\&"\&"\&" . 379Escape sequences work the same way in multi-line strings; however, literal newline 380characters will be included as-is, without needing to escape them with 381.Ql \[rs]r 382or 383.Ql \[rs]n . 384.Pp 385The following functions operate on string expressions. 386Most of them return a string, however some of these functions actually return an integer and can be used as part of an integer expression! 387.Bl -column "STRSUB(str, pos, len)" 388.It Sy Name Ta Sy Operation 389.It Fn STRLEN str Ta Returns the number of characters in Ar str . 390.It Fn STRCAT strs... Ta Concatenates Ar strs . 391.It Fn STRCMP str1 str2 Ta Returns -1 if Ar str1 No is alphabetically lower than Ar str2 No , zero if they match, 1 if Ar str1 No is greater than Ar str2 . 392.It Fn STRIN str1 str2 Ta Returns the first position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 . 393.It Fn STRRIN str1 str2 Ta Returns the last position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 . 394.It Fn STRSUB str pos len Ta Returns a substring from Ar str No starting at Ar pos No (first character is position 1, last is position -1) and Ar len No characters long. If Ar len No is not specified the substring continues to the end of Ar str . 395.It Fn STRUPR str Ta Returns Ar str No with all letters in uppercase. 396.It Fn STRLWR str Ta Returns Ar str No with all letters in lowercase. 397.It Fn STRRPL str old new Ta Returns Ar str No with each non-overlapping occurrence of the substring Ar old No replaced with Ar new . 398.It Fn STRFMT fmt args... Ta Returns the string Ar fmt No with each 399.Ql %spec 400pattern replaced by interpolating the format 401.Ar spec 402.Pq using the same syntax as Sx Symbol interpolation 403with its corresponding argument in 404.Ar args 405.Pq So %% Sc is replaced by the So % Sc character . 406.It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap. 407.It Fn CHARSUB str pos Ta Returns the substring for the charmap entry at Ar pos No in Ar str No (first character is position 1, last is position -1) with the current charmap. 408.El 409.Ss Character maps 410When writing text strings that are meant to be displayed on the Game Boy, the character encoding in the ROM may need to be different than the source file encoding. 411For example, the tiles used for uppercase letters may be placed starting at tile index 128, which differs from ASCII starting at 65. 412.Pp 413Character maps allow mapping strings to arbitrary 8-bit values: 414.Bd -literal -offset indent 415CHARMAP "<LF>", 10 416CHARMAP "í", 20 417CHARMAP "A", 128 418.Ed 419This would result in 420.Ql db \(dqAmen<LF>\(dq 421being equivalent to 422.Ql db 128, 109, 101, 110, 10 . 423.Pp 424Any characters in a string without defined mappings will be copied directly, using the source file's encoding of characters to bytes. 425.Pp 426It is possible to create multiple character maps and then switch between them as desired. 427This can be used to encode debug information in ASCII and use a different encoding for other purposes, for example. 428Initially, there is one character map called 429.Sq main 430and it is automatically selected as the current character map from the beginning. 431There is also a character map stack that can be used to save and restore which character map is currently active. 432.Bl -column "NEWCHARMAP name, basename" 433.It Sy Command Ta Sy Meaning 434.It Ic NEWCHARMAP Ar name Ta Creates a new, empty character map called Ar name No and switches to it. 435.It Ic NEWCHARMAP Ar name , basename Ta Creates a new character map called Ar name , No copied from character map Ar basename , No and switches to it. 436.It Ic SETCHARMAP Ar name Ta Switch to character map Ar name . 437.It Ic PUSHC Ta Push the current character map onto the stack. 438.It Ic POPC Ta Pop a character map off the stack and switch to it. 439.El 440.Pp 441.Sy Note: 442Modifications to a character map take effect immediately from that point onward. 443.Ss Other functions 444There are a few other functions that do various useful things: 445.Bl -column "DEF(symbol)" 446.It Sy Name Ta Sy Operation 447.It Fn BANK arg Ta Returns a bank number. 448If 449.Ar arg 450is the symbol 451.Ic @ , 452this function returns the bank of the current section. 453If 454.Ar arg 455is a string, it returns the bank of the section that has that name. 456If 457.Ar arg 458is a label, it returns the bank number the label is in. 459The result may be constant if 460.Nm 461is able to compute it. 462.It Fn SIZEOF arg Ta Returns the size of the section named 463.Ar arg . 464The result is not constant, since only RGBLINK can compute its value. 465.It Fn STARTOF arg Ta Returns the starting address of the section named 466.Ar arg . 467The result is not constant, since only RGBLINK can compute its value. 468.It Fn DEF symbol Ta Returns TRUE (1) if 469.Ar symbol 470has been defined, FALSE (0) otherwise. 471String constants are not expanded within the parentheses. 472.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. 473.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 . 474.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 475.Ic IF ) , 476or 0 if only RGBLINK can compute its value. 477.El 478.Sh SECTIONS 479Before you can start writing code, you must define a section. 480This tells the assembler what kind of information follows and, if it is code, where to put it. 481.Pp 482.Dl SECTION Ar name , type 483.Dl SECTION Ar name , type , options 484.Dl SECTION Ar name , type Ns Bo Ar addr Bc 485.Dl SECTION Ar name , type Ns Bo Ar addr Bc , Ar options 486.Pp 487.Ar name 488is a string enclosed in double quotes, and can be a new name or the name of an existing section. 489If the type doesn't match, an error occurs. 490All other sections must have a unique name, even in different source files, or the linker will treat it as an error. 491.Pp 492Possible section 493.Ar type Ns s 494are as follows: 495.Bl -tag -width Ds 496.It Ic ROM0 497A ROM section. 498.Ar addr 499can range from 500.Ad $0000 501to 502.Ad $3FFF , 503or 504.Ad $0000 505to 506.Ad $7FFF 507if tiny ROM mode is enabled in the linker. 508.It Ic ROMX 509A banked ROM section. 510.Ar addr 511can range from 512.Ad $4000 513to 514.Ad $7FFF . 515.Ar bank 516can range from 1 to 511. 517Becomes an alias for 518.Ic ROM0 519if tiny ROM mode is enabled in the linker. 520.It Ic VRAM 521A banked video RAM section. 522.Ar addr 523can range from 524.Ad $8000 525to 526.Ad $9FFF . 527.Ar bank 528can be 0 or 1, but bank 1 is unavailable if DMG mode is enabled in the linker. 529.It Ic SRAM 530A banked external (save) RAM section. 531.Ar addr 532can range from 533.Ad $A000 534to 535.Ad $BFFF . 536.Ar bank 537can range from 0 to 15. 538.It Ic WRAM0 539A general-purpose RAM section. 540.Ar addr 541can range from 542.Ad $C000 543to 544.Ad $CFFF , 545or 546.Ad $C000 547to 548.Ad $DFFF 549if WRAM0 mode is enabled in the linker. 550.It Ic WRAMX 551A banked general-purpose RAM section. 552.Ar addr 553can range from 554.Ad $D000 555to 556.Ad $DFFF . 557.Ar bank 558can range from 1 to 7. 559Becomes an alias for 560.Ic WRAM0 561if WRAM0 mode is enabled in the linker. 562.It Ic OAM 563An object attribute RAM section. 564.Ar addr 565can range from 566.Ad $FE00 567to 568.Ad $FE9F . 569.It Ic HRAM 570A high RAM section. 571.Ar addr 572can range from 573.Ad $FF80 574to 575.Ad $FFFE . 576.Pp 577.Sy Note : 578While 579.Nm 580will automatically optimize 581.Ic ld 582instructions to the smaller and faster 583.Ic ldh 584(see 585.Xr gbz80 7 ) 586whenever possible, it is generally unable to do so when a label is involved. 587Using the 588.Ic ldh 589instruction directly is recommended. 590This forces the assembler to emit a 591.Ic ldh 592instruction and the linker to check if the value is in the correct range. 593.El 594.Pp 595Since RGBDS produces ROMs, code and data can only be placed in 596.Ic ROM0 597and 598.Ic ROMX 599sections. 600To put some in RAM, have it stored in ROM, and copy it to RAM. 601.Pp 602.Ar option Ns s are comma-separated and may include: 603.Bl -tag -width Ds 604.It Ic BANK Ns Bq Ar bank 605Specify which 606.Ar bank 607for the linker to place the section in. 608See above for possible values for 609.Ar bank , 610depending on 611.Ar type . 612.It Ic ALIGN Ns Bq Ar align , offset 613Place the section at an address whose 614.Ar align 615least-significant bits are equal to 616.Ar offset . 617(Note that 618.Ic ALIGN Ns Bq Ar align 619is a shorthand for 620.Ic ALIGN Ns Bq Ar align , No 0 ) . 621This option can be used with 622.Bq Ar addr , 623as long as they don't contradict eachother. 624It's also possible to request alignment in the middle of a section, see 625.Sx Requesting alignment 626below. 627.El 628.Pp 629If 630.Bq Ar addr 631is not specified, the section is considered 632.Dq floating ; 633the linker will automatically calculate an appropriate address for the section. 634Similarly, if 635.Ic BANK Ns Bq Ar bank 636is not specified, the linker will automatically find a bank with enough space. 637.Pp 638Sections can also be placed by using a linker script file. 639The format is described in 640.Xr rgblink 5 . 641They allow the user to place floating sections in the desired bank in the order specified in the script. 642This is useful if the sections can't be placed at an address manually because the size may change, but they have to be together. 643.Pp 644Section examples: 645.Bl -item 646.It 647.Bd -literal -offset indent 648SECTION "Cool Stuff",ROMX 649.Ed 650This switches to the section called 651.Dq CoolStuff , 652creating it if it doesn't already exist. 653It can end up in any ROM bank. 654Code and data may follow. 655.It 656If it is needed, the the base address of the section can be specified: 657.Bd -literal -offset indent 658SECTION "Cool Stuff",ROMX[$4567] 659.Ed 660.It 661An example with a fixed bank: 662.Bd -literal -offset indent 663SECTION "Cool Stuff",ROMX[$4567],BANK[3] 664.Ed 665.It 666And if you want to force only the section's bank, and not its position within the bank, that's also possible: 667.Bd -literal -offset indent 668SECTION "Cool Stuff",ROMX,BANK[7] 669.Ed 670.It 671Alignment examples: 672The first one could be useful for defining an OAM buffer to be DMA'd, since it must be aligned to 256 bytes. 673The second could also be appropriate for GBC HDMA, or for an optimized copy code that requires alignment. 674.Bd -literal -offset indent 675SECTION "OAM Data",WRAM0,ALIGN[8] ;\ align to 256 bytes 676SECTION "VRAM Data",ROMX,BANK[2],ALIGN[4] ;\ align to 16 bytes 677.Ed 678.El 679.Ss Section stack 680.Ic POPS 681and 682.Ic PUSHS 683provide the interface to the section stack. 684The number of entries in the stack is limited only by the amount of memory in your machine. 685.Pp 686.Ic PUSHS 687will push the current section context on the section stack. 688.Ic POPS 689can then later be used to restore it. 690Useful for defining sections in included files when you don't want to override the section context at the point the file was included. 691.Ss RAM code 692Sometimes you want to have some code in RAM. 693But then you can't simply put it in a RAM section, you have to store it in ROM and copy it to RAM at some point. 694.Pp 695This means the code (or data) will not be stored in the place it gets executed. 696Luckily, 697.Ic LOAD 698blocks are the perfect solution to that. 699Here's an example of how to use them: 700.Bd -literal -offset indent 701SECTION "LOAD example", ROMX 702CopyCode: 703 ld de, RAMCode 704 ld hl, RAMLocation 705 ld c, RAMLocation.end - RAMLocation 706\&.loop 707 ld a, [de] 708 inc de 709 ld [hli], a 710 dec c 711 jr nz, .loop 712 ret 713 714RAMCode: 715 LOAD "RAM code", WRAM0 716RAMLocation: 717 ld hl, .string 718 ld de, $9864 719\&.copy 720 ld a, [hli] 721 ld [de], a 722 inc de 723 and a 724 jr nz, .copy 725 ret 726 727\&.string 728 db "Hello World!", 0 729\&.end 730 ENDL 731.Ed 732.Pp 733A 734.Ic LOAD 735block feels similar to a 736.Ic SECTION 737declaration because it creates a new one. 738All data and code generated within such a block is placed in the current section like usual, but all labels are created as if they were placed in this newly-created section. 739.Pp 740In the example above, all of the code and data will end up in the "LOAD example" section. 741You will notice the 742.Sq RAMCode 743and 744.Sq RAMLocation 745labels. 746The former is situated in ROM, where the code is stored, the latter in RAM, where the code will be loaded. 747.Pp 748You cannot nest 749.Ic LOAD 750blocks, nor can you change the current section within them. 751.Pp 752.Ic LOAD 753blocks can use the 754.Ic UNION 755or 756.Ic FRAGMENT 757modifiers, as described below. 758.Ss Unionized sections 759When you're tight on RAM, you may want to define overlapping static memory allocations, as explained in the 760.Sx Unions 761section. 762However, a 763.Ic UNION 764only 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. 765Unionized sections solve this problem. 766To declare an unionized section, add a 767.Ic UNION 768keyword after the 769.Ic SECTION 770one; the declaration is otherwise not different. 771Unionized sections follow some different rules from normal sections: 772.Bl -bullet -offset indent 773.It 774The same unionized section (i.e. having the same name) can be declared several times per 775.Nm 776invocation, and across several invocations. 777Different declarations are treated and merged identically whether within the same invocation, or different ones. 778.It 779If one section has been declared as unionized, all sections with the same name must be declared unionized as well. 780.It 781All declarations must have the same type. 782For example, even if 783.Xr rgblink 1 Ap s 784.Fl w 785flag is used, 786.Ic WRAM0 787and 788.Ic WRAMX 789types are still considered different. 790.It 791Different constraints (alignment, bank, etc.) can be specified for each unionized section declaration, but they must all be compatible. 792For example, alignment must be compatible with any fixed address, all specified banks must be the same, etc. 793.It 794Unionized sections cannot have type 795.Ic ROM0 796or 797.Ic ROMX . 798.El 799.Pp 800Different declarations of the same unionized section are not appended, but instead overlaid on top of eachother, just like 801.Sx Unions . 802Similarly, the size of an unionized section is the largest of all its declarations. 803.Ss Section fragments 804Section fragments are sections with a small twist: when several of the same name are encountered, they are concatenated instead of producing an error. 805This works within the same file (paralleling the behavior "plain" sections has in previous versions), but also across object files. 806To declare an section fragment, add a 807.Ic FRAGMENT 808keyword after the 809.Ic SECTION 810one; the declaration is otherwise not different. 811However, similarly to 812.Sx Unionized sections , 813some rules must be followed: 814.Bl -bullet -offset indent 815.It 816If one section has been declared as fragment, all sections with the same name must be declared fragments as well. 817.It 818All declarations must have the same type. 819For example, even if 820.Xr rgblink 1 Ap s 821.Fl w 822flag is used, 823.Ic WRAM0 824and 825.Ic WRAMX 826types are still considered different. 827.It 828Different constraints (alignment, bank, etc.) can be specified for each unionized section declaration, but they must all be compatible. 829For example, alignment must be compatible with any fixed address, all specified banks must be the same, etc. 830.It 831A section fragment may not be unionized; after all, that wouldn't make much sense. 832.El 833.Pp 834When RGBASM merges two fragments, the one encountered later is appended to the one encountered earlier. 835.Pp 836When RGBLINK merges two fragments, the one whose file was specified last is appended to the one whose file was specified first. 837For example, assuming 838.Ql bar.o , 839.Ql baz.o , 840and 841.Ql foo.o 842all contain a fragment with the same name, the command 843.Dl rgblink -o rom.gb baz.o foo.o bar.o 844would produce the fragment from 845.Ql baz.o 846first, followed by the one from 847.Ql foo.o , 848and the one from 849.Ql bar.o 850last. 851.Sh SYMBOLS 852RGBDS supports several types of symbols: 853.Bl -hang 854.It Sy Label 855Numeric symbol designating a memory location. 856May or may not have a value known at assembly time. 857.It Sy Constant 858Numeric symbol whose value has to be known at assembly time. 859.It Sy Macro 860A block of 861.Nm 862code that can be invoked later. 863.It Sy String 864A text string that can be expanded later, similarly to a macro. 865.El 866.Pp 867Symbol names can contain ASCII letters, numbers, underscores 868.Sq _ , 869hashes 870.Sq # 871and at signs 872.Sq @ . 873However, they must begin with either a letter or an underscore. 874Additionally, label names can contain up to a single dot 875.Ql \&. , 876which may not be the first character. 877.Pp 878A symbol cannot have the same name as a reserved keyword. 879.Ss Labels 880One of the assembler's main tasks is to keep track of addresses for you, so you can work with meaningful names instead of 881.Dq magic 882numbers. 883Labels enable just that: a label ties a name to a specific location within a section. 884A label resolves to a bank and address, determined at the same time as its parent section's (see further in this section). 885.Pp 886A label is defined by writing its name at the beginning of a line, followed by one or two colons, without any whitespace between the label name and the colon(s). 887Declaring a label (global or local) with two colons 888.Ql :: 889will define and 890.Ic EXPORT 891it at the same time. 892(See 893.Sx Exporting and importing symbols 894below). 895When defining a local label, the colon can be omitted, and 896.Nm 897will act as if there was only one. 898.Pp 899A label is said to be 900.Em local 901if its name contains a dot 902.Ql \&. ; 903otherwise, it is said to be 904.Em global 905(not to be mistaken with 906.Dq exported , 907explained in 908.Sx Exporting and importing symbols 909further below). 910More than one dot in label names is not allowed. 911.Pp 912For convenience, local labels can use a shorthand syntax: when a symbol name starting with a dot is found (for example, inside an expression, or when declaring a label), then the current 913.Dq label scope 914is implicitly prepended. 915.Pp 916Defining a global label sets it as the current 917.Dq label scope , 918until the next global label definition, or the end of the current section. 919.Pp 920Here are some examples of label definitions: 921.Bd -literal -offset indent 922GlobalLabel: 923AnotherGlobal: 924\&.locallabel ;\ This defines "AnotherGlobal.locallabel" 925\&.another_local: 926AnotherGlobal.with_another_local: 927ThisWillBeExported:: ;\ Note the two colons 928ThisWillBeExported.too:: 929.Ed 930.Pp 931In a numeric expression, a label evaluates to its address in memory. 932.Po To obtain its bank, use the 933.Ql BANK() 934function described in 935.Sx Other functions 936.Pc . 937For example, given the following, 938.Ql ld de, vPlayerTiles 939would be equivalent to 940.Ql ld de, $80C0 941assuming the section ends up at 942.Ad $80C0 : 943.Bd -literal -offset indent 944SECTION "Player tiles", VRAM 945PlayerTiles: 946 ds 6 * 16 947.end 948.Ed 949.Pp 950A label's location (and thus value) is usually not determined until the linking stage, so labels usually cannot be used as constants. 951However, if the section in which the label is defined has a fixed base address, its value is known at assembly time. 952.Pp 953Also, while 954.Nm 955obviously can compute the difference between two labels if both are constant, it is also able to compute the difference between two non-constant labels if they both belong to the same section, such as 956.Ql PlayerTiles 957and 958.Ql PlayerTiles.end 959above. 960.Ss Anonymous labels 961Anonymous labels are useful for short blocks of code. 962They are defined like normal labels, but without a name before the colon. 963Anonymous labels are independent of label scoping, so defining one does not change the scoped label, and referencing one is not affected by the current scoped label. 964.Pp 965Anonymous labels are referenced using a colon 966.Ql \&: 967followed by pluses 968.Ql + 969or minuses 970.Ql - . 971Thus 972.Ic :+ 973references the next one after the expression, 974.Ic :++ 975the one after that; 976.Ic :- 977references the one before the expression; 978and so on. 979.Bd -literal -offset indent 980 ld hl, :++ 981: ld a, [hli] ; referenced by "jr nz" 982 ldh [c], a 983 dec c 984 jr nz, :- 985 ret 986 987: ; referenced by "ld hl" 988 dw $7FFF, $1061, $03E0, $58A5 989.Ed 990.Ss Variables 991An equal sign 992.Ic = 993is used to define mutable numeric symbols. 994Unlike the other symbols described below, variables can be redefined. 995This is useful for internal symbols in macros, for counters, etc. 996.Bd -literal -offset indent 997DEF ARRAY_SIZE EQU 4 998DEF COUNT = 2 999DEF COUNT = 3 1000DEF COUNT = ARRAY_SIZE + COUNT 1001COUNT = COUNT*2 1002;\ COUNT now has the value 14 1003.Ed 1004.Pp 1005Note that colons 1006.Ql \&: 1007following the name are not allowed. 1008.Pp 1009Variables can be conveniently redefined by compound assignment operators like in C: 1010.Bl -column -offset indent "*= /= %=" 1011.It Sy Operator Ta Sy Meaning 1012.It Li += -= Ta Compound plus/minus 1013.It Li *= /= %= Ta Compound multiply/divide/modulo 1014.It Li <<= >>= Ta Compound shift left/right 1015.It Li &= \&|= ^= Ta Compound and/or/xor 1016.El 1017.Pp 1018Examples: 1019.Bd -literal -offset indent 1020DEF x = 10 1021DEF x += 1 ; x == 11 1022DEF y = x - 1 ; y == 10 1023DEF y *= 2 ; y == 20 1024DEF y >>= 1 ; y == 10 1025DEF x ^= y ; x == 1 1026.Ed 1027.Ss Numeric constants 1028.Ic EQU 1029is used to define immutable numeric symbols. 1030Unlike 1031.Ic = 1032above, constants defined this way cannot be redefined. 1033These constants can be used for unchanging values such as properties of the hardware. 1034.Bd -literal -offset indent 1035def SCREEN_WIDTH equ 160 ;\ In pixels 1036def SCREEN_HEIGHT equ 144 1037.Ed 1038.Pp 1039Note that colons 1040.Ql \&: 1041following the name are not allowed. 1042.Pp 1043If you 1044.Em really 1045need to, the 1046.Ic REDEF 1047keyword will define or redefine a numeric constant symbol. 1048(It can also be used for variables, although it's not necessary since they are mutable.) 1049This can be used, for example, to update a constant using a macro, without making it mutable in general. 1050.Bd -literal -offset indent 1051 def NUM_ITEMS equ 0 1052MACRO add_item 1053 redef NUM_ITEMS equ NUM_ITEMS + 1 1054 def ITEM_{02x:NUM_ITEMS} equ \[rs]1 1055ENDM 1056 add_item 1 1057 add_item 4 1058 add_item 9 1059 add_item 16 1060 assert NUM_ITEMS == 4 1061 assert ITEM_04 == 16 1062.Ed 1063.Ss Offset constants 1064The RS group of commands is a handy way of defining structure offsets: 1065.Bd -literal -offset indent 1066 RSRESET 1067DEF str_pStuff RW 1 1068DEF str_tData RB 256 1069DEF str_bCount RB 1 1070DEF str_SIZEOF RB 0 1071.Ed 1072.Pp 1073The example defines four constants as if by: 1074.Bd -literal -offset indent 1075DEF str_pStuff EQU 0 1076DEF str_tData EQU 2 1077DEF str_bCount EQU 258 1078DEF str_SIZEOF EQU 259 1079.Ed 1080.Pp 1081There are five commands in the RS group of commands: 1082.Bl -column "RSSET constexpr" 1083.It Sy Command Ta Sy Meaning 1084.It Ic RSRESET Ta Equivalent to Ql RSSET 0 . 1085.It Ic RSSET Ar constexpr Ta Sets the Ic _RS No counter to Ar constexpr . 1086.It Ic RB Ar constexpr Ta Sets the preceding symbol to Ic _RS No and adds Ar constexpr No to Ic _RS . 1087.It Ic RW Ar constexpr Ta Sets the preceding symbol to Ic _RS No and adds Ar constexpr No * 2 to Ic _RS . 1088.It Ic RL Ar constexpr Ta Sets the preceding symbol to Ic _RS No and adds Ar constexpr No * 4 to Ic _RS . 1089.El 1090.Pp 1091If the argument to 1092.Ic RB , RW , 1093or 1094.Ic RL 1095is omitted, it's assumed to be 1. 1096.Pp 1097Note that colons 1098.Ql \&: 1099following the name are not allowed. 1100.Ss String constants 1101.Ic EQUS 1102is used to define string constant symbols. 1103Wherever the assembler reads a string constant, it gets 1104.Em expanded : 1105the symbol's name is replaced with its contents. 1106If you are familiar with C, you can think of it as similar to 1107.Fd #define . 1108This expansion is disabled in a few contexts: 1109.Ql DEF(name) , 1110.Ql DEF name EQU/=/EQUS/etc ... , 1111.Ql PURGE name , 1112and 1113.Ql MACRO name 1114will not expand string constants in their names. 1115.Bd -literal -offset indent 1116DEF COUNTREG EQUS "[hl+]" 1117 ld a,COUNTREG 1118 1119DEF PLAYER_NAME EQUS "\[rs]"John\[rs]"" 1120 db PLAYER_NAME 1121.Ed 1122.Pp 1123This will be interpreted as: 1124.Bd -literal -offset indent 1125 ld a,[hl+] 1126 db "John" 1127.Ed 1128.Pp 1129String constants can also be used to define small one-line macros: 1130.Bd -literal -offset indent 1131DEF pusha EQUS "push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n" 1132.Ed 1133.Pp 1134Note that colons 1135.Ql \&: 1136following the name are not allowed. 1137.Pp 1138String constants can't be exported or imported. 1139.Pp 1140String constants, like numeric constants, cannot be redefined. 1141However, the 1142.Ic REDEF 1143keyword will define or redefine a string constant symbol. 1144For example: 1145.Bd -literal -offset indent 1146DEF s EQUS "Hello, " 1147REDEF s EQUS "{s}world!" 1148; prints "Hello, world!" 1149PRINTLN "{s}\n" 1150.Ed 1151.Pp 1152.Sy Important note : 1153When a string constant is expanded, its expansion may contain another string constant, which will be expanded as well. 1154If this creates an infinite loop, 1155.Nm 1156will error out once a certain depth is 1157reached. 1158See the 1159.Fl r 1160command-line option in 1161.Xr rgbasm 1 . 1162The same problem can occur if the expansion of a macro invokes another macro, recursively. 1163.Pp 1164The examples above for 1165.Ql EQU , 1166.Ql = , 1167.Ql RB , 1168.Ql RW , 1169.Ql RL , 1170and 1171.Ql EQUS 1172all start with 1173.Ql DEF . 1174(A variable definition may start with 1175.Ql REDEF 1176instead, since they are redefinable.) 1177You may use the older syntax without 1178.Ql DEF , 1179but then the name being defined 1180.Em must not 1181have any whitespace before it; 1182otherwise 1183.Nm 1184will treat it as a macro invocation. 1185Furthermore, without the 1186.Ql DEF 1187keyword, 1188string constants may be expanded for the name. 1189This can lead to surprising results: 1190.Bd -literal -offset indent 1191X EQUS "Y" 1192; this defines Y, not X! 1193X EQU 42 1194; prints "Y $2A" 1195PRINTLN "{X} {Y}" 1196.Ed 1197.Ss Macros 1198One of the best features of an assembler is the ability to write macros for it. 1199Macros can be called with arguments, and can react depending on input using 1200.Ic IF 1201constructs. 1202.Bd -literal -offset indent 1203MACRO MyMacro 1204 ld a, 80 1205 call MyFunc 1206ENDM 1207.Ed 1208.Pp 1209The example above defines 1210.Ql MyMacro 1211as a new macro. 1212String constants are not expanded within the name of the macro. 1213You may use the older syntax 1214.Ql MyMacro: MACRO 1215instead of 1216.Ql MACRO MyMacro , 1217with a single colon 1218.Ql \&: 1219following the macro's name. 1220With the older syntax, string constants may be expanded for the name. 1221.Pp 1222Macros can't be exported or imported. 1223.Pp 1224Plainly nesting macro definitions is not allowed, but this can be worked around using 1225.Ic EQUS . 1226So this won't work: 1227.Bd -literal -offset indent 1228MACRO outer 1229 MACRO inner 1230 PRINTLN "Hello!" 1231 ENDM 1232ENDM 1233.Ed 1234.Pp 1235But this will: 1236.Bd -literal -offset indent 1237MACRO outer 1238DEF definition EQUS "MACRO inner\[rs]nPRINTLN \[rs]"Hello!\[rs]"\[rs]nENDM" 1239 definition 1240 PURGE definition 1241ENDM 1242.Ed 1243.Pp 1244Macro arguments support all the escape sequences of strings, as well as 1245.Ql \[rs], 1246to escape commas, as well as 1247.Ql \[rs]( 1248and 1249.Ql \[rs]) 1250to escape parentheses, since those otherwise separate and enclose arguments, respectively. 1251.Ss Exporting and importing symbols 1252Importing and exporting of symbols is a feature that is very useful when your project spans many source files and, for example, you need to jump to a routine defined in another file. 1253.Pp 1254Exporting of symbols has to be done manually, importing is done automatically if 1255.Nm 1256finds a symbol it does not know about. 1257.Pp 1258The following will cause 1259.Ar symbol1 , symbol2 1260and so on to be accessible to other files during the link process: 1261.Dl Ic EXPORT Ar symbol1 Bq , Ar symbol2 , No ... 1262.Pp 1263For example, if you have the following three files: 1264.Pp 1265.Ql a.asm : 1266.Bd -literal -compact 1267SECTION "a", WRAM0 1268LabelA: 1269.Ed 1270.Pp 1271.Ql b.asm : 1272.Bd -literal -compact 1273SECTION "b", WRAM0 1274ExportedLabelB1:: 1275ExportedLabelB2: 1276 EXPORT ExportedLabelB2 1277.Ed 1278.Pp 1279.Ql c.asm : 1280.Bd -literal -compact 1281SECTION "C", ROM0[0] 1282 dw LabelA 1283 dw ExportedLabelB1 1284 dw ExportedLabelB2 1285.Ed 1286.Pp 1287Then 1288.Ql c.asm 1289can use 1290.Ql ExportedLabelB1 1291and 1292.Ql ExportedLabelB2 , 1293but not 1294.Ql LabelA , 1295so linking them together will fail: 1296.Bd -literal 1297$ rgbasm -o a.o a.asm 1298$ rgbasm -o b.o b.asm 1299$ rgbasm -o c.o c.asm 1300$ rgblink a.o b.o c.o 1301error: c.asm(2): Unknown symbol "LabelA" 1302Linking failed with 1 error 1303.Ed 1304.Pp 1305Note also that only exported symbols will appear in symbol and map files produced by 1306.Xr rgblink 1 . 1307.Ss Purging symbols 1308.Ic PURGE 1309allows you to completely remove a symbol from the symbol table as if it had never existed. 1310.Em USE WITH EXTREME CAUTION!!! 1311I can't stress this enough, 1312.Sy you seriously need to know what you are doing . 1313DON'T purge a symbol that you use in expressions the linker needs to calculate. 1314When not sure, it's probably not safe to purge anything other than variables, numeric or string constants, or macros. 1315.Bd -literal -offset indent 1316DEF Kamikaze EQUS "I don't want to live anymore" 1317DEF AOLer EQUS "Me too" 1318 PURGE Kamikaze, AOLer 1319.Ed 1320.Pp 1321String constants are not expanded within the symbol names. 1322.Ss Predeclared symbols 1323The following symbols are defined by the assembler: 1324.Bl -column -offset indent "EQUS" "__ISO_8601_LOCAL__" 1325.It Sy Name Ta Sy Type Ta Sy Contents 1326.It Dv @ Ta Ic EQU Ta PC value (essentially, the current memory address) 1327.It Dv _RS Ta Ic = Ta _RS Counter 1328.It Dv _NARG Ta Ic EQU Ta Number of arguments passed to macro, updated by Ic SHIFT 1329.It Dv __LINE__ Ta Ic EQU Ta The current line number 1330.It Dv __FILE__ Ta Ic EQUS Ta The current filename 1331.It Dv __DATE__ Ta Ic EQUS Ta Today's date 1332.It Dv __TIME__ Ta Ic EQUS Ta The current time 1333.It Dv __ISO_8601_LOCAL__ Ta Ic EQUS Ta ISO 8601 timestamp (local) 1334.It Dv __ISO_8601_UTC__ Ta Ic EQUS Ta ISO 8601 timestamp (UTC) 1335.It Dv __UTC_YEAR__ Ta Ic EQU Ta Today's year 1336.It Dv __UTC_MONTH__ Ta Ic EQU Ta Today's month number, 1\[en]12 1337.It Dv __UTC_DAY__ Ta Ic EQU Ta Today's day of the month, 1\[en]31 1338.It Dv __UTC_HOUR__ Ta Ic EQU Ta Current hour, 0\[en]23 1339.It Dv __UTC_MINUTE__ Ta Ic EQU Ta Current minute, 0\[en]59 1340.It Dv __UTC_SECOND__ Ta Ic EQU Ta Current second, 0\[en]59 1341.It Dv __RGBDS_MAJOR__ Ta Ic EQU Ta Major version number of RGBDS 1342.It Dv __RGBDS_MINOR__ Ta Ic EQU Ta Minor version number of RGBDS 1343.It Dv __RGBDS_PATCH__ Ta Ic EQU Ta Patch version number of RGBDS 1344.It Dv __RGBDS_RC__ Ta Ic EQU Ta Release candidate ID of RGBDS, not defined for final releases 1345.It Dv __RGBDS_VERSION__ Ta Ic EQUS Ta Version of RGBDS, as printed by Ql rgbasm --version 1346.El 1347.Pp 1348The current time values will be taken from the 1349.Dv SOURCE_DATE_EPOCH 1350environment variable if that is defined as a UNIX timestamp. 1351Refer to the spec at 1352.Lk https://reproducible-builds.org/docs/source-date-epoch/ . 1353.Sh DEFINING DATA 1354.Ss Statically allocating space in RAM 1355.Ic DS 1356statically allocates a number of empty bytes. 1357This is the preferred method of allocating space in a RAM section. 1358You can also use 1359.Ic DB , DW 1360and 1361.Ic DL 1362without any arguments instead (see 1363.Sx Defining constant data in ROM 1364below). 1365.Bd -literal -offset indent 1366DS 42 ;\ Allocates 42 bytes 1367.Ed 1368.Pp 1369Empty space in RAM sections will not be initialized. 1370In ROM sections, it will be filled with the value passed to the 1371.Fl p 1372command-line option, except when using overlays with 1373.Fl O . 1374.Ss Defining constant data in ROM 1375.Ic DB 1376defines a list of bytes that will be stored in the final image. 1377Ideal for tables and text. 1378.Bd -literal -offset indent 1379DB 1,2,3,4,"This is a string" 1380.Ed 1381.Pp 1382Alternatively, you can use 1383.Ic DW 1384to store a list of words (16-bit) or 1385.Ic DL 1386to store a list of double-words/longs (32-bit). 1387.Pp 1388Strings are handled a little specially: they first undergo charmap conversion (see 1389.Sx Character maps ) , 1390then each resulting character is output individually. 1391For example, under the default charmap, the following two lines are identical: 1392.Bd -literal -offset indent 1393DW "Hello!" 1394DW "H", "e", "l", "l", "o", "!" 1395.Ed 1396.Pp 1397If you do not want this special handling, enclose the string in parentheses. 1398.Pp 1399.Ic DS 1400can also be used to fill a region of memory with some repeated values. 1401For example: 1402.Bd -literal -offset indent 1403; outputs 3 bytes: $AA, $AA, $AA 1404DS 3, $AA 1405; outputs 7 bytes: $BB, $CC, $BB, $CC, $BB, $CC, $BB 1406DS 7, $BB, $CC 1407.Ed 1408.Pp 1409You can also use 1410.Ic DB , DW 1411and 1412.Ic DL 1413without arguments. 1414This works exactly like 1415.Ic DS 1 , DS 2 1416and 1417.Ic DS 4 1418respectively. 1419Consequently, no-argument 1420.Ic DB , DW 1421and 1422.Ic DL 1423can be used in a 1424.Ic WRAM0 1425/ 1426.Ic WRAMX 1427/ 1428.Ic HRAM 1429/ 1430.Ic VRAM 1431/ 1432.Ic SRAM 1433section. 1434.Ss Including binary files 1435You probably have some graphics, level data, etc. you'd like to include. 1436Use 1437.Ic INCBIN 1438to include a raw binary file as it is. 1439If the file isn't found in the current directory, the include-path list passed to 1440.Xr rgbasm 1 1441(see the 1442.Fl i 1443option) on the command line will be searched. 1444.Bd -literal -offset indent 1445INCBIN "titlepic.bin" 1446INCBIN "sprites/hero.bin" 1447.Ed 1448.Pp 1449You can also include only part of a file with 1450.Ic INCBIN . 1451The example below includes 256 bytes from data.bin, starting from byte 78. 1452.Bd -literal -offset indent 1453INCBIN "data.bin",78,256 1454.Ed 1455.Pp 1456The length argument is optional. 1457If only the start position is specified, the bytes from the start position until the end of the file will be included. 1458.Ss Unions 1459Unions allow multiple static memory allocations to overlap, like unions in C. 1460This does not increase the amount of memory available, but allows re-using the same memory region for different purposes. 1461.Pp 1462A union starts with a 1463.Ic UNION 1464keyword, and ends at the corresponding 1465.Ic ENDU 1466keyword. 1467.Ic NEXTU 1468separates each block of allocations, and you may use it as many times within a union as necessary. 1469.Bd -literal -offset indent 1470 ; Let's say PC = $C0DE here 1471 UNION 1472 ; Here, PC = $C0DE 1473Name: ds 8 1474 ; PC = $C0E6 1475Nickname: ds 8 1476 ; PC = $C0EE 1477 NEXTU 1478 ; PC is back to $C0DE 1479Health: dw 1480 ; PC = $C0E0 1481Something: ds 6 1482 ; And so on 1483Lives: db 1484 NEXTU 1485VideoBuffer: ds 19 1486 ENDU 1487.Ed 1488.Pp 1489In the example above, 1490.Sq Name , Health , VideoBuffer 1491all have the same value, as do 1492.Sq Nickname 1493and 1494.Sq Lives . 1495Thus, keep in mind that 1496.Ic ld [Health], a 1497is identical to 1498.Ic ld [Name], a . 1499.Pp 1500The size of this union is 19 bytes, as this is the size of the largest block (the last one, containing 1501.Sq VideoBuffer ) . 1502Nesting unions is possible, with each inner union's size being considered as described above. 1503.Pp 1504Unions may be used in any section, but inside them may only be 1505.Ic DS - 1506like commands (see 1507.Sx Statically allocating space in RAM ) . 1508.Sh THE MACRO LANGUAGE 1509.Ss Invoking macros 1510You execute the macro by inserting its name. 1511.Bd -literal -offset indent 1512 add a,b 1513 ld sp,hl 1514 MyMacro ;\ This will be expanded 1515 sub a,87 1516.Ed 1517.Pp 1518It's valid to call a macro from a macro (yes, even the same one). 1519.Pp 1520When 1521.Nm 1522sees 1523.Ic MyMacro 1524it will insert the macro definition (the code enclosed in 1525.Ic MACRO 1526/ 1527.Ic ENDM ) . 1528.Pp 1529Suppose your macro contains a loop. 1530.Bd -literal -offset indent 1531MACRO LoopyMacro 1532 xor a,a 1533\&.loop ld [hl+],a 1534 dec c 1535 jr nz,.loop 1536ENDM 1537.Ed 1538.Pp 1539This is fine, but only if you use the macro no more than once per scope. 1540To get around this problem, there is the escape sequence 1541.Ic \[rs]@ 1542that expands to a unique string. 1543.Pp 1544.Ic \[rs]@ 1545also works in 1546.Ic REPT 1547blocks. 1548.Bd -literal -offset indent 1549MACRO LoopyMacro 1550 xor a,a 1551\&.loop\[rs]@ ld [hl+],a 1552 dec c 1553 jr nz,.loop\[rs]@ 1554ENDM 1555.Ed 1556.Pp 1557.Sy Important note : 1558Since a macro can call itself (or a different macro that calls the first one), there can be circular dependency problems. 1559If this creates an infinite loop, 1560.Nm 1561will error out once a certain depth is 1562reached. 1563See the 1564.Fl r 1565command-line option in 1566.Xr rgbasm 1 . 1567Also, a macro can have inside an 1568.Sy EQUS 1569which references the same macro, which has the same problem. 1570.Pp 1571It's possible to pass arguments to macros as well! 1572You retrieve the arguments by using the escape sequences 1573.Ic \[rs]1 1574through 1575.Ic \[rs]9 , \[rs]1 1576being the first argument specified on the macro invocation. 1577.Bd -literal -offset indent 1578MACRO LoopyMacro 1579 ld hl,\[rs]1 1580 ld c,\[rs]2 1581 xor a,a 1582\&.loop\[rs]@ ld [hl+],a 1583 dec c 1584 jr nz,.loop\[rs]@ 1585 ENDM 1586.Ed 1587.Pp 1588Now you can call the macro specifying two arguments, the first being the address and the second being a byte count. 1589The generated code will then reset all bytes in this range. 1590.Bd -literal -offset indent 1591LoopyMacro MyVars,54 1592.Ed 1593.Pp 1594Arguments are passed as string constants, although there's no need to enclose them in quotes. 1595Thus, an expression will not be evaluated first but kind of copy-pasted. 1596This means that it's probably a very good idea to use brackets around 1597.Ic \[rs]1 1598to 1599.Ic \[rs]9 1600if you perform further calculations on them. 1601For instance, consider the following: 1602.Bd -literal -offset indent 1603MACRO print_double 1604 PRINTLN \[rs]1 * 2 1605ENDM 1606 print_double 1 + 2 1607.Ed 1608.Pp 1609The 1610.Ic PRINTLN 1611statement will expand to 1612.Ql PRINTLN 1 + 2 * 2 , 1613which will print 5 and not 6 as you might have expected. 1614.Pp 1615Line continuations work as usual inside macros or lists of macro arguments. 1616However, some characters need to be escaped, as in the following example: 1617.Bd -literal -offset indent 1618MACRO PrintMacro1 1619 PRINTLN STRCAT(\[rs]1) 1620ENDM 1621 PrintMacro1 "Hello "\[rs], \[rs] 1622 "world" 1623MACRO PrintMacro2 1624 PRINT \[rs]1 1625ENDM 1626 PrintMacro2 STRCAT("Hello ", \[rs] 1627 "world\[rs]n") 1628.Ed 1629.Pp 1630The comma in 1631.Ql PrintMacro1 1632needs to be escaped to prevent it from starting another macro argument. 1633The comma in 1634.Ql PrintMacro2 1635does not need escaping because it is inside parentheses, similar to macro arguments in C. 1636The backslash in 1637.Ql \[rs]n 1638also does not need escaping because string literals work as usual inside macro arguments. 1639.Pp 1640Since there are only nine digits, you can only access the first nine macro arguments like this. 1641To use the rest, you need to put the multi-digit argument number in angle brackets, like 1642.Ql \[rs]<10> . 1643This bracketed syntax supports decimal numbers and numeric constant symbols. 1644For example, 1645.Ql \[rs]<_NARG> 1646will get the last argument. 1647.Pp 1648Other macro arguments and symbol interpolations will be expanded inside the angle brackets. 1649For example, if 1650.Ql \[rs]1 1651is 1652.Ql 13 , 1653then 1654.Ql \[rs]<\[rs]1> 1655will expand to 1656.Ql \[rs]<13> . 1657Or if 1658.Ql v10 = 42 1659and 1660.Ql x = 10 , 1661then 1662.Ql \[rs]<v{d:x}> 1663will expand to 1664.Ql \[rs]<42> . 1665.Pp 1666Another way to access more than nine macro arguments is the 1667.Ic SHIFT 1668command, a special command only available in macros. 1669It will shift the arguments by one to the left, and decrease 1670.Dv _NARG 1671by 1. 1672.Ic \[rs]1 1673will get the value of 1674.Ic \[rs]2 , \[rs]2 1675will get the value of 1676.Ic \[rs]3 , 1677and so forth. 1678.Pp 1679.Ic SHIFT 1680can optionally be given an integer parameter, and will apply the above shifting that number of times. 1681A negative parameter will shift the arguments in reverse. 1682.Pp 1683.Ic SHIFT 1684is useful in 1685.Ic REPT 1686blocks to repeat the same commands with multiple arguments. 1687.Ss Printing things during assembly 1688The 1689.Ic PRINT 1690and 1691.Ic PRINTLN 1692commands print text and values to the standard output. 1693Useful for debugging macros, or wherever you may feel the need to tell yourself some important information. 1694.Bd -literal -offset indent 1695PRINT "Hello world!\[rs]n" 1696PRINTLN "Hello world!" 1697PRINT _NARG, " arguments\[rs]n" 1698PRINTLN "sum: ", 2+3, " product: ", 2*3 1699PRINTLN "Line #", __LINE__ 1700PRINTLN STRFMT("E = %f", 2.718) 1701.Ed 1702.Bl -inset 1703.It Ic PRINT 1704prints out each of its comma-separated arguments. 1705Numbers are printed as unsigned uppercase hexadecimal with a leading 1706.Ic $ . 1707For different formats, use 1708.Ic STRFMT . 1709.It Ic PRINTLN 1710prints out each of its comma-separated arguments, if any, followed by a line feed 1711.Pq Ql \[rs]n . 1712.El 1713.Ss Automatically repeating blocks of code 1714Suppose you want to unroll a time consuming loop without copy-pasting it. 1715.Ic REPT 1716is here for that purpose. 1717Everything between 1718.Ic REPT 1719and the matching 1720.Ic ENDR 1721will be repeated a number of times just as if you had done a copy/paste operation yourself. 1722The following example will assemble 1723.Ql add a,c 1724four times: 1725.Bd -literal -offset indent 1726REPT 4 1727 add a,c 1728ENDR 1729.Ed 1730.Pp 1731You can also use 1732.Ic REPT 1733to generate tables on the fly: 1734.Bd -literal -offset indent 1735; Generate a 256-byte sine table with values in the range [0, 128] 1736; (shifted and scaled from the range [-1.0, 1.0]) 1737ANGLE = 0.0 1738 REPT 256 1739 db (MUL(64.0, SIN(ANGLE)) + 64.0) >> 16 1740ANGLE = ANGLE + 256.0 ; 256.0 = 65536 degrees / 256 entries 1741 ENDR 1742.Ed 1743.Pp 1744As in macros, you can also use the escape sequence 1745.Ic \[rs]@ . 1746.Ic REPT 1747blocks can be nested. 1748.Pp 1749A common pattern is to repeat a block for each value in some range. 1750.Ic FOR 1751is simpler than 1752.Ic REPT 1753for that purpose. 1754Everything between 1755.Ic FOR 1756and the matching 1757.Ic ENDR 1758will be repeated for each value of a given symbol. 1759String constants are not expanded within the symbol name. 1760For example, this code will produce a table of squared values from 0 to 255: 1761.Bd -literal -offset indent 1762FOR N, 256 1763 dw N * N 1764ENDR 1765.Ed 1766.Pp 1767It acts just as if you had done: 1768.Bd -literal -offset indent 1769N = 0 1770 dw N * N 1771N = 1 1772 dw N * N 1773N = 2 1774 dw N * N 1775; ... 1776N = 255 1777 dw N * N 1778N = 256 1779.Ed 1780.Pp 1781You can customize the range of 1782.Ic FOR 1783values, similarly to Python's 1784.Ql range 1785function: 1786.Bl -column "FOR V, start, stop, step" 1787.It Sy Code Ta Sy Range 1788.It Ic FOR Ar V , stop Ta Ar V No increments from 0 to Ar stop 1789.It Ic FOR Ar V , start , stop Ta Ar V No increments from Ar start No to Ar stop 1790.It Ic FOR Ar V , start , stop , step Ta Ar V No goes from Ar start No to Ar stop No by Ar step 1791.El 1792.Pp 1793The 1794.Ic FOR 1795value will be updated by 1796.Ar step 1797until it reaches or exceeds 1798.Ar stop . 1799For example: 1800.Bd -literal -offset indent 1801FOR V, 4, 25, 5 1802 PRINT "{d:V} " 1803ENDR 1804 PRINTLN "done {d:V}" 1805.Ed 1806.Pp 1807This will print: 1808.Bd -literal -offset indent 18094 9 14 19 24 done 29 1810.Ed 1811.Pp 1812Just like with 1813.Ic REPT 1814blocks, you can use the escape sequence 1815.Ic \[rs]@ 1816inside of 1817.Ic FOR 1818blocks, and they can be nested. 1819.Pp 1820You can stop a repeating block with the 1821.Ic BREAK 1822command. 1823A 1824.Ic BREAK 1825inside of a 1826.Ic REPT 1827or 1828.Ic FOR 1829block will interrupt the current iteration and not repeat any more. 1830It will continue running code after the block's 1831.Ic ENDR . 1832For example: 1833.Bd -literal -offset indent 1834FOR V, 1, 100 1835 PRINT "{d:V}" 1836 IF V == 5 1837 PRINT " stop! " 1838 BREAK 1839 ENDC 1840 PRINT ", " 1841ENDR 1842 PRINTLN "done {d:V}" 1843.Ed 1844.Pp 1845This will print: 1846.Bd -literal -offset indent 18471, 2, 3, 4, 5 stop! done 5 1848.Ed 1849.Ss Aborting the assembly process 1850.Ic FAIL 1851and 1852.Ic WARN 1853can be used to print errors and warnings respectively during the assembly process. 1854This is especially useful for macros that get an invalid argument. 1855.Ic FAIL 1856and 1857.Ic WARN 1858take a string as the only argument and they will print this string out as a normal error with a line number. 1859.Pp 1860.Ic FAIL 1861stops assembling immediately while 1862.Ic WARN 1863shows the message but continues afterwards. 1864.Pp 1865If you need to ensure some assumption is correct when compiling, you can use 1866.Ic ASSERT 1867and 1868.Ic STATIC_ASSERT . 1869Syntax examples are given below: 1870.Bd -literal -offset indent 1871Function: 1872 xor a 1873ASSERT LOW(MyByte) == 0 1874 ld h, HIGH(MyByte) 1875 ld l, a 1876 ld a, [hli] 1877; You can also indent this! 1878 ASSERT BANK(OtherFunction) == BANK(Function) 1879 call OtherFunction 1880; Lowercase also works 1881 ld hl, FirstByte 1882 ld a, [hli] 1883assert FirstByte + 1 == SecondByte 1884 ld b, [hl] 1885 ret 1886\&.end 1887 ; If you specify one, a message will be printed 1888 STATIC_ASSERT .end - Function < 256, "Function is too large!" 1889.Ed 1890.Pp 1891First, the difference between 1892.Ic ASSERT 1893and 1894.Ic STATIC_ASSERT 1895is that the former is evaluated by RGBASM if it can, otherwise by RGBLINK; but the latter is only ever evaluated by RGBASM. 1896If RGBASM cannot compute the value of the argument to 1897.Ic STATIC_ASSERT , 1898it will produce an error. 1899.Pp 1900Second, as shown above, a string can be optionally added at the end, to give insight into what the assertion is checking. 1901.Pp 1902Finally, you can add one of 1903.Ic WARN , FAIL 1904or 1905.Ic FATAL 1906as the first optional argument to either 1907.Ic ASSERT 1908or 1909.Ic STATIC_ASSERT . 1910If the assertion fails, 1911.Ic WARN 1912will cause a simple warning (controlled by 1913.Xr rgbasm 1 1914flag 1915.Fl Wassert ) 1916to be emitted; 1917.Ic FAIL 1918(the default) will cause a non-fatal error; and 1919.Ic FATAL 1920immediately aborts. 1921.Ss Including other source files 1922Use 1923.Ic INCLUDE 1924to process another assembler file and then return to the current file when done. 1925If the file isn't found in the current directory, the include path list (see the 1926.Fl i 1927option in 1928.Xr rgbasm 1 ) 1929will be searched. 1930You may nest 1931.Ic INCLUDE 1932calls infinitely (or until you run out of memory, whichever comes first). 1933.Bd -literal -offset indent 1934 INCLUDE "irq.inc" 1935.Ed 1936.Ss Conditional assembling 1937The four commands 1938.Ic IF , ELIF , ELSE , 1939and 1940.Ic ENDC 1941let you have 1942.Nm 1943skip over parts of your code depending on a condition. 1944This is a powerful feature commonly used in macros. 1945.Bd -literal -offset indent 1946IF NUM < 0 1947 PRINTLN "NUM < 0" 1948ELIF NUM == 0 1949 PRINTLN "NUM == 0" 1950ELSE 1951 PRINTLN "NUM > 0" 1952ENDC 1953.Ed 1954.Pp 1955The 1956.Ic ELIF 1957(standing for "else if") and 1958.Ic ELSE 1959blocks are optional. 1960.Ic IF 1961/ 1962.Ic ELIF 1963/ 1964.Ic ELSE 1965/ 1966.Ic ENDC 1967blocks can be nested. 1968.Pp 1969Note that if an 1970.Ic ELSE 1971block is found before an 1972.Ic ELIF 1973block, the 1974.Ic ELIF 1975block will be ignored. 1976All 1977.Ic ELIF 1978blocks must go before the 1979.Ic ELSE 1980block. 1981Also, if there is more than one 1982.Ic ELSE 1983block, all of them but the first one are ignored. 1984.Sh MISCELLANEOUS 1985.Ss Changing options while assembling 1986.Ic OPT 1987can be used to change some of the options during assembling from within the source, instead of defining them on the command-line. 1988.Pp 1989.Ic OPT 1990takes a comma-separated list of options as its argument: 1991.Bd -literal -offset indent 1992PUSHO 1993 OPT g.oOX, Wdiv, L ; acts like command-line -g.oOX -Wdiv -L 1994 DW `..ooOOXX ; uses the graphics constant characters from OPT g 1995 PRINTLN $80000000/-1 ; prints a warning about division 1996 LD [$FF88], A ; encoded as LD, not LDH 1997POPO 1998 DW `00112233 ; uses the default graphics constant characters 1999 PRINTLN $80000000/-1 ; no warning by default 2000 LD [$FF88], A ; optimized to use LDH by default 2001.Ed 2002.Pp 2003The options that OPT can modify are currently: 2004.Cm b , g , p , h , L , 2005and 2006.Cm W . 2007The Boolean flag options 2008.Cm h 2009and 2010.Cm L 2011can be negated as 2012.Ql OPT !h 2013and 2014.Ql OPT !L 2015to act like omitting them from the command-line. 2016.Pp 2017.Ic POPO 2018and 2019.Ic PUSHO 2020provide the interface to the option stack. 2021.Ic PUSHO 2022will push the current set of options on the option stack. 2023.Ic POPO 2024can then later be used to restore them. 2025Useful if you want to change some options in an include file and you don't want to destroy the options set by the program that included your file. 2026The stack's number of entries is limited only by the amount of memory in your machine. 2027.Ss Requesting alignment 2028While 2029.Ic ALIGN 2030as presented in 2031.Sx SECTIONS 2032is often useful as-is, sometimes you instead want a particular piece of data (or code) in the middle of the section to be aligned. 2033This is made easier through the use of mid-section 2034.Ic ALIGN Ar align , offset . 2035It will alter the section's attributes to ensure that the location the 2036.Ic ALIGN 2037directive is at, has its 2038.Ar align 2039lower bits equal to 2040.Ar offset . 2041.Pp 2042If the constraint cannot be met (for example because the section is fixed at an incompatible address), an error is produced. 2043Note that 2044.Ic ALIGN Ar align 2045is a shorthand for 2046.Ic ALIGN Ar align , No 0 . 2047.Sh SEE ALSO 2048.Xr rgbasm 1 , 2049.Xr rgblink 1 , 2050.Xr rgblink 5 , 2051.Xr rgbds 5 , 2052.Xr rgbds 7 , 2053.Xr gbz80 7 2054.Sh HISTORY 2055.Nm 2056was originally written by Carsten S\(/orensen as part of the ASMotor package, 2057and was later packaged in RGBDS by Justin Lloyd. 2058It is now maintained by a number of contributors at 2059.Lk https://github.com/gbdev/rgbds . 2060