diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 7734af1173..1ca6b88156 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -338,6 +338,7 @@
+
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs
index 12a15c7311..5d23863f4b 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs
@@ -12,7 +12,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{
//state
int reg_addr;
- bool chr_mode, prg_mode;
+ public bool get_chr_mode { get { return chr_mode; } } // one of the pirate mappers needs this
+ bool chr_mode;
+ bool prg_mode;
public ByteBuffer regs = new ByteBuffer(8);
public byte mirror;
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/RexSoftSL1632.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/RexSoftSL1632.cs
new file mode 100644
index 0000000000..919f3555f6
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/RexSoftSL1632.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.NES
+{
+ // p-p-p-p-pirate?
+ // http://svn.opennestopia.staulkor.com/Nestopia/core/board/NstBoardRexSoftSl1632.cpp
+ public class RexSoftSL1632 : MMC3Board_Base
+ {
+ // state
+ byte exmode;
+ int[] exprg = new int[4];
+ int[] exchr = new int[8];
+ byte exnmt;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ switch (Cart.board_type)
+ {
+ case "UNIF_UNL-SL1632":
+ break;
+ default:
+ return false;
+ }
+ BaseSetup();
+ exprg[3] = prg_mask;
+ exprg[2] = prg_mask - 1;
+ return true;
+ }
+
+ public override void SyncState(BizHawk.Common.Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("exmode", ref exmode);
+ ser.Sync("exprg", ref exprg, false);
+ ser.Sync("exchr", ref exchr, false);
+ ser.Sync("exnmt", ref exnmt);
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ if (exmode.Bit(1))
+ {
+ return base.ReadPRG(addr);
+ }
+ else
+ {
+ int b = addr >> 13;
+ b = exprg[b];
+ b &= prg_mask;
+ return ROM[addr & 0x1fff | b << 13];
+ }
+ }
+
+ void SinkMirror()
+ {
+ SetMirrorType(exnmt.Bit(0) ? EMirrorType.Vertical : EMirrorType.Horizontal);
+ }
+
+ readonly static byte[] modes = { 5, 5, 3, 1 };
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int bank;
+ if (exmode.Bit(1))
+ {
+ bank = Get_CHRBank_1K(addr);
+ int tmp = mmc3.get_chr_mode ? 2 : 0;
+ bank |= exmode << modes[addr >> 11 ^ tmp] & 0x100;
+ }
+ else
+ {
+ bank = exchr[addr >> 10];
+ }
+ bank &= chr_mask;
+ return VROM[addr & 0x3ff | bank << 10];
+ }
+ else
+ {
+ return base.ReadPPU(addr);
+ }
+ }
+
+
+ // this is stupid as hell
+ public override void WritePRG(int addr, byte value)
+ {
+ Console.WriteLine("{0:x4}:{1:x2}", addr, value);
+
+ if ((addr & 0x2131) == 0x2131)
+ {
+ exmode = value;
+ if (!exmode.Bit(1))
+ {
+ SinkMirror();
+ }
+ }
+
+ if (exmode.Bit(1))
+ {
+ switch (addr & 0x6001)
+ {
+ case 0x0000: base.WritePRG(0x0000, value); break;
+ case 0x0001: base.WritePRG(0x0001, value); break;
+ case 0x2000: SinkMirror(); break;
+ case 0x2001: base.WritePRG(0x2001, value); break;
+ case 0x4000: base.WritePRG(0x4000, value); break;
+ case 0x4001: base.WritePRG(0x4001, value); break;
+ case 0x6000: base.WritePRG(0x6000, value); break;
+ case 0x6001: base.WritePRG(0x6001, value); break;
+
+ }
+ }
+ else if (addr >= 3000 && addr <= 0x6003)
+ {
+ int offset = addr << 2 & 4;
+ addr = ((((addr & 0x2) | addr >> 10) >> 1) + 2) & 0x7;
+ exchr[addr] = (exchr[addr] & 0xf0 >> offset) | ((value & 0x0f) >> offset);
+ // sync chr
+ }
+ else
+ {
+ switch (addr & 0x7003)
+ {
+ case 0x0000: exprg[0] = value; break;
+ case 0x1000: exnmt = value; SinkMirror(); break;
+ case 0x2000: exprg[1] = value; break;
+ }
+ }
+ }
+
+
+
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/SxROM.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/SxROM.cs
index 073353eb0c..d62b70753f 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/SxROM.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/SxROM.cs
@@ -532,6 +532,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
Cart.vram_size = 8;
Cart.wram_size = 8;
Cart.wram_battery = true; // all SUROM boards had batteries
+ Console.WriteLine("Guessing SUROM for 512KiB PRG ROM");
break;
case "NES-SUROM": //dragon warrior 4
case "HVC-SUROM":