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

Numbers

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.

Example

%00011110 = $1e = 30

Bitmasks

There are many data structures involving specific bits in a byte. Take this example from data/ages/treasureObjectData.s:

; Data format:
; b0: bit 7    = next 2 bytes are a pointer
;     bits 4-6 = spawn mode
;     bit 3    = ?
;     bits 0-2 = collect mode
; b1: Parameter (value of 'c' to pass to "giveTreasure")
; b2: Low text ID on pickup ($ff for no text; high byte of ID is always $00)
; b3: Graphics to use. (Gets copied to object's subid, so graphics are determined by the
;     corresponding value for interaction $60 in data/interactionData.s.)

This is describing the format of 4 bytes. For example, these 2 rows in the same file define data for the switch hook and long hook, conforming to the above description:

treasureObjectData0a:
	.db $38 $01 $30 $1f
	.db $38 $02 $28 $1f

The format of bytes 1-3 are relatively straightforward (just byte values), but byte 0 has a specific format. Let's break down the format of byte 0, which has value $38 for both rows above:

$38 = %00111000
       ^^^^^^^^
  Bit  76543210

bit 7    = 0
bits 4-6 = %011 = 3
bit 3    = 1
bits 0-2 = %000 = 0

Memory

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).

Banks

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.

Notation

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.

Conversion

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.