diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 71b27acb6c..9d899f7fb8 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -615,6 +615,7 @@
+
@@ -626,6 +627,7 @@
+
@@ -655,6 +657,8 @@
+
+
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs
index 52262fb360..307d7e2eec 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs
@@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
//state
int prg, chr;
- bool is173;
+ bool is172, is173;
public override bool Configure(NES.EDetectionOrigin origin)
{
@@ -22,6 +22,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
case "MAPPER132":
case "UNIF_UNL-22211":
break;
+ case "MAPPER172":
+ is172 = true;
+ break;
case "MAPPER173":
is173 = true;
break;
@@ -35,20 +38,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return true;
}
- public void sync()
+ public void sync(byte value)
{
+ prg=reg[2]>>2;
+ prg &= prg_mask;
- prg=reg[2]>>2;
- prg &= prg_mask;
+ if (is172)
+ {
+ chr = (((value ^ reg[2]) >> 3) & 2) | (((value ^ reg[2]) >> 5) & 1);
+ }
+ else
+ {
chr = (reg[2] & 0x3);
- chr &= chr_mask;
-
+ }
+ chr &= chr_mask;
}
public override void WritePRG(int addr, byte value)
{
- sync();
+ sync(value);
}
public override void WriteEXP(int addr, byte value)
@@ -80,7 +89,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{
return VROM[addr + (chr << 13)];
}
- else return base.ReadPPU(addr);
+
+ return base.ReadPPU(addr);
}
public override void SyncState(Serializer ser)
@@ -88,6 +98,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
base.SyncState(ser);
ser.Sync("chr", ref chr);
ser.Sync("prg", ref prg);
+ ser.Sync("is172", ref is172);
ser.Sync("is173", ref is173);
ser.Sync("reg", ref reg);
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs
new file mode 100644
index 0000000000..a1c3ecf361
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs
@@ -0,0 +1,121 @@
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.NES
+{
+ public sealed class Mapper142 : NES.NESBoardBase
+ {
+ private ByteBuffer reg = new ByteBuffer(8);
+ private byte cmd;
+ private int lastBank;
+
+ private bool isirqused = false;
+ private byte IRQa = 0;
+ private int IRQCount = 0;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ switch (Cart.board_type)
+ {
+ case "MAPPER142":
+ case "UNIF_UNL-KS7032":
+ break;
+ default:
+ return false;
+ }
+
+ lastBank = Cart.prg_size / 8 - 1;
+
+ return true;
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ return ROM[(reg[4] << 13) + (addr & 0x1FFF)];
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ if (addr < 0x2000) { return ROM[(reg[1] << 13) + (addr & 0x1FFF)]; }
+ if (addr < 0x4000) { return ROM[(reg[2] << 13) + (addr & 0x1FFF)]; }
+ if (addr < 0x6000) { return ROM[(reg[3] << 13) + (addr & 0x1FFF)]; }
+
+ return ROM[(lastBank << 13) + (addr & 0x1FFF)];
+ }
+
+ public override void WriteEXP(int addr, byte value)
+ {
+ Write(addr + 0x4000, value);
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ Write(addr + 0x6000, value);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ Write(addr + 0x8000, value);
+ }
+
+ private void IRQHook(int a)
+ {
+ if (IRQa > 0)
+ {
+ IRQCount += a;
+ if (IRQCount >= 0xFFFF)
+ {
+ IRQa = 0;
+ IRQCount = 0;
+
+ IRQSignal = true;
+ }
+ }
+ }
+
+ public override void ClockPPU()
+ {
+ IRQHook(1);
+ }
+
+ private void Write(int addr, byte value)
+ {
+ switch (addr & 0xF000)
+ {
+ case 0x8000:
+ IRQSignal = false;
+ IRQCount = (IRQCount & 0x000F) | (value & 0x0F);
+ isirqused = true;
+ break;
+ case 0x9000:
+ IRQSignal = false;
+ IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4);
+ isirqused = true;
+ break;
+ case 0xA000:
+ IRQSignal = false;
+ IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8);
+ isirqused = true;
+ break;
+ case 0xB000:
+ IRQSignal = false;
+ IRQCount = (IRQCount & 0xF000) | (value << 12);
+ isirqused = true;
+ break;
+ case 0xC000:
+ if (isirqused)
+ {
+ IRQSignal = false;
+ IRQa = 1;
+ }
+ break;
+
+ case 0xE000:
+ cmd = (byte)(value & 7);
+ break;
+ case 0xF000:
+ reg[cmd] = value;
+ break;
+ }
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs
new file mode 100644
index 0000000000..c035458b65
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs
@@ -0,0 +1,124 @@
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.NES
+{
+ // Adpated from FCEUX src
+ public sealed class Mapper183 : NES.NESBoardBase
+ {
+ private ByteBuffer prg = new ByteBuffer(4);
+ private ByteBuffer chr = new ByteBuffer(8);
+
+ private int prg_bank_mask_8k, chr_bank_mask_1k;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ switch (Cart.board_type)
+ {
+ case "MAPPER183":
+ break;
+ default:
+ return false;
+ }
+
+ prg_bank_mask_8k = Cart.prg_size / 8 - 1;
+ chr_bank_mask_1k = Cart.chr_size - 1;
+
+ return true;
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("prg", ref prg);
+ ser.Sync("chr", ref chr);
+ }
+
+ private void SetMirroring(int mirr)
+ {
+ switch (mirr & 3)
+ {
+ case 0: SetMirrorType(EMirrorType.Vertical); break;
+ case 1: SetMirrorType(EMirrorType.Horizontal); break;
+ case 2: SetMirrorType(EMirrorType.OneScreenA); break;
+ case 3: SetMirrorType(EMirrorType.Vertical); break;
+ }
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ WriteReg(addr + 0x6000, value);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ WriteReg(addr + 0x8000, value);
+ }
+
+ private void WriteReg(int addr, byte value)
+ {
+ if ((addr & 0xF800) == 0x6800)
+ {
+ prg[3] = (byte)(addr & 0x3F);
+ }
+ else if (((addr & 0xF80C) >= 0xB000) && ((addr & 0xF80C) <= 0xE00C))
+ {
+ int index = (((addr >> 11) - 6) | (addr >> 3)) & 7;
+ chr[index] = (byte)((chr[index] & (0xF0 >> (addr & 4))) | ((value & 0x0F) << (addr & 4)));
+ }
+ else switch (addr & 0xF80C)
+ {
+ case 0x8800: prg[0] = value; break;
+ case 0xA800: prg[1] = value; break;
+ case 0xA000: prg[2] = value; break;
+ case 0x9800: SetMirroring(value & 3); break;
+
+ // TODO: IRQ
+ case 0xF000: break;
+ case 0xF004: break;
+ case 0xF008: break;
+ case 0xF00C: break;
+ }
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int x = (addr >> 10) & 7;
+ int bank = (chr[x] & chr_bank_mask_1k) << 10;
+ return VROM[bank + (addr & 0x3FF)]; // TODO
+ }
+
+ return base.ReadPPU(addr);
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ return ROM[((prg[3] & prg_bank_mask_8k)) << 13 + (addr & 0x1FFF)];
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_8k;
+ if (addr < 0x2000) // 0x8000
+ {
+ bank_8k = prg[0] & prg_bank_mask_8k;
+
+ }
+ else if (addr < 0x4000) // 0xA000
+ {
+ bank_8k = prg[1] & prg_bank_mask_8k;
+ }
+ else if (addr < 0x6000) // 0xC000
+ {
+ bank_8k = prg[2] & prg_bank_mask_8k;
+ }
+ else
+ {
+ bank_8k = prg_bank_mask_8k;
+ }
+
+ return ROM[(bank_8k << 13) + (addr & 0x1FFF)];
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs
new file mode 100644
index 0000000000..ace7642525
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs
@@ -0,0 +1,138 @@
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.NES
+{
+ // Adapted from FCEUX src
+ public sealed class Mapper252 : NES.NESBoardBase
+ {
+ private ByteBuffer preg = new ByteBuffer(2);
+ private ByteBuffer creg = new ByteBuffer(8);
+
+ private int prg_bank_mask_8k, chr_bank_mask_1k;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "MAPPER252":
+ break;
+ default:
+ return false;
+ }
+
+ prg_bank_mask_8k = Cart.prg_size / 8 - 1;
+ chr_bank_mask_1k = Cart.chr_size - 1;
+
+ return true;
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("preg", ref preg);
+ ser.Sync("creg", ref creg);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ WriteReg((addr + 0x8000), value);
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ WriteReg((addr + 0x6000), value);
+ }
+
+ public void WriteReg(int addr, byte value)
+ {
+ if (addr >= 0xB000 && addr < 0xF000)
+ {
+ var ind = ((((addr & 8) | (addr >> 8)) >> 3) + 2) & 7;
+ var sar = addr & 4;
+ creg[ind] = (byte)((creg[ind] & (0xF0 >> sar)) | ((value & 0x0F) << sar));
+ }
+ else
+ {
+ switch (addr & 0xF00C)
+ {
+ case 0x8000:
+ case 0x8004:
+ case 0x8008:
+ case 0x800C:
+ preg[0] = value;
+ break;
+
+ case 0xA000:
+ case 0xA004:
+ case 0xA008:
+ case 0xA00C:
+ preg[1] = value;
+ break;
+
+ // TODO IRQ
+ case 0xF000: break;
+ case 0xF004: break;
+ case 0xF008: break;
+ }
+ }
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ return ROM[addr];
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank;
+
+ if (addr < 0x2000)
+ {
+ bank = preg[0] & prg_bank_mask_8k;
+ }
+ else if (addr < 0x4000)
+ {
+ bank = preg[1] & prg_bank_mask_8k;
+ }
+ else if (addr < 0x6000)
+ {
+ bank = prg_bank_mask_8k - 1;
+ }
+ else
+ {
+ bank = prg_bank_mask_8k;
+ }
+
+
+ return ROM[(bank << 13) + (addr & 0x1FFF)];
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int x = (addr >> 10) & 7;
+
+ int bank;
+ if (creg[x] == 6 || creg[x] == 7)
+ {
+ bank = creg[x] & 1;
+ }
+ else
+ {
+ bank = (creg[x] & chr_bank_mask_1k) << 10;
+ }
+
+ if (addr == 0x400)
+ {
+ int zzz = 0;
+ }
+
+ return VROM[bank + (addr & 0x3FF)];
+ }
+
+ return base.ReadPPU(addr);
+ }
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs
new file mode 100644
index 0000000000..fb476ec808
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs
@@ -0,0 +1,128 @@
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Nintendo.NES
+{
+ public class Mapper253 : NES.NESBoardBase
+ {
+ private ByteBuffer prg = new ByteBuffer(2);
+ private ByteBuffer chrlo = new ByteBuffer(8);
+ private ByteBuffer chrhi = new ByteBuffer(8);
+ private bool vlock;
+
+ private int prg_bank_mask_8k, chr_bank_mask_1k;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "MAPPER253":
+ break;
+ default:
+ return false;
+ }
+
+ prg_bank_mask_8k = Cart.prg_size / 8 - 1;
+ chr_bank_mask_1k = Cart.chr_size - 1;
+
+ return true;
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("preg", ref prg);
+ ser.Sync("chrlo", ref chrlo);
+ ser.Sync("chrhi", ref chrhi);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ addr += 0x8000;
+ if ((addr >= 0xB000) && (addr <= 0xE00C))
+ {
+ var ind = ((((addr & 8) | (addr >> 8)) >> 3) + 2) & 7;
+ var sar = addr & 4;
+ var clo = (chrlo[ind] & (0xF0 >> sar)) | ((value & 0x0F) << sar);
+ chrlo[ind] = (byte)clo;
+ if (ind == 0)
+ {
+ if (clo == 0xc8)
+ vlock = false;
+ else if (clo == 0x88)
+ vlock = true;
+ }
+ if (sar > 0)
+ chrhi[ind] = (byte)(value >> 4);
+ }
+ else
+ {
+ switch (addr)
+ {
+ case 0x8010: prg[0] = value; break;
+ case 0xA010: prg[1] = value; break;
+ case 0x9400: SetMirroring(value); break;
+
+ // TODO: IRQ
+ case 0xF000: break;
+ case 0xF004: break;
+ case 0xF008: break;
+ }
+ }
+ }
+
+ private void SetMirroring(int mirr)
+ {
+ switch(mirr & 3)
+ {
+ case 0: SetMirrorType(EMirrorType.Vertical); break;
+ case 1: SetMirrorType(EMirrorType.Horizontal); break;
+ case 2: SetMirrorType(EMirrorType.OneScreenA); break;
+ case 3: SetMirrorType(EMirrorType.Vertical); break;
+ }
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ return ROM[addr];
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank;
+
+ if (addr < 0x2000)
+ {
+ bank = prg[0];
+ }
+ else if (addr < 0x4000)
+ {
+ bank = prg[1];
+ }
+ else if (addr < 0x6000)
+ {
+ bank = prg_bank_mask_8k - 1;
+ }
+ else
+ {
+ bank = prg_bank_mask_8k;
+ }
+
+
+ return ROM[(bank << 13) + (addr & 0x1FFF)];
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int x = (addr >> 10) & 7;
+ var chr = chrlo[x] | (chrhi[x] << 8);
+ int bank = (chr & chr_bank_mask_1k) << 10;
+ return VROM[bank + (addr & 0x3FF)];
+ }
+
+ return base.ReadPPU(addr);
+ }
+ }
+}