GBHawk: Cleanup ppus

This commit is contained in:
alyosha-tas 2018-05-09 20:05:53 -04:00
parent 056c24e4cf
commit 32f78cd311
5 changed files with 101 additions and 142 deletions

View File

@ -4,8 +4,8 @@ namespace BizHawk.Emulation.Common.Components.LR35902
{
public partial class LR35902
{
private int totalExecutedCycles;
public int TotalExecutedCycles { get { return totalExecutedCycles; } set { totalExecutedCycles = value; } }
private ulong totalExecutedCycles;
public ulong TotalExecutedCycles { get { return totalExecutedCycles; } set { totalExecutedCycles = value; } }
private int EI_pending;
private bool interrupts_enabled;

View File

@ -295,7 +295,8 @@ namespace BizHawk.Emulation.Common.Components.LR35902
// call the interrupt processor after 4 extra cycles
if (!Halt_bug_3)
{
INTERRUPT_GBC_NOP();
INTERRUPT_GBC_NOP();
//INTERRUPT_();
}
else
{

View File

@ -58,9 +58,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public override byte ReadReg(int addr)
{
byte ret = 0;
//Console.WriteLine(Core.cpu.TotalExecutedCycles);
switch (addr)
{
{
case 0xFF40: ret = LCDC; break; // LCDC
case 0xFF41: ret = STAT; break; // STAT
case 0xFF42: ret = scroll_y; break; // SCY
@ -350,7 +350,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
cycle = 0;
LY_actual = LY;
LY += LY_inc;
Core.cpu.LY = LY;
// 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;
}
no_scan = false;
@ -359,6 +366,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LY_inc = 1;
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
// meaning it will pick up where it left off if re-enabled later
// so we don't reset it in the scanline loop
@ -368,8 +381,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
window_is_reset = true;
}
Core.cpu.LY = LY;
// Automatically restore access to VRAM at this time (force end drawing)
// Who Framed Roger Rabbit seems to run into this.
VRAM_access_write = true;
@ -381,34 +392,6 @@ 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
if (LCD_was_off)
{
@ -424,25 +407,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// also, the LCD does not enter mode 2 on scanline 0 when first turned on
no_scan = true;
cycle = 4;
cycle = 8;
}
// the VBL stat is continuously asserted
if ((LY_actual >= 144))
if ((LY >= 144))
{
if (STAT.Bit(4))
{
if ((cycle >= 0) && (LY_actual == 144))
if ((cycle >= 4) && (LY == 144))
{
VBL_INT = true;
}
else if (LY_actual > 144)
else if (LY > 144)
{
VBL_INT = true;
}
}
if ((cycle == 0) && (LY_actual == 144)) {
if ((cycle == 4) && (LY == 144)) {
HBL_INT = false;
@ -454,15 +437,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Core.REG_FF0F |= 0x01;
}
if ((LY_actual >= 144) && (cycle == 0))
if ((LY >= 144) && (cycle == 4))
{
// 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_actual == 153) && (cycle == 4))
if ((LY == 153) && (cycle == 8))
{
LY_actual = 0;
LY = 0;
LY_inc = 0;
Core.cpu.LY = LY;
}
}
@ -475,7 +459,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// there is no mode 2 (presumably it missed the trigger)
// mode 3 is very short, probably in some self test mode before turning on?
if (cycle == 4)
if (cycle == 8)
{
if (LY != LYC)
{
@ -491,9 +475,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
if (cycle == 80)
if (cycle == 84)
{
STAT &= 0xFC;
STAT |= 0x03;
OAM_INT = false;
@ -504,7 +487,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
VRAM_access_write = false;
}
if (cycle == 252)
if (cycle == 256)
{
STAT &= 0xFC;
OAM_INT = false;
@ -519,9 +502,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
if (cycle < 76)
if (cycle < 80)
{
if (cycle == 0)
if (cycle == 4)
{
// apparently, writes can make it to OAM one cycle longer then reads
OAM_access_write = false;
@ -529,24 +512,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// here mode 2 will be set to true and interrupts fired if enabled
STAT &= 0xFC;
STAT |= 0x2;
if (STAT.Bit(5)) { OAM_INT = true; }
HBL_INT = false;
// DMG exits VBlank into mode 0, but not GBC, so this line is needed
// (This is important for Wacky Racers and Altered Space)
VBL_INT = false;
}
// here OAM scanning is performed
OAM_scan(cycle + 4);
OAM_scan(cycle);
}
else if (cycle >= 76 && LY_actual < 144)
else if ((cycle >= 80) && (LY < 144))
{
if (cycle == 76)
{
OAM_access_read = false;
OAM_access_write = true;
VRAM_access_read = false;
}
if (cycle == 80)
if (cycle == 84)
{
STAT &= 0xFC;
STAT |= 0x03;
@ -556,20 +537,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// render the screen and handle hblank
render(cycle - 76);
render(cycle - 80);
}
}
if (cycle >= 452)
{
OAM_access_read = false;
OAM_scan(cycle - 452);
}
}
if ((LY_inc == 0))
{
if (cycle == 8)
if (cycle == 12)
{
LYC_INT = false;
STAT &= 0xFB;
@ -583,14 +558,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// also 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 (cycle == 88) { OAM_INT = false; }
//if (cycle == 92) { OAM_INT = false; }
}
// here LY=LYC will be asserted
if ((cycle == 0) && (LY_actual != 0))
if ((cycle == 4) && (LY != 0))
{
if ((LY == LYC) && !STAT.Bit(2))
{
@ -613,7 +588,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LCD_was_off = true;
LY = 0;
LY_actual = 0;
Core.cpu.LY = LY;
cycle = 0;
@ -647,6 +621,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// i.e. just keeping track of the lowest x-value sprite
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_latch = window_x;
@ -1411,6 +1389,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
if (OAM_cycle == 0)
{
OAM_access_read = false;
OAM_scan_index = 0;
SL_sprites_index = 0;
write_sprite = 0;

View File

@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public int TotalExecutedCycles
{
get { return cpu.TotalExecutedCycles; }
get { return (int)cpu.TotalExecutedCycles; }
}
}
}

View File

@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
break;
case 0xFF44: // LY
LY = LY_actual = 0; /*reset*/
LY = 0; /*reset*/
break;
case 0xFF45: // LYC
LYC = value;
@ -125,7 +125,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
cycle = 0;
LY_actual = LY;
LY += LY_inc;
Core.cpu.LY = LY;
// 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;
}
no_scan = false;
@ -134,6 +142,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LY_inc = 1;
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
// meaning it will pick up where it left off if re-enabled later
// so we don't reset it in the scanline loop
@ -154,34 +167,6 @@ 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
if (LCD_was_off)
{
@ -197,25 +182,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// also, the LCD does not enter mode 2 on scanline 0 when first turned on
no_scan = true;
cycle = 4;
cycle = 8;
}
// the VBL stat is continuously asserted
if ((LY_actual >= 144))
if ((LY >= 144))
{
if (STAT.Bit(4))
{
if ((cycle >= 0) && (LY_actual == 144))
if ((cycle >= 4) && (LY == 144))
{
VBL_INT = true;
}
else if (LY_actual > 144)
else if (LY > 144)
{
VBL_INT = true;
}
}
if ((cycle == 0) && (LY_actual == 144)) {
if ((cycle == 4) && (LY == 144)) {
HBL_INT = false;
@ -227,15 +212,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Core.REG_FF0F |= 0x01;
}
if ((LY_actual >= 144) && (cycle == 0))
if ((LY >= 144) && (cycle == 4))
{
// a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1
if (STAT.Bit(5)) { OAM_INT = true; }
}
if ((LY_actual == 153) && (cycle == 4))
if ((LY == 153) && (cycle == 8))
{
LY_actual = 0;
LY = 0;
LY_inc = 0;
Core.cpu.LY = LY;
}
}
@ -248,7 +234,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// there is no mode 2 (presumably it missed the trigger)
// mode 3 is very short, probably in some self test mode before turning on?
if (cycle == 4)
if (cycle == 8)
{
if (LY != LYC)
{
@ -264,7 +250,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
if (cycle == 80)
if (cycle == 84)
{
STAT &= 0xFC;
@ -277,7 +263,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
VRAM_access_write = false;
}
if (cycle == 252)
if (cycle == 256)
{
STAT &= 0xFC;
OAM_INT = false;
@ -292,9 +278,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else
{
if (cycle < 76)
if (cycle < 80)
{
if (cycle == 0)
if (cycle == 4)
{
// apparently, writes can make it to OAM one cycle longer then reads
OAM_access_write = false;
@ -308,18 +294,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// here OAM scanning is performed
OAM_scan(cycle + 4);
OAM_scan(cycle);
}
else if ((cycle >= 76) && (LY_actual < 144))
else if ((cycle >= 80) && (LY < 144))
{
if (cycle == 76)
{
OAM_access_read = false;
OAM_access_write = true;
VRAM_access_read = false;
}
if (cycle == 80)
if (cycle == 84)
{
STAT &= 0xFC;
STAT |= 0x03;
@ -329,20 +308,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// render the screen and handle hblank
render(cycle - 76);
render(cycle - 80);
}
}
if (cycle >= 452)
{
if (LY != 144) { OAM_access_read = false; }
OAM_scan(cycle - 452);
}
}
}
if ((LY_inc == 0))
{
if (cycle == 8)
if (cycle == 12)
{
LYC_INT = false;
STAT &= 0xFB;
@ -359,11 +332,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (STAT.Bit(5)) { OAM_INT = true; }
}
if (cycle == 88) { OAM_INT = false; }
if (cycle == 92) { OAM_INT = false; }
}
// here LY=LYC will be asserted
if ((cycle == 0) && (LY_actual != 0))
if ((cycle == 4) && (LY != 0))
{
if ((LY == LYC) && !STAT.Bit(2))
{
@ -386,7 +359,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
LCD_was_off = true;
LY = 0;
LY_actual = 0;
Core.cpu.LY = LY;
cycle = 0;
@ -420,6 +392,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// i.e. just keeping track of the lowest x-value sprite
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_latch = window_x;
@ -924,14 +900,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (LCDC.Bit(2))
{
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
y = LY - (SL_sprites[sl_use_index * 4] - 16);
y = 15 - y;
sprite_sel[0] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2];
sprite_sel[1] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1];
}
else
{
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
y = LY - (SL_sprites[sl_use_index * 4] - 16);
y = 7 - y;
sprite_sel[0] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2];
sprite_sel[1] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1];
@ -941,13 +917,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (LCDC.Bit(2))
{
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
y = LY - (SL_sprites[sl_use_index * 4] - 16);
sprite_sel[0] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2];
sprite_sel[1] = Core.VRAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1];
}
else
{
y = LY_actual - (SL_sprites[sl_use_index * 4] - 16);
y = LY - (SL_sprites[sl_use_index * 4] - 16);
sprite_sel[0] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2];
sprite_sel[1] = Core.VRAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1];
}
@ -1085,6 +1061,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines?
if (OAM_cycle == 0)
{
OAM_access_read = false;
OAM_scan_index = 0;
SL_sprites_index = 0;
write_sprite = 0;