addrnamer/wbitsdescription
$FF00P1/JOYPR/W[7:6]=unused [5]=select buttons [4]=select d-pad [3:0]=inputJoypad input. Write bit4/5 to select row; read bits 0–3 for pressed keys (0=pressed).
$FF01SBR/W[7:0]=serial transfer dataSerial transfer data register. Write the byte to send; read to get the received byte.
$FF02SCR/W[7]=transfer start [1]=clock speed (CGB) [0]=shift clockSerial transfer control. Bit7=1 starts transfer. Bit0=1 means internal clock (master).
$FF04DIVR/W[7:0]=upper 8 bits of internal 16-bit counterDivider register. Increments at 16384 Hz. Writing any value resets it to 0.
$FF05TIMAR/W[7:0]=timer counterTimer counter. Overflows at 256 and resets to TMA, then triggers INT 0x50.
$FF06TMAR/W[7:0]=timer moduloTimer modulo. TIMA is reset to this value on overflow.
$FF07TACR/W[7:3]=unused [2]=timer stop [1:0]=input clock selectTimer control. Bit2 enables timer. Bits1:0: 00=4096Hz, 01=262144Hz, 10=65536Hz, 11=16384Hz.
$FF0FIFR/W[7:5]=unused [4]=joypad [3]=serial [2]=timer [1]=lcd stat [0]=vblankInterrupt flag. Bit set = interrupt pending. Write 0 to acknowledge (or let ISR do it).
$FF10NR10R/W[6:4]=sweep period [3]=negate [2:0]=shiftChannel 1 sweep. Frequency sweep period, direction (negate=decrease), and shift magnitude.
$FF11NR11R/W[7:6]=duty [5:0]=lengthChannel 1 length/duty. Duty: 00=12.5%, 01=25%, 10=50%, 11=75%.
$FF12NR12R/W[7:4]=initial volume [3]=direction [2:0]=sweep paceChannel 1 volume envelope. Initial volume 0–15; bit3=increase.
$FF13NR13W[7:0]=freq low 8 bitsChannel 1 frequency low byte (write-only). Full freq = NR13 | (NR14[2:0]<<8).
$FF14NR14R/W[7]=trigger [6]=length enable [5:3]=unused [2:0]=freq high bitsChannel 1 control. Write bit7=1 to trigger. Bit6 enables length counter.
$FF16NR21R/W[7:6]=duty [5:0]=lengthChannel 2 length/duty.
$FF17NR22R/W[7:4]=volume [3]=dir [2:0]=paceChannel 2 volume envelope.
$FF18NR23W[7:0]=freq lowChannel 2 frequency low (write-only).
$FF19NR24R/W[7]=trigger [6]=len enable [2:0]=freq highChannel 2 control.
$FF1ANR30R/W[7]=DAC on/off [6:0]=unusedChannel 3 DAC enable.
$FF1BNR31W[7:0]=lengthChannel 3 length.
$FF1CNR32R/W[6:5]=output level [4:0]=unusedChannel 3 volume. 00=mute, 01=100%, 10=50%, 11=25%.
$FF1DNR33W[7:0]=freq lowChannel 3 frequency low.
$FF1ENR34R/W[7]=trigger [6]=len enable [2:0]=freq highChannel 3 control.
$FF30WAVE0–FR/W[7:4]=first sample [3:0]=second sampleWave RAM (FF30–FF3F): 16 bytes × 2 samples = 32 4-bit samples for Ch3 playback.
$FF20NR41W[5:0]=lengthChannel 4 length.
$FF21NR42R/W[7:4]=volume [3]=dir [2:0]=paceChannel 4 volume envelope.
$FF22NR43R/W[7:4]=shift [3]=LFSR width [2:0]=divisorChannel 4 LFSR. Shift=clock shift, bit3=0 for 15-bit LFSR, 1 for 7-bit.
$FF23NR44R/W[7]=trigger [6]=len enableChannel 4 control.
$FF24NR50R/W[7]=VIN left [6:4]=left vol [3]=VIN right [2:0]=right volMaster volume and VIN panning.
$FF25NR51R/W[7:4]=left mix [3:0]=right mix (bits=ch4 ch3 ch2 ch1)Sound panning. Each bit enables a channel on the left or right output.
$FF26NR52R/W[7]=all sound on [3:0]=ch4 ch3 ch2 ch1 status (RO)Sound on/off. Bit7 enables all sound. Bits 0–3 show channel active status (read-only).
$FF40LCDCR/W[7]=LCD on [6]=window tile map [5]=window on [4]=BG tile data [3]=BG tile map [2]=OBJ size [1]=OBJ on [0]=BG onLCD control. All display rendering controlled here. Bit7=0 turns LCD off (only safe in VBlank).
$FF41STATR/W[6]=LYC=LY int [5]=OAM int [4]=VBlank int [3]=HBlank int [2]=LYC=LY flag [1:0]=modeLCD status. Mode: 0=HBlank, 1=VBlank, 2=OAM scan, 3=Drawing. Interrupts triggered by bits 3–6.
$FF42SCYR/W[7:0]=Y scrollBackground scroll Y. BG map viewport top.
$FF43SCXR/W[7:0]=X scrollBackground scroll X.
$FF44LYR[7:0]=current scanline (0–153)Current scanline. 144–153 = VBlank. Writing resets to 0.
$FF45LYCR/W[7:0]=LY compareLY compare. STAT bit2 set when LY=LYC. Can trigger STAT interrupt.
$FF46DMAW[7:0]=source address (>>8)OAM DMA transfer. Write XX to copy 160 bytes from XX00–XX9F to OAM (FE00–FE9F) in 160 cycles.
$FF47BGPR/W[7:6]=color3 [5:4]=color2 [3:2]=color1 [1:0]=color0BG/Window palette (DMG only). Each 2-bit pair: 00=white, 01=light, 10=dark, 11=black.
$FF48OBP0R/W[7:6]=color3 [5:4]=color2 [3:2]=color1 [1:0]=unusedOBJ palette 0 (DMG). Bit0–1 ignored (transparent).
$FF49OBP1R/W[7:6]=color3 [5:4]=color2 [3:2]=color1 [1:0]=unusedOBJ palette 1 (DMG).
$FF4AWYR/W[7:0]=window Y positionWindow Y coordinate. Window rendered when WY<=LY and WX-7<=X.
$FF4BWXR/W[7:0]=window X+7Window X coordinate + 7. WX=7 places window at left edge.
$FF4DKEY1R/W[7]=current speed [0]=prepare switch(CGB) CPU speed switch. Write bit0=1, then STOP to toggle between 1× and 2× speed.
$FF4FVBKR/W[0]=VRAM bank select(CGB) VRAM bank select. 0=bank0, 1=bank1 (BG attributes + sprite tiles).
$FF51HDMA1W[7:0]=source high byte(CGB) HDMA source address high byte.
$FF52HDMA2W[7:4]=source low [3:0]=0(CGB) HDMA source address low byte.
$FF53HDMA3W[4:0]=dest high (0x8–0x9)(CGB) HDMA destination high byte (VRAM only).
$FF54HDMA4W[7:4]=dest low [3:0]=0(CGB) HDMA destination low byte.
$FF55HDMA5R/W[7]=mode [6:0]=length/5-1(CGB) HDMA control. Bit7=0=General DMA, 1=H-Blank DMA.
$FF68BCPSR/W[7]=auto-increment [5:3]=palette [2:1]=color [0]=low/high(CGB) BG color palette specification. Index into BG palette RAM.
$FF69BCPDR/W[7:0]=palette data(CGB) BG color palette data (RGB555).
$FF6AOCPSR/W[7]=auto-increment [5:3]=palette [2:1]=color [0]=low/high(CGB) OBJ color palette specification.
$FF6BOCPDR/W[7:0]=palette data(CGB) OBJ color palette data.
$FF70SVBKR/W[2:0]=WRAM bank (1–7)(CGB) WRAM bank select. Bank 0 fixed; banks 1–7 swappable at D000–DFFF.
$FFFFIER/W[4]=joypad [3]=serial [2]=timer [1]=lcd stat [0]=vblankInterrupt enable register. Set bits to enable corresponding interrupts (must also set IME via EI).