Background information

From ZeldaHacking Wiki
Jump to: navigation, search

Many of the pages on this wiki will assume that you understand the concepts presented on this page.

Basic knowledge


If you don't know what hexadecimal is, here's the quick version: it's a number using the digits 0-9 as well as a-f.

Hexadecimal numbers are prefixed with $, ie. $1f. Numbers prefixed with % are binary, ie. %10001000. Numbers prefixed with nothing are usually decimal (there are a few exceptions which will be explained).

You should also know that using 0x for hexadecimal numbers is more common in general, ie. 0x1f. However, most assemblers (including WLA) don't support this syntax.


%00011110 = $1e = 30


Get acquainted with the gameboy memory map (aka "address space"). Important parts:

  • $0000-$3fff: ROM Bank 0. This is the first 16KB of your ROM file.
  • $4000-$7fff: Switchable ROM Bank. This is a 16KB chunk of your ROM file. The program can decide which chunk it references at any given time.
  • $a000-$bfff: External RAM (SRAM). This is your save file.
  • $c000-$cfff: Work RAM (WRAM) Bank 0. 4KB of RAM which can be used for variables.
  • $d000-$dfff: Switchable WRAM Bank. This references a 4KB chunk of the gameboy's RAM (of 32KB total). The program can decide which chunk it references at any given time.
  • $ff80-$fffe: High RAM (HRAM). 127 bytes of RAM that can be accessed slightly more quickly than WRAM.

The important takeaways: addresses $0000-$7fff reference your ROM, and they are read-only. Variables are stored in WRAM ($c000-$dfff) and HRAM ($ff80-$fffe).


As you can see in the memory map above, both ROM and WRAM have "switchable banks". The gameboy's address space goes from $0000-$ffff, which is only 64KB. Since the oracle ROMs are at least 1MB large, this means only a portion of the ROM can be visible in the address space. So, the switchable ROM bank is used to reference a varying portion of the ROM.


Most ROM addresses will be given in terms of their bank number and their location in the address space.

Example: the "parseObjectData" function at 12:55b7 (ROM address $495b7) is responsible for loading the room's objects.

RAM addresses are treated similarly. The RAM bank is a number from 0-7. The RAM bank may be omitted when talking about bank 0 (since addresses from $c000-$cfff are implicitly bank 0).

Example: The current room's layout is stored at $cf00. There is a copy of it at 03:df00.

These addresses will not always have $ or 0x prefixed to them. This is because when writing addresses, it makes no sense to put them in anything but hexadecimal format. This applies to the bank number as well.


Given a ROM bank number and an address in memory, convert it to an offset in your ROM with the following formula:

romAddress = bank * 0x4000 + (memoryAddress & 0x3fff)

And the reverse:

memoryAddress = (romAddress & 0x3fff) + 0x4000 (for bank 0, omit the + $4000)

bank = (romAddress / 0x4000) (ignore remainder)

Useful links

  • The Gameboy, a hardware autopsy - A great video explaining the basics of the Gameboy CPU. (See part 2 for memory mapping and banking)
  • Gameboy Pan Docs - Comprehensive documentation on the Gameboy's inner workings.
  • Gbdev Wiki - Contains a wikified version of the pandocs as well as some gb-z80 programming tutorials.
  • Gameboy CPU Manual - Much of the contents are the same as the pandocs, but this focuses more heavily on the CPU, explaining the instructions in more detail.