From 079f9d9958d875d965c54cce37b7a7469c160c06 Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 10 Jun 2011 01:14:52 +0000 Subject: [PATCH] [NES] fix broken scroll and shaky statusbars regression --- .../Consoles/Nintendo/NES/Boards/ExROM.cs | 2 + .../Consoles/Nintendo/NES/PPU.cs | 4 +- .../Consoles/Nintendo/NES/PPU.regs.cs | 8 ++- .../Consoles/Nintendo/NES/PPU.run.cs | 69 +++++++++++-------- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/ExROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/ExROM.cs index 790b3c5219..663d8c0ef5 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/ExROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/ExROM.cs @@ -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; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs index 643331230d..c4927a2521 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs @@ -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; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs index b8719b8920..66ae5064f1 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs @@ -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()); } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs index 9f77554d38..f7a22e9a9b 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs @@ -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