GBHawk: Fix GBC compatibility mode for GB games

This commit is contained in:
alyosha-tas 2018-03-28 10:15:05 -04:00
parent 220b41cc16
commit 3e50881ab9
4 changed files with 59 additions and 21 deletions

View File

@ -679,7 +679,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// start shifting data into the LCD // start shifting data into the LCD
if (render_counter >= (render_offset + 8)) if (render_counter >= (render_offset + 8))
{ {
if (tile_data_latch[2].Bit(5)) if (tile_data_latch[2].Bit(5) && Core.GBC_compat)
{ {
pixel = tile_data_latch[0].Bit(render_counter % 8) ? 1 : 0; pixel = tile_data_latch[0].Bit(render_counter % 8) ? 1 : 0;
pixel |= tile_data_latch[1].Bit(render_counter % 8) ? 2 : 0; pixel |= tile_data_latch[1].Bit(render_counter % 8) ? 2 : 0;
@ -692,13 +692,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
int ref_pixel = pixel; int ref_pixel = pixel;
if (LCDC.Bit(0)) if (!Core.GBC_compat)
{ {
//pixel = (BGP >> (pixel * 2)) & 3; if (LCDC.Bit(0))
} {
else pixel = (BGP >> (pixel * 2)) & 3;
{ }
//pixel = 0; else
{
pixel = 0;
}
} }
int pal_num = tile_data_latch[2] & 0x7; int pal_num = tile_data_latch[2] & 0x7;
@ -739,7 +742,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
// There is another priority bit in GBC, that can still override sprite priority // There is another priority bit in GBC, that can still override sprite priority
if (LCDC.Bit(0) && tile_data_latch[2].Bit(7)) if (LCDC.Bit(0) && tile_data_latch[2].Bit(7) && Core.GBC_compat)
{ {
use_sprite = false; use_sprite = false;
} }
@ -749,28 +752,45 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{ {
pal_num = sprite_attr & 7; pal_num = sprite_attr & 7;
/* if (!Core.GBC_compat)
if (sprite_attr.Bit(4))
{ {
pixel = (obj_pal_1 >> (s_pixel * 2)) & 3; pal_num = sprite_attr.Bit(4) ? 1 : 0;
}
else if (sprite_attr.Bit(4))
{ {
pixel = (obj_pal_0 >> (s_pixel * 2)) & 3; pixel = (obj_pal_1 >> (s_pixel * 2)) & 3;
} }
*/ else
{
pixel = (obj_pal_0 >> (s_pixel * 2)) & 3;
}
}
} }
} }
} }
// based on sprite priority and pixel values, pick a final pixel color // based on sprite priority and pixel values, pick a final pixel color
if (use_sprite) if (Core.GBC_compat)
{ {
Core._vidbuffer[LY * 160 + pixel_counter] = (int)OBJ_palette[pal_num * 4 + s_pixel]; if (use_sprite)
{
Core._vidbuffer[LY * 160 + pixel_counter] = (int)OBJ_palette[pal_num * 4 + s_pixel];
}
else
{
Core._vidbuffer[LY * 160 + pixel_counter] = (int)BG_palette[pal_num * 4 + pixel];
}
} }
else else
{ {
Core._vidbuffer[LY * 160 + pixel_counter] = (int)BG_palette[pal_num * 4 + pixel]; if (use_sprite)
{
Core._vidbuffer[LY * 160 + pixel_counter] = (int)OBJ_palette[pal_num * 4 + pixel];
}
else
{
Core._vidbuffer[LY * 160 + pixel_counter] = (int)BG_palette[pixel];
}
} }
pixel_counter++; pixel_counter++;
@ -832,7 +852,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch]; tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
tile_data[2] = Core.VRAM[0x3800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch]; tile_data[2] = Core.VRAM[0x3800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0; VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
BG_V_flip = tile_data[2].Bit(6); BG_V_flip = tile_data[2].Bit(6) & Core.GBC_compat;
} }
else else
{ {
@ -948,6 +968,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch]; tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch];
tile_data[2] = Core.VRAM[0x3800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch]; tile_data[2] = Core.VRAM[0x3800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0; VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
BG_V_flip = tile_data[2].Bit(6) & Core.GBC_compat;
} }
else else
{ {

View File

@ -87,6 +87,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync("RAM_Bank", ref RAM_Bank); ser.Sync("RAM_Bank", ref RAM_Bank);
ser.Sync("VRAM_Bank", ref VRAM_Bank); ser.Sync("VRAM_Bank", ref VRAM_Bank);
ser.Sync("is_GBC", ref is_GBC); ser.Sync("is_GBC", ref is_GBC);
ser.Sync("GBC_compat", ref GBC_compat);
ser.Sync("double_speed", ref double_speed); ser.Sync("double_speed", ref double_speed);
ser.Sync("speed_switch", ref speed_switch); ser.Sync("speed_switch", ref speed_switch);
ser.Sync("HDMA_transfer", ref HDMA_transfer); ser.Sync("HDMA_transfer", ref HDMA_transfer);

View File

@ -54,6 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int RAM_Bank; public int RAM_Bank;
public byte VRAM_Bank; public byte VRAM_Bank;
public bool is_GBC; public bool is_GBC;
public bool GBC_compat; // compatibility mode for GB games played on GBC
public bool double_speed; public bool double_speed;
public bool speed_switch; public bool speed_switch;
public bool HDMA_transfer; // stalls CPU when in progress public bool HDMA_transfer; // stalls CPU when in progress
@ -276,6 +277,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
private void HardReset() private void HardReset()
{ {
GB_bios_register = 0; // bios enable GB_bios_register = 0; // bios enable
GBC_compat = true;
in_vblank = true; // we start off in vblank since the LCD is off in_vblank = true; // we start off in vblank since the LCD is off
in_vblank_old = true; in_vblank_old = true;

View File

@ -309,6 +309,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ppu.WriteReg(addr, value); ppu.WriteReg(addr, value);
break; break;
// GBC compatibility register (I think)
case 0xFF4C:
if (value != 0xC0)
{
GBC_compat = false;
}
break;
// Speed Control for GBC // Speed Control for GBC
case 0xFF4D: case 0xFF4D:
if (is_GBC) if (is_GBC)
@ -382,6 +390,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (((REG_FF0F & 0x1F) & REG_FFFF) == 0) { cpu.FlagI = false; } if (((REG_FF0F & 0x1F) & REG_FFFF) == 0) { cpu.FlagI = false; }
break; break;
default:
Console.Write(addr);
Console.Write(" ");
Console.WriteLine(value);
break;
} }
} }