[NES] fix broken scroll and shaky statusbars regression

This commit is contained in:
zeromus 2011-06-10 01:14:52 +00:00
parent f72be10bd1
commit 079f9d9958
4 changed files with 49 additions and 34 deletions

View File

@ -403,6 +403,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
if (NES.ppu.ppur.status.cycle != 336)
return;
if (!NES.ppu.reg_2001.PPUON)
return;
int sl = NES.ppu.ppur.status.sl + 1;

View File

@ -25,8 +25,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//when the ppu issues a read it goes through here and into the game board
public byte ppubus_read(int addr, bool ppu)
{
//speculative -- hardware doesnt touch the bus when the PPU is disabled
//(without this, smb3 title screen creates garbage when skipped)
//hardware doesnt touch the bus when the PPU is disabled
if (!reg_2001.PPUON && ppu)
return 0xFF;
@ -155,7 +154,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//hack
public bool PAL = false;
bool SPRITELIMIT = true;
const int MAXSPRITES = 8;
}

View File

@ -20,7 +20,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
partial class PPU
{
class Reg_2001
public class Reg_2001
{
public Bit color_disable; //Color disable (0: normal color; 1: AND all palette entries with 110000, effectively producing a monochrome display)
public Bit show_bg_leftmost; //Show leftmost 8 pixels of background
@ -298,7 +298,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
bool Reg2002_vblank_clear_pending; //ppu's clear of vblank flag is pending
public PPUREGS ppur;
public Reg_2000 reg_2000;
Reg_2001 reg_2001;
public Reg_2001 reg_2001;
byte reg_2003;
void regs_reset()
{
@ -387,11 +387,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
ppur._ht= value >> 3;
ppur.fh = value & 7;
//nes.LogLine("scroll wrote ht = {0} and fh = {1}", ppur._ht, ppur.fh);
}
else
{
ppur._vt = value >> 3;
ppur._fv = value & 7;
//nes.LogLine("scroll wrote vt = {0} and fv = {1}", ppur._vt, ppur._fv);
}
vtoggle ^= true;
}
@ -407,6 +409,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppur._h = (value >> 2) & 1;
ppur._v = (value >> 3) & 1;
ppur._fv = (value >> 4) & 3;
//nes.LogLine("scroll wrote fv = {0}", ppur._fv);
}
else
{
@ -414,6 +417,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppur._vt |= (value >> 5);
ppur._ht = value & 31;
ppur.install_latches();
//nes.LogLine("scroll wrote vt = {0}, ht = {1}", ppur._vt, ppur._ht);
nes.board.AddressPPU(ppur.get_2007access());
}

View File

@ -119,12 +119,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//render 241 scanlines (including 1 dummy at beginning)
for (int sl = 0; sl < 241; sl++)
{
//TODO - correctly emulate PPU OFF state
if (!reg_2001.PPUON)
{
runppu(kLineTime);
continue;
}
//if (!reg_2001.PPUON)
//{
// runppu(kLineTime);
// continue;
//}
ppur.status.sl = sl;
@ -211,10 +210,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//1. is it sprite#0?
//2. is the bg pixel nonzero?
//then, it is spritehit.
if (oam->index == 0)
{
int zzz = 9;
}
if (oam->index == 0 && pixel != 0 && rasterpos < 255)
{
Reg2002_objhit = true;
@ -239,7 +234,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
}//oamcount loop
xbuf[target] = PaletteAdjustPixel(pixelcolor);
if (reg_2001.PPUON)
xbuf[target] = PaletteAdjustPixel(pixelcolor);
target++;
} //loop across 8 pixels
@ -292,17 +289,20 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppuphase = PPUPHASE.OBJ;
//fetch sprite patterns
for (int s = 0; s < MAXSPRITES; s++)
int oam_todo = oamcount;
if (oam_todo < 8)
oam_todo = 8;
for (int s = 0; s < oam_todo; s++)
{
//if we have hit our eight sprite pattern and we dont have any more sprites, then bail
if (s == oamcount && s >= 8)
break;
//if this is a real sprite sprite, then it is not above the 8 sprite limit.
//this is how we support the no 8 sprite limit feature.
//not that at some point we may need a virtual CALL_PPUREAD which just peeks and doesnt increment any counters
//this could be handy for the debugging tools also
bool realSprite = (s < 8);
bool junksprite = (s >= oamcount);
if (!reg_2001.PPUON)
junksprite = true;
TempOAM* oam = &oams[(scanslot << 6) + s];
{
@ -369,20 +369,31 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//TODO - fake sprites should not come through ppubus_read but rather peek it
//(at least, they should not probe it with AddressPPU. maybe the difference between peek and read is not necessary)
//pattern table fetches
int addr = patternAddress;
oam->patterns[0] = ppubus_read(addr, true);
if (realSprite) runppu(kFetchTime);
addr += 8;
oam->patterns[1] = ppubus_read(addr, true);
if (realSprite) runppu(kFetchTime);
//hflip
if ((oam->oam[2] & 0x40) == 0)
if (junksprite)
{
oam->patterns[0] = BITREV.byte_8[oam->patterns[0]];
oam->patterns[1] = BITREV.byte_8[oam->patterns[1]];
if (realSprite)
{
ppubus_read(patternAddress, true);
ppubus_read(patternAddress, true);
runppu(kFetchTime * 2);
}
}
else
{
int addr = patternAddress;
oam->patterns[0] = ppubus_read(addr, true);
if (realSprite) runppu(kFetchTime);
addr += 8;
oam->patterns[1] = ppubus_read(addr, true);
if (realSprite) runppu(kFetchTime);
//hflip
if ((oam->oam[2] & 0x40) == 0)
{
oam->patterns[0] = BITREV.byte_8[oam->patterns[0]];
oam->patterns[1] = BITREV.byte_8[oam->patterns[1]];
}
}
} //c# fixed oam