Game Boy Images

The Game Boy has a 160×144 pixel LCD that shows four shades of grey. There is no full-screen bitmap: the picture is built from 8×8 tiles held in video RAM and arranged by a tile map, drawn as a scrolling background with an optional window overlay. This page covers the tile format, the two background layers, and the registers that control the display.

Game Boy Images

Overview

The screen is 160 pixels across and 144 down. Each pixel is one of four shades, so a pixel needs 2 bits. The display never reads a straight bitmap; it composes each line from tiles named by a tile map. Tiles are stored once in video RAM and reused across the map, so a repeating scene costs little memory. Colour comes not from a stored value but from a palette that maps the 2-bit pixel value to one of the four LCD shades.

PropertyValue
Resolution160 × 144 pixels
Shades4 (2 bits per pixel)
Tile size8 × 8 pixels, 16 bytes
Tile storeVRAM $8000 – $97FF (384 tiles)
Tile maps$9800 and $9C00, 32 × 32 each
Background paletteBGP $FF47

Tile data format

A tile is 8×8 pixels at 2 bits each, taking 16 bytes. The store runs from $8000 to $97FF and holds up to 384 tiles. Each row of a tile is two bytes, one per bit-plane. Reading a pixel means taking one bit from each byte: the low byte supplies the low bit of the pixel value, the high byte the high bit.

ByteRowPlane
0, 1Row 0Low bits, then high bits
2, 3Row 1Low bits, then high bits
14, 15Row 7Low bits, then high bits

Within each byte the most significant bit is the leftmost pixel. So for the pixel at column x of a row, bit 7 - x of the first byte gives value bit 0 and the same bit of the second byte gives value bit 1, forming a number 0 to 3. That 2-bit value is then mapped through the background palette to a shade.

The background layer

The background is a 32×32 grid of tiles, 256×256 pixels in all, far larger than the screen. A tile map, a block of 1024 bytes, holds one tile index per cell. The display reads the map, fetches the named tile, and draws it. The map lies at either $9800 or $9C00, chosen by a bit in LCDC. Which region of the tile store the index points into depends on the addressing mode, also set in LCDC.

The visible screen is a 160×144 window onto this 256×256 field. The scroll registers SCX ($FF43) and SCY ($FF42) set the top-left pixel of the screen within the field, and the background wraps at the edges, so scrolling either register slides the whole picture and repeats seamlessly.

The window layer

The window is a second tile-mapped layer that draws on top of the background. It does not scroll with SCX and SCY; instead it is fixed by its own position registers WX ($FF4B) and WY ($FF4A), which set where its top-left corner appears on screen. It is used for status bars and panels that must stay still while the background scrolls beneath them.

RegisterAddressMeaning
WY$FF4AScreen row where the window starts.
WX$FF4BScreen column plus 7 where the window starts.

The window uses its own map region, again $9800 or $9C00 chosen by an LCDC bit, and reads tiles from the same store as the background. It is enabled by an LCDC bit and always begins drawing from its own top-left tile.

Display registers

The display is controlled through a handful of registers in the I/O range. LCDC at $FF40 is the main control byte, with one bit each for display on, tile map choice, addressing mode, object size and layer enables.

RegisterAddressRole
LCDC$FF40Display and layer control, one bit per feature.
SCY$FF42Background vertical scroll.
SCX$FF43Background horizontal scroll.
LY$FF44The line currently being drawn (read only).
BGP$FF47Background palette: four 2-bit shades.
WY, WX$FF4A, $FF4BWindow position.

BGP packs the four shades into one byte: bits 1–0 give the shade for pixel value 0, bits 3–2 for value 1, and so on up to bits 7–6 for value 3. Changing BGP alone recolours the whole background without touching any tile.