GBHawk: window timing fixes

This commit is contained in:
alyosha-tas 2019-10-10 09:57:40 -04:00
parent 78cbb9aac5
commit 931a4dcde9
4 changed files with 131 additions and 39 deletions

View File

@ -398,6 +398,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// meaning it will pick up where it left off if re-enabled later
// so we don't reset it in the scanline loop
window_y_tile = 0;
window_y_latch = window_y;
window_y_tile_inc = 0;
window_started = false;
if (!LCDC.Bit(5)) { window_is_reset = true; }
@ -721,7 +722,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
total_counter = 0;
// TODO: If Window is turned on midscanline what happens? When is this check done exactly?
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y)))
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y_latch)))
{
window_y_tile_inc++;
if (window_y_tile_inc==8)
@ -739,19 +740,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// before anything else, we have to check if windowing is in effect
if (window_latch && !window_started && (LY >= window_y) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
{
if (window_latch && !window_started && (LY >= window_y_latch) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
{
/*
Console.Write(LY);
Console.Write(" ");
Console.Write(cycle);
Console.Write(" ");
Console.Write(window_y_tile_inc);
Console.Write(" ");
Console.Write(window_x_latch);
Console.Write(" ");
Console.WriteLine(pixel_counter);
Console.Write(LY);
Console.Write(" ");
Console.Write(cycle);
Console.Write(" ");
Console.Write(window_y_tile);
Console.Write(" ");
Console.Write(render_offset);
Console.Write(" ");
Console.Write(window_x_latch);
Console.Write(" ");
Console.WriteLine(pixel_counter);
*/
if (window_x_latch == 0)
{
// if the window starts at zero, we still do the first access to the BG
@ -762,12 +766,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
read_case = 9;
read_case = 10;
}
}
else
{
// otherwise, just restart the whole process as if starting BG again
read_case = 4;
}
@ -1086,13 +1089,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here we set up rendering
// unlike for the normal background case, there is no pre-render period for the window
// so start shifting in data to the screen right away
render_offset = 0;
render_counter = 8;
if (window_x_latch <= 7)
{
if (render_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
}
render_counter = 8 - render_offset;
render_offset = 0;
}
else
{
render_offset = 0;
read_case = 4;
render_counter = 8;
}
latch_counter = 0;
latch_new_data = true;
window_pre_render = false;
read_case = 4;
window_pre_render = false;
}
else
{
@ -1121,16 +1141,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (hbl_countdown == 0)
{
STAT &= 0xFC;
STAT |= 0x00;
OAM_access_read = true;
OAM_access_write = true;
VRAM_access_read = true;
VRAM_access_write = true;
STAT &= 0xFC;
STAT |= 0x00;
}
else
{
{
if (STAT.Bit(3)) { HBL_INT = true; }
}
}
@ -1143,6 +1163,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// for it in read case 0
read_case = 4;
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
read_case--;
break;
}
internal_cycle++;
@ -1552,6 +1582,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_y = 0x0;
window_x = 0x0;
window_x_latch = 0xFF;
window_y_latch = 0xFF;
LY_inc = 1;
no_scan = false;
OAM_access_read = true;

View File

@ -400,6 +400,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// meaning it will pick up where it left off if re-enabled later
// so we don't reset it in the scanline loop
window_y_tile = 0;
window_y_latch = window_y;
window_y_tile_inc = 0;
window_started = false;
if (!LCDC.Bit(5)) { window_is_reset = true; }
@ -716,7 +717,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
total_counter = 0;
// TODO: If Window is turned on midscanline what happens? When is this check done exactly?
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y)))
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y_latch)))
{
window_y_tile_inc++;
if (window_y_tile_inc==8)
@ -734,7 +735,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// before anything else, we have to check if windowing is in effect
if (window_latch && !window_started && (LY >= window_y) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
if (window_latch && !window_started && (LY >= window_y_latch) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
{
/*
Console.Write(LY);
@ -757,14 +758,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
read_case = 9;
read_case = 10;
}
}
else
{
// otherwise, just restart the whole process as if starting BG again
read_case = 4;
}
window_pre_render = true;
window_counter = 0;
@ -1120,13 +1121,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here we set up rendering
// unlike for the normal background case, there is no pre-render period for the window
// so start shifting in data to the screen right away
render_offset = 0;
render_counter = 8;
if (window_x_latch <= 7)
{
if (render_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
}
render_counter = 8 - render_offset;
render_offset = 0;
}
else
{
render_offset = 0;
read_case = 4;
render_counter = 8;
}
latch_counter = 0;
latch_new_data = true;
window_pre_render = false;
read_case = 4;
}
else
{
@ -1175,6 +1193,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// for it in read case 0
read_case = 4;
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
read_case--;
break;
}
internal_cycle++;
@ -1605,6 +1633,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_y = 0x0;
window_x = 0x0;
window_x_latch = 0xFF;
window_y_latch = 0xFF;
LY_inc = 1;
no_scan = false;
OAM_access_read = true;
@ -1722,6 +1751,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
obj_pal_0 = ppu2.obj_pal_0;
obj_pal_1 = ppu2.obj_pal_1;
window_y = ppu2.window_y;
window_y_latch = ppu2.window_y_latch;
window_x = ppu2.window_x;
DMA_start = ppu2.DMA_start;
DMA_clock = ppu2.DMA_clock;

View File

@ -160,6 +160,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// meaning it will pick up where it left off if re-enabled later
// so we don't reset it in the scanline loop
window_y_tile = 0;
window_y_latch = window_y;
window_y_tile_inc = 0;
window_started = false;
if (!LCDC.Bit(5)) { window_is_reset = true; }
@ -464,7 +465,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
total_counter = 0;
// TODO: If Window is turned on midscanline what happens? When is this check done exactly?
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y)))
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY >= window_y_latch)))
{
window_y_tile_inc++;
if (window_y_tile_inc==8)
@ -482,7 +483,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// before anything else, we have to check if windowing is in effect
if (window_latch && !window_started && (LY >= window_y) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
if (window_latch && !window_started && (LY >= window_y_latch) && (pixel_counter >= (window_x_latch - 7)) && (window_x_latch < 167))
{
/*
Console.Write(LY);
@ -505,14 +506,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
read_case = 9;
read_case = 10;
}
}
else
{
// otherwise, just restart the whole process as if starting BG again
read_case = 4;
}
window_pre_render = true;
window_counter = 0;
@ -795,13 +796,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here we set up rendering
// unlike for the normal background case, there is no pre-render period for the window
// so start shifting in data to the screen right away
render_offset = 0;
render_counter = 8;
if (window_x_latch <= 7)
{
if (render_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
}
render_counter = 8 - render_offset;
render_offset = 0;
}
else
{
render_offset = 0;
read_case = 4;
render_counter = 8;
}
latch_counter = 0;
latch_new_data = true;
window_pre_render = false;
read_case = 4;
}
else
{
@ -841,6 +859,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// for it in read case 0
read_case = 4;
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
read_case--;
break;
}
internal_cycle++;
@ -1160,6 +1188,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_y = 0x0;
window_x = 0x0;
window_x_latch = 0xFF;
window_y_latch = 0xFF;
LY_inc = 1;
no_scan = false;
OAM_access_read = true;

View File

@ -103,6 +103,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int window_x_tile;
public int window_y_tile_inc;
public int window_x_latch;
public int window_y_latch;
public int hbl_countdown;
@ -259,6 +260,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(window_x_tile), ref window_x_tile);
ser.Sync(nameof(window_y_tile_inc), ref window_y_tile_inc);
ser.Sync(nameof(window_x_latch), ref window_x_latch);
ser.Sync(nameof(window_y_latch), ref window_y_latch);
ser.Sync(nameof(hbl_countdown), ref hbl_countdown);
}