diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 320234fae9..47ddefc5d8 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 2b2922ee86..b4c58a9a61 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs @@ -44,6 +44,8 @@ UNROM 2 8 0 UOROM 2 16 0 CNROM 3 2 2 CNROM 3 2 4 +ANROM 7 8 0 +AOROM 7 16 0 "; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs new file mode 100644 index 0000000000..60f294c323 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AxROM.cs @@ -0,0 +1,83 @@ +using System; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo.Boards +{ + //generally mapper7 + + public class AxROM : NES.NESBoardBase + { + string type; + bool bus_conflict; + byte[] cram; + int cram_mask; + int prg_mask; + int prg; + + public AxROM(string type) + { + this.type = type; + switch (type) + { + case "ANROM": bus_conflict = false; break; + case "AOROM": bus_conflict = true; break; + } + } + public override void Initialize(NES.RomInfo romInfo, NES nes) + { + base.Initialize(romInfo, nes); + + //guess CRAM size (this is a very confident guess!) + if (RomInfo.CRAM_Size == -1) RomInfo.CRAM_Size = 8; + + cram = new byte[RomInfo.CRAM_Size * 1024]; + cram_mask = cram.Length - 1; + + if (type == "ANROM") + { + Debug.Assert(RomInfo.PRG_Size == 8, "not sure how to handle this; please report"); + prg_mask = 3; + } + if (type == "AOROM") + { + Debug.Assert(RomInfo.PRG_Size == 16 || RomInfo.PRG_Size == 8, "not sure how to handle this; please report"); + prg_mask = RomInfo.PRG_Size-1; + } + + WritePRG(0, 0); + } + + public override byte ReadPRG(int addr) + { + return RomInfo.ROM[addr + (prg << 15)]; + } + + public override void WritePRG(int addr, byte value) + { + prg = value & prg_mask; + if ((value & 0x10) == 0) + SetMirrorType(NES.EMirrorType.OneScreenA); + else + SetMirrorType(NES.EMirrorType.OneScreenB); + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + return cram[addr & cram_mask]; + } + else return base.ReadPPU(addr); + } + + public override void WritePPU(int addr, byte value) + { + if (addr < 0x2000) + { + cram[addr & cram_mask] = value; + } + else base.WritePPU(addr,value); + } + + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index bbdac0d154..37c24115d2 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -16,11 +16,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo None, INes } - public enum EMirrorType - { - Vertical, Horizontal, Other - } - public EHeaderType HeaderType; public int PRG_Size = -1, CHR_Size = -1; public int CRAM_Size = -1, NVWRAM_Size = -1, WRAM_Size = -1; @@ -35,6 +30,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo public byte[] ROM, VROM; } + public enum EMirrorType + { + Vertical, Horizontal, + OneScreenA, OneScreenB, + //unknown or controlled by the board + External + } + public interface INESBoard { byte ReadPRG(int addr); @@ -52,12 +55,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo { this.RomInfo = romInfo; this.NES = nes; - switch (romInfo.MirrorType) - { - case RomInfo.EMirrorType.Horizontal: SetMirroring(0, 0, 1, 1); break; - case RomInfo.EMirrorType.Vertical: SetMirroring(0, 1, 0, 1); break; - default: SetMirroring(-1, -1, -1, -1); break; //crash! - } + SetMirrorType(romInfo.MirrorType); } public RomInfo RomInfo { get; set; } public NES NES { get; set; } @@ -71,6 +69,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo mirroring[3] = d; } + protected void SetMirrorType(EMirrorType mirrorType) + { + switch (mirrorType) + { + case EMirrorType.Horizontal: SetMirroring(0, 0, 1, 1); break; + case EMirrorType.Vertical: SetMirroring(0, 1, 0, 1); break; + case EMirrorType.OneScreenA: SetMirroring(0, 0, 0, 0); break; + case EMirrorType.OneScreenB: SetMirroring(1, 1, 1, 1); break; + default: SetMirroring(-1, -1, -1, -1); break; //crash! + } + } + int ApplyMirroring(int addr) { int block = (addr >> 10) & 3; @@ -535,9 +545,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo ret.MapperNumber |= (ROM_type2 & 0xF0); int mirroring = (ROM_type&1); if((ROM_type&8)!=0) mirroring=2; - if (mirroring == 0) ret.MirrorType = RomInfo.EMirrorType.Horizontal; - else if (mirroring == 1) ret.MirrorType = RomInfo.EMirrorType.Vertical; - else ret.MirrorType = RomInfo.EMirrorType.Other; + if (mirroring == 0) ret.MirrorType = EMirrorType.Horizontal; + else if (mirroring == 1) ret.MirrorType = EMirrorType.Vertical; + else ret.MirrorType = EMirrorType.External; ret.PRG_Size = ROM_size; if (ret.PRG_Size == 0) ret.PRG_Size = 256; @@ -602,8 +612,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo romInfo.BoardName = dict["board"]; switch (dict["mirror"]) { - case "V": romInfo.MirrorType = RomInfo.EMirrorType.Vertical; break; - case "H": romInfo.MirrorType = RomInfo.EMirrorType.Horizontal; break; + case "V": romInfo.MirrorType = EMirrorType.Vertical; break; + case "H": romInfo.MirrorType = EMirrorType.Horizontal; break; + case "X": romInfo.MirrorType = EMirrorType.External; break; } if (dict.ContainsKey("PRG")) romInfo.PRG_Size = int.Parse(dict["PRG"]); @@ -622,6 +633,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo case "UNROM": board = new Boards.UxROM("UNROM"); break; case "UOROM": board = new Boards.UxROM("UOROM"); break; case "CNROM": board = new Boards.CxROM("CNROM"); break; + case "ANROM": board = new Boards.AxROM("ANROM"); break; + case "AOROM": board = new Boards.AxROM("AOROM"); break; } if (board == null) throw new InvalidOperationException("Couldn't classify NES rom"); diff --git a/BizHawk.MultiClient/output/gamedb.txt b/BizHawk.MultiClient/output/gamedb.txt index 688f856b9b..13e6f46e7e 100644 --- a/BizHawk.MultiClient/output/gamedb.txt +++ b/BizHawk.MultiClient/output/gamedb.txt @@ -2351,5 +2351,18 @@ C2E8AD9E054DD3AF022404856DC8916F ASO - Armored Scrum Object (J) NES board=CNRO 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 +5DB8BC3BD36484BB164EEA6097A1E313 Cybernoid - The Fighting Machine (U) NES board=CNROM;mirror=V;PRG=2;CHR=4 +;ANROM 8,0 +81706ABDAE6D1D11B0C8986FC4383EC0 Marble Madness (U) NES board=ANROM;mirror=X;PRG=8;CHR=0 +5D50D8F9CF3D6D311A2AC7F010D83BE0 Marble Madness (E) NES board=ANROM;mirror=X;PRG=8;CHR=0 +8B179585FD5D6D7F4ECAA9196381A46D + +;AOROM 8,0 +C6809FA829814A356446CE0B36F60EBF Time Lord (E) NES board=AOROM;mirror=X;PRG=8;CHR=0 +8B179585FD5D6D7F4ECAA9196381A46D Time Lord (U) NES board=AOROM;mirror=X;PRG=8;CHR=0 + +;AOROM 16,0 +DBF8909B943AB0F7ED0F210CE85FAFAF Battletoads (E) NES board=AOROM;mirror=X;PRG=16;CHR=0 +318D9C03FB183F6F8CD2FC89FDD0DBB2 Battletoads (J) NES board=AOROM;mirror=X;PRG=16;CHR=0 +EEFAC97AC3B85048F3685E1623210EFB Battletoads (U) NES board=AOROM;mirror=X;PRG=16;CHR=0 \ No newline at end of file