diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index 3b32531857..e7f0f806d3 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -64,12 +64,12 @@
Code
+
+
+
Code
-
- Code
-
Code
@@ -80,6 +80,7 @@
+
@@ -230,6 +231,7 @@
+
diff --git a/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt b/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt
new file mode 100644
index 0000000000..2045c3cad3
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt
@@ -0,0 +1,127 @@
+mappers:
+key:
+
+Complete - what it sounds like
+Good - thought to be complete
+Decent - mostly compatible, but many significant edge cases not tested
+Minimal - Important games are playable, but emulation is known not to be complete
+~NEEDED~ - Needed for neshawk 1.0
+Needed - Someone should do this
+Nothing - Not implemented
+Junk - Who cares about this. Not enough games, or unlicensed junk or no interesting games
+
+Mapper compatibility does not warrant game compatibility, which may be contingent on other aspects of emulation.
+It is just a rough guide for future work.
+Open bus and bus conflict emulation is not considered complete or thorough in any event.
+
+000 NROM Complete
+001 SxROM=MMC1 Decent
+002 UxROM Good
+003 CNROM Good
+004 MMC3 Decent
+005 ExRom=MMC5 Minimal
+007 AxROM Good
+009 PxROM=MMC2 ~NEEDED~
+010 MMC4 Needed (easy once 009 is done)
+011 Misc Complete
+013 CPROM Complete
+015 Multicart Junk
+016 Bandai Nothing (+159)
+018 Jaleco* Nothing
+019 Namcot106 Needed (+210)
+021 VRC4 Needed
+022 VRC2 Nothing
+023 VRC*? Nothing
+024 VRC6 Needed
+025 VRC4? Nothing
+026 VRC6? Nothing
+032 Irem_G101 Complete
+033 Taito Complete
+034 Misc Complete
+044 Multicart Junk
+045 Multicart Junk
+046 Multicart Junk
+047 MMC3Multi Needed (1st party)
+048 MMC3Variant Needed (similar to mmc3, should inherit)
+049 Multicart Junk
+050 Pirate Junk
+052 Multicart Junk
+057 Multicart Junk
+058 Multicart Junk
+060 Multicart Junk
+061 Multicart Junk
+062 Multicart Junk
+064 Tengen Needed
+065 Misc (J) Nothing
+066 GxROM Complete
+067 Misc (J) Nothing
+068 Sunsoft4 Complete
+069 FME7 Minimal
+070 Misc Nothing
+071 Camerica Complete
+072 Misc (J) Nothing
+073 VRC3 Nothing
+074 Pirate (CN) Junk
+075 VRC1 Nothing
+076 Misc (J) Nothing
+077 Misc (J) Nothing
+078 Misc Nothing
+079 NINA-06 Complete
+080 Misc (J) Nothing
+082 Misc (J) Nothing
+085 VRC7 Needed (lagrange point)
+086 Misc (J) Nothing
+087 Misc (J) Nothing (easy)
+088 Misc (J) Nothing
+089 Misc (J) Nothing (easy)
+090 Garbage Junk (+209)
+091 Pirate Junk
+092 Misc (J) Nothing (similar to 072)
+093 Misc (J) Nothing (easy)
+094 Misc (J) Nothing (easy)
+095 MMC3Variant Complete
+096 Misc (J) Nothing
+097 Misc (J) Nothing (easy)
+105 NES-EVENT ~NEEDED~
+107 Misc Nothing (easy)
+112 Misc (CN) Nothing
+113 =USELESS= Junk
+115 MMC3Variant Nothing
+118 TLSROM Complete
+119 TQROM Complete
+140 Misc (J) Complete
+152 Misc (J) Nothing
+154 Misc (J) Nothing
+159 Bandai {{See 016}}
+164 Pirate Junk
+165 Pirate Junk
+180 Misc (J) Nothing
+182 MMC3Variant Nothing
+184 Sunsoft-1 Complete
+185 Misc (J) Nothing
+189 MMC3Variant Nothing
+191 Pirate Junk
+192 Pirate Junk
+193 Unlicensed Junk
+194 Pirate Junk
+200 Multicart Junk
+201 Multicart Junk
+203 Multicart Junk
+205 Multicart Junk
+207 Misc (J) Nothing
+209 Garbage {{See 090}}
+210 Namcot106 {{See 019}}
+225 Multicart Junk
+226 Multicart Junk
+227 Multicart Junk
+228 Unlicensed Nothing
+230 Multicart Junk
+231 Multicart Junk
+232 Camerica Complete
+233 Multicart Junk
+234 Misc Nothing
+240 Misc (CN) Nothing
+242 Misc (CN) Complete
+243 Misc Nothing
+245 Pirate Junk
+246 Misc (CN) Nothing
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
index 283039fc4e..bc8ca1923d 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
@@ -304,7 +304,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
if (dict.ContainsKey("PAD_H"))
cart.pad_h = byte.Parse(dict["PAD_H"]);
if (dict.ContainsKey("PAD_V"))
- cart.pad_h = byte.Parse(dict["PAD_V"]);
+ cart.pad_v = byte.Parse(dict["PAD_V"]);
if (dict.ContainsKey("bad"))
cart.bad = true;
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AVE-NINA.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AVE-NINA.cs
index edc59186fa..ea52e6bde7 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AVE-NINA.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/AVE-NINA.cs
@@ -4,63 +4,171 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
- /*
-
- */
+ //AKA half of mapper 034 (the other half is BxROM which is entirely different..)
+ class AVE_NINA_001 : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_32k, chr_bank_mask_4k;
- class AVI_NINA_001 : NES.NESBoardBase
- {
- public override bool Configure(NES.EDetectionOrigin origin)
- {
- //configure
+ //state
+ IntBuffer chr_banks_4k = new IntBuffer(2);
+ int prg_bank_32k;
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ chr_banks_4k.Dispose();
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("chr_banks_4k", ref chr_banks_4k);
+ ser.Sync("prg_bank_32k", ref prg_bank_32k);
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
switch (Cart.board_type)
{
- case "AVI_NINA_001":
+ case "AVE-NINA-01": //Impossible Mission 2 (U)
+ AssertPrg(64); AssertChr(64); AssertWram(8); AssertVram(0);
break;
+
default:
return false;
}
- SetMirrorType(Cart.pad_h, Cart.pad_v);
- return true;
- }
- public override byte ReadPPU(int addr)
- {
- return base.ReadPPU(addr);
- }
+ prg_bank_mask_32k = Cart.prg_size / 32 - 1;
+ chr_bank_mask_4k = Cart.chr_size / 4 - 1;
+
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ return true;
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int bank_4k = addr >> 12;
+ int ofs = addr & ((1 << 12) - 1);
+ bank_4k = chr_banks_4k[bank_4k];
+ addr = (bank_4k << 12) | ofs;
+ return VROM[addr];
+ }
+ else return base.ReadPPU(addr);
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ addr |= (prg_bank_32k << 15);
+ return ROM[addr];
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ switch (addr)
+ {
+ case 0x1FFD: //$7FFD: Select 32k PRG @ $8000
+ prg_bank_32k = value;
+ prg_bank_32k &= prg_bank_mask_32k;
+ break;
+ case 0x1FFE:
+ chr_banks_4k[0] = value;
+ chr_banks_4k[0] &= chr_bank_mask_4k;
+ break;
+ case 0x1FFF:
+ chr_banks_4k[1] = value;
+ chr_banks_4k[1] &= chr_bank_mask_4k;
+ break;
+ default:
+ //apparently these regs are patched in over the WRAM..
+ base.WriteWRAM(addr,value);
+ break;
+ }
+ }
+
+ }
+
+ //AKA mapper 079
+ //historically, mapper 113 is confused with this, but I can't find any need for mapper 113. bootgod's db has nothing for mapper 113
+ class AVE_NINA_006 : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_32k, chr_bank_mask_8k;
+ bool mirror_control_enabled;
+
+ //state
+ int chr_bank_8k, prg_bank_32k;
public override void SyncState(Serializer ser)
- {
+ {
base.SyncState(ser);
- }
- }
-
- /*
- */
- class AVI_Misc : NES.NESBoardBase
- {
- public override bool Configure(NES.EDetectionOrigin origin)
- {
- //configure
- switch (Cart.board_type)
- {
- case "AVI_Misc":
- break;
- default:
- return false;
- }
- SetMirrorType(Cart.pad_h, Cart.pad_v);
- return true;
- }
+ ser.Sync("chr_bank_8k", ref chr_bank_8k);
+ ser.Sync("prg_bank_32k", ref prg_bank_32k);
+ }
- public override byte ReadPPU(int addr)
- {
- return base.ReadPPU(addr);
- }
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //configure
+ switch (Cart.board_type)
+ {
+ case "AVE-NINA-06": //Blackjack (U)
+ case "AVE-NINA-03": //F-15 City War (U)
+ case "AVE-MB-91": //Deathbots (U)
+ AssertPrg(32, 64); AssertChr(32, 64); AssertWram(0); AssertVram(0);
+ break;
+
+ default:
+ return false;
+ }
+
+ prg_bank_mask_32k = Cart.prg_size / 32 - 1;
+ chr_bank_mask_8k = Cart.chr_size / 8 - 1;
+
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ prg_bank_32k = 0;
+
+ return true;
+ }
+
+ //FCEUX responds to this for PRG writes as well.. ?
+ public override void WriteEXP(int addr, byte value)
+ {
+ addr &= 0x4100;
+ switch (addr)
+ {
+ case 0x0100: //$4100: [.CPP PCCC]
+ chr_bank_8k = (value & 7) | ((value >> 3) & 0x8);
+ chr_bank_8k = ((value >> 3) & 7);
+ prg_bank_32k &= prg_bank_mask_32k;
+ prg_bank_32k &= chr_bank_mask_8k;
+ if (mirror_control_enabled)
+ SetMirrorType(value.Bit(7) ? EMirrorType.Vertical : EMirrorType.Horizontal);
+ //NES.LogLine("chr={0:X2}, prg={1:X2}, with val={2:X2}", chr_reg, prg_reg, value);
+ break;
+ }
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ addr |= (prg_bank_32k << 15);
+ return ROM[addr];
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ addr |= (chr_bank_8k << 13);
+ return VROM[addr];
+ }
+ else return base.ReadPPU(addr);
+ }
+
+
+ }
- public override void SyncState(Serializer ser)
- {
- base.SyncState(ser);
- }
- }
}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BxROM.cs
new file mode 100644
index 0000000000..ad9474ad0e
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BxROM.cs
@@ -0,0 +1,55 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //AKA half of mapper 034 (the other half is AVE_NINA_001 which is entirely different..)
+ class BxROM : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_32k;
+
+ //state
+ int prg_bank_32k;
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("prg_bank_32k", ref prg_bank_32k);
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ switch (Cart.board_type)
+ {
+ case "IREM-BNROM": //Mashou (J).nes
+ case "NES-BNROM": //Deadly Towers (U)
+ AssertPrg(128); AssertChr(0); AssertWram(0); AssertVram(8);
+ break;
+
+ default:
+ return false;
+ }
+
+ prg_bank_mask_32k = Cart.prg_size / 32 - 1;
+
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ return true;
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ addr |= (prg_bank_32k << 15);
+ return ROM[addr];
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ value = HandleNormalPRGConflict(addr, value);
+ prg_bank_32k = value & prg_bank_mask_32k;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CNROM.cs
similarity index 88%
rename from BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs
rename to BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CNROM.cs
index e2c883d593..7cf5bf2dfa 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CxROM.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/CNROM.cs
@@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//Bump 'n' Jump
//Cybernoid
- public class CxROM : NES.NESBoardBase
+ public class CNROM : NES.NESBoardBase
{
//configuration
int prg_mask,chr_mask;
@@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
case "NES-CNROM": //adventure island
case "HVC-CNROM":
- AssertPrg(16, 32); AssertChr(16,32);
+ AssertPrg(16, 32); AssertChr(8,16,32);
break;
default:
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Camerica.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Camerica.cs
new file mode 100644
index 0000000000..fe4e369d5c
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Camerica.cs
@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //AKA mapper 071
+ //TODO - apparently this mapper contains good nes timing test cases
+ class Camerica_Mapper071 : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_16k;
+ bool mirror_control_enabled;
+
+ //state
+ IntBuffer prg_banks_16k = new IntBuffer(2);
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ prg_banks_16k.Dispose();
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("prg_banks_16k", ref prg_banks_16k);
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //configure
+ switch (Cart.board_type)
+ {
+ case "CAMERICA-ALGQ": //Linus Spacehead's Cosmic Crusade (U)
+ AssertPrg(128,256); AssertChr(0); AssertWram(0); AssertVram(8);
+ break;
+ case "CAMERICA-BF9093": //Big Nose Freaks Out (U)
+ AssertPrg(64,128,256); AssertChr(0); AssertWram(0); AssertVram(8);
+ break;
+ case "CAMERICA-BF9097": //Fire Hawk
+ AssertPrg(128); AssertChr(0); AssertWram(0); AssertVram(8);
+ mirror_control_enabled = true;
+ break;
+ default:
+ return false;
+ }
+
+ prg_bank_mask_16k = Cart.prg_size / 16 - 1;
+
+ prg_banks_16k[0] = 0x00;
+ prg_banks_16k[1] = 0xFF & prg_bank_mask_16k;
+
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ return true;
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ addr &= 0x7000;
+ switch (addr)
+ {
+ //$8000-9FFF: [...M ....] Mirroring (for Fire Hawk only!)
+ case 0x0000:
+ case 0x1000:
+ if(mirror_control_enabled)
+ SetMirrorType(value.Bit(4) ? EMirrorType.OneScreenB : EMirrorType.OneScreenA);
+ break;
+
+ //$C000-FFFF: PRG Select (16k @ $8000)
+ case 0x4000: case 0x5000:
+ case 0x6000: case 0x7000:
+ prg_banks_16k[0] = value & prg_bank_mask_16k;
+ break;
+ }
+ }
+
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_16k = addr >> 14;
+ int ofs = addr & ((1 << 14) - 1);
+ bank_16k = prg_banks_16k[bank_16k];
+ addr = (bank_16k << 14) | ofs;
+ return ROM[addr];
+ }
+ }
+
+ //AKA mapper 232
+ class Camerica_Mapper232 : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_16k;
+
+ //state
+ IntBuffer prg_banks_16k = new IntBuffer(2);
+ int prg_block, prg_page;
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ prg_banks_16k.Dispose();
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("prg_banks_16k", ref prg_banks_16k);
+ ser.Sync("prg_block", ref prg_block);
+ ser.Sync("prg_page", ref prg_page);
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //configure
+ switch (Cart.board_type)
+ {
+ case "CAMERICA-ALGQ": //Quattro Adventure (U)
+ case "CAMERICA-9096": //Quattro Arcade (U)
+ AssertPrg(256); AssertChr(0); AssertWram(0); AssertVram(8);
+ break;
+ default:
+ return false;
+ }
+
+ prg_bank_mask_16k = Cart.prg_size / 16 - 1;
+
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+ SyncPRG();
+
+
+ return true;
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ addr &= 0x4000;
+ switch (addr)
+ {
+ case 0x0000:
+ prg_block = (value>>3)&3;
+ SyncPRG();
+ break;
+ case 0x4000:
+ prg_page = value & 3;
+ SyncPRG();
+ break;
+ }
+ }
+
+ void SyncPRG()
+ {
+ prg_banks_16k[0] = (prg_block << 2) | prg_page;
+ prg_banks_16k[1] = (prg_block << 2) | 3;
+ prg_banks_16k[0] &= prg_bank_mask_16k;
+ prg_banks_16k[1] &= prg_bank_mask_16k;
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_16k = addr >> 14;
+ int ofs = addr & ((1 << 14) - 1);
+ bank_16k = prg_banks_16k[bank_16k];
+ addr = (bank_16k<<14) | ofs;
+ return ROM[addr];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs
index bb60db9989..e9dd9d8f86 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/IC_74x377.cs
@@ -4,7 +4,7 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
- //mapper 11
+ //mapper 011
//Crystal Mines
//Metal Fighter
@@ -22,6 +22,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
switch (Cart.board_type)
{
+ case "Discrete_74x377-FLEX":
+ break;
case "COLORDREAMS-74*377":
AssertPrg(32,64,128); AssertChr(16,32,64,128); AssertVram(0); AssertWram(0);
break;
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Jaleco-JF_11_14.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Jaleco-JF_11_14.cs
index 46666f9ed4..a4a0e87f7f 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Jaleco-JF_11_14.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Jaleco-JF_11_14.cs
@@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
* Life Span: October 1986 - April 1987
PCB Class: Jaleco-JF-11
Jaleco-JF-14
-iNES Mapper #140
+iNES Mapper 140
JF-11
PRG-ROM: 128kb
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper069.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper069.cs
new file mode 100644
index 0000000000..c35de4edc3
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper069.cs
@@ -0,0 +1,269 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //Mapper 069 is FME7
+ //or, Sunsoft-5, which is FME7 with additional sound hardware
+
+ class Sunsoft_5 : Sunsoft_FME7
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //configure
+ switch (Cart.board_type)
+ {
+ case "SUNSOFT-5A": //Batman (J)
+ AssertPrg(128); AssertChr(128); AssertWram(0); AssertVram(0); AssertBattery(false);
+ break;
+ case "SUNSOFT-5B": //Gimmick! (J)
+ AssertPrg(256); AssertChr(128); AssertWram(0); AssertVram(0); AssertBattery(false);
+ break;
+ default:
+ return false;
+ }
+
+ BaseConfigure();
+
+ return true;
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ //TODO - sound
+ base.WritePRG(addr, value);
+ }
+ }
+
+ class Sunsoft_FME7 : NES.NESBoardBase
+ {
+ //configuration
+ int prg_bank_mask_8k, chr_bank_mask_1k, wram_bank_mask_8k;
+
+ //state
+ int addr_reg;
+ ByteBuffer regs = new ByteBuffer(12);
+ ByteBuffer prg_banks_8k = new ByteBuffer(4);
+ int wram_bank;
+ bool wram_ram_selected, wram_ram_enabled;
+ ushort irq_counter;
+ bool irq_countdown, irq_enabled, irq_asserted;
+ int clock_counter;
+
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("addr_reg", ref addr_reg);
+ ser.Sync("regs", ref regs);
+ ser.Sync("prg_banks_8k", ref prg_banks_8k);
+ ser.Sync("wram_bank", ref wram_bank);
+ ser.Sync("wram_ram_selected", ref wram_ram_selected);
+ ser.Sync("wram_ram_enabled", ref wram_ram_enabled);
+ ser.Sync("irq_counter", ref irq_counter);
+ ser.Sync("irq_countdown", ref irq_countdown);
+ ser.Sync("irq_enabled", ref irq_enabled);
+ ser.Sync("irq_asserted", ref irq_asserted);
+ ser.Sync("clock_counter", ref clock_counter);
+ }
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ regs.Dispose();
+ prg_banks_8k.Dispose();
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //configure
+ switch (Cart.board_type)
+ {
+ case "MAPPER069-FLEX":
+ break;
+ case "SUNSOFT-FME-7": //Barcode World (J)
+ AssertPrg(128,256); AssertChr(256); AssertWram(0,8); AssertVram(0);
+ break;
+ case "NES-BTR": //Batman - Return of the Joker (U)
+ AssertPrg(128); AssertChr(256); AssertWram(8); AssertVram(0); AssertBattery(false);
+ break;
+ default:
+ return false;
+ }
+
+ BaseConfigure();
+
+ return true;
+ }
+
+ protected void BaseConfigure()
+ {
+ prg_bank_mask_8k = (Cart.prg_size / 8) - 1;
+ wram_bank_mask_8k = (Cart.wram_size / 8) - 1;
+ chr_bank_mask_1k = Cart.chr_size - 1;
+ prg_banks_8k[3] = 0xFF;
+ SetMirrorType(EMirrorType.Vertical);
+ }
+
+ void SyncPRG()
+ {
+ wram_ram_enabled = (regs[8] & 0x80) != 0;
+ wram_ram_selected = (regs[8]&0x40)!=0;
+ wram_bank = (byte)(regs[8] & 0x7F);
+ for(int i=0;i<3;i++)
+ {
+ prg_banks_8k[i] = regs[8 + i + 1];
+ }
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ addr &= 0xE000;
+ switch (addr)
+ {
+ case 0x0000: //$8000: [.... AAAA] Address for use with $A000
+ addr_reg = value & 0xF;
+ break;
+ case 0x2000: //$A000: [DDDD DDDD] Data port
+ switch(addr_reg)
+ {
+ case 0: case 1: case 2: case 3:
+ case 4: case 5: case 6: case 7:
+ regs[addr_reg] = value;
+ //NES.LogLine("cr set to {0},{1},{2},{3},{4},{5},{6},{7}", regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7]);
+ break;
+ case 8: case 9: case 0xA: case 0xB:
+ regs[addr_reg] = value;
+ //NES.LogLine("pr/wr set to {0},{1},{2},{3},~0xFF~", regs[8], regs[9], regs[10], regs[11]);
+ SyncPRG();
+ break;
+ case 0xC:
+ switch (value & 3)
+ {
+ case 0: SetMirrorType(EMirrorType.Vertical); break;
+ case 1: SetMirrorType(EMirrorType.Horizontal); break;
+ case 2: SetMirrorType(EMirrorType.OneScreenA); break;
+ case 3: SetMirrorType(EMirrorType.OneScreenB); break;
+ }
+ break;
+ case 0xD:
+ irq_countdown = value.Bit(7);
+ irq_enabled = value.Bit(0);
+ //if (value != 0) NES.LogLine("irq set to {0},{1} with value {2:x2}", irq_countdown, irq_enabled, value);
+ if (!irq_enabled) irq_asserted = false;
+ SyncIrq();
+ break;
+ case 0xE:
+ irq_counter &= 0xFF00;
+ irq_counter |= value;
+ //NES.LogLine("irq_counter set to {0:x4}", irq_counter);
+ break;
+ case 0xF:
+ irq_counter &= 0x00FF;
+ irq_counter |= (ushort)(value << 8);
+ //NES.LogLine("irq_counter set to {0:x4}", irq_counter);
+ break;
+ }
+ break;
+ }
+ }
+
+ void SyncIrq()
+ {
+ NES.irq_cart = irq_asserted;
+ }
+
+ void ClockCPU()
+ {
+ if (!irq_countdown) return;
+ irq_counter--;
+ if (irq_counter == 0xFFFF)
+ {
+ irq_asserted = true;
+ SyncIrq();
+ }
+ }
+
+ public override void ClockPPU()
+ {
+ clock_counter++;
+ if (clock_counter == 3)
+ {
+ ClockCPU();
+ clock_counter = 0;
+ }
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_8k = addr >> 13;
+ int ofs = addr & ((1<<13)-1);
+ bank_8k = prg_banks_8k[bank_8k];
+ bank_8k &= prg_bank_mask_8k;
+ addr = (bank_8k << 13) | ofs;
+ return ROM[addr];
+ }
+
+ int CalcWRAMAddress(int addr, int bank_mask_8k)
+ {
+ int ofs = addr & ((1 << 13) - 1);
+ int bank_8k = wram_bank;
+ bank_8k &= bank_mask_8k;
+ addr = (bank_8k << 13) | ofs;
+ return addr;
+ }
+
+ int CalcPPUAddress(int addr)
+ {
+ int bank_1k = addr >> 10;
+ int ofs = addr & ((1 << 10) - 1);
+ bank_1k = regs[bank_1k];
+ bank_1k &= chr_bank_mask_1k;
+ return (bank_1k<<10) | ofs;
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ return VROM[CalcPPUAddress(addr)];
+ else return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000)
+ { }
+ else base.WritePPU(addr, value);
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ if (!wram_ram_selected)
+ {
+ addr = CalcWRAMAddress(addr, prg_bank_mask_8k);
+ return ROM[addr];
+ }
+ else if (!wram_ram_enabled)
+ return 0xFF; //empty bus
+ else
+ {
+ addr = CalcWRAMAddress(addr, wram_bank_mask_8k);
+ return WRAM[addr];
+ }
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ if (!wram_ram_selected) return;
+ else if (!wram_ram_enabled)
+ return; //empty bus
+ else
+ {
+ addr = CalcWRAMAddress(addr, wram_bank_mask_8k);
+ WRAM[addr] = value;
+ }
+ }
+
+ }
+}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper242.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper242.cs
index 6a008661db..77d28176d2 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper242.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper242.cs
@@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
/*
PCB Class: Unknown
-iNES Mapper #242
+iNES Mapper 242
PRG-ROM: 32KB
PRG-RAM: None
CHR-ROM: 16KB
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft1.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft1.cs
index 438e8b3b61..6bcb7d3500 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft1.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft1.cs
@@ -7,7 +7,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
/*
* Life Span: April 1986 - July 1986
PCB Class: SUNSOFT-1
-iNES Mapper #184
+iNES Mapper 184
PRG-ROM: 32KB
PRG-RAM: None
CHR-ROM: 16KB
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
index f6d7429282..ea5c20fb2a 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
@@ -16,8 +16,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
static readonly bool USE_DATABASE = true;
//Game issues:
- //Dragon warrior 3/4 certainly need some additional work done to the mapper wiring to get to the super big PRG (probably SXROM too)
//Tecmo superbowl - wobbly "NFL" logo at the end of a game (even skipped game) [zeromus cant test this; how do you skip game?]
+ //Bigfoot (U) seems not to work
+ //Bill and ted's excellent video game adventure (U) doesnt work until more detailed emulation exists (check 001.txt)
//---
//Game issues for tester to check off.
@@ -381,6 +382,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
Console.WriteLine("headerless rom hash: {0}", hash_sha1);
Console.WriteLine("headerless rom hash: {0}", hash_md5);
+ Type boardType = null;
CartInfo choice = null;
if(USE_DATABASE)
choice = IdentifyFromBootGodDB(hash_sha1);
@@ -403,8 +405,28 @@ namespace BizHawk.Emulation.Consoles.Nintendo
string iNES_board = iNESBoardDetector.Detect(choice);
if (iNES_board == null)
throw new Exception("couldnt identify NES rom");
- Console.WriteLine("Chose board from iNES heuristics: " + iNES_board);
choice.board_type = iNES_board;
+
+ //try spinning up a board with 8K wram and with 0K wram to see if one answers
+ try
+ {
+ boardType = FindBoard(choice, origin);
+ }
+ catch { }
+ if (boardType == null)
+ {
+ if (choice.wram_size == 8) choice.wram_size = 0;
+ else if (choice.wram_size == 0) choice.wram_size = 8;
+ try
+ {
+ boardType = FindBoard(choice, origin);
+ }
+ catch { }
+ if (boardType != null)
+ Console.WriteLine("Ambiguous iNES wram size resolved as {0}k", choice.wram_size);
+ }
+
+ Console.WriteLine("Chose board from iNES heuristics: " + iNES_board);
choice.game.name = game.Name;
origin = EDetectionOrigin.INES;
}
@@ -425,7 +447,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
game_name = choice.game.name;
//find a INESBoard to handle this
- Type boardType = null;
boardType = FindBoard(choice, origin);
if (boardType == null)
throw new Exception("No class implements the necessary board type: " + choice.board_type);
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/iNES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/iNES.cs
index 2cfcc54f81..c9e444ef27 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/iNES.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/iNES.cs
@@ -91,13 +91,20 @@ static string ClassifyTable = @"
4 512 128 8 0 NES-TKROM; Pool of radiance (J)
7 128 0 8 0 NES-ANROM; marble madness
7 256 0 8 8 NES-AOROM; battletoads
+11 -1 -1 -1 -1 Discrete_74x377-FLEX; Bible Adventures (U) ?
13 32 0 8 16 NES-CPROM; videomation
65 -1 -1 -1 -1 IREM-H3001-FLEX; //Ai Sensei No Oshiete - Watashi No Hoshi (J).nes
66 64 16 8 0 NES-MHROM; super mario bros / duck hunt
66 128 32 8 0 NES-GNROM; gumshoe
68 128 256 8 0 SUNSOFT-4; After Burner 2 (J)
+69 -1 -1 -1 -1 MAPPER069-FLEX; Gimmick! (J)
+71 -1 -1 -1 -1 CAMERICA-BF9093; Micro Machines (U)
+79 -1 -1 -1 -1 AVE-NINA-06; Blackjack (U)
+113 -1 -1 -1 -1 AVE-NINA-06; ???
+232 -1 -1 -1 -1 CAMERICA-ALGQ; Quattro Adventure
";
}
+//;232 -1 -1 -1 -1 Camerica_BF9096-FLEX; Quattro Adventure
unsafe struct iNES_HEADER
{
diff --git a/BizHawk.MultiClient/output/gamedb.txt b/BizHawk.MultiClient/output/gamedb.txt
index 0840c6c7fb..b60c244add 100644
--- a/BizHawk.MultiClient/output/gamedb.txt
+++ b/BizHawk.MultiClient/output/gamedb.txt
@@ -2284,6 +2284,7 @@ sha1:192C543866F1037276D2778046ABEDCA84868E26 Bio Senshi Dan - Increaser To No
sha1:E80FF0B707B0D675FDBEF474E3FDB1A83E2B7C44 Mississippi Satsujin Jiken (J) NES board=JALECO-JF-11;PRG=128;CHR=32;PAD_H=1
sha1:8A5FD1061ADACDEABF422A2D2E555FF70749AE7C Mississippi Satsujin Jiken (Alt) (J) NES board=GXROM_HACKY;PRG=128;CHR=32;PAD_H=1
sha1:8C7D33753649A2BAF2EAAF8D5FFC2AE8E9316A13 Akira (J) NES board=TAITO-TC0190FMC;PRG=128;CHR=256;WRAM=0
+sha1:0AE47BD83202A5A2235B0BC16278F56D66038AB5 Deathbots (U) NES board=AVE-NINA-06;PRG=64;CHR=64;PAD_H=1;PAD_V=0
;these roms are in goodNES but theyre junk
sha1:4D6117577CE301BB987C5C32FEEF7B132A21B046 Afro Man (Mega Man 3 Hack) (UNL) NES board=TXROM-HOMEBREW;PRG=256;CHR=128;WRAM=8