GBHawk: Restructure to pass all other tests (as before)
This commit is contained in:
parent
f36e252d5e
commit
d4eb3da512
|
@ -497,7 +497,6 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
||||||
if (Halt_bug_2 && I_use)
|
if (Halt_bug_2 && I_use)
|
||||||
{
|
{
|
||||||
RegPC--;
|
RegPC--;
|
||||||
|
|
||||||
if (!interrupts_enabled) { Halt_bug_3 = true; }
|
if (!interrupts_enabled) { Halt_bug_3 = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
||||||
IDLE,
|
IDLE,
|
||||||
HALT_CHK,
|
HALT_CHK,
|
||||||
IDLE,
|
IDLE,
|
||||||
HALT, 1 };
|
HALT, 0 };
|
||||||
skip_once = true;
|
skip_once = true;
|
||||||
// If the interrupt flag is not currently set, but it does get set in the first check
|
// If the interrupt flag is not currently set, but it does get set in the first check
|
||||||
// then a bug is triggered
|
// then a bug is triggered
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
||||||
break;
|
break;
|
||||||
case 0xFF44: // LY
|
case 0xFF44: // LY
|
||||||
LY = 0; /*reset*/
|
LY = LY_actual = 0; /*reset*/
|
||||||
break;
|
break;
|
||||||
case 0xFF45: // LYC
|
case 0xFF45: // LYC
|
||||||
LYC = value;
|
LYC = value;
|
||||||
|
@ -110,7 +110,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
{
|
{
|
||||||
// the ppu only does anything if it is turned on via bit 7 of LCDC
|
// the ppu only does anything if it is turned on via bit 7 of LCDC
|
||||||
if (LCDC.Bit(7))
|
if (LCDC.Bit(7))
|
||||||
{
|
{
|
||||||
// start the next scanline
|
// start the next scanline
|
||||||
if (cycle == 456)
|
if (cycle == 456)
|
||||||
{
|
{
|
||||||
|
@ -125,24 +125,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle = 0;
|
cycle = 0;
|
||||||
LY += LY_inc;
|
LY_actual = LY;
|
||||||
no_scan = false;
|
|
||||||
|
|
||||||
// here is where LY = LYC gets cleared (but only if LY isnt 0 as that's a special case)
|
no_scan = false;
|
||||||
if (LY_inc == 1)
|
|
||||||
{
|
|
||||||
LYC_INT = false;
|
|
||||||
STAT &= 0xFB;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LY == 0 && LY_inc == 0)
|
if (LY == 0 && LY_inc == 0)
|
||||||
{
|
{
|
||||||
LY_inc = 1;
|
LY_inc = 1;
|
||||||
Core.in_vblank = false;
|
Core.in_vblank = false;
|
||||||
VBL_INT = false;
|
|
||||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
|
||||||
|
|
||||||
STAT &= 0xFC;
|
|
||||||
|
|
||||||
// special note here, the y coordiate of the window is kept if the window is deactivated
|
// special note here, the y coordiate of the window is kept if the window is deactivated
|
||||||
// meaning it will pick up where it left off if re-enabled later
|
// meaning it will pick up where it left off if re-enabled later
|
||||||
|
@ -153,8 +143,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
window_is_reset = true;
|
window_is_reset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.cpu.LY = LY;
|
|
||||||
|
|
||||||
// Automatically restore access to VRAM at this time (force end drawing)
|
// Automatically restore access to VRAM at this time (force end drawing)
|
||||||
// Who Framed Roger Rabbit seems to run into this.
|
// Who Framed Roger Rabbit seems to run into this.
|
||||||
VRAM_access_write = true;
|
VRAM_access_write = true;
|
||||||
|
@ -166,6 +154,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cycle == 452)
|
||||||
|
{
|
||||||
|
LY += LY_inc;
|
||||||
|
|
||||||
|
// here is where LY = LYC gets cleared (but only if LY isnt 0 as that's a special case)
|
||||||
|
if (LY_inc == 1)
|
||||||
|
{
|
||||||
|
LYC_INT = false;
|
||||||
|
STAT &= 0xFB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VBL_INT = false;
|
||||||
|
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||||
|
|
||||||
|
STAT &= 0xFC;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core.cpu.LY = LY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((LY == 153) && (cycle == 0))
|
||||||
|
{
|
||||||
|
LY = 0;
|
||||||
|
LY_inc = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// exit vblank if LCD went from off to on
|
// exit vblank if LCD went from off to on
|
||||||
if (LCD_was_off)
|
if (LCD_was_off)
|
||||||
{
|
{
|
||||||
|
@ -185,21 +201,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
// the VBL stat is continuously asserted
|
// the VBL stat is continuously asserted
|
||||||
if ((LY >= 144))
|
if ((LY_actual >= 144))
|
||||||
{
|
{
|
||||||
if (STAT.Bit(4))
|
if (STAT.Bit(4))
|
||||||
{
|
{
|
||||||
if ((cycle >= 4) && (LY == 144))
|
if ((cycle >= 0) && (LY_actual == 144))
|
||||||
{
|
{
|
||||||
VBL_INT = true;
|
VBL_INT = true;
|
||||||
}
|
}
|
||||||
else if (LY > 144)
|
else if (LY_actual > 144)
|
||||||
{
|
{
|
||||||
VBL_INT = true;
|
VBL_INT = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cycle == 0) && (LY == 144)) {
|
if ((cycle == 0) && (LY_actual == 144)) {
|
||||||
|
|
||||||
HBL_INT = false;
|
HBL_INT = false;
|
||||||
|
|
||||||
|
@ -209,19 +225,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
if (Core.REG_FFFF.Bit(0)) { Core.cpu.FlagI = true; }
|
if (Core.REG_FFFF.Bit(0)) { Core.cpu.FlagI = true; }
|
||||||
Core.REG_FF0F |= 0x01;
|
Core.REG_FF0F |= 0x01;
|
||||||
//Console.WriteLine(Core.cpu.TotalExecutedCycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((LY >= 144) && (cycle == 4))
|
if ((LY_actual >= 144) && (cycle == 0))
|
||||||
{
|
{
|
||||||
// a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
|
// a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
|
||||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((LY == 153) && (cycle == 8))
|
if ((LY_actual == 153) && (cycle == 4))
|
||||||
{
|
{
|
||||||
LY = 0;
|
LY_actual = 0;
|
||||||
LY_inc = 0;
|
|
||||||
Core.cpu.LY = LY;
|
Core.cpu.LY = LY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +248,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// there is no mode 2 (presumably it missed the trigger)
|
// there is no mode 2 (presumably it missed the trigger)
|
||||||
// mode 3 is very short, probably in some self test mode before turning on?
|
// mode 3 is very short, probably in some self test mode before turning on?
|
||||||
|
|
||||||
if (cycle == 8)
|
if (cycle == 4)
|
||||||
{
|
{
|
||||||
if (LY != LYC)
|
if (LY != LYC)
|
||||||
{
|
{
|
||||||
|
@ -250,7 +264,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle == 84)
|
if (cycle == 80)
|
||||||
{
|
{
|
||||||
|
|
||||||
STAT &= 0xFC;
|
STAT &= 0xFC;
|
||||||
|
@ -263,7 +277,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
VRAM_access_write = false;
|
VRAM_access_write = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle == 256)
|
if (cycle == 252)
|
||||||
{
|
{
|
||||||
STAT &= 0xFC;
|
STAT &= 0xFC;
|
||||||
OAM_INT = false;
|
OAM_INT = false;
|
||||||
|
@ -278,9 +292,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cycle < 80)
|
if (cycle < 76)
|
||||||
{
|
{
|
||||||
if (cycle == 4)
|
if (cycle == 0)
|
||||||
{
|
{
|
||||||
// apparently, writes can make it to OAM one cycle longer then reads
|
// apparently, writes can make it to OAM one cycle longer then reads
|
||||||
OAM_access_write = false;
|
OAM_access_write = false;
|
||||||
|
@ -288,18 +302,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// here mode 2 will be set to true and interrupts fired if enabled
|
// here mode 2 will be set to true and interrupts fired if enabled
|
||||||
STAT &= 0xFC;
|
STAT &= 0xFC;
|
||||||
STAT |= 0x2;
|
STAT |= 0x2;
|
||||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
if (STAT.Bit(5))
|
||||||
|
{
|
||||||
|
OAM_INT = true;
|
||||||
|
}
|
||||||
|
|
||||||
HBL_INT = false;
|
HBL_INT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// here OAM scanning is performed
|
|
||||||
OAM_scan(cycle);
|
|
||||||
}
|
|
||||||
else if (cycle >= 80 && LY < 144)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (cycle == 84)
|
// here OAM scanning is performed
|
||||||
|
OAM_scan(cycle + 4);
|
||||||
|
}
|
||||||
|
else if ((cycle >= 76) && (LY_actual < 144))
|
||||||
|
{
|
||||||
|
if (cycle == 76)
|
||||||
|
{
|
||||||
|
OAM_access_read = false;
|
||||||
|
OAM_access_write = true;
|
||||||
|
VRAM_access_read = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cycle == 80)
|
||||||
{
|
{
|
||||||
STAT &= 0xFC;
|
STAT &= 0xFC;
|
||||||
STAT |= 0x03;
|
STAT |= 0x03;
|
||||||
|
@ -309,14 +333,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the screen and handle hblank
|
// render the screen and handle hblank
|
||||||
render(cycle - 80);
|
render(cycle - 76);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cycle >= 452)
|
||||||
|
{
|
||||||
|
OAM_access_read = false;
|
||||||
|
OAM_scan(cycle - 452);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((LY_inc == 0))
|
if ((LY_inc == 0))
|
||||||
{
|
{
|
||||||
if (cycle == 12)
|
if (cycle == 8)
|
||||||
{
|
{
|
||||||
LYC_INT = false;
|
LYC_INT = false;
|
||||||
STAT &= 0xFB;
|
STAT &= 0xFB;
|
||||||
|
@ -333,11 +363,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if (STAT.Bit(5)) { OAM_INT = true; }
|
if (STAT.Bit(5)) { OAM_INT = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle == 92) { OAM_INT = false; }
|
if (cycle == 88) { OAM_INT = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// here LY=LYC will be asserted
|
// here LY=LYC will be asserted
|
||||||
if ((cycle == 4) && (LY != 0))
|
if ((cycle == 0) && (LY_actual != 0))
|
||||||
{
|
{
|
||||||
if ((LY == LYC) && !STAT.Bit(2))
|
if ((LY == LYC) && !STAT.Bit(2))
|
||||||
{
|
{
|
||||||
|
@ -360,6 +390,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
LCD_was_off = true;
|
LCD_was_off = true;
|
||||||
|
|
||||||
LY = 0;
|
LY = 0;
|
||||||
|
LY_actual = 0;
|
||||||
Core.cpu.LY = LY;
|
Core.cpu.LY = LY;
|
||||||
|
|
||||||
cycle = 0;
|
cycle = 0;
|
||||||
|
@ -367,7 +398,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
// assert the STAT IRQ line if the line went from zero to 1
|
// assert the STAT IRQ line if the line went from zero to 1
|
||||||
stat_line = VBL_INT | LYC_INT | HBL_INT | OAM_INT;
|
stat_line = VBL_INT | LYC_INT | HBL_INT | OAM_INT;
|
||||||
|
/*
|
||||||
|
if (stat_line) {
|
||||||
|
Console.Write("OAM: ");
|
||||||
|
Console.Write(OAM_INT);
|
||||||
|
Console.Write(" LYC: ");
|
||||||
|
Console.Write(LYC_INT);
|
||||||
|
Console.Write(" VBL: ");
|
||||||
|
Console.Write(VBL_INT);
|
||||||
|
Console.Write(" HBL: ");
|
||||||
|
Console.Write(HBL_INT);
|
||||||
|
Console.WriteLine(Core.cpu.TotalExecutedCycles);
|
||||||
|
}
|
||||||
|
*/
|
||||||
if (stat_line && !stat_line_old)
|
if (stat_line && !stat_line_old)
|
||||||
{
|
{
|
||||||
if (Core.REG_FFFF.Bit(1)) { Core.cpu.FlagI = true; }
|
if (Core.REG_FFFF.Bit(1)) { Core.cpu.FlagI = true; }
|
||||||
|
@ -393,10 +436,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// i.e. just keeping track of the lowest x-value sprite
|
// i.e. just keeping track of the lowest x-value sprite
|
||||||
if (render_cycle == 0)
|
if (render_cycle == 0)
|
||||||
{
|
{
|
||||||
OAM_access_read = false;
|
|
||||||
OAM_access_write = true;
|
|
||||||
VRAM_access_read = false;
|
|
||||||
|
|
||||||
// window X is latched for the scanline, mid-line changes have no effect
|
// window X is latched for the scanline, mid-line changes have no effect
|
||||||
window_x_latch = window_x;
|
window_x_latch = window_x;
|
||||||
|
|
||||||
|
@ -411,6 +450,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
fetch_sprite_01 = false;
|
fetch_sprite_01 = false;
|
||||||
fetch_sprite_4 = false;
|
fetch_sprite_4 = false;
|
||||||
going_to_fetch = false;
|
going_to_fetch = false;
|
||||||
|
first_fetch = true;
|
||||||
no_sprites = false;
|
no_sprites = false;
|
||||||
evaled_sprites = 0;
|
evaled_sprites = 0;
|
||||||
|
|
||||||
|
@ -543,7 +583,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if (pixel_counter == 160)
|
if (pixel_counter == 160)
|
||||||
{
|
{
|
||||||
read_case = 8;
|
read_case = 8;
|
||||||
hbl_countdown = 7;
|
hbl_countdown = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((render_counter >= render_offset) && (pixel_counter < 0))
|
else if ((render_counter >= render_offset) && (pixel_counter < 0))
|
||||||
|
@ -840,7 +880,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if (going_to_fetch)
|
if (going_to_fetch)
|
||||||
{
|
{
|
||||||
going_to_fetch = false;
|
going_to_fetch = false;
|
||||||
sprite_fetch_counter = 0;
|
sprite_fetch_counter = first_fetch ? 2 : 0;
|
||||||
|
first_fetch = false;
|
||||||
|
|
||||||
if (fetch_sprite_01)
|
if (fetch_sprite_01)
|
||||||
{
|
{
|
||||||
|
@ -1060,8 +1101,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
|
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
|
||||||
if (OAM_cycle == 0)
|
if (OAM_cycle == 0)
|
||||||
{
|
{
|
||||||
OAM_access_read = false;
|
|
||||||
|
|
||||||
OAM_scan_index = 0;
|
OAM_scan_index = 0;
|
||||||
SL_sprites_index = 0;
|
SL_sprites_index = 0;
|
||||||
write_sprite = 0;
|
write_sprite = 0;
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
public byte scroll_y;
|
public byte scroll_y;
|
||||||
public byte scroll_x;
|
public byte scroll_x;
|
||||||
public byte LY;
|
public byte LY;
|
||||||
|
public byte LY_actual;
|
||||||
public byte LY_inc;
|
public byte LY_inc;
|
||||||
public byte LYC;
|
public byte LYC;
|
||||||
public byte DMA_addr;
|
public byte DMA_addr;
|
||||||
|
@ -68,6 +69,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
public bool fetch_sprite_01;
|
public bool fetch_sprite_01;
|
||||||
public bool fetch_sprite_4;
|
public bool fetch_sprite_4;
|
||||||
public bool going_to_fetch;
|
public bool going_to_fetch;
|
||||||
|
public bool first_fetch;
|
||||||
public int sprite_fetch_counter;
|
public int sprite_fetch_counter;
|
||||||
public byte[] sprite_attr_list = new byte[160];
|
public byte[] sprite_attr_list = new byte[160];
|
||||||
public byte[] sprite_pixel_list = new byte[160];
|
public byte[] sprite_pixel_list = new byte[160];
|
||||||
|
@ -171,6 +173,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
ser.Sync("scroll_y", ref scroll_y);
|
ser.Sync("scroll_y", ref scroll_y);
|
||||||
ser.Sync("scroll_x", ref scroll_x);
|
ser.Sync("scroll_x", ref scroll_x);
|
||||||
ser.Sync("LY", ref LY);
|
ser.Sync("LY", ref LY);
|
||||||
|
ser.Sync("LY_actual", ref LY_actual);
|
||||||
ser.Sync("LYinc", ref LY_inc);
|
ser.Sync("LYinc", ref LY_inc);
|
||||||
ser.Sync("LYC", ref LYC);
|
ser.Sync("LYC", ref LYC);
|
||||||
ser.Sync("DMA_addr", ref DMA_addr);
|
ser.Sync("DMA_addr", ref DMA_addr);
|
||||||
|
@ -217,6 +220,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
ser.Sync("fetch_sprite_01", ref fetch_sprite_01);
|
ser.Sync("fetch_sprite_01", ref fetch_sprite_01);
|
||||||
ser.Sync("fetch_sprite_4", ref fetch_sprite_4);
|
ser.Sync("fetch_sprite_4", ref fetch_sprite_4);
|
||||||
ser.Sync("going_to_fetch", ref going_to_fetch);
|
ser.Sync("going_to_fetch", ref going_to_fetch);
|
||||||
|
ser.Sync("first_fetch", ref first_fetch);
|
||||||
ser.Sync("sprite_fetch_counter", ref sprite_fetch_counter);
|
ser.Sync("sprite_fetch_counter", ref sprite_fetch_counter);
|
||||||
ser.Sync("sprite_attr_list", ref sprite_attr_list, false);
|
ser.Sync("sprite_attr_list", ref sprite_attr_list, false);
|
||||||
ser.Sync("sprite_pixel_list", ref sprite_pixel_list, false);
|
ser.Sync("sprite_pixel_list", ref sprite_pixel_list, false);
|
||||||
|
|
Loading…
Reference in New Issue