diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 47ddefc5d8..752c786d32 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -56,7 +56,9 @@ + + diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs index b4c58a9a61..955fd754f6 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs @@ -31,21 +31,24 @@ namespace BizHawk.Emulation.Consoles.Nintendo { var parts = line.Split('\t'); if (parts.Length < 4) continue; - line = line.Replace(parts[0],""); - line = line.TrimStart('\t'); - Table[line] = parts[0]; + line = line.Replace(parts[3],""); + line = line.TrimEnd('\t'); + Table[line] = parts[3]; } } -//board MAP PRG CHR +//MAP PRG CHR BOARD static string ClassifyTable = @" -NROM 0 1 1 -NROM 0 2 1 -UNROM 2 8 0 -UOROM 2 16 0 -CNROM 3 2 2 -CNROM 3 2 4 -ANROM 7 8 0 -AOROM 7 16 0 +0 1 1 NROM +0 2 1 NROM +2 8 0 UNROM +2 16 0 UOROM +3 2 2 CNROM +3 2 4 CNROM +7 8 0 ANROM +7 16 0 AOROM +11 4 2 Discrete_74x377 +11 2 4 Discrete_74x377 +13 2 0 CPROM "; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs index 60f294c323..ba47cfd0fe 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs @@ -44,6 +44,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards prg_mask = RomInfo.PRG_Size-1; } + //it is necessary to write during initialization to set the mirroring WritePRG(0, 0); } @@ -54,6 +55,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards 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."); + } prg = value & prg_mask; if ((value & 0x10) == 0) SetMirrorType(NES.EMirrorType.OneScreenA); diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CPROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CPROM.cs new file mode 100644 index 0000000000..e54b1e6d17 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CPROM.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo.Boards +{ + //generally mapper3 + + public class CPROM : NES.NESBoardBase + { + byte[] cram; + int chr; + + public CPROM() + { + } + public override void Initialize(NES.RomInfo romInfo, NES nes) + { + base.Initialize(romInfo, nes); + cram = new byte[16*1024]; + } + + public override void WritePRG(int addr, byte value) + { + value = HandleNormalPRGConflict(addr,value); + chr = value&3; + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x1000) + return cram[addr]; + else if(addr<0x2000) + return cram[addr-0x1000 + (chr<<12)]; + else return base.ReadPPU(addr); + } + + public override void WritePPU(int addr, byte value) + { + if (addr < 0x1000) + cram[addr] = value; + else if (addr < 0x2000) + cram[addr - 0x1000 + (chr << 12)] = value; + else base.WritePPU(addr,value); + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs index f8c8fa00ec..a65bf1094d 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs @@ -29,7 +29,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards 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); + //Console.WriteLine("at {0}, set chr={1}", NES.ppu.ppur.status.sl, chr); } public override byte ReadPPU(int addr) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs new file mode 100644 index 0000000000..de30bc1f37 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs @@ -0,0 +1,51 @@ +using System; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo.Boards +{ + //mapper 11 + + public class Discrete_74x377 : NES.NESBoardBase + { + int prg_mask, chr_mask; + int prg, chr; + bool bus_conflict = true; + + public override void Initialize(NES.RomInfo romInfo, NES nes) + { + base.Initialize(romInfo, nes); + + Debug.Assert(romInfo.PRG_Size == 2 || romInfo.PRG_Size == 4 || romInfo.PRG_Size == 8); + prg_mask = (romInfo.PRG_Size/2)-1; + + Debug.Assert(romInfo.CHR_Size == 2 || romInfo.CHR_Size == 4 || romInfo.CHR_Size == 8 || romInfo.CHR_Size == 16); + chr_mask = (romInfo.CHR_Size - 1); + } + public override byte ReadPRG(int addr) + { + return RomInfo.ROM[addr + (prg<<15)]; + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + return RomInfo.VROM[addr + (chr << 13)]; + } + else return base.ReadPPU(addr); + } + + 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 Discrete_74x377 bus conflict. please report."); + } + + prg = (value & 3) & prg_mask; + chr = (value >> 4) & chr_mask; + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs index 362b482abf..551cb5e0bd 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/UxROM.cs @@ -5,6 +5,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards { //generally mapper2 + //TODO - simplify logic and handle fewer (known) cases (e.g. no IsPowerOfTwo, but rather hardcoded cases) + public class UxROM : NES.NESBoardBase { string type; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index 37c24115d2..d125da34b1 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Collections.Generic; @@ -89,6 +90,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo return (block << 10) | ofs | 0x2000; } + protected byte HandleNormalPRGConflict(int addr, byte value) + { + byte old_value = value; + value &= ReadPRG(addr); + Debug.Assert(old_value == value, "Found a test case of bus conflict. please report."); + return value; + } public virtual byte ReadPRG(int addr) { return RomInfo.ROM[addr];} public virtual void WritePRG(int addr, byte value) { } @@ -635,16 +643,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo case "CNROM": board = new Boards.CxROM("CNROM"); break; case "ANROM": board = new Boards.AxROM("ANROM"); break; case "AOROM": board = new Boards.AxROM("AOROM"); break; + case "Discrete_74x377": board = new Boards.Discrete_74x377(); break; + case "CPROM": board = new Boards.CPROM(); break; } if (board == null) throw new InvalidOperationException("Couldn't classify NES rom"); - board.Initialize(romInfo, this); //we're going to go ahead and copy these out, just in case we need to pad them alter romInfo.ROM = new byte[romInfo.PRG_Size * 16 * 1024]; romInfo.VROM = new byte[romInfo.CHR_Size * 8 * 1024]; Array.Copy(file, 16, romInfo.ROM, 0, romInfo.ROM.Length); Array.Copy(file, 16 + romInfo.ROM.Length, romInfo.VROM, 0, romInfo.VROM.Length); + + board.Initialize(romInfo, this); } HardReset();