---
# System prepended metadata

title: Fantasy GB Assembly

---

# Fantasy GB Assembly

gbrs = Game Boy Rusty Style

hello-world.gbrs
```rust
#![mbc(none)]
#![ram(none)]
#![entry(EntryPoint)]

// Using the above attributes, the correct header would
// be generated automatically. We don't have to fiddle
// with adding the correct amount of space and that stuff.

const ZERO = 0; // a literal alias uses rust-like syntax

#[link(rom0)]
section "EntryPoint" {
  // this specific indentation style is not mandatory, but doing it
  // with labels 1 level in and code 2 levels in lets vscode and
  // similar editors automatically know how to code fold it.
  EntryPoint:
    //	Shut down audio circuitry
    ld a, ZERO
    ld [rNR52], a

  WaitVBlank:
    // Do not turn the LCD off outside of VBlank
    ld a, [rLY]
    cp 144
    jp c, WaitVBlank

    // Turn the LCD off
    ld a, 0
    ld [rLCDC], a

    // Copy the tile data
    ld de, Tiles
    ld hl, $9000
    ld bc, size_of_val!(TILES)
  CopyTiles:
    ld a, [de]
    ld [hli], a
    inc de
    dec bc
    ld a, b
    or a, c
    jp nz, CopyTiles

    // Copy the tilemap
    ld de, Tilemap
    ld hl, $9800
    ld bc, size_of_val!(TILE_MAP)
  CopyTilemap:
    ld a, [de]
    ld [hli], a
    inc de
    dec bc
    ld a, b
    or a, c
    jp nz, CopyTilemap

    // Turn the LCD on
    ld a, LCDCF_ON | LCDCF_BGON
    ld [rLCDC], a

    // During the first (blank) frame,
    // initialize display registers
    ld a, %11100100
    ld [rBGP], a

  Done:
    jp Done
}

#[link(rom0)]
static TILES: &[u8] = include_bytes!("tiles.dat");

// if there's no link attribute, assume rom0
static TILE_MAP: &[u8] = include_bytes!("tile_map.dat");
```
