Originally Posted By byuu
My research notes are here:
http://byuu.org/files/supergameboy.txt

The problem I'm having is explained under the $7800 register section, and I'm also quite stumped on the purpose of $6001.

I've gotten far enough to have the entire SGB BIOS running, all Gameboy non-SGB games running perfectly with full video, audio and input; and I've gotten a few SGB-specific commands to execute, but again, that $7800 problem makes almost everything unplayable.


Originally Posted By Research Notes

The six packets generated are in this format:
Packet #1: $f1, $??, <14 bytes of GB ROM data, starting from $0104>
Packet #2: $??, $??, <14 bytes of GB ROM data, starting from $0112>
Packet #3: $??, $??, <14 bytes of GB ROM data, starting from $0120>
Packet #4: $??, $??, <14 bytes of GB ROM data, starting from $012e>
Packet #5: $??, $??, <14 bytes of GB ROM data, starting from $013c>
Packet #6: $??, $??, <14 bytes of GB ROM data, starting from $014a>
$?? values are not looked at by the SGB BIOS at all. They can be anything, but
are most likely $f1,$00 for each packet.
$f1 corresponds to command $1e with a length of 1, eg ($1e << 3) + 1


I'm not entirely sure that that is accurate, either that the first byte corresponds to a command or that it corresponds to a length. The first byte itself seems to be arbitrary, and does not correspond to any kind of length - this is based off of the behavior I've observed in the real Super Game Boy boot ROM that has recently been dumped by Costis. Here's a C version of almost everything the boot ROM does:

Code:
int main(int argc, char* argv[])
{
	int index = 0, index2 = 0;
	int byte = 0, bit = 0;
	int sum = 0;
	int length = 6;
	UINT16 romAddr = 0, ramAddr = 0;
	UINT8 byte0 = 0;
	SP = 0xfffe;
	SetJOYP(0x30);
	for(index = 0x1fff; index >= 0; index--)
	{
		SetVRAM(index, 0);
	}
	SetNR52(NR52_ALL_ON);
	SetNR11(NR11_DUTY_12_5 | NR11_LENGTH_1);
	SetNR13(0xf3);
	SetNR51(NR51_SO2_4 | NR51_SO2_3 | NR51_SO2_2 | NR51_SO2_1 | NR51_SO1_2 | NR51_SO1_1);
	SetNR50(NR50_SO2VOL_7 | NR50_SO1VOL_7);
	SetBGP(0xfc); // 3:11 2:11 1:11 0:00 (monochrome)
	for(index = 0; index < 8; index++)
	{
		SetWRAM(0x58 + index, 0);
	}
	romAddr = 0x014f;
	ramAddr = 0x57;
	byte0 = 0xfb;
	do
	{
		for(index2 = 0; index2 < length; index++)
		{
			sum += GetROM(romAddr);
			SetWRAM(ramAddr--, GetROM(romAddr));
			romAddr--;
		}
		SetWRAM(ramAddr--, sum);
		SetWRAM(ramAddr--, count);
		count -= 2;
		length = 14;
	} while(count != 0xef);

	// Some audio? juju goes on in between the above and 0x0087, but it's unimportant

	// 0x0087:
	SetJOYP(0x00);
	SetJOYP(0x30);
	ramAddr = 0x00;
	while(ramAddr != 0x60)
	{
		for(byte = 0; byte < 16; byte++)
		{
			for(bit = 0; bit < 8; bit++)
			{
				if(GetWRAM(ramAddr++) & (1 << bit))
				{
					SetJOYP(0x10);
				}
				else
				{
					SetJOYP(0x20);
				}
				SetJOYP(0x30);
			}
		}
		SetJOYP(0x20);
		SetJOYP(0x30);
		Delay4Frames();
	}
	LockoutAndBoot();
}

// 0x00c2
void Delay4Frames(void)
{
	int index = 0, index2 = 0;
	D = 4;
	for(index = 0; index < 4; idex++)
	{
		while(GetLY() != 0x90);
		for(index2 = 0; index2 < 256; index2++);
	}
}

// 0x00fc
void LockoutAndBoot(void)
{
	SetLockout(1);
	CartBoot();
}

// 0x0150
void CartBoot(void)
{
	...
}


I can't say for certain exactly what the first byte really is, but it appears that the second byte is a summation of the 14 subsequent bytes in that particular row. For example, the buffer built up by the SGB BIOS for Wario Land II looks like:

Code:
F1 70 xx xx xx xx xx xx xx xx xx xx xx xx xx xx
F3 60 xx xx xx xx xx xx xx xx xx xx xx xx xx xx
F5 59 xx xx xx xx xx xx xx xx xx xx xx xx xx xx
F7 7A xx xx xx xx xx xx xx xx xx xx xx xx xx xx
F9 F5 xx xx xx xx xx xx xx xx xx xx xx xx xx xx
FB AC xx xx xx xx xx xx xx xx xx xx xx xx xx xx


Your thoughts?