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.
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.
| Property | Value |
|---|---|
| Resolution | 160 × 144 pixels |
| Shades | 4 (2 bits per pixel) |
| Tile size | 8 × 8 pixels, 16 bytes |
| Tile store | VRAM $8000 – $97FF (384 tiles) |
| Tile maps | $9800 and $9C00, 32 × 32 each |
| Background palette | BGP $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.
| Byte | Row | Plane |
|---|---|---|
| 0, 1 | Row 0 | Low bits, then high bits |
| 2, 3 | Row 1 | Low bits, then high bits |
| … | … | … |
| 14, 15 | Row 7 | Low 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.
| Register | Address | Meaning |
|---|---|---|
| WY | $FF4A | Screen row where the window starts. |
| WX | $FF4B | Screen 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.
| Register | Address | Role |
|---|---|---|
| LCDC | $FF40 | Display and layer control, one bit per feature. |
| SCY | $FF42 | Background vertical scroll. |
| SCX | $FF43 | Background horizontal scroll. |
| LY | $FF44 | The line currently being drawn (read only). |
| BGP | $FF47 | Background palette: four 2-bit shades. |
| WY, WX | $FF4A, $FF4B | Window 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.