;
; Quick syntax example (rgbds documentation intro).
;
SECTION "My Code", ROM0 ; a directive
MyFunction: ; a label
 push hl ; an instruction
 /* ...and multiple instructions,
 with mixed case */
 ld a, [hli] :: LD H, [HL] :: Ld l, a
 pop /*wait for it*/ hl
 ret

 ; Multiline definitions.
 DB 1, 2, 3, \
 4, 5, 6, \ ; Put it before any comments
 7, 8, 9

;
; Numeric formats.
;
 ld a, 1234
 ld a, 10_000
 ld a, 0o777
 ld a, &777
 ld a, $cafe
 ld a, 0xcafe
 ld a, 89bfh
 ld a, %000_1111
 ld a, 0b00001111
 ld a, 12.34
 ld a, 10_000.000_345
 ld a, 12.34q8
 ld a, `01230123

;
; Case-insensitivity.
;
def MyVar equ 42
section "case", rom0
 xor a
 ld a, MyVar
 HALT

;
; Multiline strings and comments.
;
PRINT """First line,
second line, containing a \"{symbol}\",
third line with "single" quotes and an \{escaped symbol}
last line."""
/* First line,
 second line,
 third line. */

;
; Raw strings
;
PRINT "String \n {symbol}"
PRINT #"Raw string \n {rawsymbol}"
PRINT #"""Raw string (multiline) \n \{test\} \ "
second line,
third line"""

;
; Character maps.
;
CHARMAP "A", 42
CHARMAP ":)", 39
CHARMAP "<br>", 13, 10
CHARMAP "&euro;", $20ac

;
; Section definitions and stack.
;
SECTION "Cool Stuff", ROMX
SECTION "Cool Stuff", ROMX[$4567]
SECTION "Cool Stuff", ROMX[$4567], BANK[3]
SECTION "Cool Stuff", ROMX, BANK[7]
SECTION "OAM Data", WRAM0, ALIGN[8] ; align to 256 bytes
SECTION "VRAM Data", ROMX, BANK[2], ALIGN[4] ; align to 16 bytes
 PUSHS "Variables", WRAM0
 wAnswer: db
 POPS
 ld [wAnswer], a

; Bank and Section are also functions. They should appear as such here.
DEF myBank EQU BANK(wAnswer)
DEF mySection EQU SECTION(wAnswer)

;
; Using @, . and .. builtins.
;
SECTION "test floating", ROM0
FloatingStart:
 ds 6, (@ - FloatingStart) * 2 + zero
 ds 10, (@ - FloatingStart) + zero, (@ - FloatingStart) * 3 + zero, (@ - FloatingStart) * 4 + zero
 PUSHS .
 LOAD ..

;
; Labels.
;
GlobalLabel:
AnotherGlobal:
.locallabel ; This defines "AnotherGlobal.locallabel"
.another_local:
AnotherGlobal.with_another_local:
ThisWillBeExported:: ; Note the two colons
ThisWillBeExported.too::
 JR Z, .locallabel
 JR C, AnotherGlobal.with_another_local
 CALL GlobalLabel

; Anonymous labels.
 ld hl, :++
: ld a, [hli] ; referenced by "jr nz"
 ldh [c], a
 dec c
 jr nz, :-
 ret
: ; referenced by "ld hl"
 dw $7FFF, $1061, $03E0, $58A5

;
; Predefined builtins.
;
PRINTLN(__UTC_YEAR__)
PRINTLN(__UTC_MONTH__)
PRINTLN(__UTC_DAY__)
PRINTLN(__UTC_HOUR__)
PRINTLN(__UTC_MINUTE__)
PRINTLN(__UTC_SECOND__)
PRINTLN(__DATE__)
PRINTLN(__TIME__)
PRINTLN(__RGBDS_MAJOR__)
PRINTLN(__RGBDS_MINOR__)
PRINTLN(__RGBDS_PATCH__)
PRINTLN(__RGBDS_RC__)
PRINTLN(__RGBDS_VERSION__)
PRINTLN(__MYVAR__) ; Not a builtin.

;
; Variables, constants and operators.
;
DEF ARRAY_SIZE EQU 4
DEF COUNT = 2
DEF COUNT = 3
DEF COUNT = ARRAY_SIZE + COUNT
DEF COUNT *= 2
; COUNT now has the value 14

DEF x = 10
DEF x += 1 ; x == 11
DEF y = x - 1 ; y == 10
DEF y *= 2 ; y == 20
DEF y >>= 1 ; y == 10
DEF x ^= y ; x == 1

; Purging symbols and using DEF() function alongside DEF keyword.
DEF Var1 EQUS "Var1 is defined"
Var2: DB "Var2 is also defined"
PURGE Var1, Var2
ASSERT !DEF(Var1) && !DEF(Var2)
DEF isDefined EQU DEF(Var1)

; Variable substitutions.
SECTION "Test", ROM0[2]
X: ; This works with labels **whose address is known**
DEF Y = 3 ; This also works with variables
DEF SUM EQU X + Y ; And likewise with numeric constants
; Prints "%0010 + $3 == 5"
PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}"

RSSET 32
DEF PERCENT RB 1 ; Same with offset constants
DEF VALUE = 20
DEF RESULT = MUL(20.0, 0.32)
; Prints "32% of 20 = 6.40"
PRINTLN "{d:PERCENT}% of {d:VALUE} = {f:RESULT}"

DEF WHO EQUS STRLWR("WORLD")
; Prints "Hello world!"
PRINTLN "Hello {s:WHO}!"

; Escaping curly brackets does not cause interpolation.
PRINTLN "The raw symbol is \{s:WHO}!"

; Offset constants.
RSRESET
DEF str_pStuff RW 1
DEF str_tData RB 256
DEF str_bCount RB 1
DEF str_SIZEOF RL 0

 ; Offsets constants use "RL" which is also contained in two opcodes.
 ; The instructions below should appear as keywords, not built-in names.
 RL A
 RLC A

; String constants.
DEF COUNTREG EQUS "[hl+]"
 ld a, COUNTREG

DEF PLAYER_NAME EQUS "\"John\""
 db PLAYER_NAME

DEF pusha EQUS "push af\npush bc\npush de\npush hl\n"

DEF s EQUS "Hello, "
REDEF s EQUS "{s}world!"
; prints "Hello, world!"
PRINTLN "{s}\n"

DEF topic EQUS "life, the universe, and \"everything\""
DEF meaning EQUS "answer"
; Defines answer = 42
DEF {meaning} = 42
; Prints "The answer to life, the universe, and "everything" is $2A"
PRINTLN "The {meaning} to {topic} is {{meaning}}"

;
; Defining data, reserving memory space.
;

; Defining data in ROM
DB 1,2,3,4,"This is a string"
DW "Hello!"
DW "H", "e", "l", "l", "o", "!"
; outputs 3 bytes: $AA, $AA, $AA
DS 3, $AA
; outputs 7 bytes: $BB, $CC, $BB, $CC, $BB, $CC, $BB
DS 7, $BB, $CC

; Defining data in RAM
DS 42 ; Allocates 42 bytes

; Allocating overlapping space in RAM
; Let's say PC == $C0DE here
UNION
 ; Here, PC == $C0DE
 wName:: ds 10
 ; Now, PC == $C0E8
 wNickname:: ds 10
 ; PC == $C0F2
NEXTU
 ; PC is back to $C0DE
 wHealth:: dw
 ; PC == $C0E0
 wLives:: db
 ; PC == $C0E1
 ds 7
 ; PC == $C0E8
 wBonus:: db
 ; PC == $C0E9
NEXTU
 ; PC is back to $C0DE again
 wVideoBuffer: ds 16
 ; PC == $C0EE
ENDU
; Afterward, PC == $C0F2

;
; Including files.
;
INCLUDE "header.inc"

INCBIN "titlepic.bin"
INCBIN "sprites/hero.bin"
INCBIN "data.bin", 78, 256

;
; Repeating code.
;
REPT 4
 ADD A, H
ENDR

FOR V, 1, 100
 PRINT "{d:V}"
 IF V == 5
 PRINT " stop! "
 BREAK
 ENDC
 PRINT ", "
ENDR

;
; Conditionals.
;
IF NUM < 0
 PRINTLN "NUM < 0"
ELIF NUM == 0
 PRINTLN "NUM == 0"
ELSE
 PRINTLN "NUM > 0"
ENDC

;
; Assertions.
;
Function:
 xor a
ASSERT LOW(MyByte) == 0
 ld h, HIGH(MyByte)
 ld l, a
 ld a, [hli]
; You can also indent this!
 ASSERT BANK(OtherFunction) == BANK(Function)
 call OtherFunction
; Lowercase also works
 ld hl, FirstByte
 ld a, [hli]
assert FirstByte + 1 == SecondByte
 ld b, [hl]
 ret
.end
 ; If you specify one, a message will be printed
 STATIC_ASSERT .end - Function < 256, "Function is too large!"

;
; Macros.
;
MACRO lb
 ld \1, (\2) << 8 | (\3)
ENDM
 lb hl, 20, 18 ; Expands to "ld hl, ((20) << 8) | (18)"
 lb de, 3 + 1, NUM**2 ; Expands to "ld de, ((3 + 1) << 8) | (NUM**2)"

; Unique symbol name affix.
MACRO loop_c_times_fixed
 xor a, a
.loop\@
 ld [hl+], a
 dec c
 jr nz, .loop\@
ENDM

; Arguments and more complex symbol expansion.
def NUM_ITEMS equ 0
def v10 = 42
def x = 10
MACRO add_item
 redef NUM_ITEMS equ NUM_ITEMS + 1
 def ITEM_{02x:NUM_ITEMS} equ \1

 ; Special bracketed arguments.
 def lastArg equ \<_NARG>
 redef lastArg equ \<-1>
 def version equ \<v{d:x}> ; will expand to ‘\<42>’.
ENDM
 add_item 1
 add_item 4
 add_item 8
 assert NUM_ITEMS == 3
 assert ITEM_03 == 8

;
; Options.
;
PUSHO
 OPT g.oOX, Wdiv ; acts like command-line -g.oOX -Wdiv
 DW `..ooOOXX ; uses the graphics constant characters from OPT g
 PRINTLN $80000000/-1 ; prints a warning about division
POPO
 DW `00112233 ; uses the default graphics constant characters
 PRINTLN $80000000/-1 ; no warning by default

PUSHO g.oOX, Wdiv ; Also works directly with PUSHO
 DW `..ooOOXX
 PRINTLN $80000000/-1
POPO