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
- 1 Registers
- 2 $6004-$6007 write: Controller Data for Player 1-4
- 3 Timing
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