Claim set · data/claims/gb-hardware.yaml

Game Boy hardware (Pan Docs)

The Game Boy's video RAM holds two 32 by 32 tile maps, each 256 by 256 pixels, and either can be shown as the background or the window; the screen shows 160 by 144 of those pixels. gb-hardware/tile-maps

About: Status bar split

Value
{
 "maps": 2,
 "columns": 32,
 "rows": 32,
 "screen": [
  160,
  144
 ]
}
WikiPan Docs: Tile Maps · VRAM Tile MapsThe 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.Pan Docs: Tile Maps · Tile IndexesSince 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.Checked by claude-agent, 2026-10-21 — read the pinned capture

Two registers, SCY and SCX ($FF42-$FF43), place the 160 by 144 view in the 256 by 256 background map, and the PPU re-reads them during the line, so a write between lines moves the lines below it. gb-hardware/scroll

About: Raster effects

Value
{
 "registers": [
  "$FF42",
  "$FF43"
 ]
}
WikiPan Docs: LCD Position and Scrolling · FF42–FF43 — SCY, SCXThese two registers specify the top-left coordinates of the visible 160×144 pixel area within the 256×256 pixels BG map.Pan Docs: LCD Position and Scrolling · Mid-frame behaviorThe scroll registers are re-read on each tile fetch, except for the low 3 bits of SCX, which are only read at the beginning of the scanlineChecked by claude-agent, 2026-10-21 — read the pinned capture

Cited by: Raster effects

The window is a second background layer whose top-left corner sits at screen position (WX − 7, WY), set by WY and WX ($FF4A-$FF4B); it can't be scrolled and always starts from its tile map's top-left tile. From the line where LY equals WY, the PPU switches from the background to the window when the line reaches WX, drawing the window's current row, and that row advances once for each line the window is drawn on; at WX 7 and WY 0 it covers the whole background. gb-hardware/window

About: Status bar split

Value
{
 "registers": [
  "$FF4A",
  "$FF4B"
 ],
 "xOffset": 7,
 "maxWX": 166,
 "maxWY": 143
}
WikiPan Docs: Tile Maps · WindowThe 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).Pan Docs: Window · FF4A–FF4B — WY, WXThese two registers specify the on-screen coordinates of the Window’s top-left pixel. The Window is visible (if enabled) when WX and WY are in the range [0; 166] and [0; 143] respectively. Values WX=7, WY=0 place the Window at the top left of the screen, completely covering the background.Pan Docs: Window · Window rendering criteriaAt the beginning of each scanline, if the value of WY is equal to LY, the Y condition becomes true (and remains so for subsequent scanlines).Pan Docs: Window · Window rendering criteriaWhen this counter is equal to WX, if the Y condition is true and the Window enable bit is set in LCDC, background rendering is reset, beginning anew from the active row of the Window’s tilemap. The coordinate of the active Window row is then incremented.Pan Docs: Window · Window mid-frame behaviorIf intending to hide the Window for part of the screen (e.g. to have a status bar at the top of the screen instead of the bottom), hide it by setting WX to a high value rather than writing to LCDC.Checked by claude-agent, 2026-10-21 — read the Tile Maps page's Window section and the Window page's WY/WX section and rendering criteria in the pinned captures

Pan Docs' tip about hiding the window for a status bar at the top implies the bottom is the plain case; a top bar needs a mid-frame change.

Cited by: Status bar split

The PPU shows up to 40 objects (sprites), 8 by 8 or 8 by 16 pixels, and at most 10 on one scanline; each line's OAM scan picks the first 10 whose Y range covers it. gb-hardware/oam

About: Sprite flicker

Value
{
 "objects": 40,
 "perLine": 10
}
WikiPan Docs: Object Attribute Memory (OAM) · leadThe Game Boy PPU can display up to 40 movable objects (or sprites), each 8×8 or 8×16 pixels. Because of a limitation of hardware, only ten objects can be displayed per scanline.Pan Docs: Object Attribute Memory (OAM) · Selection priorityThe PPU scans OAM sequentially (from $FE00 to $FE9F), selecting the first (up to) 10 suitably-positioned objects.Checked by claude-agent, 2026-10-21 — read the pinned capture

LY ($FF44) counts the line being drawn, 0 to 153, with 144 to 153 in vertical blank. The STAT register ($FF41) can raise the LCD interrupt when LY equals LYC ($FF45) or when the PPU enters horizontal blank (mode 0), vertical blank (mode 1), or the OAM scan (mode 2). gb-hardware/stat-interrupt

About: Raster effects

Value
{
 "lines": 154,
 "visible": 144,
 "sources": [
  "LYC",
  "mode-0",
  "mode-1",
  "mode-2"
 ]
}
WikiPan Docs: LCD Status Registers · FF44 — LYLY can hold any value from 0 to 153, with values from 144 to 153 indicating the VBlank period.Pan Docs: LCD Status Registers · FF45 — LYCWhen both values are identical, the “LYC=LY” flag in the STAT register is set, and (if enabled) a STAT interrupt is requested.Pan Docs: Rendering Overview · PPU modes (diagram)Mode 2 OAM scan … Mode 0 Horizontal blank … Mode 1 Vertical blankPan Docs: LCD Status Registers · FF41 — STATLYC int select (Read/Write): If set, selects the LYC == LY condition for the STAT interrupt. Mode 2 int select (Read/Write): If set, selects the Mode 2 condition for the STAT interrupt. Mode 1 int select (Read/Write): If set, selects the Mode 1 condition for the STAT interrupt. Mode 0 int select (Read/Write): If set, selects the Mode 0 condition for the STAT interrupt.Checked by claude-agent, 2026-10-21 — read the STAT page and the mode names in the Rendering page's diagram, in the pinned captures

Cited by: Raster effects

The Game Boy has four sound channels, each specialized, with two pulse channels with four fixed duty settings, a wave channel that plays a user-supplied wave, and a noise channel. gb-hardware/channels

About: Music driver

Value
{
 "channels": 4
}
WikiPan Docs: Audio Overview · ArchitectureChannels 1 and 2, the “pulse channels”, produce pulse width modulated waves with 4 fixed pulse width settings. Channel 3, the “wave” channel, produces arbitrary user-supplied waves. Channel 4 is the “noise” channel, producing a pseudo-random wave.Checked by claude-agent, 2026-10-21 — read the pinned capture

Cited by: Music driver, Sampled sound

A pulse channel's duty is 12.5%, 25%, 50%, or 75%, and its 8-step waveform is clocked at 1,048,576 Hz divided by 2048−p for an 11-bit period value p, so the tone is 131072/(2048−p) Hz. gb-hardware/pulse

About: Music driver

Value
{
 "duty": [
  0.125,
  0.25,
  0.5,
  0.75
 ],
 "clockHz": 1048576,
 "steps": 8
}
WikiPan Docs: Audio Registers · FF11 — NR1100 12.5 % 01 25 % 10 50 % 11 75 %Pan Docs: Audio Registers · FF13 — NR13The pulse channels’ period dividers are clocked at 1048576 Hz, once per four dots, and their waveform is 8 samples long.Checked by claude-agent, 2026-10-21 — read the duty table and the NR13 frequency text in the pinned capture

The tone formula is the clock divided by the 8 steps; Pan Docs prints it as a fraction that the captured text flattens.

The wave channel loops 32 4-bit samples from wave RAM ($FF30-$FF3F, 16 bytes, upper nibble first), clocked at 2,097,152 Hz divided by 2048−p, so a full wave repeats at 65536/(2048−p) Hz. Its output level is 100%, 50%, 25%, or off. gb-hardware/wave

About: Sampled sound

Value
{
 "samples": 32,
 "bits": 4,
 "bytes": 16,
 "clockHz": 2097152,
 "levels": [
  0,
  1,
  0.5,
  0.25
 ]
}
WikiPan Docs: Audio Registers · FF30–FF3F — Wave pattern RAMWave RAM is 16 bytes long; each byte holds two “samples”, each 4 bits. As CH3 plays, it reads wave RAM left to right, upper nibble first.Pan Docs: Audio Registers · FF1D — NR33The wave channel’s period divider is clocked at 2097152 Hz, once per two dots, and its waveform is 32 samples long.Pan Docs: Audio Registers · FF1C — NR32100% volume (use samples read from Wave RAM as-is)Pan Docs: Audio Registers · Sound Channel 3 — Wave outputIt’s also possible to artificially “increase” the wave’s length by loading a new wave as soon as the whole buffer has been read; this is sometimes used for full-on sample playback.Checked by claude-agent, 2026-10-21 — read the wave RAM, NR32, and NR33 sections in the pinned capture

NR32's other settings are 50% and 25% (shifting the samples right once or twice) and mute.

Cited by: Sampled sound