From c713b9a8f06b3fdaf3b4469411cc7669fb889137 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 28 Feb 2011 09:13:27 +0000 Subject: [PATCH] [NES] add CxROM and fix a severe timing issue which repairs many obvious glitches --- BizHawk.Emulation/BizHawk.Emulation.csproj | 1 + .../Consoles/Nintendo/NES/BoardDetector.cs | 2 + .../Consoles/Nintendo/NES/Boards/CxROM.cs | 49 +++++++++++++++++++ .../Consoles/Nintendo/NES/Boards/NROM.cs | 2 +- .../Consoles/Nintendo/NES/Boards/UxROM.cs | 5 +- .../Consoles/Nintendo/NES/NES.cs | 21 ++++++-- .../Consoles/Nintendo/NES/PPU.cs | 5 +- .../Consoles/Nintendo/NES/PPU.regs.cs | 6 +-- .../Consoles/Nintendo/NES/PPU.run.cs | 4 -- BizHawk.MultiClient/output/gamedb.txt | 20 +++++++- 10 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index e390549732..320234fae9 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -55,6 +55,7 @@ + diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs index a9a3871f0b..2b2922ee86 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs @@ -42,6 +42,8 @@ NROM 0 1 1 NROM 0 2 1 UNROM 2 8 0 UOROM 2 16 0 +CNROM 3 2 2 +CNROM 3 2 4 "; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs new file mode 100644 index 0000000000..f8c8fa00ec --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs @@ -0,0 +1,49 @@ +using System; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo.Boards +{ + //generally mapper3 + + public class CxROM : NES.NESBoardBase + { + string type; + public CxROM(string type) + { + this.type = type; + } + public override void Initialize(NES.RomInfo romInfo, NES nes) + { + base.Initialize(romInfo, nes); + Debug.Assert(Util.IsPowerOfTwo(RomInfo.CHR_Size)); + chr_mask = RomInfo.CHR_Size - 1; + bus_conflict = true; + } + + public override void WritePRG(int addr, byte value) + { + if (bus_conflict) + { + byte old_value = value; + value &= ReadPRG(addr); + Debug.Assert(old_value == value,"Found a test case of CxROM bus conflict. please report."); + } + chr = value&chr_mask; + Console.WriteLine("at {0}, set chr={1}", NES.ppu.ppur.status.sl, chr); + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + return RomInfo.VROM[addr + (chr<<13)]; + } + else return base.ReadPPU(addr); + } + + int chr; + int chr_mask; + bool bus_conflict; + + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/NROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/NROM.cs index 57e5760a9d..ec9c26e4d7 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/NROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/NROM.cs @@ -5,7 +5,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards { public class NROM : NES.NESBoardBase { - public virtual void Initialize(NES.RomInfo romInfo, NES nes) + public override void Initialize(NES.RomInfo romInfo, NES nes) { base.Initialize(romInfo, nes); Debug.Assert(romInfo.PRG_Size < 3); diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs index 1c0a2e19bc..362b482abf 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs @@ -3,6 +3,8 @@ using System.Diagnostics; namespace BizHawk.Emulation.Consoles.Nintendo.Boards { + //generally mapper2 + public class UxROM : NES.NESBoardBase { string type; @@ -29,13 +31,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards { int block = addr >> 14; int page = block == 1 ? pagemask : prg; - page &= pagemask; int ofs = addr & 0x3FFF; return RomInfo.ROM[(page << 14) | ofs]; } public override void WritePRG(int addr, byte value) { - prg = value; + prg = value & pagemask; } public override byte ReadPPU(int addr) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index 4071b7125a..bbdac0d154 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -114,7 +114,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo //hardware protected MOS6502 cpu; INESBoard board; - PPU ppu; + public PPU ppu; RomInfo romInfo; byte[] ram; @@ -237,9 +237,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo int pixel = emu.ppu.xbuf[i]; int deemph = pixel >> 8; int palentry = pixel & 0xFF; - int r = emu.palette[pixel, 0]; - int g = emu.palette[pixel, 1]; - int b = emu.palette[pixel, 2]; + int r = emu.palette[palentry, 0]; + int g = emu.palette[palentry, 1]; + int b = emu.palette[palentry, 2]; Palettes.ApplyDeemphasis(ref r, ref g, ref b, deemph); pixels[i] = (r<<16)|(g<<8)|b; i++; @@ -278,9 +278,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo ppu.FrameAdvance(); } + int cpu_accumulate; protected void RunCpu(int cycles) { - cpu.Execute(cycles); + if (ppu.PAL) + cycles *= 15; + else + cycles *= 16; + + cpu_accumulate += cycles; + int todo = cpu_accumulate / 48; + cpu_accumulate -= todo * 48; + if(todo>0) + cpu.Execute(todo); } interface IPortDevice @@ -611,6 +621,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo case "NROM": board = new Boards.NROM(); break; case "UNROM": board = new Boards.UxROM("UNROM"); break; case "UOROM": board = new Boards.UxROM("UOROM"); break; + case "CNROM": board = new Boards.CxROM("CNROM"); break; } if (board == null) throw new InvalidOperationException("Couldn't classify NES rom"); diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs index c9fb5141bc..988b0d4914 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs @@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo { partial class NES { - partial class PPU + public partial class PPU { //when the ppu issues a write it goes through here and into the game board void ppubus_write(int addr, byte value) @@ -74,13 +74,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo //DON'T LIKE THIS.... ppur.status.cycle = (ppur.status.cycle + x) % ppur.status.end_cycle; - nes.RunCpu(x); //pputime -= cputodo<<2; } //hack - bool PAL = false; + 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 9973baa567..c093431661 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs @@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo } - struct PPUSTATUS + public struct PPUSTATUS { public int sl; public int cycle, end_cycle; @@ -62,7 +62,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo //uses the internal counters concept at http://nesdev.icequake.net/PPU%20addressing.txt //TODO - this should be turned into a state machine - class PPUREGS + public class PPUREGS { PPU ppu; public PPUREGS(PPU ppu) @@ -242,7 +242,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo Bit Reg2002_objhit; //Sprite 0 overlap. Set when a nonzero pixel of sprite 0 is drawn overlapping a nonzero background pixel. Used for raster timing. Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started) byte PPUGenLatch; - PPUREGS ppur; + public PPUREGS ppur; Reg_2000 reg_2000; Reg_2001 reg_2001; byte reg_2003; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs index 27b0e88162..ab1f0053dd 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs @@ -25,10 +25,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo void Read_bgdata(ref BGDataRecord bgdata) { int addr = ppur.get_ntread(); - if (addr == 0x2043) - { - int zzz = 9; - } bgdata.nt = ppubus_read(addr); runppu(kFetchTime); diff --git a/BizHawk.MultiClient/output/gamedb.txt b/BizHawk.MultiClient/output/gamedb.txt index a090c15b58..688f856b9b 100644 --- a/BizHawk.MultiClient/output/gamedb.txt +++ b/BizHawk.MultiClient/output/gamedb.txt @@ -2314,8 +2314,8 @@ C7538FE4132AADC1A2535042C6BBF29C Spelunker (U) NES board=NROM;mirror=V;PRG=2;C 22F4719A16FCF0DEFE1DF7F4C6C7D83D Spy Vs Spy (U) NES board=NROM;mirror=H;PRG=2;CHR=1 96250E185FF5B8C596A210803484322E Sqoon (U) NES board=NROM;mirror=V;PRG=2;CHR=1 80F94BBB851A5466BF773DBBC6D056F2 Stack-Up (JU) NES board=NROM;mirror=H;PRG=2;CHR=1 -8E3630186E35D477231BF8FD50E54CDD Super Mario Bros (Rev 0) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1;bug=1 -D7176817CDE28CE3F6589B5E833089A4 Super Mario Bros (Rev 1) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1;bug=1 +8E3630186E35D477231BF8FD50E54CDD Super Mario Bros (Rev 0) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1 +D7176817CDE28CE3F6589B5E833089A4 Super Mario Bros (Rev 1) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1 FA57750AD33815E99C40986F26FC697E Tag Team Wrestling (U) NES board=NROM;mirror=H;PRG=2;CHR=1; 7A471AC3E9F2ED9B252C0EE6C5B69F5B Volleyball (U) NES board=NROM;mirror=V;PRG=2;CHR=1 E7D7225DAD044B624FBAD9C9CA96E835 Wrecking Crew (JUE) NES board=NROM;mirror=H;PRG=2;CHR=1 @@ -2337,3 +2337,19 @@ C0C74CC78E6CD34775A83CC21A0C75B5 Paperboy 2 (U) NES board=UOROM;mirror=H;PRG=1 ;mapper66? mhrom? wtf?? ;27100B746D50E6AE6FBAE2C794173240 Metal Gear (U) NES board=UXROM;mirror=H;PRG=8;CHR=0;CRAM=8;bug=1 + +;CNROM 2,2 +646ADDFCC3F43330681482061BEF9493 Arkanoid (J) NES board=CNROM;mirror=H;PRG=2;CHR=2 +0CCC1A2FE5214354C3FD75A6C81550CC Arkanoid (U) NES board=CNROM;mirror=H;PRG=2;CHR=2 + +;CNROM 2,4 +39FC2CB541D2D2E32ED5E5E45E54CE74 Solomon's Key (U) NES board=CNROM;mirror=H;PRG=2;CHR=4 +248BA1ACBFED28BE4E6839A858A5C60A Hudson's Adventure Island (U) NES board=CNROM;mirror=V;PRG=2;CHR=4 +C3263D7DE9FD9AA6BDC416526399314E Adventures of Dino Riki (U) NES board=CNROM;mirror=V;PRG=2;CHR=4 +6307B2766D33A38AE68C639019DC8890 Alpha Mission (U) NES board=CNROM;mirror=H;PRG=2;CHR=4 +C2E8AD9E054DD3AF022404856DC8916F ASO - Armored Scrum Object (J) NES board=CNROM;mirror=H;PRG=2;CHR=4 +930371365F634BECEFA5538D0C3065C5 Athletic World (U) NES board=CNROM;mirror=V;PRG=2;CHR=4 +797383138B0590CE00ED0F6FDEA14053 Arkista's Ring (U) NES board=CNROM;mirror=H;PRG=2;CHR=4 +8E7811BE263CF530ADECF3368B9E6012 Bump'n'Jump (U) NES board=CNROM;mirror=H;PRG=2;CHR=4 +5DB8BC3BD36484BB164EEA6097A1E313 Cybernoid - The Fighting Machine (U) NES board=CNROM;mirror=V;PRG=2;CHR=4;bug=1 +