GBHawk: ppu refactor for window and bus

This commit is contained in:
alyosha-tas 2020-05-24 16:26:07 -04:00
parent 334844bde2
commit 21779a2a6f
5 changed files with 144 additions and 130 deletions

View File

@ -599,7 +599,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -659,7 +659,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -781,7 +781,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
fetch_sprite = false;
going_to_fetch = false;
first_fetch = true;
consecutive_sprite = -render_offset + 8;
consecutive_sprite = -scroll_offset + 8;
no_sprites = false;
evaled_sprites = 0;
window_pre_render = false;
@ -825,7 +825,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
// if the window starts at zero, we still do the first access to the BG
// but then restart all over again at the window
if ((render_offset % 7) <= 6)
if ((scroll_offset % 7) <= 6)
{
read_case = 9;
}
@ -1018,9 +1018,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
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];
bus_return = tile_data[2];
bus_address = 0x3800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch;
tile_data[2] = Core.VRAM[bus_address];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
@ -1046,7 +1046,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -1055,11 +1056,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
bus_return = tile_data[0];
read_case = 2;
}
break;
@ -1085,7 +1085,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte += 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -1094,10 +1096,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
}
bus_return = tile_data[1];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
if (pre_render)
{
@ -1115,7 +1117,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
break;
case 3: // read from sprite data
case 3: // read from tile data
if ((internal_cycle % 2) == 1)
{
read_case = 0;
@ -1128,12 +1130,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
temp_fetch = window_y_tile * 32 + (window_x_tile + window_tile_inc) % 32;
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];
bus_address = 0x3800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch;
tile_data[2] = Core.VRAM[bus_address];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
BG_V_flip = tile_data[2].Bit(6) & Core.GBC_compat;
bus_return = tile_data[2];
window_tile_inc++;
read_case = 5;
}
@ -1143,7 +1146,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 5: // read from tile graphics (for the window)
if ((window_counter % 2) == 1)
{
y_scroll_offset = (window_y_tile_inc) % 8;
y_scroll_offset = window_y_tile_inc % 8;
if (BG_V_flip)
{
@ -1152,7 +1155,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -1161,10 +1165,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2];
}
bus_return = tile_data[0];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
read_case = 6;
}
@ -1174,7 +1178,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 6: // read from tile graphics (for the window)
if ((window_counter % 2) == 1)
{
y_scroll_offset = (window_y_tile_inc) % 8;
y_scroll_offset = window_y_tile_inc % 8;
if (BG_V_flip)
{
@ -1188,7 +1192,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte += 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -1197,10 +1203,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
}
bus_return = tile_data[1];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
if (window_pre_render)
{
@ -1209,15 +1215,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// so start shifting in data to the screen right away
if (window_x_latch <= 7)
{
if (render_offset == 0)
if (scroll_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
read_case = 8 + scroll_offset;
}
render_counter = 8 - render_offset;
render_counter = 8 - scroll_offset;
render_offset = 7 - window_x_latch;
}
@ -1240,7 +1246,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_counter++;
break;
case 7: // read from sprite data
case 7: // read from tile data (window)
if ((window_counter % 2) == 1)
{
read_case = 4;
@ -1334,21 +1340,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels)
if (first_fetch || (last_eval >= consecutive_sprite))
{
if (((last_eval + render_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + render_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + render_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + render_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + render_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + render_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 7) { sprite_fetch_counter += 0; }
if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; }
consecutive_sprite = (int)Math.Floor((double)(last_eval + render_offset) / 8) * 8 + 8 - render_offset;
consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset;
// special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it.
if (last_eval == 0 && render_offset != 0)
if (last_eval == 0 && scroll_offset != 0)
{
sprite_fetch_counter += render_offset;
sprite_fetch_counter += scroll_offset;
}
}

View File

@ -589,7 +589,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -650,7 +650,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -779,7 +779,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
fetch_sprite = false;
going_to_fetch = false;
first_fetch = true;
consecutive_sprite = -render_offset + 8;
consecutive_sprite = -scroll_offset + 8;
no_sprites = false;
evaled_sprites = 0;
window_pre_render = false;
@ -815,7 +815,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Console.Write(" ");
Console.Write(window_y_tile);
Console.Write(" ");
Console.Write(render_offset);
Console.Write(scroll_offset);
Console.Write(" ");
Console.Write(window_x_latch);
Console.Write(" ");
@ -826,7 +826,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
// if the window starts at zero, we still do the first access to the BG
// but then restart all over again at the window
if ((render_offset % 7) <= 6)
if ((scroll_offset % 7) <= 6)
{
read_case = 9;
}
@ -979,9 +979,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
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];
bus_return = tile_data[2];
bus_address = 0x3800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch;
tile_data[2] = Core.VRAM[bus_address];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
@ -1007,7 +1007,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -1016,10 +1017,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2];
}
bus_return = tile_data[0];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
read_case = 2;
}
@ -1046,7 +1047,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte += 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -1055,10 +1058,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
}
bus_return = tile_data[1];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
if (pre_render)
{
@ -1076,7 +1079,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
break;
case 3: // read from sprite data
case 3: // read from tile data
if ((internal_cycle % 2) == 1)
{
read_case = 0;
@ -1089,9 +1092,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
temp_fetch = window_y_tile * 32 + (window_x_tile + window_tile_inc) % 32;
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];
bus_return = tile_data[2];
bus_address = 0x3800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch;
tile_data[2] = Core.VRAM[bus_address];
VRAM_sel = tile_data[2].Bit(3) ? 1 : 0;
BG_V_flip = tile_data[2].Bit(6);
@ -1105,7 +1108,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 5: // read from tile graphics (for the window)
if ((window_counter % 2) == 1)
{
y_scroll_offset = (window_y_tile_inc) % 8;
y_scroll_offset = window_y_tile_inc % 8;
if (BG_V_flip)
{
@ -1114,7 +1117,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -1123,10 +1127,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2];
}
bus_return = tile_data[0];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
read_case = 6;
}
@ -1136,7 +1140,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 6: // read from tile graphics (for the window)
if ((window_counter % 2) == 1)
{
y_scroll_offset = (window_y_tile_inc) % 8;
y_scroll_offset = window_y_tile_inc % 8;
if (BG_V_flip)
{
@ -1150,7 +1154,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte += 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = (VRAM_sel * 0x2000) + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -1159,10 +1165,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[(VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
}
bus_return = tile_data[1];
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
if (window_pre_render)
{
@ -1171,15 +1177,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// so start shifting in data to the screen right away
if (window_x_latch <= 7)
{
if (render_offset == 0)
if (scroll_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
read_case = 8 + scroll_offset;
}
render_counter = 8 - render_offset;
render_counter = 8 - scroll_offset;
render_offset = 7 - window_x_latch;
}
@ -1202,7 +1208,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_counter++;
break;
case 7: // read from sprite data
case 7: // read from tile data (window)
if ((window_counter % 2) == 1)
{
read_case = 4;
@ -1297,21 +1303,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels)
if (first_fetch || (last_eval >= consecutive_sprite))
{
if (((last_eval + render_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + render_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + render_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + render_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + render_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + render_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 7) { sprite_fetch_counter += 0; }
if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; }
consecutive_sprite = (int)Math.Floor((double)(last_eval + render_offset) / 8) * 8 + 8 - render_offset;
consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset;
// special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it.
if (last_eval == 0 && render_offset != 0)
if (last_eval == 0 && scroll_offset != 0)
{
sprite_fetch_counter += render_offset;
sprite_fetch_counter += scroll_offset;
}
}

View File

@ -303,7 +303,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -365,7 +365,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// this is fine since nothing has started in the rendering until the second cycle
// calculate the column number of the tile to start with
x_tile = scroll_x >> 3;
render_offset = scroll_x % 8;
render_offset = scroll_offset = scroll_x % 8;
}
// render the screen and handle hblank
@ -472,7 +472,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
fetch_sprite = false;
going_to_fetch = false;
first_fetch = true;
consecutive_sprite = -render_offset + 8;
consecutive_sprite = -scroll_offset + 8;
no_sprites = false;
evaled_sprites = 0;
window_pre_render = false;
@ -516,7 +516,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
// if the window starts at zero, we still do the first access to the BG
// but then restart all over again at the window
if ((render_offset % 7) <= 6)
if ((scroll_offset % 7) <= 6)
{
read_case = 9;
}
@ -657,9 +657,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
y_tile = (((int)scroll_y + LY) >> 3) % 32;
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
bus_return = (byte)tile_byte;
bus_address = 0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch;
tile_byte = Core.VRAM[bus_address];
read_case = 1;
if (!pre_render)
@ -676,7 +677,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[tile_byte * 16 + y_scroll_offset * 2];
bus_address = tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -685,10 +687,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2];
bus_address = 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
bus_return = tile_data[0];
read_case = 2;
}
break;
@ -710,7 +713,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte += 256;
}
tile_data[1] = Core.VRAM[tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -720,11 +724,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
bus_return = tile_data[1];
if (pre_render)
{
// here we set up rendering
@ -741,7 +744,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
break;
case 3: // read from sprite data
case 3: // read from tile data
if ((internal_cycle % 2) == 1)
{
read_case = 0;
@ -753,9 +756,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((window_counter % 2) == 1)
{
temp_fetch = window_y_tile * 32 + (window_x_tile + window_tile_inc) % 32;
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch];
bus_return = (byte)tile_byte;
bus_address = 0x1800 + (LCDC.Bit(6) ? 1 : 0) * 0x400 + temp_fetch;
tile_byte = Core.VRAM[bus_address];
window_tile_inc++;
read_case = 5;
@ -770,9 +773,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (LCDC.Bit(4))
{
tile_data[0] = Core.VRAM[tile_byte * 16 + y_scroll_offset * 2];
bus_address = tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
else
{
@ -782,11 +784,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte -= 256;
}
tile_data[0] = Core.VRAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2];
bus_address = 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
tile_data[0] = Core.VRAM[bus_address];
}
bus_return = tile_data[0];
read_case = 6;
}
window_counter++;
@ -804,7 +805,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte += 256;
}
tile_data[1] = Core.VRAM[tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
else
{
@ -814,11 +816,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
tile_byte -= 256;
}
tile_data[1] = Core.VRAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1];
bus_address = 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
tile_data[1] = Core.VRAM[bus_address];
}
bus_return = tile_data[1];
if (window_pre_render)
{
// here we set up rendering
@ -826,15 +827,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// so start shifting in data to the screen right away
if (window_x_latch <= 7)
{
if (render_offset == 0)
if (scroll_offset == 0)
{
read_case = 4;
}
else
{
read_case = 9 + render_offset - 1;
read_case = 8 + scroll_offset;
}
render_counter = 8 - render_offset;
render_counter = 8 - scroll_offset;
render_offset = 7 - window_x_latch;
}
@ -857,7 +858,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_counter++;
break;
case 7: // read from sprite data
case 7: // read from tile data (window)
if ((window_counter % 2) == 1)
{
read_case = 4;
@ -950,21 +951,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels)
if (first_fetch || (last_eval >= consecutive_sprite))
{
if (((last_eval + render_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + render_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + render_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + render_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + render_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + render_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + render_offset) % 8) == 7) { sprite_fetch_counter += 0; }
if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; }
else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; }
else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; }
else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; }
else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; }
else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; }
else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; }
consecutive_sprite = (int)Math.Floor((double)(last_eval + render_offset) / 8) * 8 + 8 - render_offset;
consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset;
// special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it.
if (last_eval == 0 && render_offset != 0)
if (last_eval == 0 && scroll_offset != 0)
{
sprite_fetch_counter += render_offset;
sprite_fetch_counter += scroll_offset;
}
}

View File

@ -139,7 +139,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (ppu.pixel_counter == 160)
{
return ppu.bus_return;
return VRAM[ppu.bus_address];
}
return 0xFF;

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool clear_screen;
// TODO: need a test ROM for the details here
public byte bus_return;
public int bus_address;
public bool rendering_complete;
// register variables
@ -84,6 +84,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool latch_new_data;
public int render_counter;
public int render_offset;
public int scroll_offset;
public int pixel_counter;
public int pixel;
public byte[] sprite_data = new byte[2];
@ -179,7 +180,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(OBJ_palette), ref OBJ_palette, false);
ser.Sync(nameof(HDMA_active), ref HDMA_active);
ser.Sync(nameof(clear_screen), ref clear_screen);
ser.Sync(nameof(bus_return), ref bus_return);
ser.Sync(nameof(bus_address), ref bus_address);
ser.Sync(nameof(rendering_complete), ref rendering_complete);
ser.Sync(nameof(LCDC), ref LCDC);