From GbdevWiki
Jump to: navigation, search

In the Super Game Boy accessory, the ICD2 provides a bridge between the Game Boy system on chip and the Super NES Control Deck. It has the following duties:

  • Accumulating pixels from the GB LCD output and reformatting them into tile rows for the Super NES to read
  • Collecting 128-bit command packets from the GB's P15 and P14 bits and relaying them to the S-CPU
  • Relaying keypresses from the S-CPU to the GB


 6000       R  LCD Character Row and Buffer Write-Row
 6001       W  Character Buffer Read Row Select
 6002       R  16-Byte Packet Available Flag
 6003       W  Reset/Multiplayer/Speed Control
 6004-6007  W  Controller Data for Player 1-4
 7000-700F  R  16-byte command packet
 7800-780F  R  Character Buffer Data (320 bytes of currently selected row)

The ICD2 chip decodes only A0-A3,A11-A15,A22 (mask $40F80F). Reading unused or write-only addresses appears to return some sort of open bus.

$6000 read: LCD Character Row and Buffer Write-Row

  • 7-3: Current tile row on LCD, or $11 if in vblank (approximates LY)
  • 1-0: Row of ring buffer that the ICD is writing

$6001 write: Character Buffer Read Row Select

  • 1-0: Select row of ring buffer to read out through $7800

This is intended for reading complete buffers that the ICD has filled. Reading the incomplete buffer that the ICD is still filling (by setting [$6001] = [$6000] & $03) isn't quite predictable.

$6002 read: 16-Byte Packet Available Flag

Bit 0 is set to 1 if a new command packet can be read at $7000-$700F. It is cleared to 0 once $7000 has been read.

$6003 write: Reset/Multiplayer/Speed Control

  • 7: Run/reset (0: Reset DMG SoC; 1: Run)
  • 5-4: Number of controllers (0: one; 1: two; 3: four, requiring multitap)
  • 1-0: Clock divider (4, 5, 7, or 9, resulting in 5.37, 4.30, 3.06, or 2.39 MHz)

The SGB system software changes $6003 based on MLT_REQ packets sent by the Game Boy program.

$6004-$6007 write: Controller Data for Player 1-4

These bits are active-low (0: pressed, 1: released). They are also nibble-swapped compared to the bit order on the Game Boy Advance.

  • 7: Start not pressed
  • 6: Select not pressed
  • 5: B not pressed
  • 4: A not pressed
  • 3: Down not pressed
  • 2: Up not pressed
  • 1: Left not pressed
  • 0: Right not pressed

The Super NES reads its own controllers, reorders the bits, and writes controller data here. The ICD then forwards the data one controller at a time to the Game Boy. If the number of controllers is greater than one (see $6003), the ICD switches to the next controller when P15 goes low and then both P15 and P14 go high.

$7000-$700F read: Command packet

The Game Boy program sends 128 bytes of data by manipulating P15 and P14. The ICD forwards the packet to the Super NES through these addresses. Reading $7000 also clears $6002.

$7800 read: Character Buffer Data

After selecting a tile row through $6001, copy 320 bytes from this address using fixed source address DMA. Usually the copy is bounced off a buffer in WRAM through the WRAM's B Bus port at $2180-$2183. (If more than 320 bytes are read, it appears that the next 192 bytes are $FF, and then the 320 bytes of the same tile row repeat.)


The Game Boy runs one T-state every 5 cycles of the Super NES's 21.47 MHz master clock. There are 1364 master clocks in a Super NES scanline and 456 T-states in a Game Boy scanline.

  • 1364/5 = 272.8 GB tstates per SNES scanline
  • 456*5/1364 = 1.67 SNES scanlines per GB scanline
  • 1364*37/5/456 = 22.1 GB scanlines per SNES vblank

ICD2 stores four tile rows: three completed and one in progress. Over the course of one Super NES vblank, just under three lines will be completed in the ICD2.

  • 456*5*8/1364 = 13.4 SNES scanlines to fill one ICD tile row
  • 456*5*24/1364 = 40.1 SNES scanlines to fill three ICD tile rows

Of the 1364 master clocks in a line, 40 are spoken for to refresh Super NES WRAM, which is implemented as DRAM. Memory copies to or from WRAM using the DMA hardware take 8 master clocks per byte.

  • (1364-40)/8 = 165.5 bytes per SNES scanline
  • 160*8/4 = 320 bytes per tile row
  • 320/165.5 = 1.9 scanlines to pull one tile row from ICD to WRAM
  • 160*144/4 = 5760 bytes per frame buffer
  • 5760/165.5 = 34.8 scanlines to push front buffer from WRAM to VRAM