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

View File

@ -20,7 +20,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{ {
partial class PPU 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 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 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 bool Reg2002_vblank_clear_pending; //ppu's clear of vblank flag is pending
public PPUREGS ppur; public PPUREGS ppur;
public Reg_2000 reg_2000; public Reg_2000 reg_2000;
Reg_2001 reg_2001; public Reg_2001 reg_2001;
byte reg_2003; byte reg_2003;
void regs_reset() void regs_reset()
{ {
@ -387,11 +387,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{ {
ppur._ht= value >> 3; ppur._ht= value >> 3;
ppur.fh = value & 7; ppur.fh = value & 7;
//nes.LogLine("scroll wrote ht = {0} and fh = {1}", ppur._ht, ppur.fh);
} }
else else
{ {
ppur._vt = value >> 3; ppur._vt = value >> 3;
ppur._fv = value & 7; ppur._fv = value & 7;
//nes.LogLine("scroll wrote vt = {0} and fv = {1}", ppur._vt, ppur._fv);
} }
vtoggle ^= true; vtoggle ^= true;
} }
@ -407,6 +409,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppur._h = (value >> 2) & 1; ppur._h = (value >> 2) & 1;
ppur._v = (value >> 3) & 1; ppur._v = (value >> 3) & 1;
ppur._fv = (value >> 4) & 3; ppur._fv = (value >> 4) & 3;
//nes.LogLine("scroll wrote fv = {0}", ppur._fv);
} }
else else
{ {
@ -414,6 +417,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppur._vt |= (value >> 5); ppur._vt |= (value >> 5);
ppur._ht = value & 31; ppur._ht = value & 31;
ppur.install_latches(); ppur.install_latches();
//nes.LogLine("scroll wrote vt = {0}, ht = {1}", ppur._vt, ppur._ht);
nes.board.AddressPPU(ppur.get_2007access()); 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) //render 241 scanlines (including 1 dummy at beginning)
for (int sl = 0; sl < 241; sl++) for (int sl = 0; sl < 241; sl++)
{ {
//TODO - correctly emulate PPU OFF state //if (!reg_2001.PPUON)
if (!reg_2001.PPUON) //{
{ // runppu(kLineTime);
runppu(kLineTime); // continue;
continue; //}
}
ppur.status.sl = sl; ppur.status.sl = sl;
@ -211,10 +210,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//1. is it sprite#0? //1. is it sprite#0?
//2. is the bg pixel nonzero? //2. is the bg pixel nonzero?
//then, it is spritehit. //then, it is spritehit.
if (oam->index == 0)
{
int zzz = 9;
}
if (oam->index == 0 && pixel != 0 && rasterpos < 255) if (oam->index == 0 && pixel != 0 && rasterpos < 255)
{ {
Reg2002_objhit = true; Reg2002_objhit = true;
@ -239,7 +234,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
}//oamcount loop }//oamcount loop
if (reg_2001.PPUON)
xbuf[target] = PaletteAdjustPixel(pixelcolor); xbuf[target] = PaletteAdjustPixel(pixelcolor);
target++; target++;
} //loop across 8 pixels } //loop across 8 pixels
@ -292,17 +289,20 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppuphase = PPUPHASE.OBJ; ppuphase = PPUPHASE.OBJ;
//fetch sprite patterns //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. //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. //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 //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 //this could be handy for the debugging tools also
bool realSprite = (s < 8); bool realSprite = (s < 8);
bool junksprite = (s >= oamcount);
if (!reg_2001.PPUON)
junksprite = true;
TempOAM* oam = &oams[(scanslot << 6) + s]; TempOAM* oam = &oams[(scanslot << 6) + s];
{ {
@ -369,7 +369,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//TODO - fake sprites should not come through ppubus_read but rather peek it //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) //(at least, they should not probe it with AddressPPU. maybe the difference between peek and read is not necessary)
//pattern table fetches if (junksprite)
{
if (realSprite)
{
ppubus_read(patternAddress, true);
ppubus_read(patternAddress, true);
runppu(kFetchTime * 2);
}
}
else
{
int addr = patternAddress; int addr = patternAddress;
oam->patterns[0] = ppubus_read(addr, true); oam->patterns[0] = ppubus_read(addr, true);
if (realSprite) runppu(kFetchTime); if (realSprite) runppu(kFetchTime);
@ -384,6 +394,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
oam->patterns[0] = BITREV.byte_8[oam->patterns[0]]; oam->patterns[0] = BITREV.byte_8[oam->patterns[0]];
oam->patterns[1] = BITREV.byte_8[oam->patterns[1]]; oam->patterns[1] = BITREV.byte_8[oam->patterns[1]];
} }
}
} //c# fixed oam } //c# fixed oam
} //sprite pattern fetch loop } //sprite pattern fetch loop