VRAM Tile Maps

The Game Boy contains two 32×32 tile maps in VRAM at the memory areas $9800-$9BFF and $9C00-$9FFF. Any of these maps can be used to display the Background or the Window.

Tile Indexes

Each tile map contains the 1-byte indexes of the tiles to be displayed.

Tiles are obtained from the Tile Data Table using either of the two addressing modes (described in VRAM Tile Data), which can be selected via the LCDC register.

Since one tile has 8×8 pixels, each map holds a 256×256 pixels picture. Only 160×144 of those pixels are displayed on the LCD at any given time.

BG Map Attributes (CGB Mode only)

In CGB Mode, an additional map of 32×32 bytes is stored in VRAM Bank 1 (each byte defines attributes for the corresponding tile-number map entry in VRAM Bank 0, that is, 1:9800 defines the attributes for the tile at 0:9800):

76543210
BG attributesPriorityY flipX flipBankColor palette
  • Priority: 0 = No; 1 = Colors 1–3 of the corresponding BG/Window tile are drawn over OBJ, regardless of OBJ priority
  • Y flip: 0 = Normal; 1 = Tile is drawn vertically mirrored
  • X flip: 0 = Normal; 1 = Tile is drawn horizontally mirrored
  • Bank: 0 = Fetch tile from VRAM bank 0; 1 = Fetch tile from VRAM bank 1
  • Color palette: Which of BGP0–7 to use

Bit 4 is ignored by the hardware, but can be written to and read from normally.

Note that, for example, if the byte at 0:9800 is $2A, the attribute at 1:9800 doesn’t define properties for ALL tiles $2A on-screen, but only the one at 0:9800!

BG-to-OBJ Priority in CGB Mode

In CGB Mode, the priority between the BG (and window) layer and the OBJ layer is declared in three different places:

We can infer the following rules from the table below:

  • If the BG color index is 0, the OBJ will always have priority;
  • Otherwise, if LCDC bit 0 is clear, the OBJ will always have priority;
  • Otherwise, if both the BG Attributes and the OAM Attributes have bit 7 clear, the OBJ will have priority;
  • Otherwise, BG will have priority.

The following table shows the relations between the 3 flags:

LCDC bit 0OAM attr bit 7BG attr bit 7Priority
000OBJ
001OBJ
010OBJ
011OBJ
100OBJ
101BG color 1–3, otherwise OBJ
110BG color 1–3, otherwise OBJ
111BG color 1–3, otherwise OBJ

This test ROM can be used to observe the above.

Keep in mind that:

  • OAM Attributes bit 7 will grant OBJ priority when clear, not when set.
  • Priority between all OBJs is resolved before priority with the BG layer is considered. Please refer to this page for more details.

Background (BG)

The SCY and SCX registers can be used to scroll the Background, specifying the origin of the visible 160×144 pixel area within the total 256×256 pixel Background map. The visible area of the Background wraps around the Background map (that is, when part of the visible area goes beyond the map edge, it starts displaying the opposite side of the map).

In Non-CGB mode, the Background (and the Window) can be disabled using LCDC bit 0.

Window

Besides the Background, there is also a Window overlaying it. The content of the Window is not scrollable; it is always displayed starting at the top left tile of its tile map. The only way to adjust the Window is by modifying its position on the screen, which is done via the WX and WY registers. The screen coordinates of the top left corner of the Window are (WX-7,WY). The tiles for the Window are stored in the Tile Data Table. Both the Background and the Window share the same Tile Data Table.

Whether the Window is displayed can be toggled using LCDC bit 5. But in Non-CGB mode this bit is only functional as long as LCDC bit 0 is set. Enabling the Window makes Mode 3 slightly longer on scanlines where it’s visible. (See WX and WY for the definition of “Window visibility”.)

Window Internal Line Counter

The window keeps an internal line counter that’s functionally similar to LY, and increments alongside it. However, it only gets incremented when the window is visible, as described here.

This line counter determines what window line is to be rendered on the current scanline.