diff --git a/source/fceux/boards/01-222.cpp b/source/fceux/boards/01-222.cpp
new file mode 100644
index 0000000..414d62d
--- /dev/null
+++ b/source/fceux/boards/01-222.cpp
@@ -0,0 +1,111 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * TXC mappers, originally much complex banksitching
+ *
+ * P/N PRG MAP, UNIF Name
+ * 01-22111-000 (05-00002-010) (132, 22211) - MGC-001 Qi Wang
+ * 01-22110-000 (52S ) - MGC-002 2-in-1 Gun
+ * 01-22111-100 (02-00002-010) (173 ) - MGC-008 Mahjong Block
+ * (079 ) - MGC-012 Poke Block
+ * 01-22110-200 (05-00002-010) (036 ) - MGC-014 Strike Wolf
+ * 01-22000-400 (05-00002-010) (036 ) - MGC-015 Policeman
+ * 01-22017-000 (05-PT017-080) (189 ) - MGC-017 Thunder Warrior
+ * 01-11160-000 (04-02310-000) ( , 11160) - MGC-023 6-in-1
+ * 01-22026-000 (05-04010-090) ( ) - MGC-026 4-in-1
+ * 01-22270-000 (05-00002-010) (132, 22211) - MGC-xxx Creatom
+ * 01-22200-400 (------------) (079 ) - ET.03 F-15 City War
+ * (172 ) - 1991 Du Ma Racing
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[4], cmd, is172, is173;
+static SFORMAT StateRegs[] =
+{
+ { reg, 4, "REGS" },
+ { &cmd, 1, "CMD" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, (reg[2] >> 2) & 1);
+ if (is172)
+ setchr8((((cmd ^ reg[2]) >> 3) & 2) | (((cmd ^ reg[2]) >> 5) & 1)); // 1991 DU MA Racing probably CHR bank sequence is WRONG, so it is possible to
+ // rearrange CHR banks for normal UNIF board and mapper 172 is unneccessary
+ else
+ setchr8(reg[2] & 3);
+}
+
+static DECLFW(UNL22211WriteLo) {
+// FCEU_printf("bs %04x %02x\n",A,V);
+ reg[A & 3] = V;
+}
+
+static DECLFW(UNL22211WriteHi) {
+// FCEU_printf("bs %04x %02x\n",A,V);
+ cmd = V;
+ Sync();
+}
+
+static DECLFR(UNL22211ReadLo) {
+ return (reg[1] ^ reg[2]) | (is173 ? 0x01 : 0x40);
+// if(reg[3])
+// return reg[2];
+// else
+// return X.DB;
+}
+
+static void UNL22211Power(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetReadHandler(0x4100, 0x4100, UNL22211ReadLo);
+ SetWriteHandler(0x4100, 0x4103, UNL22211WriteLo);
+ SetWriteHandler(0x8000, 0xFFFF, UNL22211WriteHi);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void UNL22211_Init(CartInfo *info) {
+ is172 = 0;
+ is173 = 0;
+ info->Power = UNL22211Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+void Mapper172_Init(CartInfo *info) {
+ is172 = 1;
+ is173 = 0;
+ info->Power = UNL22211Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+void Mapper173_Init(CartInfo *info) {
+ is172 = 0;
+ is173 = 1;
+ info->Power = UNL22211Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/09-034a.cpp b/source/fceux/boards/09-034a.cpp
new file mode 100644
index 0000000..7847cd9
--- /dev/null
+++ b/source/fceux/boards/09-034a.cpp
@@ -0,0 +1,97 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * FDS Conversions
+ *
+ * Super Mario Bros 2j (Alt Full) is a BAD incomplete dump, should be mapper 43
+ *
+ * Both Voleyball and Zanac by Whirlind Manu shares the same PCB, but with
+ * some differences: Voleyball has 8K CHR ROM and 8K ROM at 6000K, Zanac
+ * have 8K CHR RAM and banked 16K ROM mapper at 6000 as two 8K banks.
+*
+ * Super Mario Bros 2j (Alt Small) uses additionally IRQ timer to drive framerate
+ *
+ * PCB for this mapper is "09-034A"
+ */
+
+#include "mapinc.h"
+
+static uint8 prg;
+static uint32 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQCount, 4, "IRQC" },
+ { &IRQa, 4, "IRQA" },
+ { &prg, 1, "PRG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8r(1, 0x6000, prg);
+ setprg32(0x8000, 0);
+ setchr8(0);
+}
+
+static DECLFW(UNLSMB2JWrite1) {
+ prg = V & 1;
+ Sync();
+}
+
+static DECLFW(UNLSMB2JWrite2) {
+ IRQa = V & 1;
+ IRQCount = 0;
+ X6502_IRQEnd(FCEU_IQEXT);
+}
+
+static DECLFR(UNLSMB2JRead) {
+ return 0xFF;
+}
+
+static void UNLSMB2JPower(void) {
+ prg = 0;
+ Sync();
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetReadHandler(0x4042, 0x4055, UNLSMB2JRead);
+ SetWriteHandler(0x4068, 0x4068, UNLSMB2JWrite2);
+ SetWriteHandler(0x4027, 0x4027, UNLSMB2JWrite1);
+}
+
+static void UNLSMB2JIRQHook(int a) {
+ if (IRQa)
+ {
+ if (IRQCount < 5750) // completely by guess
+ IRQCount += a;
+ else {
+ IRQa = 0;
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void UNLSMB2J_Init(CartInfo *info) {
+ info->Power = UNLSMB2JPower;
+ MapIRQHook = UNLSMB2JIRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/103.cpp b/source/fceux/boards/103.cpp
new file mode 100644
index 0000000..16a622c
--- /dev/null
+++ b/source/fceux/boards/103.cpp
@@ -0,0 +1,112 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg0, reg1, reg2;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { ®0, 1, "REG0" },
+ { ®1, 1, "REG1" },
+ { ®2, 1, "REG2" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8(0);
+ setprg8(0x8000, 0xc);
+ setprg8(0xe000, 0xf);
+ if (reg2 & 0x10) {
+ setprg8(0x6000, reg0);
+ setprg8(0xa000, 0xd);
+ setprg8(0xc000, 0xe);
+ } else {
+ setprg8r(0x10, 0x6000, 0);
+ setprg4(0xa000, (0xd << 1));
+ setprg2(0xb000, (0xd << 2) + 2);
+ setprg2r(0x10, 0xb800, 4);
+ setprg2r(0x10, 0xc000, 5);
+ setprg2r(0x10, 0xc800, 6);
+ setprg2r(0x10, 0xd000, 7);
+ setprg2(0xd800, (0xe << 2) + 3);
+ }
+ setmirror(reg1 ^ 1);
+}
+
+static DECLFW(M103RamWrite0) {
+ WRAM[A & 0x1FFF] = V;
+}
+
+static DECLFW(M103RamWrite1) {
+ WRAM[0x2000 + ((A - 0xB800) & 0x1FFF)] = V;
+}
+
+static DECLFW(M103Write0) {
+ reg0 = V & 0xf;
+ Sync();
+}
+
+static DECLFW(M103Write1) {
+ reg1 = (V >> 3) & 1;
+ Sync();
+}
+
+static DECLFW(M103Write2) {
+ reg2 = V;
+ Sync();
+}
+
+static void M103Power(void) {
+ reg0 = reg1 = 0; reg2 = 0;
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, M103RamWrite0);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0xB800, 0xD7FF, M103RamWrite1);
+ SetWriteHandler(0x8000, 0x8FFF, M103Write0);
+ SetWriteHandler(0xE000, 0xEFFF, M103Write1);
+ SetWriteHandler(0xF000, 0xFFFF, M103Write2);
+}
+
+static void M103Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper103_Init(CartInfo *info) {
+ info->Power = M103Power;
+ info->Close = M103Close;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 16384;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/106.cpp b/source/fceux/boards/106.cpp
new file mode 100644
index 0000000..e427d29
--- /dev/null
+++ b/source/fceux/boards/106.cpp
@@ -0,0 +1,108 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[16], IRQa;
+static uint32 IRQCount;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 4, "IRQC" },
+ { reg, 16, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr1(0x0000, reg[0] & 0xfe);
+ setchr1(0x0400, reg[1] | 1);
+ setchr1(0x0800, reg[2] & 0xfe);
+ setchr1(0x0c00, reg[3] | 1);
+ setchr1(0x1000, reg[4]);
+ setchr1(0x1400, reg[5]);
+ setchr1(0x1800, reg[6]);
+ setchr1(0x1c00, reg[7]);
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000, (reg[0x8] & 0xf) | 0x10);
+ setprg8(0xA000, (reg[0x9] & 0x1f));
+ setprg8(0xC000, (reg[0xa] & 0x1f));
+ setprg8(0xE000, (reg[0xb] & 0xf) | 0x10);
+ setmirror((reg[0xc] & 1) ^ 1);
+}
+
+static DECLFW(M106Write) {
+ A &= 0xF;
+ switch (A) {
+ case 0xD: IRQa = 0; IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xE: IRQCount = (IRQCount & 0xFF00) | V; break;
+ case 0xF: IRQCount = (IRQCount & 0x00FF) | (V << 8); IRQa = 1; break;
+ default: reg[A] = V; Sync(); break;
+ }
+}
+
+static void M106Power(void) {
+ reg[8] = reg[9] = reg[0xa] = reg[0xb] = -1;
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetWriteHandler(0x8000, 0xFFFF, M106Write);
+}
+
+static void M106Reset(void) {
+}
+
+static void M106Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+void M106CpuHook(int a) {
+ if (IRQa) {
+ IRQCount += a;
+ if (IRQCount > 0x10000) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQa = 0;
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper106_Init(CartInfo *info) {
+ info->Reset = M106Reset;
+ info->Power = M106Power;
+ info->Close = M106Close;
+ MapIRQHook = M106CpuHook;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/108.cpp b/source/fceux/boards/108.cpp
new file mode 100644
index 0000000..4c463f9
--- /dev/null
+++ b/source/fceux/boards/108.cpp
@@ -0,0 +1,58 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x6000, reg);
+ setprg32(0x8000, ~0);
+ setchr8(0);
+}
+
+static DECLFW(M108Write) {
+ reg = V;
+ Sync();
+}
+
+static void M108Power(void) {
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0x8FFF, M108Write); // regular 108
+ SetWriteHandler(0xF000, 0xFFFF, M108Write); // simplified Kaiser BB Hack
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper108_Init(CartInfo *info) {
+ info->Power = M108Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/112.cpp b/source/fceux/boards/112.cpp
new file mode 100644
index 0000000..f0ee7ac
--- /dev/null
+++ b/source/fceux/boards/112.cpp
@@ -0,0 +1,90 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NTDEC, ASDER games
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[8];
+static uint8 mirror, cmd, bank;
+static uint8 *WRAM = NULL;
+
+static SFORMAT StateRegs[] =
+{
+ { &cmd, 1, "CMD" },
+ { &mirror, 1, "MIRR" },
+ { &bank, 1, "BANK" },
+ { reg, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(mirror ^ 1);
+ setprg8(0x8000, reg[0]);
+ setprg8(0xA000, reg[1]);
+ setchr2(0x0000, (reg[2] >> 1));
+ setchr2(0x0800, (reg[3] >> 1));
+ setchr1(0x1000, ((bank & 0x10) << 4) | reg[4]);
+ setchr1(0x1400, ((bank & 0x20) << 3) | reg[5]);
+ setchr1(0x1800, ((bank & 0x40) << 2) | reg[6]);
+ setchr1(0x1C00, ((bank & 0x80) << 1) | reg[7]);
+}
+
+static DECLFW(M112Write) {
+ switch (A) {
+ case 0xe000: mirror = V & 1; Sync();; break;
+ case 0x8000: cmd = V & 7; break;
+ case 0xa000: reg[cmd] = V; Sync(); break;
+ case 0xc000: bank = V; Sync(); break;
+ }
+}
+
+static void M112Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void M112Power(void) {
+ bank = 0;
+ setprg16(0xC000, ~0);
+ setprg8r(0x10, 0x6000, 0);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M112Write);
+ SetWriteHandler(0x4020, 0x5FFF, M112Write);
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(8, 0x6000, WRAM);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper112_Init(CartInfo *info) {
+ info->Power = M112Power;
+ info->Close = M112Close;
+ GameStateRestore = StateRestore;
+ WRAM = (uint8*)FCEU_gmalloc(8192);
+ SetupCartPRGMapping(0x10, WRAM, 8192, 1);
+ AddExState(WRAM, 8192, 0, "WRAM");
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/116.cpp b/source/fceux/boards/116.cpp
new file mode 100644
index 0000000..555f6c4
--- /dev/null
+++ b/source/fceux/boards/116.cpp
@@ -0,0 +1,324 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2011 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * SL12 Protected 3-in-1 mapper hardware (VRC2, MMC3, MMC1)
+ * the same as 603-5052 board (TODO: add reading registers, merge)
+ * SL1632 2-in-1 protected board, similar to SL12 (TODO: find difference)
+ *
+ * Known PCB:
+ *
+ * Garou Densetsu Special (G0904.PCB, Huang-1, GAL dip: W conf.)
+ * Kart Fighter (008, Huang-1, GAL dip: W conf.)
+ * Somari (008, C5052-13, GAL dip: P conf., GK2-P/GK2-V maskroms)
+ * Somari (008, Huang-1, GAL dip: W conf., GK1-P/GK1-V maskroms)
+ * AV Mei Shao Nv Zhan Shi (aka AV Pretty Girl Fighting) (SL-12 PCB, Hunag-1, GAL dip: unk conf. SL-11A/SL-11B maskroms)
+ * Samurai Spirits (Full version) (Huang-1, GAL dip: unk conf. GS-2A/GS-4A maskroms)
+ * Contra Fighter (603-5052 PCB, C5052-3, GAL dip: unk conf. SC603-A/SCB603-B maskroms)
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 mode;
+static uint8 vrc2_chr[8], vrc2_prg[2], vrc2_mirr;
+static uint8 mmc3_regs[10], mmc3_ctrl, mmc3_mirr;
+static uint8 IRQCount, IRQLatch, IRQa;
+static uint8 IRQReload;
+static uint8 mmc1_regs[4], mmc1_buffer, mmc1_shift;
+
+static SFORMAT StateRegs[] =
+{
+ { &mode, 1, "MODE" },
+ { vrc2_chr, 8, "VRCC" },
+ { vrc2_prg, 2, "VRCP" },
+ { &vrc2_mirr, 1, "VRCM" },
+ { mmc3_regs, 10, "M3RG" },
+ { &mmc3_ctrl, 1, "M3CT" },
+ { &mmc3_mirr, 1, "M3MR" },
+ { &IRQReload, 1, "IRQR" },
+ { &IRQCount, 1, "IRQC" },
+ { &IRQLatch, 1, "IRQL" },
+ { &IRQa, 1, "IRQA" },
+ { mmc1_regs, 4, "M1RG" },
+ { &mmc1_buffer, 1, "M1BF" },
+ { &mmc1_shift, 1, "M1MR" },
+ { 0 }
+};
+
+static void SyncPRG(void) {
+ switch (mode & 3) {
+ case 0:
+ setprg8(0x8000, vrc2_prg[0]);
+ setprg8(0xA000, vrc2_prg[1]);
+ setprg8(0xC000, ~1);
+ setprg8(0xE000, ~0);
+ break;
+ case 1:
+ {
+ uint32 swap = (mmc3_ctrl >> 5) & 2;
+ setprg8(0x8000, mmc3_regs[6 + swap]);
+ setprg8(0xA000, mmc3_regs[7]);
+ setprg8(0xC000, mmc3_regs[6 + (swap ^ 2)]);
+ setprg8(0xE000, mmc3_regs[9]);
+ break;
+ }
+ case 2:
+ case 3:
+ {
+ uint8 bank = mmc1_regs[3] & 0xF;
+ if (mmc1_regs[0] & 8) {
+ if (mmc1_regs[0] & 4) {
+ setprg16(0x8000, bank);
+ setprg16(0xC000, 0x0F);
+ } else {
+ setprg16(0x8000, 0);
+ setprg16(0xC000, bank);
+ }
+ } else
+ setprg32(0x8000, bank >> 1);
+ break;
+ }
+ }
+}
+
+static void SyncCHR(void) {
+ uint32 base = (mode & 4) << 6;
+ switch (mode & 3) {
+ case 0:
+ setchr1(0x0000, base | vrc2_chr[0]);
+ setchr1(0x0400, base | vrc2_chr[1]);
+ setchr1(0x0800, base | vrc2_chr[2]);
+ setchr1(0x0c00, base | vrc2_chr[3]);
+ setchr1(0x1000, base | vrc2_chr[4]);
+ setchr1(0x1400, base | vrc2_chr[5]);
+ setchr1(0x1800, base | vrc2_chr[6]);
+ setchr1(0x1c00, base | vrc2_chr[7]);
+ break;
+ case 1: {
+ uint32 swap = (mmc3_ctrl & 0x80) << 5;
+ setchr1(0x0000 ^ swap, base | ((mmc3_regs[0]) & 0xFE));
+ setchr1(0x0400 ^ swap, base | (mmc3_regs[0] | 1));
+ setchr1(0x0800 ^ swap, base | ((mmc3_regs[1]) & 0xFE));
+ setchr1(0x0c00 ^ swap, base | (mmc3_regs[1] | 1));
+ setchr1(0x1000 ^ swap, base | mmc3_regs[2]);
+ setchr1(0x1400 ^ swap, base | mmc3_regs[3]);
+ setchr1(0x1800 ^ swap, base | mmc3_regs[4]);
+ setchr1(0x1c00 ^ swap, base | mmc3_regs[5]);
+ break;
+ }
+ case 2:
+ case 3:
+ if (mmc1_regs[0] & 0x10) {
+ setchr4(0x0000, mmc1_regs[1]);
+ setchr4(0x1000, mmc1_regs[2]);
+ } else
+ setchr8(mmc1_regs[1] >> 1);
+ break;
+ }
+}
+
+static void SyncMIR(void) {
+ switch (mode & 3) {
+ case 0: {
+ setmirror((vrc2_mirr & 1) ^ 1);
+ break;
+ }
+ case 1: {
+ setmirror((mmc3_mirr & 1) ^ 1);
+ break;
+ }
+ case 2:
+ case 3: {
+ switch (mmc1_regs[0] & 3) {
+ case 0: setmirror(MI_0); break;
+ case 1: setmirror(MI_1); break;
+ case 2: setmirror(MI_V); break;
+ case 3: setmirror(MI_H); break;
+ }
+ break;
+ }
+ }
+}
+
+static void Sync(void) {
+ SyncPRG();
+ SyncCHR();
+ SyncMIR();
+}
+
+static DECLFW(UNLSL12ModeWrite) {
+// FCEU_printf("%04X:%02X\n",A,V);
+ if ((A & 0x4100) == 0x4100) {
+ mode = V;
+ if (A & 1) { // hacky hacky, there are two configuration modes on SOMARI HUANG-1 PCBs
+ // Solder pads with P1/P2 shorted called SOMARI P,
+ // Solder pads with W1/W2 shorted called SOMARI W
+ // Both identical 3-in-1 but W wanted MMC1 registers
+ // to be reset when switch to MMC1 mode P one - doesn't
+ // There is issue with W version of Somari at starting copyrights
+ mmc1_regs[0] = 0xc;
+ mmc1_regs[3] = 0;
+ mmc1_buffer = 0;
+ mmc1_shift = 0;
+ }
+ Sync();
+ }
+}
+
+static DECLFW(UNLSL12Write) {
+// FCEU_printf("%04X:%02X\n",A,V);
+ switch (mode & 3) {
+ case 0: {
+ if ((A >= 0xB000) && (A <= 0xE003)) {
+ int32 ind = ((((A & 2) | (A >> 10)) >> 1) + 2) & 7;
+ int32 sar = ((A & 1) << 2);
+ vrc2_chr[ind] = (vrc2_chr[ind] & (0xF0 >> sar)) | ((V & 0x0F) << sar);
+ SyncCHR();
+ } else
+ switch (A & 0xF000) {
+ case 0x8000: vrc2_prg[0] = V; SyncPRG(); break;
+ case 0xA000: vrc2_prg[1] = V; SyncPRG(); break;
+ case 0x9000: vrc2_mirr = V; SyncMIR(); break;
+ }
+ break;
+ }
+ case 1: {
+ switch (A & 0xE001) {
+ case 0x8000: {
+ uint8 old_ctrl = mmc3_ctrl;
+ mmc3_ctrl = V;
+ if ((old_ctrl & 0x40) != (mmc3_ctrl & 0x40))
+ SyncPRG();
+ if ((old_ctrl & 0x80) != (mmc3_ctrl & 0x80))
+ SyncCHR();
+ break;
+ }
+ case 0x8001:
+ mmc3_regs[mmc3_ctrl & 7] = V;
+ if ((mmc3_ctrl & 7) < 6)
+ SyncCHR();
+ else
+ SyncPRG();
+ break;
+ case 0xA000:
+ mmc3_mirr = V;
+ SyncMIR();
+ break;
+ case 0xC000:
+ IRQLatch = V;
+ break;
+ case 0xC001:
+ IRQReload = 1;
+ break;
+ case 0xE000:
+ X6502_IRQEnd(FCEU_IQEXT);
+ IRQa = 0;
+ break;
+ case 0xE001:
+ IRQa = 1;
+ break;
+ }
+ break;
+ }
+ case 2:
+ case 3: {
+ if (V & 0x80) {
+ mmc1_regs[0] |= 0xc;
+ mmc1_buffer = mmc1_shift = 0;
+ SyncPRG();
+ } else {
+ uint8 n = (A >> 13) - 4;
+ mmc1_buffer |= (V & 1) << (mmc1_shift++);
+ if (mmc1_shift == 5) {
+ mmc1_regs[n] = mmc1_buffer;
+ mmc1_buffer = mmc1_shift = 0;
+ switch (n) {
+ case 0: SyncMIR();
+ case 2: SyncCHR();
+ case 3:
+ case 1: SyncPRG();
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+static void UNLSL12HBIRQ(void) {
+ if ((mode & 3) == 1) {
+ int32 count = IRQCount;
+ if (!count || IRQReload) {
+ IRQCount = IRQLatch;
+ IRQReload = 0;
+ } else
+ IRQCount--;
+ if (!IRQCount) {
+ if (IRQa)
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+static void UNLSL12Power(void) {
+ mode = 0;
+ vrc2_chr[0] = ~0;
+ vrc2_chr[1] = ~0;
+ vrc2_chr[2] = ~0;
+ vrc2_chr[3] = ~0; // W conf. of Somari wanted CHR3 has to be set to BB bank (or similar), but doesn't do that directly
+ vrc2_chr[4] = 4;
+ vrc2_chr[5] = 5;
+ vrc2_chr[6] = 6;
+ vrc2_chr[7] = 7;
+ vrc2_prg[0] = 0;
+ vrc2_prg[1] = 1;
+ vrc2_mirr = 0;
+ mmc3_regs[0] = 0;
+ mmc3_regs[1] = 2;
+ mmc3_regs[2] = 4;
+ mmc3_regs[3] = 5;
+ mmc3_regs[4] = 6;
+ mmc3_regs[5] = 7;
+ mmc3_regs[6] = ~3;
+ mmc3_regs[7] = ~2;
+ mmc3_regs[8] = ~1;
+ mmc3_regs[9] = ~0;
+ mmc3_ctrl = mmc3_mirr = IRQCount = IRQLatch = IRQa = 0;
+ mmc1_regs[0] = 0xc;
+ mmc1_regs[1] = 0;
+ mmc1_regs[2] = 0;
+ mmc1_regs[3] = 0;
+ mmc1_buffer = 0;
+ mmc1_shift = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x4100, 0x7FFF, UNLSL12ModeWrite);
+ SetWriteHandler(0x8000, 0xFFFF, UNLSL12Write);
+}
+
+void UNLSL12_Init(CartInfo *info) {
+ info->Power = UNLSL12Power;
+ GameHBIRQHook = UNLSL12HBIRQ;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/117.cpp b/source/fceux/boards/117.cpp
new file mode 100644
index 0000000..3a50ce2
--- /dev/null
+++ b/source/fceux/boards/117.cpp
@@ -0,0 +1,91 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 prgreg[4], chrreg[8], mirror;
+static uint8 IRQa, IRQCount, IRQLatch;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 1, "IRQC" },
+ { &IRQLatch, 1, "IRQL" },
+ { prgreg, 4, "PREG" },
+ { chrreg, 8, "CREG" },
+ { &mirror, 1, "MREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x8000, prgreg[0]);
+ setprg8(0xa000, prgreg[1]);
+ setprg8(0xc000, prgreg[2]);
+ setprg8(0xe000, prgreg[3]);
+ int i;
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, chrreg[i]);
+ setmirror(mirror ^ 1);
+}
+
+static DECLFW(M117Write) {
+ if (A < 0x8004) {
+ prgreg[A & 3] = V;
+ Sync();
+ } else if ((A >= 0xA000) && (A <= 0xA007)) {
+ chrreg[A & 7] = V;
+ Sync();
+ } else switch (A) {
+ case 0xc001: IRQLatch = V; break;
+ case 0xc003: IRQCount = IRQLatch; IRQa |= 2; break;
+ case 0xe000: IRQa &= ~1; IRQa |= V & 1; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xc002: X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xd000: mirror = V & 1;
+ }
+}
+
+static void M117Power(void) {
+ prgreg[0] = ~3; prgreg[1] = ~2; prgreg[2] = ~1; prgreg[3] = ~0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M117Write);
+}
+
+static void M117IRQHook(void) {
+ if (IRQa == 3 && IRQCount) {
+ IRQCount--;
+ if (!IRQCount) {
+ IRQa &= 1;
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper117_Init(CartInfo *info) {
+ info->Power = M117Power;
+ GameHBIRQHook = M117IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/120.cpp b/source/fceux/boards/120.cpp
new file mode 100644
index 0000000..aee1982
--- /dev/null
+++ b/source/fceux/boards/120.cpp
@@ -0,0 +1,59 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x6000, reg);
+ setprg32(0x8000, 2);
+ setchr8(0);
+}
+
+static DECLFW(M120Write) {
+ if (A == 0x41FF) {
+ reg = V & 7;
+ Sync();
+ }
+}
+
+static void M120Power(void) {
+ reg = 0;
+ Sync();
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x4100, 0x5FFF, M120Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper120_Init(CartInfo *info) {
+ info->Power = M120Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/121.cpp b/source/fceux/boards/121.cpp
new file mode 100644
index 0000000..aa4e5c2
--- /dev/null
+++ b/source/fceux/boards/121.cpp
@@ -0,0 +1,129 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007-2008 Mad Dumper, CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Panda prince pirate.
+ * MK4, MK6, A9711/A9713 board
+ * 6035052 seems to be the same too, but with prot array in reverse
+ * A9746 seems to be the same too, check
+ * 187 seems to be the same too, check (A98402 board)
+ *
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static void Sync() {
+ switch (EXPREGS[5] & 0x3F) {
+ case 0x20: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break;
+ case 0x29: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break;
+ case 0x26: EXPREGS[7] = 0; EXPREGS[0] = EXPREGS[6]; break;
+ case 0x2B: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break;
+ case 0x2C: EXPREGS[7] = 1; if (EXPREGS[6]) EXPREGS[0] = EXPREGS[6]; break;
+ case 0x3C:
+ case 0x3F: EXPREGS[7] = 1; EXPREGS[0] = EXPREGS[6]; break;
+ case 0x28: EXPREGS[7] = 0; EXPREGS[1] = EXPREGS[6]; break;
+ case 0x2A: EXPREGS[7] = 0; EXPREGS[2] = EXPREGS[6]; break;
+ case 0x2F: break;
+ default: EXPREGS[5] = 0; break;
+ }
+}
+
+static void M121CW(uint32 A, uint8 V) {
+ if (PRGsize[0] == CHRsize[0]) { // A9713 multigame extension hack!
+ setchr1(A, V | ((EXPREGS[3] & 0x80) << 1));
+ } else {
+ if ((A & 0x1000) == ((MMC3_cmd & 0x80) << 5))
+ setchr1(A, V | 0x100);
+ else
+ setchr1(A, V);
+ }
+}
+
+static void M121PW(uint32 A, uint8 V) {
+ if (EXPREGS[5] & 0x3F) {
+// FCEU_printf("prot banks: %02x %02x %02x %02x\n",V,EXPREGS[2],EXPREGS[1],EXPREGS[0]);
+ setprg8(A, (V & 0x1F) | ((EXPREGS[3] & 0x80) >> 2));
+ setprg8(0xE000, (EXPREGS[0]) | ((EXPREGS[3] & 0x80) >> 2));
+ setprg8(0xC000, (EXPREGS[1]) | ((EXPREGS[3] & 0x80) >> 2));
+ setprg8(0xA000, (EXPREGS[2]) | ((EXPREGS[3] & 0x80) >> 2));
+ } else {
+// FCEU_printf("gen banks: %04x %02x\n",A,V);
+ setprg8(A, (V & 0x1F) | ((EXPREGS[3] & 0x80) >> 2));
+ }
+}
+
+static DECLFW(M121Write) {
+// FCEU_printf("write: %04x:%04x\n",A&0xE003,V);
+ switch (A & 0xE003) {
+ case 0x8000:
+// EXPREGS[5] = 0;
+// FCEU_printf("gen: %02x\n",V);
+ MMC3_CMDWrite(A, V);
+ FixMMC3PRG(MMC3_cmd);
+ break;
+ case 0x8001:
+ EXPREGS[6] = ((V & 1) << 5) | ((V & 2) << 3) | ((V & 4) << 1) | ((V & 8) >> 1) | ((V & 0x10) >> 3) | ((V & 0x20) >> 5);
+// FCEU_printf("bank: %02x (%02x)\n",V,EXPREGS[6]);
+ if (!EXPREGS[7]) Sync();
+ MMC3_CMDWrite(A, V);
+ FixMMC3PRG(MMC3_cmd);
+ break;
+ case 0x8003:
+ EXPREGS[5] = V;
+// EXPREGS[7] = 0;
+// FCEU_printf("prot: %02x\n",EXPREGS[5]);
+ Sync();
+ MMC3_CMDWrite(0x8000, V);
+ FixMMC3PRG(MMC3_cmd);
+ break;
+ }
+}
+
+static uint8 prot_array[16] = { 0x83, 0x83, 0x42, 0x00 };
+static DECLFW(M121LoWrite) {
+ EXPREGS[4] = prot_array[V & 3]; // 0x100 bit in address seems to be switch arrays 0, 2, 2, 3 (Contra Fighter)
+ if ((A & 0x5180) == 0x5180) { // A9713 multigame extension
+ EXPREGS[3] = V;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+ }
+// FCEU_printf("write: %04x:%04x\n",A,V);
+}
+
+static DECLFR(M121Read) {
+// FCEU_printf("read: %04x->\n",A,EXPREGS[0]);
+ return EXPREGS[4];
+}
+
+static void M121Power(void) {
+ EXPREGS[3] = 0x80;
+ EXPREGS[5] = 0;
+ GenMMC3Power();
+ SetReadHandler(0x5000, 0x5FFF, M121Read);
+ SetWriteHandler(0x5000, 0x5FFF, M121LoWrite);
+ SetWriteHandler(0x8000, 0x9FFF, M121Write);
+}
+
+void Mapper121_Init(CartInfo *info) {
+ GenMMC3_Init(info, 128, 256, 8, 0);
+ pwrap = M121PW;
+ cwrap = M121CW;
+ info->Power = M121Power;
+ AddExState(EXPREGS, 8, 0, "EXPR");
+}
diff --git a/source/fceux/boards/12in1.cpp b/source/fceux/boards/12in1.cpp
new file mode 100644
index 0000000..add67cc
--- /dev/null
+++ b/source/fceux/boards/12in1.cpp
@@ -0,0 +1,73 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * 7-in-1 Darkwing Duck, Snake, MagicBlock (PCB marked as "12 in 1")
+ * 12-in-1 1991 New Star Co. Ltd.
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 prgchr[2], ctrl;
+static SFORMAT StateRegs[] =
+{
+ { prgchr, 2, "REGS" },
+ { &ctrl, 1, "CTRL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint8 bank = (ctrl & 3) << 3;
+ setchr4(0x0000, (prgchr[0] >> 3) | (bank << 2));
+ setchr4(0x1000, (prgchr[1] >> 3) | (bank << 2));
+ if (ctrl & 8) {
+ setprg16(0x8000, bank | (prgchr[0] & 6) | 0); // actually, both 0 and 1 registers used, but they will switch each PA12 transition
+ setprg16(0xc000, bank | (prgchr[0] & 6) | 1); // if bits are different for both registers, so they must be programmed strongly the same!
+ } else {
+ setprg16(0x8000, bank | (prgchr[0] & 7));
+ setprg16(0xc000, bank | 7 );
+ }
+ setmirror(((ctrl & 4) >> 2) ^ 1);
+}
+
+static DECLFW(BMC12IN1Write) {
+ switch (A & 0xE000) {
+ case 0xA000: prgchr[0] = V; Sync(); break;
+ case 0xC000: prgchr[1] = V; Sync(); break;
+ case 0xE000: ctrl = V & 0x0F; Sync(); break;
+ }
+}
+
+static void BMC12IN1Power(void) {
+ prgchr[0] = prgchr[1] = ctrl = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, BMC12IN1Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void BMC12IN1_Init(CartInfo *info) {
+ info->Power = BMC12IN1Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/15.cpp b/source/fceux/boards/15.cpp
new file mode 100644
index 0000000..01f55cd
--- /dev/null
+++ b/source/fceux/boards/15.cpp
@@ -0,0 +1,117 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "mapinc.h"
+
+static uint16 latchea;
+static uint8 latched;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+static SFORMAT StateRegs[] =
+{
+ { &latchea, 2, "AREG" },
+ { &latched, 1, "DREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ int i;
+ setmirror(((latched >> 6) & 1) ^ 1);
+ switch (latchea & 3) {
+ case 0:
+ for (i = 0; i < 4; i++)
+ setprg8(0x8000 + (i << 13), ((latched & 0x3F) << 1) + i);
+ break;
+ case 2:
+ for (i = 0; i < 4; i++)
+ setprg8(0x8000 + (i << 13), ((latched & 0x3F) << 1) + (latched >> 7));
+ break;
+ case 1:
+ case 3:
+ for (i = 0; i < 4; i++) {
+ unsigned int b;
+ b = latched & 0x3F;
+ if (i >= 2 && !(latchea & 0x2))
+ b = b | 0x07;
+ setprg8(0x8000 + (i << 13), (i & 1) + (b << 1));
+ }
+ break;
+ }
+ setchr8(0);
+}
+
+static DECLFW(M15Write) {
+ latchea = A;
+ latched = V;
+ // cah4e3 02.10.19 once again, there may be either two similar mapper 15 exist. the one for 110in1 or 168in1 carts with complex multi game features.
+ // and another implified version for subor/waixing chinese originals and hacks with no different modes, working only in mode 0 and which does not
+ // expect there is any CHR write protection. protecting CHR writes only for mode 3 fixes the problem, all roms may be run on the same source again.
+ if((latchea & 3) == 3)
+ SetupCartCHRMapping(0, CHRptr[0], 0x2000, 0);
+ else
+ SetupCartCHRMapping(0, CHRptr[0], 0x2000, 1);
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+static void M15Power(void) {
+ latchea = 0x8000;
+ latched = 0;
+ setprg8r(0x10, 0x6000, 0);
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetWriteHandler(0x8000, 0xFFFF, M15Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+ Sync();
+}
+
+static void M15Reset(void) {
+ latchea = 0x8000;
+ latched = 0;
+ Sync();
+}
+
+static void M15Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+void Mapper15_Init(CartInfo *info) {
+ info->Power = M15Power;
+ info->Reset = M15Reset;
+ info->Close = M15Close;
+ GameStateRestore = StateRestore;
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/151.cpp b/source/fceux/boards/151.cpp
new file mode 100644
index 0000000..2d9335f
--- /dev/null
+++ b/source/fceux/boards/151.cpp
@@ -0,0 +1,59 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 regs[8];
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x8000, regs[0]);
+ setprg8(0xA000, regs[2]);
+ setprg8(0xC000, regs[4]);
+ setprg8(0xE000, ~0);
+ setchr4(0x0000, regs[6]);
+ setchr4(0x1000, regs[7]);
+}
+
+static DECLFW(M151Write) {
+ regs[(A >> 12) & 7] = V;
+ Sync();
+}
+
+static void M151Power(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M151Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper151_Init(CartInfo *info) {
+ info->Power = M151Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/156.cpp b/source/fceux/boards/156.cpp
new file mode 100644
index 0000000..6693962
--- /dev/null
+++ b/source/fceux/boards/156.cpp
@@ -0,0 +1,114 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 chrlo[8], chrhi[8], prg, mirr, mirrisused = 0;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { &prg, 1, "PREG" },
+ { chrlo, 8, "CRGL" },
+ { chrhi, 8, "CRGH" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint32 i;
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, chrlo[i] | (chrhi[i] << 8));
+ setprg8r(0x10, 0x6000, 0);
+ setprg16(0x8000, prg);
+ setprg16(0xC000, ~0);
+ if (mirrisused)
+ setmirror(mirr ^ 1);
+ else
+ setmirror(MI_0);
+}
+
+static DECLFW(M156Write) {
+ switch (A) {
+ case 0xC000:
+ case 0xC001:
+ case 0xC002:
+ case 0xC003: chrlo[A & 3] = V; Sync(); break;
+ case 0xC004:
+ case 0xC005:
+ case 0xC006:
+ case 0xC007: chrhi[A & 3] = V; Sync(); break;
+ case 0xC008:
+ case 0xC009:
+ case 0xC00A:
+ case 0xC00B: chrlo[4 + (A & 3)] = V; Sync(); break;
+ case 0xC00C:
+ case 0xC00D:
+ case 0xC00E:
+ case 0xC00F: chrhi[4 + (A & 3)] = V; Sync(); break;
+ case 0xC010: prg = V; Sync(); break;
+ case 0xC014: mirr = V; mirrisused = 1; Sync(); break;
+ }
+}
+
+static void M156Reset(void) {
+ uint32 i;
+ for (i = 0; i < 8; i++) {
+ chrlo[i] = 0;
+ chrhi[i] = 0;
+ }
+ prg = 0;
+ mirr = 0;
+ mirrisused = 0;
+}
+
+static void M156Power(void) {
+ M156Reset();
+ Sync();
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetWriteHandler(0xC000, 0xCFFF, M156Write);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M156Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper156_Init(CartInfo *info) {
+ info->Reset = M156Reset;
+ info->Power = M156Power;
+ info->Close = M156Close;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/158B.cpp b/source/fceux/boards/158B.cpp
new file mode 100644
index 0000000..765c8fc
--- /dev/null
+++ b/source/fceux/boards/158B.cpp
@@ -0,0 +1,71 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2015 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * "Blood Of Jurassic" protected MMC3 based board (GD-98 Cart ID, 158B PCB ID)
+ *
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static uint8 lut[8] = { 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0F, 0x00 };
+
+static void UNL158BPW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x80) {
+ uint32 bank = EXPREGS[0] & 7;
+ if(EXPREGS[0] & 0x20) { // 32Kb mode
+ setprg32(0x8000, bank >> 1);
+ } else { // 16Kb mode
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else {
+ setprg8(A, V & 0xF);
+ }
+}
+
+static DECLFW(UNL158BProtWrite) {
+ EXPREGS[A & 7] = V;
+ switch(A & 7) {
+ case 0:
+ FixMMC3PRG(MMC3_cmd);
+ break;
+ case 7:
+ FCEU_printf("UNK PROT WRITE\n");
+ break;
+ }
+
+}
+
+static DECLFR(UNL158BProtRead) {
+ return X.DB | lut[A & 7];
+}
+
+static void UNL158BPower(void) {
+ GenMMC3Power();
+ SetWriteHandler(0x5000, 0x5FFF, UNL158BProtWrite);
+ SetReadHandler(0x5000, 0x5FFF, UNL158BProtRead);
+}
+
+void UNL158B_Init(CartInfo *info) {
+ GenMMC3_Init(info, 128, 128, 0, 0);
+ pwrap = UNL158BPW;
+ info->Power = UNL158BPower;
+ AddExState(EXPREGS, 8, 0, "EXPR");
+}
diff --git a/source/fceux/boards/164.cpp b/source/fceux/boards/164.cpp
new file mode 100644
index 0000000..6eb963b
--- /dev/null
+++ b/source/fceux/boards/164.cpp
@@ -0,0 +1,232 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Xodnizel 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * It seems that 162/163/164 mappers are the same mapper with just different
+ * mapper modes enabled or disabled in software or hardware, need more nanjing
+ * carts
+ */
+
+#include "mapinc.h"
+
+static uint8 laststrobe, trigger;
+static uint8 reg[8];
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static writefunc pcmwrite;
+
+static void (*WSync)(void);
+
+static SFORMAT StateRegs[] =
+{
+ { &laststrobe, 1, "STB" },
+ { &trigger, 1, "TRG" },
+ { reg, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8r(0x10, 0x6000, 0);
+ setprg32(0x8000, (reg[0] << 4) | (reg[1] & 0xF));
+ setchr8(0);
+}
+
+static void StateRestore(int version) {
+ WSync();
+}
+
+static DECLFR(ReadLow) {
+ switch (A & 0x7700) {
+ case 0x5100: return reg[2] | reg[0] | reg[1] | reg[3] ^ 0xff; break;
+ case 0x5500:
+ if (trigger)
+ return reg[2] | reg[1]; // Lei Dian Huang Bi Ka Qiu Chuan Shuo (NJ046) may broke other games
+ else
+ return 0;
+ }
+ return 4;
+}
+
+static void M163HB(void) {
+ if (reg[1] & 0x80) {
+ if (scanline == 239) {
+ setchr4(0x0000, 0);
+ setchr4(0x1000, 0);
+ } else if (scanline == 127) {
+ setchr4(0x0000, 1);
+ setchr4(0x1000, 1);
+ }
+/*
+ if(scanline>=127) // Hu Lu Jin Gang (NJ039) (Ch) [!] don't like it
+ {
+ setchr4(0x0000,1);
+ setchr4(0x1000,1);
+ }
+ else
+ {
+ setchr4(0x0000,0);
+ setchr4(0x1000,0);
+ }
+*/
+ }
+}
+
+static DECLFW(Write) {
+ switch (A & 0x7300) {
+ case 0x5100: reg[0] = V; WSync(); break;
+ case 0x5000: reg[1] = V; WSync(); break;
+ case 0x5300: reg[2] = V; break;
+ case 0x5200: reg[3] = V; WSync(); break;
+ }
+}
+
+static void Power(void) {
+ memset(reg, 0, 8);
+ reg[1] = 0xFF;
+ SetWriteHandler(0x5000, 0x5FFF, Write);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+ WSync();
+}
+
+static void Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+void Mapper164_Init(CartInfo *info) {
+ info->Power = Power;
+ info->Close = Close;
+ WSync = Sync;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+static DECLFW(Write2) {
+ if (A == 0x5101) {
+ if (laststrobe && !V) {
+ trigger ^= 1;
+ }
+ laststrobe = V;
+ } else if (A == 0x5100 && V == 6) //damn thoose protected games
+ setprg32(0x8000, 3);
+ else
+ switch (A & 0x7300) {
+ case 0x5200: reg[0] = V; WSync(); break;
+ case 0x5000: reg[1] = V; WSync(); if (!(reg[1] & 0x80) && (scanline < 128)) setchr8(0); /* setchr8(0); */ break;
+ case 0x5300: reg[2] = V; break;
+ case 0x5100: reg[3] = V; WSync(); break;
+ }
+}
+
+static void Power2(void) {
+ memset(reg, 0, 8);
+ laststrobe = 1;
+ pcmwrite = GetWriteHandler(0x4011);
+ SetReadHandler(0x5000, 0x5FFF, ReadLow);
+ SetWriteHandler(0x5000, 0x5FFF, Write2);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+ WSync();
+}
+
+void Mapper163_Init(CartInfo *info) {
+ info->Power = Power2;
+ info->Close = Close;
+ WSync = Sync;
+ GameHBIRQHook = M163HB;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+static void Sync3(void) {
+ setchr8(0);
+ setprg8r(0x10, 0x6000, 0);
+ switch (reg[3] & 7) {
+ case 0:
+ case 2: setprg32(0x8000, (reg[0] & 0xc) | (reg[1] & 2) | ((reg[2] & 0xf) << 4)); break;
+ case 1:
+ case 3: setprg32(0x8000, (reg[0] & 0xc) | (reg[2] & 0xf) << 4); break;
+ case 4:
+ case 6: setprg32(0x8000, (reg[0] & 0xe) | ((reg[1] >> 1) & 1) | ((reg[2] & 0xf) << 4)); break;
+ case 5:
+ case 7: setprg32(0x8000, (reg[0] & 0xf) | ((reg[2] & 0xf) << 4)); break;
+ }
+}
+
+static DECLFW(Write3) {
+// FCEU_printf("bs %04x %02x\n",A,V);
+ reg[(A >> 8) & 3] = V;
+ WSync();
+}
+
+static void Power3(void) {
+ reg[0] = 3;
+ reg[1] = 0;
+ reg[2] = 0;
+ reg[3] = 7;
+ SetWriteHandler(0x5000, 0x5FFF, Write3);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+ WSync();
+}
+
+void UNLFS304_Init(CartInfo *info) {
+ info->Power = Power3;
+ info->Close = Close;
+ WSync = Sync3;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/168.cpp b/source/fceux/boards/168.cpp
new file mode 100644
index 0000000..c85b221
--- /dev/null
+++ b/source/fceux/boards/168.cpp
@@ -0,0 +1,78 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+static uint8 *CHRRAM = NULL;
+static uint32 CHRRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr4r(0x10, 0x0000, 0);
+ setchr4r(0x10, 0x1000, reg & 0x0f);
+ setprg16(0x8000, reg >> 6);
+ setprg16(0xc000, ~0);
+}
+
+static DECLFW(M168Write) {
+ reg = V;
+ Sync();
+}
+
+static DECLFW(M168Dummy) {
+}
+
+static void M168Power(void) {
+ reg = 0;
+ Sync();
+ SetWriteHandler(0x4020, 0x7fff, M168Dummy);
+ SetWriteHandler(0xB000, 0xB000, M168Write);
+ SetWriteHandler(0xF000, 0xF000, M168Dummy);
+ SetWriteHandler(0xF080, 0xF080, M168Dummy);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void M168Close(void) {
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ CHRRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper168_Init(CartInfo *info) {
+ info->Power = M168Power;
+ info->Close = M168Close;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+
+ CHRRAMSIZE = 8192 * 8;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
+}
diff --git a/source/fceux/boards/170.cpp b/source/fceux/boards/170.cpp
new file mode 100644
index 0000000..9a8a8e5
--- /dev/null
+++ b/source/fceux/boards/170.cpp
@@ -0,0 +1,62 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2011 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg16(0x8000, 0);
+ setprg16(0xc000, ~0);
+ setchr8(0);
+}
+
+static DECLFW(M170ProtW) {
+ reg = V << 1 & 0x80;
+}
+
+static DECLFR(M170ProtR) {
+ return reg | (X.DB & 0x7F);
+}
+
+static void M170Power(void) {
+ Sync();
+ SetWriteHandler(0x6502, 0x6502, M170ProtW);
+ SetWriteHandler(0x7000, 0x7000, M170ProtW);
+ SetReadHandler(0x7001, 0x7001, M170ProtR);
+ SetReadHandler(0x7777, 0x7777, M170ProtR);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper170_Init(CartInfo *info) {
+ info->Power = M170Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/175.cpp b/source/fceux/boards/175.cpp
new file mode 100644
index 0000000..8278607
--- /dev/null
+++ b/source/fceux/boards/175.cpp
@@ -0,0 +1,79 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg, delay, mirr;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REG" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8(reg);
+ if (!delay) {
+ setprg16(0x8000, reg);
+ setprg8(0xC000, reg << 1);
+ }
+ setprg8(0xE000, (reg << 1) + 1);
+ setmirror(((mirr & 4) >> 2) ^ 1);
+}
+
+static DECLFW(M175Write1) {
+ mirr = V;
+ delay = 1;
+ Sync();
+}
+
+static DECLFW(M175Write2) {
+ reg = V & 0x0F;
+ delay = 1;
+ Sync();
+}
+
+static DECLFR(M175Read) {
+ if (A == 0xFFFC) {
+ delay = 0;
+ Sync();
+ }
+ return CartBR(A);
+}
+
+static void M175Power(void) {
+ reg = mirr = delay = 0;
+ SetReadHandler(0x8000, 0xFFFF, M175Read);
+ SetWriteHandler(0x8000, 0x8000, M175Write1);
+ SetWriteHandler(0xA000, 0xA000, M175Write2);
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper175_Init(CartInfo *info) {
+ info->Power = M175Power;
+ GameStateRestore = StateRestore;
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/176.cpp b/source/fceux/boards/176.cpp
new file mode 100644
index 0000000..f29ad08
--- /dev/null
+++ b/source/fceux/boards/176.cpp
@@ -0,0 +1,159 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ * Copyright (C) 2012 FCEUX team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+extern uint32 ROM_size;
+
+static uint8 prg[4], chr, sbw, we_sram;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[]=
+{
+ {prg, 4, "PRG"},
+ {&chr, 1, "CHR"},
+ {&sbw, 1, "SBW"},
+ {0}
+};
+
+static void Sync(void)
+{
+ setprg8r(0x10,0x6000,0);
+ setprg8(0x8000,prg[0]);
+ setprg8(0xA000,prg[1]);
+ setprg8(0xC000,prg[2]);
+ setprg8(0xE000,prg[3]);
+
+ setchr8(chr);
+}
+
+static DECLFW(M176Write_5001)
+{
+ printf("%04X = $%02X\n",A,V);
+ if(sbw)
+ {
+ prg[0] = V*4;
+ prg[1] = V*4+1;
+ prg[2] = V*4+2;
+ prg[3] = V*4+3;
+ }
+ Sync();
+}
+
+static DECLFW(M176Write_5010)
+{
+ printf("%04X = $%02X\n",A,V);
+ if(V == 0x24) sbw = 1;
+ Sync();
+}
+
+static DECLFW(M176Write_5011)
+{
+ printf("%04X = $%02X\n",A,V);
+ V >>= 1;
+ if(sbw)
+ {
+ prg[0] = V*4;
+ prg[1] = V*4+1;
+ prg[2] = V*4+2;
+ prg[3] = V*4+3;
+ }
+ Sync();
+}
+
+static DECLFW(M176Write_5FF1)
+{
+ printf("%04X = $%02X\n",A,V);
+ V >>= 1;
+ prg[0] = V*4;
+ prg[1] = V*4+1;
+ prg[2] = V*4+2;
+ prg[3] = V*4+3;
+ Sync();
+}
+
+static DECLFW(M176Write_5FF2)
+{
+ printf("%04X = $%02X\n",A,V);
+ chr = V;
+ Sync();
+}
+
+static DECLFW(M176Write_A001)
+{
+ we_sram = V & 0x03;
+}
+
+static DECLFW(M176Write_WriteSRAM)
+{
+// if(we_sram)
+ CartBW(A,V);
+}
+
+static void M176Power(void)
+{
+ SetReadHandler(0x6000,0x7fff,CartBR);
+ SetWriteHandler(0x6000,0x7fff,M176Write_WriteSRAM);
+ SetReadHandler(0x8000,0xFFFF,CartBR);
+ SetWriteHandler(0xA001,0xA001,M176Write_A001);
+ SetWriteHandler(0x5001,0x5001,M176Write_5001);
+ SetWriteHandler(0x5010,0x5010,M176Write_5010);
+ SetWriteHandler(0x5011,0x5011,M176Write_5011);
+ SetWriteHandler(0x5ff1,0x5ff1,M176Write_5FF1);
+ SetWriteHandler(0x5ff2,0x5ff2,M176Write_5FF2);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+
+ we_sram = 0;
+ sbw = 0;
+ prg[0] = 0;
+ prg[1] = 1;
+ prg[2] = (ROM_size-2)&63;
+ prg[3] = (ROM_size-1)&63;
+ Sync();
+}
+
+
+static void M176Close(void)
+{
+ if(WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version)
+{
+ Sync();
+}
+
+void Mapper176_Init(CartInfo *info)
+{
+ info->Power=M176Power;
+ info->Close=M176Close;
+
+ GameStateRestore=StateRestore;
+
+ WRAMSIZE=8192;
+ WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/177.cpp b/source/fceux/boards/177.cpp
new file mode 100644
index 0000000..0416060
--- /dev/null
+++ b/source/fceux/boards/177.cpp
@@ -0,0 +1,81 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8(0);
+ setprg8r(0x10, 0x6000, 0);
+ setprg32(0x8000, reg & 0x1f);
+ setmirror(((reg & 0x20) >> 5) ^ 1);
+}
+
+static DECLFW(M177Write) {
+ reg = V;
+ Sync();
+}
+
+static void M177Power(void) {
+ reg = 0;
+ Sync();
+ SetReadHandler(0x6000, 0x7fff, CartBR);
+ SetWriteHandler(0x6000, 0x7fff, CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M177Write);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M177Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper177_Init(CartInfo *info) {
+ info->Power = M177Power;
+ info->Close = M177Close;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/178.cpp b/source/fceux/boards/178.cpp
new file mode 100644
index 0000000..d577329
--- /dev/null
+++ b/source/fceux/boards/178.cpp
@@ -0,0 +1,201 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2013 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * DSOUNDV1/FL-TR8MA boards (32K WRAM, 8/16M), 178 mapper boards (8K WRAM, 4/8M)
+ * Various Education Cartridges
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[4];
+
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+// Tennis with VR sensor, very simple behaviour
+extern void GetMouseData(uint32 (&md)[3]);
+static uint32 MouseData[3], click, lastclick;
+static int32 SensorDelay;
+
+// highly experimental, not actually working, just curious if it hapen to work with some other decoder
+// SND Registers
+static uint8 pcm_enable = 0;
+//static int16 pcm_latch = 0x3F6, pcm_clock = 0x3F6;
+//static writefunc pcmwrite;
+
+static SFORMAT StateRegs[] =
+{
+ { reg, 4, "REGS" },
+ { 0 }
+};
+
+//static int16 step_size[49] = {
+// 16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
+// 41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
+// 107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
+// 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
+// 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
+//}; //49 items
+//static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 };
+
+//decode stuff
+//static int32 jedi_table[16 * 49];
+//static int32 acc = 0; //ADPCM accumulator, initial condition must be 0
+//static int32 decstep = 0; //ADPCM decoding step, initial condition must be 0
+
+//static void jedi_table_init() {
+// int step, nib;
+//
+// for (step = 0; step < 49; step++) {
+// for (nib = 0; nib < 16; nib++) {
+// int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8;
+// jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value;
+// }
+// }
+//}
+
+//static uint8 decode(uint8 code) {
+// acc += jedi_table[decstep + code];
+// if ((acc & ~0x7ff) != 0) // acc is > 2047
+// acc |= ~0xfff;
+// else acc &= 0xfff;
+// decstep += step_adj[code & 7] * 16;
+// if (decstep < 0) decstep = 0;
+// if (decstep > 48 * 16) decstep = 48 * 16;
+// return (acc >> 8) & 0xff;
+//}
+
+static void Sync(void) {
+ uint32 sbank = reg[1] & 0x7;
+ uint32 bbank = reg[2];
+ setchr8(0);
+ setprg8r(0x10, 0x6000, reg[3] & 3);
+ if (reg[0] & 2) { // UNROM mode
+ setprg16(0x8000, (bbank << 3) | sbank);
+ if (reg[0] & 4)
+ setprg16(0xC000, (bbank << 3) | 6 | (reg[1] & 1));
+ else
+ setprg16(0xC000, (bbank << 3) | 7);
+ } else { // NROM mode
+ uint32 bank = (bbank << 3) | sbank;
+ if (reg[0] & 4) {
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ } else
+ setprg32(0x8000, bank >> 1);
+ }
+ setmirror((reg[0] & 1) ^ 1);
+}
+
+static DECLFW(M178Write) {
+ reg[A & 3] = V;
+// FCEU_printf("cmd %04x:%02x\n", A, V);
+ Sync();
+}
+
+static DECLFW(M178WriteSnd) {
+ if (A == 0x5800) {
+ if (V & 0xF0) {
+ pcm_enable = 1;
+// pcmwrite(0x4011, (V & 0xF) << 3);
+// pcmwrite(0x4011, decode(V & 0xf));
+ } else
+ pcm_enable = 0;
+ }// else
+// FCEU_printf("misc %04x:%02x\n", A, V);
+}
+
+static DECLFR(M178ReadSnd) {
+ if (A == 0x5800)
+ return (X.DB & 0xBF) | ((pcm_enable ^ 1) << 6);
+ else
+ return X.DB;
+}
+
+static DECLFR(M178ReadSensor) {
+ X6502_IRQEnd(FCEU_IQEXT); // hacky-hacky, actual reg is 6000 and it clear IRQ while reading, but then I need another mapper lol
+ return 0x00;
+}
+
+static void M178Power(void) {
+ reg[0] = reg[1] = reg[2] = reg[3] = SensorDelay = 0;
+ Sync();
+// pcmwrite = GetWriteHandler(0x4011);
+ SetWriteHandler(0x4800, 0x4fff, M178Write);
+ SetWriteHandler(0x5800, 0x5fff, M178WriteSnd);
+ SetReadHandler(0x5800, 0x5fff, M178ReadSnd);
+ SetReadHandler(0x5000, 0x5000, M178ReadSensor);
+ SetReadHandler(0x6000, 0x7fff, CartBR);
+ SetWriteHandler(0x6000, 0x7fff, CartBW);
+ SetReadHandler(0x8000, 0xffff, CartBR);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M178SndClk(int a) {
+ SensorDelay += a;
+ if(SensorDelay > 0x32768) {
+ SensorDelay -= 32768;
+ GetMouseData (MouseData);
+ lastclick = click;
+ click = MouseData[2] & 1; // to prevent from continuos IRQ trigger if button is held.
+ // actual circuit is just a D-C-R edge detector for IR-sensor
+ // triggered by the active IR bat.
+ if(lastclick && !click)
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+
+// if (pcm_enable) {
+// pcm_latch -= a;
+// if (pcm_latch <= 0) {
+// pcm_latch += pcm_clock;
+// pcm_enable = 0;
+// }
+// }
+}
+
+static void M178Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper178_Init(CartInfo *info) {
+ info->Power = M178Power;
+ info->Close = M178Close;
+ GameStateRestore = StateRestore;
+ MapIRQHook = M178SndClk;
+
+// jedi_table_init();
+
+ WRAMSIZE = 32768;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/18.cpp b/source/fceux/boards/18.cpp
new file mode 100644
index 0000000..a9ac4b6
--- /dev/null
+++ b/source/fceux/boards/18.cpp
@@ -0,0 +1,134 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg[4], creg[8];
+static uint8 IRQa, mirr;
+static int32 IRQCount, IRQLatch;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { preg, 4, "PREG" },
+ { creg, 8, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 4, "IRQC" },
+ { &IRQLatch, 4, "IRQL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ int i;
+ for (i = 0; i < 8; i++) setchr1(i << 10, creg[i]);
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000, preg[0]);
+ setprg8(0xA000, preg[1]);
+ setprg8(0xC000, preg[2]);
+ setprg8(0xE000, ~0);
+ if (mirr & 2)
+ setmirror(MI_0);
+ else
+ setmirror(mirr & 1);
+}
+
+static DECLFW(M18WriteIRQ) {
+ switch (A & 0xF003) {
+ case 0xE000: IRQLatch &= 0xFFF0; IRQLatch |= (V & 0x0f) << 0x0; break;
+ case 0xE001: IRQLatch &= 0xFF0F; IRQLatch |= (V & 0x0f) << 0x4; break;
+ case 0xE002: IRQLatch &= 0xF0FF; IRQLatch |= (V & 0x0f) << 0x8; break;
+ case 0xE003: IRQLatch &= 0x0FFF; IRQLatch |= (V & 0x0f) << 0xC; break;
+ case 0xF000: IRQCount = IRQLatch; break;
+ case 0xF001: IRQa = V & 1; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xF002: mirr = V & 3; Sync(); break;
+ }
+}
+
+static DECLFW(M18WritePrg) {
+ uint32 i = ((A >> 1) & 1) | ((A - 0x8000) >> 11);
+ preg[i] &= (0xF0) >> ((A & 1) << 2);
+ preg[i] |= (V & 0xF) << ((A & 1) << 2);
+ Sync();
+}
+
+static DECLFW(M18WriteChr) {
+ uint32 i = ((A >> 1) & 1) | ((A - 0xA000) >> 11);
+ creg[i] &= (0xF0) >> ((A & 1) << 2);
+ creg[i] |= (V & 0xF) << ((A & 1) << 2);
+ Sync();
+}
+
+static void M18Power(void) {
+ IRQa = 0;
+ preg[0] = 0;
+ preg[1] = 1;
+ preg[2] = ~1;
+ preg[3] = ~0;
+ Sync();
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetWriteHandler(0x8000, 0x9FFF, M18WritePrg);
+ SetWriteHandler(0xA000, 0xDFFF, M18WriteChr);
+ SetWriteHandler(0xE000, 0xFFFF, M18WriteIRQ);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M18IRQHook(int a) {
+ if (IRQa && IRQCount) {
+ IRQCount -= a;
+ if (IRQCount <= 0) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQCount = 0;
+ IRQa = 0;
+ }
+ }
+}
+
+static void M18Close(void)
+{
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper18_Init(CartInfo *info) {
+ info->Power = M18Power;
+ info->Close = M18Close;
+ MapIRQHook = M18IRQHook;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/183.cpp b/source/fceux/boards/183.cpp
new file mode 100644
index 0000000..9ba8c2c
--- /dev/null
+++ b/source/fceux/boards/183.cpp
@@ -0,0 +1,111 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Gimmick Bootleg (VRC4 mapper)
+ */
+
+#include "mapinc.h"
+
+static uint8 prg[4], chr[8], mirr;
+static uint8 IRQCount;
+static uint8 IRQPre;
+static uint8 IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { prg, 4, "PRG" },
+ { chr, 8, "CHR" },
+ { &mirr, 1, "MIRR" },
+ { &IRQCount, 1, "IRQC" },
+ { &IRQPre, 1, "IRQP" },
+ { &IRQa, 1, "IRQA" },
+ { 0 }
+};
+
+static void SyncPrg(void) {
+ setprg8(0x6000, prg[3]);
+ setprg8(0x8000, prg[0]);
+ setprg8(0xA000, prg[1]);
+ setprg8(0xC000, prg[2]);
+ setprg8(0xE000, ~0);
+}
+
+static void SyncMirr(void) {
+ switch (mirr) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static void SyncChr(void) {
+ int i;
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, chr[i]);
+}
+
+static void StateRestore(int version) {
+ SyncPrg();
+ SyncChr();
+ SyncMirr();
+}
+
+static DECLFW(M183Write) {
+ if ((A & 0xF800) == 0x6800) {
+ prg[3] = A & 0x3F;
+ SyncPrg();
+ } else if (((A & 0xF80C) >= 0xB000) && ((A & 0xF80C) <= 0xE00C)) {
+ int index = (((A >> 11) - 6) | (A >> 3)) & 7;
+ chr[index] = (chr[index] & (0xF0 >> (A & 4))) | ((V & 0x0F) << (A & 4));
+ SyncChr();
+ } else switch (A & 0xF80C) {
+ case 0x8800: prg[0] = V; SyncPrg(); break;
+ case 0xA800: prg[1] = V; SyncPrg(); break;
+ case 0xA000: prg[2] = V; SyncPrg(); break;
+ case 0x9800: mirr = V & 3; SyncMirr(); break;
+ case 0xF000: IRQCount = ((IRQCount & 0xF0) | (V & 0xF)); break;
+ case 0xF004: IRQCount = ((IRQCount & 0x0F) | ((V & 0xF) << 4)); break;
+ case 0xF008: IRQa = V; if (!V) IRQPre = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xF00C: IRQPre = 16; break;
+ }
+}
+
+static void M183IRQCounter(void) {
+ if (IRQa) {
+ IRQCount++;
+ if ((IRQCount - IRQPre) == 238)
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+}
+
+static void M183Power(void) {
+ IRQPre = IRQCount = IRQa = 0;
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0xFFFF, M183Write);
+ SyncPrg();
+ SyncChr();
+}
+
+void Mapper183_Init(CartInfo *info) {
+ info->Power = M183Power;
+ GameHBIRQHook = M183IRQCounter;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/185.cpp b/source/fceux/boards/185.cpp
new file mode 100644
index 0000000..756864e
--- /dev/null
+++ b/source/fceux/boards/185.cpp
@@ -0,0 +1,107 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 *DummyCHR = NULL;
+static uint8 datareg;
+static void (*Sync)(void);
+
+
+static SFORMAT StateRegs[] =
+{
+ { &datareg, 1, "DREG" },
+ { 0 }
+};
+
+// on off
+//1 0x0F, 0xF0 - Bird Week
+//2 0x33, 0x00 - B-Wings
+//3 0x11, 0x00 - Mighty Bomb Jack
+//4 0x22, 0x20 - Sansuu 1 Nen, Sansuu 2 Nen
+//5 0xFF, 0x00 - Sansuu 3 Nen
+//6 0x21, 0x13 - Spy vs Spy
+//7 0x20, 0x21 - Seicross
+
+static void Sync185(void) {
+ // little dirty eh? ;_)
+ if ((datareg & 3) && (datareg != 0x13)) // 1, 2, 3, 4, 5, 6
+ setchr8(0);
+ else
+ setchr8r(0x10, 0);
+}
+
+static void Sync181(void) {
+ if (!(datareg & 1)) // 7
+ setchr8(0);
+ else
+ setchr8r(0x10, 0);
+}
+
+static DECLFW(MWrite) {
+ datareg = V;
+ Sync();
+}
+
+static void MPower(void) {
+ datareg = 0;
+ Sync();
+ setprg16(0x8000, 0);
+ setprg16(0xC000, ~0);
+ SetWriteHandler(0x8000, 0xFFFF, MWrite);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void MClose(void) {
+ if (DummyCHR)
+ FCEU_gfree(DummyCHR);
+ DummyCHR = NULL;
+}
+
+static void MRestore(int version) {
+ Sync();
+}
+
+void Mapper185_Init(CartInfo *info) {
+ Sync = Sync185;
+ info->Power = MPower;
+ info->Close = MClose;
+ GameStateRestore = MRestore;
+ DummyCHR = (uint8*)FCEU_gmalloc(8192);
+ int x;
+ for (x = 0; x < 8192; x++)
+ DummyCHR[x] = 0xff;
+ SetupCartCHRMapping(0x10, DummyCHR, 8192, 0);
+ AddExState(StateRegs, ~0, 0, 0);
+}
+
+void Mapper181_Init(CartInfo *info) {
+ Sync = Sync181;
+ info->Power = MPower;
+ info->Close = MClose;
+ GameStateRestore = MRestore;
+ DummyCHR = (uint8*)FCEU_gmalloc(8192);
+ int x;
+ for (x = 0; x < 8192; x++)
+ DummyCHR[x] = 0xff;
+ SetupCartCHRMapping(0x10, DummyCHR, 8192, 0);
+ AddExState(StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/186.cpp b/source/fceux/boards/186.cpp
new file mode 100644
index 0000000..045a0da
--- /dev/null
+++ b/source/fceux/boards/186.cpp
@@ -0,0 +1,122 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Family Study Box by Fukutake Shoten
+ *
+ * REG[0] R dddddddd / W ww---sss
+ * ddd - TAPE DATA BYTE (ready when IRQ occurs)
+ * sss - BRAM hi-bank
+ * ww - PRAM bank
+ * REG[1] R 0123---- / W ----PPPP
+ * 0 - ?
+ * 1 - ?
+ * 2 - ?
+ * 3 - ?
+ * PPPP- PROM bank
+ * REG[2] R -?--R--- / W A-BC-DEF
+ * 4 - ?
+ * R - sb4x power supply status (active low)
+ * A - ?
+ * B - ?
+ * C - ?
+ * D - ?
+ * E - ?
+ * F - ?
+ *
+ * BRAM0 4400-4FFF, 3K bank 0 (32K SWRAM) [hardwired]
+ * BRAMB 5000-5FFF, 4K banks 1-7 (32K SWRAM) [REG[0] W -----sss]
+ * PRAMB 6000-7FFF, 8K banks 1-3 (32K PRAM) [REG[0] W ww------]
+ * PROMB 8000-BFFF, 16K banks 1-15 (256K PROM)[REG[1] W ----PPPP]
+ * PROM0 C000-FFFF, 16K bank 0 (256K PROM) [hardwired]
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 SWRAM[3072];
+static uint8 *WRAM = NULL;
+static uint8 regs[4];
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 4, "DREG" },
+ { SWRAM, 3072, "SWRM" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8r(0x10, 0x6000, regs[0] >> 6);
+ setprg16(0x8000, regs[1]);
+ setprg16(0xc000, 0);
+}
+
+static DECLFW(M186Write) {
+ if (A & 0x4203) regs[A & 3] = V;
+ Sync();
+}
+
+static DECLFR(M186Read) {
+ switch (A) {
+ case 0x4200: return 0x00; break;
+ case 0x4201: return 0x00; break;
+ case 0x4202: return 0x40; break;
+ case 0x4203: return 0x00; break;
+ }
+ return 0xFF;
+}
+
+static DECLFR(ASWRAM) {
+ return(SWRAM[A - 0x4400]);
+}
+static DECLFW(BSWRAM) {
+ SWRAM[A - 0x4400] = V;
+}
+
+static void M186Power(void) {
+ setchr8(0);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0xFFFF, CartBW);
+ SetReadHandler(0x4200, 0x43FF, M186Read);
+ SetWriteHandler(0x4200, 0x43FF, M186Write);
+ SetReadHandler(0x4400, 0x4FFF, ASWRAM);
+ SetWriteHandler(0x4400, 0x4FFF, BSWRAM);
+ FCEU_CheatAddRAM(32, 0x6000, WRAM);
+ regs[0] = regs[1] = regs[2] = regs[3];
+ Sync();
+}
+
+static void M186Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void M186Restore(int version) {
+ Sync();
+}
+
+void Mapper186_Init(CartInfo *info) {
+ info->Power = M186Power;
+ info->Close = M186Close;
+ GameStateRestore = M186Restore;
+ WRAM = (uint8*)FCEU_gmalloc(32768);
+ SetupCartPRGMapping(0x10, WRAM, 32768, 1);
+ AddExState(WRAM, 32768, 0, "WRAM");
+ AddExState(StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/187.cpp b/source/fceux/boards/187.cpp
new file mode 100644
index 0000000..6e5baa2
--- /dev/null
+++ b/source/fceux/boards/187.cpp
@@ -0,0 +1,84 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static void M187CW(uint32 A, uint8 V) {
+ if ((A & 0x1000) == ((MMC3_cmd & 0x80) << 5))
+ setchr1(A, V | 0x100);
+ else
+ setchr1(A, V);
+}
+
+static void M187PW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x80) {
+ uint8 bank = EXPREGS[0] & 0x1F;
+ if (EXPREGS[0] & 0x20) {
+ if (EXPREGS[0] & 0x40)
+ setprg32(0x8000, bank >> 2);
+ else
+ setprg32(0x8000, bank >> 1); // hacky hacky! two mappers in one! need real hw carts to test
+ } else {
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else
+ setprg8(A, V & 0x3F);
+}
+
+static DECLFW(M187Write8000) {
+ EXPREGS[1] = 1;
+ MMC3_CMDWrite(A, V);
+}
+
+static DECLFW(M187Write8001) {
+ if (EXPREGS[1])
+ MMC3_CMDWrite(A, V);
+}
+
+static DECLFW(M187WriteLo) {
+ if ((A == 0x5000) || (A == 0x6000)) {
+ EXPREGS[0] = V;
+ FixMMC3PRG(MMC3_cmd);
+ }
+}
+
+static uint8 prot_data[4] = { 0x83, 0x83, 0x42, 0x00 };
+static DECLFR(M187Read) {
+ return prot_data[EXPREGS[1] & 3];
+}
+
+static void M187Power(void) {
+ EXPREGS[0] = EXPREGS[1] = 0;
+ GenMMC3Power();
+ SetReadHandler(0x5000, 0x5FFF, M187Read);
+ SetWriteHandler(0x5000, 0x6FFF, M187WriteLo);
+ SetWriteHandler(0x8000, 0x8000, M187Write8000);
+ SetWriteHandler(0x8001, 0x8001, M187Write8001);
+}
+
+void Mapper187_Init(CartInfo *info) {
+ GenMMC3_Init(info, 256, 256, 0, 0);
+ pwrap = M187PW;
+ cwrap = M187CW;
+ info->Power = M187Power;
+ AddExState(EXPREGS, 3, 0, "EXPR");
+}
diff --git a/source/fceux/boards/189.cpp b/source/fceux/boards/189.cpp
new file mode 100644
index 0000000..fb60b1b
--- /dev/null
+++ b/source/fceux/boards/189.cpp
@@ -0,0 +1,44 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static void M189PW(uint32 A, uint8 V) {
+ setprg32(0x8000, EXPREGS[0] & 7);
+}
+
+static DECLFW(M189Write) {
+ EXPREGS[0] = V | (V >> 4); //actually, there is a two versions of 189 mapper with hi or lo bits bankswitching.
+ FixMMC3PRG(MMC3_cmd);
+}
+
+static void M189Power(void) {
+ EXPREGS[0] = EXPREGS[1] = 0;
+ GenMMC3Power();
+ SetWriteHandler(0x4120, 0x7FFF, M189Write);
+}
+
+void Mapper189_Init(CartInfo *info) {
+ GenMMC3_Init(info, 256, 256, 0, 0);
+ pwrap = M189PW;
+ info->Power = M189Power;
+ AddExState(EXPREGS, 2, 0, "EXPR");
+}
diff --git a/source/fceux/boards/190.cpp b/source/fceux/boards/190.cpp
new file mode 100644
index 0000000..85b4730
--- /dev/null
+++ b/source/fceux/boards/190.cpp
@@ -0,0 +1,85 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright (C) 2017 FCEUX Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Magic Kid GooGoo
+ */
+
+#include "mapinc.h"
+
+static uint8 prgr, chrr[4];
+static uint8 *WRAM = NULL;
+
+static void Mapper190_Sync(void) {
+ setprg8r(0x10, 0x6000, 0);
+
+ setprg16(0x8000, prgr);
+ setprg16(0xC000, 0);
+ setchr2(0x0000, chrr[0]);
+ setchr2(0x0800, chrr[1]);
+ setchr2(0x1000, chrr[2]);
+ setchr2(0x1800, chrr[3]);
+}
+
+static DECLFW(Mapper190_Write89) { prgr = V&7; Mapper190_Sync(); }
+static DECLFW(Mapper190_WriteCD) { prgr = 8|(V&7); Mapper190_Sync(); }
+
+static DECLFW(Mapper190_WriteAB) {
+ int bank = A&3;
+ chrr[bank] = V&63;
+ Mapper190_Sync();
+}
+
+
+static void Mapper190_Power(void) {
+ FCEU_CheatAddRAM(0x2000 >> 10, 0x6000, WRAM);
+
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetWriteHandler(0x8000, 0x9FFF, Mapper190_Write89);
+ SetWriteHandler(0xA000, 0xBFFF, Mapper190_WriteAB);
+ SetWriteHandler(0xC000, 0xDFFF, Mapper190_WriteCD);
+ Mapper190_Sync();
+
+ setmirror(MI_V);
+}
+
+static void Mapper190_Close(void) {
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void Mapper190_Restore(int) {
+ Mapper190_Sync();
+}
+
+
+void Mapper190_Init(CartInfo *info) {
+ info->Power = Mapper190_Power;
+ info->Close = Mapper190_Close;
+ GameStateRestore = Mapper190_Restore;
+
+ WRAM = (uint8*)FCEU_gmalloc(0x2000);
+ SetupCartPRGMapping(0x10, WRAM, 0x2000, 1);
+
+ chrr[0] = chrr[1] = chrr[2] = chrr[3] = prgr = 0;
+
+ AddExState(&prgr, 1, 0, "PRGR");
+ AddExState(chrr, 4, 0, "CHRR");
+ AddExState(WRAM, 0x2000, 0, "WRAM");
+}
diff --git a/source/fceux/boards/193.cpp b/source/fceux/boards/193.cpp
new file mode 100644
index 0000000..12e96a1
--- /dev/null
+++ b/source/fceux/boards/193.cpp
@@ -0,0 +1,71 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[8];
+static uint8 mirror, cmd, bank;
+
+static SFORMAT StateRegs[] =
+{
+ { &cmd, 1, "CMD" },
+ { &mirror, 1, "MIRR" },
+ { &bank, 1, "BANK" },
+ { reg, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(mirror ^ 1);
+ setprg8(0x8000, reg[3]);
+ setprg8(0xA000, 0xD);
+ setprg8(0xC000, 0xE);
+ setprg8(0xE000, 0xF);
+ setchr4(0x0000, reg[0] >> 2);
+ setchr2(0x1000, reg[1] >> 1);
+ setchr2(0x1800, reg[2] >> 1);
+}
+
+static DECLFW(M193Write) {
+ reg[A & 3] = V;
+ Sync();
+}
+
+static void M193Power(void) {
+ bank = 0;
+ Sync();
+ SetWriteHandler(0x6000, 0x6003, M193Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, CartBW);
+}
+
+static void M193Reset(void) {
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper193_Init(CartInfo *info) {
+ info->Reset = M193Reset;
+ info->Power = M193Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/199.cpp b/source/fceux/boards/199.cpp
new file mode 100644
index 0000000..2a8ad05
--- /dev/null
+++ b/source/fceux/boards/199.cpp
@@ -0,0 +1,97 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Dragon Ball Z 2 - Gekishin Freeza! (C)
+ * Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (C)
+ * San Guo Zhi 2 (C)
+ *
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static uint8 *CHRRAM = NULL;
+static uint32 CHRRAMSIZE;
+
+static void M199PW(uint32 A, uint8 V) {
+ setprg8(A, V);
+ setprg8(0xC000, EXPREGS[0]);
+ setprg8(0xE000, EXPREGS[1]);
+}
+
+static void M199CW(uint32 A, uint8 V) {
+ setchr1r((V < 8) ? 0x10 : 0x00, A, V);
+ setchr1r((DRegBuf[0] < 8) ? 0x10 : 0x00, 0x0000, DRegBuf[0]);
+ setchr1r((EXPREGS[2] < 8) ? 0x10 : 0x00, 0x0400, EXPREGS[2]);
+ setchr1r((DRegBuf[1] < 8) ? 0x10 : 0x00, 0x0800, DRegBuf[1]);
+ setchr1r((EXPREGS[3] < 8) ? 0x10 : 0x00, 0x0c00, EXPREGS[3]);
+}
+
+static void M199MW(uint8 V) {
+// FCEU_printf("%02x\n",V);
+ switch (V & 3) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static DECLFW(M199Write) {
+ if ((A == 0x8001) && (MMC3_cmd & 8)) {
+ EXPREGS[MMC3_cmd & 3] = V;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+ } else
+ if (A < 0xC000)
+ MMC3_CMDWrite(A, V);
+ else
+ MMC3_IRQWrite(A, V);
+}
+
+static void M199Power(void) {
+ EXPREGS[0] = ~1;
+ EXPREGS[1] = ~0;
+ EXPREGS[2] = 1;
+ EXPREGS[3] = 3;
+ GenMMC3Power();
+ SetWriteHandler(0x8000, 0xFFFF, M199Write);
+}
+
+static void M199Close(void) {
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ CHRRAM = NULL;
+}
+
+void Mapper199_Init(CartInfo *info) {
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap = M199CW;
+ pwrap = M199PW;
+ mwrap = M199MW;
+ info->Power = M199Power;
+ info->Close = M199Close;
+
+ CHRRAMSIZE = 8192;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
+
+ AddExState(EXPREGS, 4, 0, "EXPR");
+}
diff --git a/source/fceux/boards/206.cpp b/source/fceux/boards/206.cpp
new file mode 100644
index 0000000..d013a8f
--- /dev/null
+++ b/source/fceux/boards/206.cpp
@@ -0,0 +1,78 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 cmd;
+static uint8 DRegs[8];
+
+static SFORMAT StateRegs[] =
+{
+ { &cmd, 1, "CMD" },
+ { DRegs, 8, "DREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr2(0x0000, DRegs[0]);
+ setchr2(0x0800, DRegs[1]);
+ int x;
+ for (x = 0; x < 4; x++)
+ setchr1(0x1000 + (x << 10), DRegs[2 + x]);
+ setprg8(0x8000, DRegs[6]);
+ setprg8(0xa000, DRegs[7]);
+ setprg8(0xc000, ~1);
+ setprg8(0xe000, ~0);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+static DECLFW(M206Write) {
+ switch (A & 0x8001) {
+ case 0x8000: cmd = V & 0x07; break;
+ case 0x8001:
+ if (cmd <= 0x05)
+ V &= 0x3F;
+ else
+ V &= 0x0F;
+ if (cmd <= 0x01) V >>= 1;
+ DRegs[cmd & 0x07] = V;
+ Sync();
+ break;
+ }
+}
+
+static void M206Power(void) {
+ cmd = 0;
+ DRegs[6] = 0;
+ DRegs[7] = 1;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M206Write);
+}
+
+
+void Mapper206_Init(CartInfo *info) {
+ info->Power = M206Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/208.cpp b/source/fceux/boards/208.cpp
new file mode 100644
index 0000000..d581b1e
--- /dev/null
+++ b/source/fceux/boards/208.cpp
@@ -0,0 +1,78 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static uint8 lut[256] = {
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
+ 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
+ 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
+ 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static void M208PW(uint32 A, uint8 V) {
+ setprg32(0x8000, EXPREGS[5]);
+}
+
+static DECLFW(M208Write) {
+ EXPREGS[5] = (V & 0x1) | ((V >> 3) & 0x2);
+ FixMMC3PRG(MMC3_cmd);
+}
+
+static DECLFW(M208ProtWrite) {
+ if (A <= 0x57FF)
+ EXPREGS[4] = V;
+ else
+ EXPREGS[(A & 0x03)] = V ^ lut[EXPREGS[4]];
+}
+
+static DECLFR(M208ProtRead) {
+ return(EXPREGS[(A & 0x3)]);
+}
+
+static void M208Power(void) {
+ EXPREGS[5] = 3;
+ GenMMC3Power();
+ SetWriteHandler(0x4800, 0x4fff, M208Write);
+ SetWriteHandler(0x6800, 0x6fff, M208Write);
+ SetWriteHandler(0x5000, 0x5fff, M208ProtWrite);
+ SetReadHandler(0x5800, 0x5fff, M208ProtRead);
+ SetReadHandler(0x8000, 0xffff, CartBR);
+}
+
+void Mapper208_Init(CartInfo *info) {
+ GenMMC3_Init(info, 128, 256, 0, 0);
+ pwrap = M208PW;
+ info->Power = M208Power;
+ AddExState(EXPREGS, 6, 0, "EXPR");
+}
diff --git a/source/fceux/boards/222.cpp b/source/fceux/boards/222.cpp
new file mode 100644
index 0000000..0db78c7
--- /dev/null
+++ b/source/fceux/boards/222.cpp
@@ -0,0 +1,99 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * (VRC4 mapper)
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 IRQCount;
+static uint8 IRQa;
+static uint8 prg_reg[2];
+static uint8 chr_reg[8];
+static uint8 mirr;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQCount, 1, "IRQC" },
+ { &IRQa, 1, "IRQA" },
+ { prg_reg, 2, "PRG" },
+ { chr_reg, 8, "CHR" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void M222IRQ(void) {
+ if (IRQa) {
+ IRQCount++;
+ if (IRQCount >= 238) {
+ X6502_IRQBegin(FCEU_IQEXT);
+// IRQa=0;
+ }
+ }
+}
+
+static void Sync(void) {
+ setprg8(0x8000, prg_reg[0]);
+ setprg8(0xA000, prg_reg[1]);
+ int i;
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, chr_reg[i]);
+ setmirror(mirr ^ 1);
+}
+
+static DECLFW(M222Write) {
+ switch (A & 0xF003) {
+ case 0x8000: prg_reg[0] = V; break;
+ case 0x9000: mirr = V & 1; break;
+ case 0xA000: prg_reg[1] = V; break;
+ case 0xB000: chr_reg[0] = V; break;
+ case 0xB002: chr_reg[1] = V; break;
+ case 0xC000: chr_reg[2] = V; break;
+ case 0xC002: chr_reg[3] = V; break;
+ case 0xD000: chr_reg[4] = V; break;
+ case 0xD002: chr_reg[5] = V; break;
+ case 0xE000: chr_reg[6] = V; break;
+ case 0xE002: chr_reg[7] = V; break;
+// case 0xF000: FCEU_printf("%04x:%02x %d\n",A,V,scanline); IRQa=V; if(!V)IRQPre=0; X6502_IRQEnd(FCEU_IQEXT); break;
+// case 0xF001: FCEU_printf("%04x:%02x %d\n",A,V,scanline); IRQCount=V; break;
+// case 0xF002: FCEU_printf("%04x:%02x %d\n",A,V,scanline); break;
+// case 0xD001: IRQa=V; X6502_IRQEnd(FCEU_IQEXT); FCEU_printf("%04x:%02x %d\n",A,V,scanline); break;
+// case 0xC001: IRQPre=16; FCEU_printf("%04x:%02x %d\n",A,V,scanline); break;
+ case 0xF000: IRQa = IRQCount = V; if (scanline < 240) IRQCount -= 8; else IRQCount += 4; X6502_IRQEnd(FCEU_IQEXT); break;
+ }
+ Sync();
+}
+
+static void M222Power(void) {
+ setprg16(0xC000, ~0);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M222Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper222_Init(CartInfo *info) {
+ info->Power = M222Power;
+ GameHBIRQHook = M222IRQ;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/225.cpp b/source/fceux/boards/225.cpp
new file mode 100644
index 0000000..fd008ea
--- /dev/null
+++ b/source/fceux/boards/225.cpp
@@ -0,0 +1,86 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2011 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 prot[4], prg, mode, chr, mirr;
+
+static SFORMAT StateRegs[] =
+{
+ { prot, 4, "PROT" },
+ { &prg, 1, "PRG" },
+ { &chr, 1, "CHR" },
+ { &mode, 1, "MODE" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if (mode) {
+ setprg16(0x8000, prg);
+ setprg16(0xC000, prg);
+ } else
+ setprg32(0x8000, prg >> 1);
+ setchr8(chr);
+ setmirror(mirr ^ 1);
+}
+
+static DECLFW(M225Write) {
+ uint32 bank = (A >> 14) & 1;
+ mirr = (A >> 13) & 1;
+ mode = (A >> 12) & 1;
+ chr = (A & 0x3f) | (bank << 6);
+ prg = ((A >> 6) & 0x3f) | (bank << 6);
+ Sync();
+}
+
+static DECLFW(M225LoWrite) {
+}
+
+static DECLFR(M225LoRead) {
+ return 0;
+}
+
+static void M225Power(void) {
+ prg = 0;
+ mode = 0;
+ Sync();
+ SetReadHandler(0x5000, 0x5FFF, M225LoRead);
+ SetWriteHandler(0x5000, 0x5FFF, M225LoWrite);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M225Write);
+}
+
+static void M225Reset(void) {
+ prg = 0;
+ mode = 0;
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper225_Init(CartInfo *info) {
+ info->Reset = M225Reset;
+ info->Power = M225Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/228.cpp b/source/fceux/boards/228.cpp
new file mode 100644
index 0000000..e64c6ac
--- /dev/null
+++ b/source/fceux/boards/228.cpp
@@ -0,0 +1,85 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 mram[4], vreg;
+static uint16 areg;
+
+static SFORMAT StateRegs[] =
+{
+ { mram, 4, "MRAM" },
+ { &areg, 2, "AREG" },
+ { &vreg, 1, "VREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint32 prgl, prgh, page = (areg >> 7) & 0x3F;
+ if ((page & 0x30) == 0x30)
+ page -= 0x10;
+ prgl = prgh = (page << 1) + (((areg >> 6) & 1) & ((areg >> 5) & 1));
+ prgh += ((areg >> 5) & 1) ^ 1;
+
+ setmirror(((areg >> 13) & 1) ^ 1);
+ setprg16(0x8000,prgl);
+ setprg16(0xc000,prgh);
+ setchr8(((vreg & 0x3) | ((areg & 0xF) << 2)));
+}
+
+static DECLFW(M228RamWrite) {
+ mram[A & 3] = V & 0x0F;
+}
+
+static DECLFR(M228RamRead) {
+ return mram[A & 3];
+}
+
+static DECLFW(M228Write) {
+ areg = A;
+ vreg = V;
+ Sync();
+}
+
+static void M228Reset(void) {
+ areg = 0x8000;
+ vreg = 0;
+ memset(mram, 0, sizeof(mram));
+ Sync();
+}
+
+static void M228Power(void) {
+ M228Reset();
+ SetReadHandler(0x5000,0x5FFF,M228RamRead);
+ SetWriteHandler(0x5000,0x5FFF,M228RamWrite);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M228Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper228_Init(CartInfo *info) {
+ info->Reset = M228Reset;
+ info->Power = M228Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/230.cpp b/source/fceux/boards/230.cpp
new file mode 100644
index 0000000..0da975d
--- /dev/null
+++ b/source/fceux/boards/230.cpp
@@ -0,0 +1,78 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ * Copyright (C) 2009 qeed
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * 22 + Contra Reset based custom mapper...
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 latche, reset;
+static SFORMAT StateRegs[] =
+{
+ { &reset, 1, "RST" },
+ { &latche, 1, "LATC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if(reset) {
+ setprg16(0x8000, latche & 7);
+ setprg16(0xC000, 7);
+ setmirror(MI_V);
+ } else {
+ uint32 bank = (latche & 0x1F) + 8;
+ if (latche & 0x20) {
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ } else
+ setprg32(0x8000, bank >> 1);
+ setmirror((latche >> 6) & 1);
+ }
+ setchr8(0);
+}
+
+static DECLFW(M230Write) {
+ latche = V;
+ Sync();
+}
+
+static void M230Reset(void) {
+ reset ^= 1;
+ Sync();
+}
+
+static void M230Power(void) {
+ latche = reset = 0;
+ Sync();
+ SetWriteHandler(0x8000, 0xFFFF, M230Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper230_Init(CartInfo *info) {
+ info->Power = M230Power;
+ info->Reset = M230Reset;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/232.cpp b/source/fceux/boards/232.cpp
new file mode 100644
index 0000000..86bb0d0
--- /dev/null
+++ b/source/fceux/boards/232.cpp
@@ -0,0 +1,68 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 bank, preg;
+static SFORMAT StateRegs[] =
+{
+ { &bank, 1, "BANK" },
+ { &preg, 1, "PREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+// uint32 bbank = (bank & 0x18) >> 1;
+ uint32 bbank = ((bank & 0x10) >> 2) | (bank & 8); // some dumps have bbanks swapped, if swap commands,
+ // then all roms can be played, but with some swapped
+ // games in menu. if not, some dumps are unplayable
+ // make hard dump for both cart types to check
+ setprg16(0x8000, bbank | (preg & 3));
+ setprg16(0xC000, bbank | 3);
+ setchr8(0);
+}
+
+static DECLFW(M232WriteBank) {
+ bank = V;
+ Sync();
+}
+
+static DECLFW(M232WritePreg) {
+ preg = V;
+ Sync();
+}
+
+static void M232Power(void) {
+ bank = preg = 0;
+ Sync();
+ SetWriteHandler(0x8000, 0xBFFF, M232WriteBank);
+ SetWriteHandler(0xC000, 0xFFFF, M232WritePreg);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper232_Init(CartInfo *info) {
+ info->Power = M232Power;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/234.cpp b/source/fceux/boards/234.cpp
new file mode 100644
index 0000000..ef47123
--- /dev/null
+++ b/source/fceux/boards/234.cpp
@@ -0,0 +1,79 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 bank, preg;
+static SFORMAT StateRegs[] =
+{
+ { &bank, 1, "BANK" },
+ { &preg, 1, "PREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if (bank & 0x40) {
+ setprg32(0x8000, (bank & 0xE) | (preg & 1));
+ setchr8(((bank & 0xE) << 2) | ((preg >> 4) & 7));
+ } else {
+ setprg32(0x8000, bank & 0xF);
+ setchr8(((bank & 0xF) << 2) | ((preg >> 4) & 3));
+ }
+ setmirror((bank >> 7) ^ 1);
+}
+
+DECLFR(M234ReadBank) {
+ uint8 r = CartBR(A);
+ if (!bank) {
+ bank = r;
+ Sync();
+ }
+ return r;
+}
+
+DECLFR(M234ReadPreg) {
+ uint8 r = CartBR(A);
+ preg = r;
+ Sync();
+ return r;
+}
+
+static void M234Reset(void) {
+ bank = preg = 0;
+ Sync();
+}
+
+static void M234Power(void) {
+ M234Reset();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetReadHandler(0xFF80, 0xFF9F, M234ReadBank);
+ SetReadHandler(0xFFE8, 0xFFF7, M234ReadPreg);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper234_Init(CartInfo *info) {
+ info->Power = M234Power;
+ info->Reset = M234Reset;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/235.cpp b/source/fceux/boards/235.cpp
new file mode 100644
index 0000000..98ce11b
--- /dev/null
+++ b/source/fceux/boards/235.cpp
@@ -0,0 +1,63 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint16 cmdreg;
+static SFORMAT StateRegs[] =
+{
+ { &cmdreg, 2, "CREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if (cmdreg & 0x400)
+ setmirror(MI_0);
+ else
+ setmirror(((cmdreg >> 13) & 1) ^ 1);
+ if (cmdreg & 0x800) {
+ setprg16(0x8000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1));
+ setprg16(0xC000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1));
+ } else
+ setprg32(0x8000, ((cmdreg & 0x300) >> 4) | (cmdreg & 0x1F));
+}
+
+static DECLFW(M235Write) {
+ cmdreg = A;
+ Sync();
+}
+
+static void M235Power(void) {
+ setchr8(0);
+ SetWriteHandler(0x8000, 0xFFFF, M235Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ cmdreg = 0;
+ Sync();
+}
+
+static void M235Restore(int version) {
+ Sync();
+}
+
+void Mapper235_Init(CartInfo *info) {
+ info->Power = M235Power;
+ GameStateRestore = M235Restore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/244.cpp b/source/fceux/boards/244.cpp
new file mode 100644
index 0000000..67c3369
--- /dev/null
+++ b/source/fceux/boards/244.cpp
@@ -0,0 +1,77 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg, creg;
+static SFORMAT StateRegs[] =
+{
+ { &preg, 1, "PREG" },
+ { &creg, 1, "CREG" },
+ { 0 }
+};
+
+static uint8 prg_perm[4][4] = {
+ { 0, 1, 2, 3, },
+ { 3, 2, 1, 0, },
+ { 0, 2, 1, 3, },
+ { 3, 1, 2, 0, },
+};
+
+static uint8 chr_perm[8][8] = {
+ { 0, 1, 2, 3, 4, 5, 6, 7, },
+ { 0, 2, 1, 3, 4, 6, 5, 7, },
+ { 0, 1, 4, 5, 2, 3, 6, 7, },
+ { 0, 4, 1, 5, 2, 6, 3, 7, },
+ { 0, 4, 2, 6, 1, 5, 3, 7, },
+ { 0, 2, 4, 6, 1, 3, 5, 7, },
+ { 7, 6, 5, 4, 3, 2, 1, 0, },
+ { 7, 6, 5, 4, 3, 2, 1, 0, },
+};
+
+static void Sync(void) {
+ setprg32(0x8000, preg);
+ setchr8(creg);
+}
+
+static DECLFW(M244Write) {
+ if (V & 8)
+ creg = chr_perm[(V >> 4) & 7][V & 7];
+ else
+ preg = prg_perm[(V >> 4) & 3][V & 3];
+ Sync();
+}
+
+static void M244Power(void) {
+ preg = creg = 0;
+ Sync();
+ SetWriteHandler(0x8000, 0xFFFF, M244Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper244_Init(CartInfo *info) {
+ info->Power = M244Power;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/246.cpp b/source/fceux/boards/246.cpp
new file mode 100644
index 0000000..ec069de
--- /dev/null
+++ b/source/fceux/boards/246.cpp
@@ -0,0 +1,87 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 regs[8];
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg2r(0x10, 0x6800, 0);
+ setprg8(0x8000, regs[0]);
+ setprg8(0xA000, regs[1]);
+ setprg8(0xC000, regs[2]);
+ setprg8(0xE000, regs[3]);
+ setchr2(0x0000, regs[4]);
+ setchr2(0x0800, regs[5]);
+ setchr2(0x1000, regs[6]);
+ setchr2(0x1800, regs[7]);
+}
+
+static DECLFW(M246Write) {
+ regs[A & 7] = V;
+ Sync();
+}
+
+static void M246Power(void) {
+ regs[0] = regs[1] = regs[2] = regs[3] = ~0;
+ Sync();
+ SetWriteHandler(0x6000, 0x67FF, M246Write);
+ SetReadHandler(0x6800, 0x6FFF, CartBR);
+ SetWriteHandler(0x6800, 0x6FFF, CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M246Close(void)
+{
+ if(WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper246_Init(CartInfo *info) {
+ info->Power = M246Power;
+ info->Close = M246Close;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 2048;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/252.cpp b/source/fceux/boards/252.cpp
new file mode 100644
index 0000000..9962e08
--- /dev/null
+++ b/source/fceux/boards/252.cpp
@@ -0,0 +1,135 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 creg[8], preg[2];
+static int32 IRQa, IRQCount, IRQClock, IRQLatch;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+static uint8 *CHRRAM = NULL;
+static uint32 CHRRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { creg, 8, "CREG" },
+ { preg, 2, "PREG" },
+ { &IRQa, 4, "IRQA" },
+ { &IRQCount, 4, "IRQC" },
+ { &IRQLatch, 4, "IRQL" },
+ { &IRQClock, 4, "IRQK" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint8 i;
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000, preg[0]);
+ setprg8(0xa000, preg[1]);
+ setprg8(0xc000, ~1);
+ setprg8(0xe000, ~0);
+ for (i = 0; i < 8; i++)
+ if ((creg[i] == 6) || (creg[i] == 7))
+ setchr1r(0x10, i << 10, creg[i] & 1);
+ else
+ setchr1(i << 10, creg[i]);
+}
+
+static DECLFW(M252Write) {
+ if ((A >= 0xB000) && (A <= 0xEFFF)) {
+ uint8 ind = ((((A & 8) | (A >> 8)) >> 3) + 2) & 7;
+ uint8 sar = A & 4;
+ creg[ind] = (creg[ind] & (0xF0 >> sar)) | ((V & 0x0F) << sar);
+ Sync();
+ } else
+ switch (A & 0xF00C) {
+ case 0x8000:
+ case 0x8004:
+ case 0x8008:
+ case 0x800C: preg[0] = V; Sync(); break;
+ case 0xA000:
+ case 0xA004:
+ case 0xA008:
+ case 0xA00C: preg[1] = V; Sync(); break;
+ case 0xF000: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xF0; IRQLatch |= V & 0xF; break;
+ case 0xF004: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0x0F; IRQLatch |= V << 4; break;
+ case 0xF008: X6502_IRQEnd(FCEU_IQEXT); IRQClock = 0; IRQCount = IRQLatch; IRQa = V & 2; break;
+ }
+}
+
+static void M252Power(void) {
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M252Write);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M252IRQ(int a) {
+ #define LCYCS 341
+ if (IRQa) {
+ IRQClock += a * 3;
+ if (IRQClock >= LCYCS) {
+ while (IRQClock >= LCYCS) {
+ IRQClock -= LCYCS;
+ IRQCount++;
+ if (IRQCount & 0x100) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQCount = IRQLatch;
+ }
+ }
+ }
+ }
+}
+
+static void M252Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ WRAM = CHRRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper252_Init(CartInfo *info) {
+ info->Power = M252Power;
+ info->Close = M252Close;
+ MapIRQHook = M252IRQ;
+
+ CHRRAMSIZE = 2048;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/253.cpp b/source/fceux/boards/253.cpp
new file mode 100644
index 0000000..3ed9bfe
--- /dev/null
+++ b/source/fceux/boards/253.cpp
@@ -0,0 +1,152 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2009 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 chrlo[8], chrhi[8], prg[2], mirr, vlock;
+static int32 IRQa, IRQCount, IRQLatch, IRQClock;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+static uint8 *CHRRAM = NULL;
+static uint32 CHRRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { chrlo, 8, "CHRL" },
+ { chrhi, 8, "CHRH" },
+ { prg, 2, "PRGR" },
+ { &mirr, 1, "MIRR" },
+ { &vlock, 1, "VLCK" },
+ { &IRQa, 4, "IRQA" },
+ { &IRQCount, 4, "IRQC" },
+ { &IRQLatch, 4, "IRQL" },
+ { &IRQClock, 4, "IRQK" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint8 i;
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000, prg[0]);
+ setprg8(0xa000, prg[1]);
+ setprg8(0xc000, ~1);
+ setprg8(0xe000, ~0);
+ for (i = 0; i < 8; i++) {
+ uint32 chr = chrlo[i] | (chrhi[i] << 8);
+ if (((chrlo[i] == 4) || (chrlo[i] == 5)) && !vlock)
+ setchr1r(0x10, i << 10, chr & 1);
+ else
+ setchr1(i << 10, chr);
+ }
+ switch (mirr) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static DECLFW(M253Write) {
+ if ((A >= 0xB000) && (A <= 0xE00C)) {
+ uint8 ind = ((((A & 8) | (A >> 8)) >> 3) + 2) & 7;
+ uint8 sar = A & 4;
+ uint8 clo = (chrlo[ind] & (0xF0 >> sar)) | ((V & 0x0F) << sar);
+ chrlo[ind] = clo;
+ if (ind == 0) {
+ if (clo == 0xc8)
+ vlock = 0;
+ else if (clo == 0x88)
+ vlock = 1;
+ }
+ if (sar)
+ chrhi[ind] = V >> 4;
+ Sync();
+ } else
+ switch (A) {
+ case 0x8010: prg[0] = V; Sync(); break;
+ case 0xA010: prg[1] = V; Sync(); break;
+ case 0x9400: mirr = V & 3; Sync(); break;
+ case 0xF000: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xF0; IRQLatch |= V & 0xF; break;
+ case 0xF004: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0x0F; IRQLatch |= V << 4; break;
+ case 0xF008: X6502_IRQEnd(FCEU_IQEXT); IRQClock = 0; IRQCount = IRQLatch; IRQa = V & 2; break;
+ }
+}
+
+static void M253Power(void) {
+ vlock = 0;
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M253Write);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M253Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ WRAM = CHRRAM = NULL;
+}
+
+static void M253IRQ(int a) {
+ #define LCYCS 341
+ if (IRQa) {
+ IRQClock += a * 3;
+ if (IRQClock >= LCYCS) {
+ while (IRQClock >= LCYCS) {
+ IRQClock -= LCYCS;
+ IRQCount++;
+ if (IRQCount & 0x100) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQCount = IRQLatch;
+ }
+ }
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper253_Init(CartInfo *info) {
+ info->Power = M253Power;
+ info->Close = M253Close;
+ MapIRQHook = M253IRQ;
+ GameStateRestore = StateRestore;
+
+ CHRRAMSIZE = 2048;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/28.cpp b/source/fceux/boards/28.cpp
new file mode 100644
index 0000000..473cca4
--- /dev/null
+++ b/source/fceux/boards/28.cpp
@@ -0,0 +1,217 @@
+/*
+ Copyright (C) 2012-2017 FCEUX team
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the this software. If not, see .
+*/
+
+#include "mapinc.h"
+
+// http://wiki.nesdev.com/w/index.php/INES_Mapper_028
+
+//config
+static int prg_mask_16k;
+
+// state
+uint8 reg;
+uint8 chr;
+uint8 prg;
+uint8 mode;
+uint8 outer;
+
+void SyncMirror()
+{
+ switch (mode & 3)
+ {
+ case 0: setmirror(MI_0); break;
+ case 1: setmirror(MI_1); break;
+ case 2: setmirror(MI_V); break;
+ case 3: setmirror(MI_H); break;
+ }
+}
+
+void Mirror(uint8 value)
+{
+ if ((mode & 2) == 0)
+ {
+ mode &= 0xfe;
+ mode |= value >> 4 & 1;
+ }
+ SyncMirror();
+}
+
+
+static void Sync()
+{
+ int prglo = 0;
+ int prghi = 0;
+
+ int outb = outer << 1;
+ //this can probably be rolled up, but i have no motivation to do so
+ //until it's been tested
+ switch (mode & 0x3c)
+ {
+ //32K modes
+ case 0x00:
+ case 0x04:
+ prglo = outb;
+ prghi = outb | 1;
+ break;
+ case 0x10:
+ case 0x14:
+ prglo = outb & ~2 | prg << 1 & 2;
+ prghi = outb & ~2 | prg << 1 & 2 | 1;
+ break;
+ case 0x20:
+ case 0x24:
+ prglo = outb & ~6 | prg << 1 & 6;
+ prghi = outb & ~6 | prg << 1 & 6 | 1;
+ break;
+ case 0x30:
+ case 0x34:
+ prglo = outb & ~14 | prg << 1 & 14;
+ prghi = outb & ~14 | prg << 1 & 14 | 1;
+ break;
+ //bottom fixed modes
+ case 0x08:
+ prglo = outb;
+ prghi = outb | prg & 1;
+ break;
+ case 0x18:
+ prglo = outb;
+ prghi = outb & ~2 | prg & 3;
+ break;
+ case 0x28:
+ prglo = outb;
+ prghi = outb & ~6 | prg & 7;
+ break;
+ case 0x38:
+ prglo = outb;
+ prghi = outb & ~14 | prg & 15;
+ break;
+ //top fixed modes
+ case 0x0c:
+ prglo = outb | prg & 1;
+ prghi = outb | 1;
+ break;
+ case 0x1c:
+ prglo = outb & ~2 | prg & 3;
+ prghi = outb | 1;
+ break;
+ case 0x2c:
+ prglo = outb & ~6 | prg & 7;
+ prghi = outb | 1;
+ break;
+ case 0x3c:
+ prglo = outb & ~14 | prg & 15;
+ prghi = outb | 1;
+ break;
+ }
+ prglo &= prg_mask_16k;
+ prghi &= prg_mask_16k;
+
+ setprg16(0x8000, prglo);
+ setprg16(0xC000, prghi);
+ setchr8(chr);
+}
+
+static DECLFW(WriteEXP)
+{
+ //uint32 addr = A;
+ uint8 value = V;
+ reg = value & 0x81;
+}
+
+static DECLFW(WritePRG)
+{
+ //uint32 addr = A;
+ uint8 value = V;
+ switch (reg)
+ {
+ case 0x00:
+ chr = value & 3;
+ Mirror(value);
+ Sync();
+ break;
+ case 0x01:
+ prg = value & 15;
+ Mirror(value);
+ Sync();
+ break;
+ case 0x80:
+ mode = value & 63;
+ SyncMirror();
+ Sync();
+ break;
+ case 0x81:
+ outer = value & 63;
+ Sync();
+ break;
+ }
+}
+
+
+
+static void M28Reset(void)
+{
+ outer = 63;
+ prg = 15;
+ Sync();
+}
+
+
+static void M28Power(void)
+{
+ prg_mask_16k = PRGsize[0] - 1;
+
+ //EXP
+ SetWriteHandler(0x5000,0x5FFF,WriteEXP);
+
+ //PRG
+ SetWriteHandler(0x8000,0xFFFF,WritePRG);
+ SetReadHandler(0x8000,0xFFFF,CartBR);
+
+ //WRAM
+ SetReadHandler(0x6000,0x7FFF,CartBR);
+ SetWriteHandler(0x6000,0x7FFF,CartBW);
+
+ M28Reset();
+}
+
+static void M28Close(void)
+{
+}
+
+static SFORMAT StateRegs[]=
+{
+ {®, 1, "REG"},
+ {&chr, 1, "CHR"},
+ {&prg, 1, "PRG"},
+ {&mode, 1, "MODE"},
+ {&outer, 1, "OUTR"},
+ {0}
+};
+
+static void StateRestore(int version)
+{
+ Sync();
+}
+
+void Mapper28_Init(CartInfo* info)
+{
+ info->Power=M28Power;
+ info->Reset=M28Reset;
+ info->Close=M28Close;
+ GameStateRestore=StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/32.cpp b/source/fceux/boards/32.cpp
new file mode 100644
index 0000000..7dd91bb
--- /dev/null
+++ b/source/fceux/boards/32.cpp
@@ -0,0 +1,103 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg[2], creg[8], mirr;
+
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { preg, 4, "PREG" },
+ { creg, 8, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint16 swap = ((mirr & 2) << 13);
+ setmirror((mirr & 1) ^ 1);
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000 ^ swap, preg[0]);
+ setprg8(0xA000, preg[1]);
+ setprg8(0xC000 ^ swap, ~1);
+ setprg8(0xE000, ~0);
+ uint8 i;
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, creg[i]);
+}
+
+static DECLFW(M32Write0) {
+ preg[0] = V;
+ Sync();
+}
+
+static DECLFW(M32Write1) {
+ mirr = V;
+ Sync();
+}
+
+static DECLFW(M32Write2) {
+ preg[1] = V;
+ Sync();
+}
+
+static DECLFW(M32Write3) {
+ creg[A & 7] = V;
+ Sync();
+}
+
+static void M32Power(void) {
+ Sync();
+ SetReadHandler(0x6000,0x7fff,CartBR);
+ SetWriteHandler(0x6000,0x7fff,CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0x8FFF, M32Write0);
+ SetWriteHandler(0x9000, 0x9FFF, M32Write1);
+ SetWriteHandler(0xA000, 0xAFFF, M32Write2);
+ SetWriteHandler(0xB000, 0xBFFF, M32Write3);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M32Close(void)
+{
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper32_Init(CartInfo *info) {
+ info->Power = M32Power;
+ info->Close = M32Close;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/33.cpp b/source/fceux/boards/33.cpp
new file mode 100644
index 0000000..daa6a77
--- /dev/null
+++ b/source/fceux/boards/33.cpp
@@ -0,0 +1,117 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 is48;
+static uint8 regs[8], mirr;
+static uint8 IRQa;
+static int16 IRQCount, IRQLatch;
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 8, "PREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 2, "IRQC" },
+ { &IRQLatch, 2, "IRQL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(mirr);
+ setprg8(0x8000, regs[0]);
+ setprg8(0xA000, regs[1]);
+ setprg8(0xC000, ~1);
+ setprg8(0xE000, ~0);
+ setchr2(0x0000, regs[2]);
+ setchr2(0x0800, regs[3]);
+ setchr1(0x1000, regs[4]);
+ setchr1(0x1400, regs[5]);
+ setchr1(0x1800, regs[6]);
+ setchr1(0x1C00, regs[7]);
+}
+
+static DECLFW(M33Write) {
+ A &= 0xF003;
+ switch(A) {
+ case 0x8000: regs[0] = V & 0x3F; if(!is48) mirr = ((V >> 6) & 1) ^ 1; Sync(); break;
+ case 0x8001: regs[1] = V & 0x3F; Sync(); break;
+ case 0x8002: regs[2] = V; Sync(); break;
+ case 0x8003: regs[3] = V; Sync(); break;
+ case 0xA000: regs[4] = V; Sync(); break;
+ case 0xA001: regs[5] = V; Sync(); break;
+ case 0xA002: regs[6] = V; Sync(); break;
+ case 0xA003: regs[7] = V; Sync(); break;
+ }
+}
+
+static DECLFW(M48Write) {
+ switch (A & 0xF003) {
+ case 0xC000: IRQLatch = V; break;
+ case 0xC001: IRQCount = IRQLatch; break;
+ case 0xC003: IRQa = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xC002: IRQa = 1; break;
+ case 0xE000: mirr = ((V >> 6) & 1) ^ 1; Sync(); break;
+ }
+}
+
+static void M33Power(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M33Write);
+}
+
+static void M48Power(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xBFFF, M33Write);
+ SetWriteHandler(0xC000, 0xFFFF, M48Write);
+}
+
+static void M48IRQ(void) {
+ if (IRQa) {
+ IRQCount++;
+ if (IRQCount == 0x100) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQa = 0;
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper33_Init(CartInfo *info) {
+ is48 = 0;
+ info->Power = M33Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+void Mapper48_Init(CartInfo *info) {
+ is48 = 1;
+ info->Power = M48Power;
+ GameHBIRQHook = M48IRQ;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/34.cpp b/source/fceux/boards/34.cpp
new file mode 100644
index 0000000..5c27b00
--- /dev/null
+++ b/source/fceux/boards/34.cpp
@@ -0,0 +1,93 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Many-in-one hacked mapper crap.
+ *
+ * Original BNROM is actually AxROM variations without mirroring control,
+ * and haven't SRAM on-board, so it must be removed from here
+ *
+ * Difficult banking is what NINA board doing, most hacks for 34 mapper are
+ * NINA hacks, so this is actually 34 mapper
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 regs[3];
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 3, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8r(0x10, 0x6000, 0);
+ setprg32(0x8000, regs[0]);
+ setchr4(0x0000, regs[1]);
+ setchr4(0x1000, regs[2]);
+}
+
+static DECLFW(M34Write) {
+ if (A >= 0x8000)
+ regs[0] = V;
+ else
+ switch (A) {
+ case 0x7ffd: regs[0] = V; break;
+ case 0x7ffe: regs[1] = V; break;
+ case 0x7fff: regs[2] = V; break;
+ }
+ Sync();
+}
+
+static void M34Power(void) {
+ regs[0] = regs[1] = 0;
+ regs[2] = 1;
+ Sync();
+ SetReadHandler(0x6000, 0x7ffc, CartBR);
+ SetWriteHandler(0x6000, 0x7ffc, CartBW);
+ SetReadHandler(0x8000, 0xffff, CartBR);
+ SetWriteHandler(0x7ffd, 0xffff, M34Write);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M34Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper34_Init(CartInfo *info) {
+ info->Power = M34Power;
+ info->Close = M34Close;
+ GameStateRestore = StateRestore;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/36.cpp b/source/fceux/boards/36.cpp
new file mode 100644
index 0000000..dea977e
--- /dev/null
+++ b/source/fceux/boards/36.cpp
@@ -0,0 +1,69 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * TXC/Micro Genius simplified mapper
+ */
+
+#include "mapinc.h"
+
+static uint8 latche, mirr;
+
+static SFORMAT StateRegs[] =
+{
+ { &latche, 1, "LATC" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, latche >> 4);
+ setchr8(latche & 0xf);
+}
+
+static DECLFW(M36Write) {
+
+ switch((A>>12)&7) { // need to 4-in-1 MGC-26 BMC, doesnt break other games though
+ case 0: mirr = MI_V; setmirror(mirr); break;
+ case 4: mirr = MI_H; setmirror(mirr); break;
+ }
+ latche = V;
+ Sync();
+}
+
+static DECLFR(M36Read) {
+ return latche; // Need by Strike Wolf, being simplified mapper, this cart still uses some TCX mapper features andrely on it
+}
+
+static void M36Power(void) {
+ latche = 0;
+ Sync();
+ SetReadHandler(0x4100, 0x4100, M36Read);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFE, M36Write); // Actually, BUS conflict there preventing from triggering the wrong banks
+}
+
+static void M36Restore(int version) {
+ Sync();
+}
+
+void Mapper36_Init(CartInfo *info) {
+ info->Power = M36Power;
+ GameStateRestore = M36Restore;
+ AddExState(StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/3d-block.cpp b/source/fceux/boards/3d-block.cpp
new file mode 100644
index 0000000..2a8b62c
--- /dev/null
+++ b/source/fceux/boards/3d-block.cpp
@@ -0,0 +1,95 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2007 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[4], IRQa;
+static int16 IRQCount, IRQPause;
+
+static int16 Count = 0x0000;
+
+static SFORMAT StateRegs[] =
+{
+ { reg, 4, "REGS" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 2, "IRQC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, 0);
+ setchr8(0);
+}
+
+//#define Count 0x1800
+#define Pause 0x010
+
+static DECLFW(UNL3DBlockWrite) {
+ switch (A) {
+//4800 32
+//4900 37
+//4a00 01
+//4e00 18
+ case 0x4800: reg[0] = V; break;
+ case 0x4900: reg[1] = V; break;
+ case 0x4a00: reg[2] = V; break;
+ case 0x4e00: reg[3] = V; IRQCount = Count; IRQPause = Pause; IRQa = 1; X6502_IRQEnd(FCEU_IQEXT); break;
+ }
+}
+
+static void UNL3DBlockPower(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x4800, 0x4E00, UNL3DBlockWrite);
+}
+
+static void UNL3DBlockReset(void) {
+ Count += 0x10;
+ FCEU_printf("Count=%04x\n", Count);
+}
+
+static void UNL3DBlockIRQHook(int a) {
+ if (IRQa) {
+ if (IRQCount > 0) {
+ IRQCount -= a;
+ } else {
+ if (IRQPause > 0) {
+ IRQPause -= a;
+ X6502_IRQBegin(FCEU_IQEXT);
+ } else {
+ IRQCount = Count;
+ IRQPause = Pause;
+ X6502_IRQEnd(FCEU_IQEXT);
+ }
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void UNL3DBlock_Init(CartInfo *info) {
+ info->Power = UNL3DBlockPower;
+ info->Reset = UNL3DBlockReset;
+ MapIRQHook = UNL3DBlockIRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/40.cpp b/source/fceux/boards/40.cpp
new file mode 100644
index 0000000..5cae497
--- /dev/null
+++ b/source/fceux/boards/40.cpp
@@ -0,0 +1,86 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * FDS Conversion
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+static uint32 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQCount, 4, "IRQC" },
+ { &IRQa, 4, "IRQA" },
+ { ®, 1, "REG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x6000, ~1);
+ setprg8(0x8000, ~3);
+ setprg8(0xa000, ~2);
+ setprg8(0xc000, reg);
+ setprg8(0xe000, ~0);
+ setchr8(0);
+}
+
+static DECLFW(M40Write) {
+ switch (A & 0xe000) {
+ case 0x8000: IRQa = 0; IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xa000: IRQa = 1; break;
+ case 0xe000: reg = V & 7; Sync(); break;
+ }
+}
+
+static void M40Power(void) {
+ reg = 0;
+ Sync();
+ SetReadHandler(0x6000, 0xffff, CartBR);
+ SetWriteHandler(0x8000, 0xffff, M40Write);
+}
+
+static void M40Reset(void) {
+}
+
+static void M40IRQHook(int a) {
+ if (IRQa) {
+ if (IRQCount < 4096)
+ IRQCount += a;
+ else{
+ IRQa = 0;
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper40_Init(CartInfo *info) {
+ info->Reset = M40Reset;
+ info->Power = M40Power;
+ MapIRQHook = M40IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/41.cpp b/source/fceux/boards/41.cpp
new file mode 100644
index 0000000..d0d9083
--- /dev/null
+++ b/source/fceux/boards/41.cpp
@@ -0,0 +1,69 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 mainreg, chrreg, mirror;
+
+static SFORMAT StateRegs[] =
+{
+ { &mainreg, 1, "MREG" },
+ { &chrreg, 1, "CREG" },
+ { &mirror, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, mainreg & 7);
+ setchr8(chrreg);
+ setmirror(mirror);
+}
+
+static DECLFW(M41Write0) {
+ mainreg = A & 0xFF;
+ mirror = ((A >> 5) & 1) ^ 1;
+ chrreg = (chrreg & 3) | ((A >> 1) & 0xC);
+ Sync();
+}
+
+static DECLFW(M41Write1) {
+ if (mainreg & 0x4) {
+ chrreg = (chrreg & 0xC) | (A & 3);
+ Sync();
+ }
+}
+
+static void M41Power(void) {
+ mainreg = chrreg = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x67FF, M41Write0);
+ SetWriteHandler(0x8000, 0xFFFF, M41Write1);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper41_Init(CartInfo *info) {
+ info->Power = M41Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/42.cpp b/source/fceux/boards/42.cpp
new file mode 100644
index 0000000..8760857
--- /dev/null
+++ b/source/fceux/boards/42.cpp
@@ -0,0 +1,84 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * FDS Conversion
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 preg, creg, mirr;
+static uint32 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { &preg, 1, "PREG" },
+ { &creg, 1, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQCount, 4, "IRQC" },
+ { &IRQa, 4, "IRQA" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x6000, preg);
+ setprg32(0x8000, ~0);
+ setchr8(creg);
+ setmirror(mirr);
+}
+
+static DECLFW(M42Write) {
+ switch (A & 0xE003) {
+ case 0x8000: creg = V; Sync(); break;
+ case 0xE000: preg = V & 0x0F; Sync(); break;
+ case 0xE001: mirr = ((V >> 3) & 1 ) ^ 1; Sync(); break;
+ case 0xE002: IRQa = V & 2; if (!IRQa) IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ }
+}
+
+static void M42Power(void) {
+ preg = 0;
+ mirr = 1; // Ai Senshi Nicol actually has fixed mirroring, but mapper forcing it's default value now
+ Sync();
+ SetReadHandler(0x6000, 0xffff, CartBR);
+ SetWriteHandler(0x6000, 0xffff, M42Write);
+}
+
+static void M42IRQHook(int a) {
+ if (IRQa) {
+ IRQCount += a;
+ if (IRQCount >= 32768) IRQCount -= 32768;
+ if (IRQCount >= 24576)
+ X6502_IRQBegin(FCEU_IQEXT);
+ else
+ X6502_IRQEnd(FCEU_IQEXT);
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper42_Init(CartInfo *info) {
+ info->Power = M42Power;
+ MapIRQHook = M42IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/43.cpp b/source/fceux/boards/43.cpp
new file mode 100644
index 0000000..396f80e
--- /dev/null
+++ b/source/fceux/boards/43.cpp
@@ -0,0 +1,91 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * FDS Conversion
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg, swap;
+static uint32 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQCount, 4, "IRQC" },
+ { &IRQa, 4, "IRQA" },
+ { ®, 1, "REG" },
+ { &swap, 1, "SWAP" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg4(0x5000, 8 << 1); // Only YS-612 advanced version
+ setprg8(0x6000, swap?0:2);
+ setprg8(0x8000, 1);
+ setprg8(0xa000, 0);
+ setprg8(0xc000, reg);
+ setprg8(0xe000, swap?8:9); // hard dump for mr.Mary is 128K,
+ // bank 9 is the last 2K ok bank 8 repeated 4 times, then till the end of 128K
+ // instead used bank A, containing some CHR data, ines rom have unused banks removed,
+ // and bank A moved to the bank 9 place for compatibility with other crappy dumps
+ setchr8(0);
+}
+
+static DECLFW(M43Write) {
+// int transo[8]={4,3,4,4,4,7,5,6};
+ int transo[8] = { 4, 3, 5, 3, 6, 3, 7, 3 }; // According to hardware tests
+ switch (A & 0xf1ff) {
+ case 0x4022: reg = transo[V & 7]; Sync(); break;
+ case 0x4120: swap = V & 1; Sync(); break;
+ case 0x8122: // hacked version
+ case 0x4122: IRQa = V & 1; X6502_IRQEnd(FCEU_IQEXT); IRQCount = 0; break; // original version
+ }
+}
+
+static void M43Power(void) {
+ reg = swap = 0;
+ Sync();
+ SetReadHandler(0x5000, 0xffff, CartBR);
+ SetWriteHandler(0x4020, 0xffff, M43Write);
+}
+
+static void M43Reset(void) {
+}
+
+static void M43IRQHook(int a) {
+ IRQCount += a;
+ if (IRQa)
+ if (IRQCount >= 4096) {
+ IRQa = 0;
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper43_Init(CartInfo *info) {
+ info->Reset = M43Reset;
+ info->Power = M43Power;
+ MapIRQHook = M43IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/46.cpp b/source/fceux/boards/46.cpp
new file mode 100644
index 0000000..04e0312
--- /dev/null
+++ b/source/fceux/boards/46.cpp
@@ -0,0 +1,69 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg0, reg1;
+
+static SFORMAT StateRegs[] =
+{
+ { ®0, 1, "REG0" },
+ { ®1, 1, "REG1" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, (reg1 & 1) + ((reg0 & 0xF) << 1));
+ setchr8(((reg1 >> 4) & 7) + ((reg0 & 0xF0) >> 1));
+}
+
+static DECLFW(M46Write0) {
+ reg0 = V;
+ Sync();
+}
+
+static DECLFW(M46Write1) {
+ reg1 = V;
+ Sync();
+}
+
+static void M46Power(void) {
+ reg0 = reg1 = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, M46Write0);
+ SetWriteHandler(0x8000, 0xFFFF, M46Write1);
+}
+
+static void M46Reset(void) {
+ reg0 = reg1 = 0;
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper46_Init(CartInfo *info) {
+ info->Power = M46Power;
+ info->Reset = M46Reset;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/50.cpp b/source/fceux/boards/50.cpp
new file mode 100644
index 0000000..40a8e42
--- /dev/null
+++ b/source/fceux/boards/50.cpp
@@ -0,0 +1,85 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * FDS Conversion
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 reg;
+static uint32 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { &IRQCount, 4, "IRQC" },
+ { &IRQa, 4, "IRQA" },
+ { ®, 1, "REG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x6000, 0xF);
+ setprg8(0x8000, 0x8);
+ setprg8(0xa000, 0x9);
+ setprg8(0xc000, reg);
+ setprg8(0xe000, 0xB);
+ setchr8(0);
+}
+
+static DECLFW(M50Write) {
+ switch (A & 0xD160) {
+ case 0x4120: IRQa = V & 1; if (!IRQa) IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0x4020: reg = ((V & 1) << 2) | ((V & 2) >> 1) | ((V & 4) >> 1) | (V & 8); Sync(); break;
+ }
+}
+
+static void M50Power(void) {
+ reg = 0;
+ Sync();
+ SetReadHandler(0x6000, 0xffff, CartBR);
+ SetWriteHandler(0x4020, 0x5fff, M50Write);
+}
+
+static void M50Reset(void) {
+}
+
+static void M50IRQHook(int a) {
+ if (IRQa) {
+ if (IRQCount < 4096)
+ IRQCount += a;
+ else{
+ IRQa = 0;
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper50_Init(CartInfo *info) {
+ info->Reset = M50Reset;
+ info->Power = M50Power;
+ MapIRQHook = M50IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/51.cpp b/source/fceux/boards/51.cpp
new file mode 100644
index 0000000..02d693c
--- /dev/null
+++ b/source/fceux/boards/51.cpp
@@ -0,0 +1,84 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 bank, mode;
+static SFORMAT StateRegs[] =
+{
+ { &bank, 1, "BANK" },
+ { &mode, 1, "MODE" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if (mode & 2) {
+ setprg8(0x6000, ((bank & 7) << 2) | 0x23);
+ setprg16(0x8000, (bank << 1) | 0);
+ setprg16(0xC000, (bank << 1) | 1);
+ } else {
+ setprg8(0x6000, ((bank & 4) << 2) | 0x2F);
+ setprg16(0x8000, (bank << 1) | (mode >> 4));
+ setprg16(0xC000, ((bank & 0xC) << 1) | 7);
+ }
+ if (mode == 0x12)
+ setmirror(MI_H);
+ else
+ setmirror(MI_V);
+ setchr8(0);
+}
+
+static DECLFW(M51WriteMode) {
+ mode = V & 0x12;
+ Sync();
+}
+
+static DECLFW(M51WriteBank) {
+ bank = V & 0x0F;
+ if (A & 0x4000)
+ mode = (mode & 2) | (V & 0x10);
+ Sync();
+}
+
+static void M51Power(void) {
+ bank = 0;
+ mode = 2;
+ Sync();
+ SetWriteHandler(0x6000, 0x7FFF, M51WriteMode);
+ SetWriteHandler(0x8000, 0xFFFF, M51WriteBank);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+}
+
+static void M51Reset(void) {
+ bank = 0;
+ mode = 2;
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper51_Init(CartInfo *info) {
+ info->Power = M51Power;
+ info->Reset = M51Reset;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/57.cpp b/source/fceux/boards/57.cpp
new file mode 100644
index 0000000..4d2b510
--- /dev/null
+++ b/source/fceux/boards/57.cpp
@@ -0,0 +1,84 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 prg_reg;
+static uint8 chr_reg;
+static uint8 hrd_flag;
+
+static SFORMAT StateRegs[] =
+{
+ { &hrd_flag, 1, "DPSW" },
+ { &prg_reg, 1, "PRG" },
+ { &chr_reg, 1, "CHR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ if (prg_reg & 0x80)
+ setprg32(0x8000, prg_reg >> 6);
+ else{
+ setprg16(0x8000, (prg_reg >> 5) & 3);
+ setprg16(0xC000, (prg_reg >> 5) & 3);
+ }
+ setmirror((prg_reg & 8) >> 3);
+ setchr8((chr_reg & 3) | (prg_reg & 7) | ((prg_reg & 0x10) >> 1));
+}
+
+static DECLFR(M57Read) {
+ return hrd_flag;
+}
+
+static DECLFW(M57Write) {
+ if ((A & 0x8800) == 0x8800)
+ prg_reg = V;
+ else
+ chr_reg = V;
+ Sync();
+}
+
+static void M57Power(void) {
+ prg_reg = 0;
+ chr_reg = 0;
+ hrd_flag = 0;
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M57Write);
+ SetReadHandler(0x6000, 0x6000, M57Read);
+ Sync();
+}
+
+static void M57Reset() {
+ hrd_flag++;
+ hrd_flag &= 3;
+ FCEU_printf("Select Register = %02x\n", hrd_flag);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper57_Init(CartInfo *info) {
+ info->Power = M57Power;
+ info->Reset = M57Reset;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/603-5052.cpp b/source/fceux/boards/603-5052.cpp
new file mode 100644
index 0000000..cf13a44
--- /dev/null
+++ b/source/fceux/boards/603-5052.cpp
@@ -0,0 +1,44 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static uint8 lut[4] = { 0x00, 0x02, 0x02, 0x03 };
+
+static DECLFW(UNL6035052ProtWrite) {
+ EXPREGS[0] = lut[V & 3];
+}
+
+static DECLFR(UNL6035052ProtRead) {
+ return EXPREGS[0];
+}
+
+static void UNL6035052Power(void) {
+ GenMMC3Power();
+ SetWriteHandler(0x4020, 0x7FFF, UNL6035052ProtWrite);
+ SetReadHandler(0x4020, 0x7FFF, UNL6035052ProtRead);
+}
+
+void UNL6035052_Init(CartInfo *info) {
+ GenMMC3_Init(info, 128, 256, 0, 0);
+ info->Power = UNL6035052Power;
+ AddExState(EXPREGS, 6, 0, "EXPR");
+}
diff --git a/source/fceux/boards/62.cpp b/source/fceux/boards/62.cpp
new file mode 100644
index 0000000..0dc2a63
--- /dev/null
+++ b/source/fceux/boards/62.cpp
@@ -0,0 +1,69 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 bank;
+static uint16 mode;
+static SFORMAT StateRegs[] =
+{
+ { &bank, 1, "BANK" },
+ { &mode, 2, "MODE" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8(((mode & 0x1F) << 2) | (bank & 0x03));
+ if (mode & 0x20) {
+ setprg16(0x8000, (mode & 0x40) | ((mode >> 8) & 0x3F));
+ setprg16(0xc000, (mode & 0x40) | ((mode >> 8) & 0x3F));
+ } else
+ setprg32(0x8000, ((mode & 0x40) | ((mode >> 8) & 0x3F)) >> 1);
+ setmirror(((mode >> 7) & 1) ^ 1);
+}
+
+static DECLFW(M62Write) {
+ mode = A & 0x3FFF;
+ bank = V & 3;
+ Sync();
+}
+
+static void M62Power(void) {
+ bank = mode = 0;
+ Sync();
+ SetWriteHandler(0x8000, 0xFFFF, M62Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void M62Reset(void) {
+ bank = mode = 0;
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper62_Init(CartInfo *info) {
+ info->Power = M62Power;
+ info->Reset = M62Reset;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/65.cpp b/source/fceux/boards/65.cpp
new file mode 100644
index 0000000..fbfd667
--- /dev/null
+++ b/source/fceux/boards/65.cpp
@@ -0,0 +1,105 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg[3], creg[8], mirr;
+static uint8 IRQa;
+static int16 IRQCount, IRQLatch;
+
+static SFORMAT StateRegs[] =
+{
+ { preg, 3, "PREG" },
+ { creg, 8, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 2, "IRQC" },
+ { &IRQLatch, 2, "IRQL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(mirr);
+ setprg8(0x8000, preg[0]);
+ setprg8(0xA000, preg[1]);
+ setprg8(0xC000, preg[2]);
+ setprg8(0xE000, ~0);
+ setchr1(0x0000, creg[0]);
+ setchr1(0x0400, creg[1]);
+ setchr1(0x0800, creg[2]);
+ setchr1(0x0C00, creg[3]);
+ setchr1(0x1000, creg[4]);
+ setchr1(0x1400, creg[5]);
+ setchr1(0x1800, creg[6]);
+ setchr1(0x1C00, creg[7]);
+ setmirror(mirr);
+}
+
+static DECLFW(M65Write) {
+ switch (A) {
+ case 0x8000: preg[0] = V; Sync(); break;
+ case 0xA000: preg[1] = V; Sync(); break;
+ case 0xC000: preg[2] = V; Sync(); break;
+ case 0x9001: mirr = ((V >> 7) & 1) ^ 1; Sync(); break;
+ case 0x9003: IRQa = V & 0x80; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0x9004: IRQCount = IRQLatch; break;
+ case 0x9005: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break;
+ case 0x9006: IRQLatch &= 0xFF00; IRQLatch |= V; break;
+ case 0xB000: creg[0] = V; Sync(); break;
+ case 0xB001: creg[1] = V; Sync(); break;
+ case 0xB002: creg[2] = V; Sync(); break;
+ case 0xB003: creg[3] = V; Sync(); break;
+ case 0xB004: creg[4] = V; Sync(); break;
+ case 0xB005: creg[5] = V; Sync(); break;
+ case 0xB006: creg[6] = V; Sync(); break;
+ case 0xB007: creg[7] = V; Sync(); break;
+ }
+}
+
+static void M65Power(void) {
+ preg[2] = ~1;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M65Write);
+}
+
+void M65IRQ(int a) {
+ if (IRQa) {
+ IRQCount -= a;
+ if (IRQCount < -4) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQa = 0;
+ IRQCount = -1;
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper65_Init(CartInfo *info) {
+ info->Power = M65Power;
+ MapIRQHook = M65IRQ;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/67.cpp b/source/fceux/boards/67.cpp
new file mode 100644
index 0000000..4e29edb
--- /dev/null
+++ b/source/fceux/boards/67.cpp
@@ -0,0 +1,106 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg, creg[4], mirr, suntoggle = 0;
+static uint8 IRQa;
+static int16 IRQCount, IRQLatch;
+
+static SFORMAT StateRegs[] =
+{
+ { &preg, 1, "PREG" },
+ { &suntoggle, 1, "STOG" },
+ { creg, 4, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 2, "IRQC" },
+ { &IRQLatch, 2, "IRQL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(mirr);
+ setprg16(0x8000, preg);
+ setprg16(0xC000, ~0);
+ setchr2(0x0000, creg[0]);
+ setchr2(0x0800, creg[1]);
+ setchr2(0x1000, creg[2]);
+ setchr2(0x1800, creg[3]);
+ switch (mirr) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static DECLFW(M67Write) {
+ switch (A & 0xF800) {
+ case 0x8800: creg[0] = V; Sync(); break;
+ case 0x9800: creg[1] = V; Sync(); break;
+ case 0xA800: creg[2] = V; Sync(); break;
+ case 0xB800: creg[3] = V; Sync(); break;
+ case 0xC000:
+ case 0xC800:
+ IRQCount &= 0xFF << (suntoggle << 3);
+ IRQCount |= V << ((suntoggle ^ 1) << 3);
+ suntoggle ^= 1;
+ break;
+ case 0xD800:
+ suntoggle = 0;
+ IRQa = V & 0x10;
+ X6502_IRQEnd(FCEU_IQEXT);
+ break;
+ case 0xE800: mirr = V & 3; Sync(); break;
+ case 0xF800: preg = V; Sync(); break;
+ }
+}
+
+static void M67Power(void) {
+ suntoggle = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M67Write);
+}
+
+void M67IRQ(int a) {
+ if (IRQa) {
+ IRQCount -= a;
+ if (IRQCount <= 0) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ IRQa = 0;
+ IRQCount = -1;
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper67_Init(CartInfo *info) {
+ info->Power = M67Power;
+ MapIRQHook = M67IRQ;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/68.cpp b/source/fceux/boards/68.cpp
new file mode 100644
index 0000000..710f443
--- /dev/null
+++ b/source/fceux/boards/68.cpp
@@ -0,0 +1,164 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2006 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 chr_reg[4];
+static uint8 kogame, prg_reg, nt1, nt2, mirr;
+
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE, count;
+
+static SFORMAT StateRegs[] =
+{
+ { &nt1, 1, "NT1" },
+ { &nt2, 1, "NT2" },
+ { &mirr, 1, "MIRR" },
+ { &prg_reg, 1, "PRG" },
+ { &kogame, 1, "KGME" },
+ { &count, 4, "CNT" },
+ { chr_reg, 4, "CHR" },
+ { 0 }
+};
+
+static void M68NTfix(void) {
+ if ((!UNIFchrrama) && (mirr & 0x10)) {
+ PPUNTARAM = 0;
+ switch (mirr & 3) {
+ case 0:
+ vnapage[0] = vnapage[2] = CHRptr[0] + (((nt1 | 128) & CHRmask1[0]) << 10);
+ vnapage[1] = vnapage[3] = CHRptr[0] + (((nt2 | 128) & CHRmask1[0]) << 10);
+ break;
+ case 1:
+ vnapage[0] = vnapage[1] = CHRptr[0] + (((nt1 | 128) & CHRmask1[0]) << 10);
+ vnapage[2] = vnapage[3] = CHRptr[0] + (((nt2 | 128) & CHRmask1[0]) << 10);
+ break;
+ case 2:
+ vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = CHRptr[0] + (((nt1 | 128) & CHRmask1[0]) << 10);
+ break;
+ case 3:
+ vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = CHRptr[0] + (((nt2 | 128) & CHRmask1[0]) << 10);
+ break;
+ }
+ } else
+ switch (mirr & 3) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static void Sync(void) {
+ setchr2(0x0000, chr_reg[0]);
+ setchr2(0x0800, chr_reg[1]);
+ setchr2(0x1000, chr_reg[2]);
+ setchr2(0x1800, chr_reg[3]);
+ setprg8r(0x10, 0x6000, 0);
+ setprg16r((PRGptr[1]) ? kogame : 0, 0x8000, prg_reg);
+ setprg16(0xC000, ~0);
+}
+
+static DECLFR(M68Read) {
+ if (!(kogame & 8)) {
+ count++;
+ if (count == 1784)
+ setprg16r(0, 0x8000, prg_reg);
+ }
+ return CartBR(A);
+}
+
+static DECLFW(M68WriteLo) {
+ if (!V) {
+ count = 0;
+ setprg16r((PRGptr[1]) ? kogame : 0, 0x8000, prg_reg);
+ }
+ CartBW(A, V);
+}
+
+static DECLFW(M68WriteCHR) {
+ chr_reg[(A >> 12) & 3] = V;
+ Sync();
+}
+
+static DECLFW(M68WriteNT1) {
+ nt1 = V;
+ M68NTfix();
+}
+
+static DECLFW(M68WriteNT2) {
+ nt2 = V;
+ M68NTfix();
+}
+
+static DECLFW(M68WriteMIR) {
+ mirr = V;
+ M68NTfix();
+}
+
+static DECLFW(M68WriteROM) {
+ prg_reg = V & 7;
+ kogame = ((V >> 3) & 1) ^ 1;
+ Sync();
+}
+
+static void M68Power(void) {
+ prg_reg = 0;
+ kogame = 0;
+ Sync();
+ M68NTfix();
+ SetReadHandler(0x6000, 0x7FFF, CartBR);
+ SetReadHandler(0x8000, 0xBFFF, M68Read);
+ SetReadHandler(0xC000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xBFFF, M68WriteCHR);
+ SetWriteHandler(0xC000, 0xCFFF, M68WriteNT1);
+ SetWriteHandler(0xD000, 0xDFFF, M68WriteNT2);
+ SetWriteHandler(0xE000, 0xEFFF, M68WriteMIR);
+ SetWriteHandler(0xF000, 0xFFFF, M68WriteROM);
+ SetWriteHandler(0x6000, 0x6000, M68WriteLo);
+ SetWriteHandler(0x6001, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M68Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+ M68NTfix();
+}
+
+void Mapper68_Init(CartInfo *info) {
+ info->Power = M68Power;
+ info->Close = M68Close;
+ GameStateRestore = StateRestore;
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/69.cpp b/source/fceux/boards/69.cpp
new file mode 100644
index 0000000..bc25621
--- /dev/null
+++ b/source/fceux/boards/69.cpp
@@ -0,0 +1,282 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 cmdreg, preg[4], creg[8], mirr;
+static uint8 IRQa;
+static int32 IRQCount;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { &cmdreg, 1, "CMDR" },
+ { preg, 4, "PREG" },
+ { creg, 8, "CREG" },
+ { &mirr, 1, "MIRR" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 4, "IRQC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint8 i;
+ if ((preg[3] & 0xC0) == 0xC0)
+ setprg8r(0x10, 0x6000, preg[3] & 0x3F);
+ else
+ setprg8(0x6000, preg[3] & 0x3F);
+ setprg8(0x8000, preg[0]);
+ setprg8(0xA000, preg[1]);
+ setprg8(0xC000, preg[2]);
+ setprg8(0xE000, ~0);
+ for (i = 0; i < 8; i++)
+ setchr1(i << 10, creg[i]);
+ switch (mirr & 3) {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+}
+
+static DECLFW(M69WRAMWrite) {
+ if ((preg[3] & 0xC0) == 0xC0)
+ CartBW(A, V);
+}
+
+static DECLFR(M69WRAMRead) {
+ if ((preg[3] & 0xC0) == 0x40)
+ return X.DB;
+ else
+ return CartBR(A);
+}
+
+static DECLFW(M69Write0) {
+ cmdreg = V & 0xF;
+}
+
+static DECLFW(M69Write1) {
+ switch (cmdreg) {
+ case 0x0: creg[0] = V; Sync(); break;
+ case 0x1: creg[1] = V; Sync(); break;
+ case 0x2: creg[2] = V; Sync(); break;
+ case 0x3: creg[3] = V; Sync(); break;
+ case 0x4: creg[4] = V; Sync(); break;
+ case 0x5: creg[5] = V; Sync(); break;
+ case 0x6: creg[6] = V; Sync(); break;
+ case 0x7: creg[7] = V; Sync(); break;
+ case 0x8: preg[3] = V; Sync(); break;
+ case 0x9: preg[0] = V; Sync(); break;
+ case 0xA: preg[1] = V; Sync(); break;
+ case 0xB: preg[2] = V; Sync(); break;
+ case 0xC: mirr = V & 3; Sync();break;
+ case 0xD: IRQa = V; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xE: IRQCount &= 0xFF00; IRQCount |= V; break;
+ case 0xF: IRQCount &= 0x00FF; IRQCount |= V << 8; break;
+ }
+}
+
+// SUNSOFT-5/FME-7 Sound
+
+static void AYSound(int Count);
+static void AYSoundHQ(void);
+static void DoAYSQ(int x);
+static void DoAYSQHQ(int x);
+
+static uint8 sndcmd, sreg[14];
+static int32 vcount[3];
+static int32 dcount[3];
+static int CAYBC[3];
+
+static SFORMAT SStateRegs[] =
+{
+ { &sndcmd, 1, "SCMD" },
+ { sreg, 14, "SREG" },
+ { 0 }
+};
+
+static DECLFW(M69SWrite0) {
+ sndcmd = V % 14;
+}
+
+static DECLFW(M69SWrite1) {
+ int x;
+ GameExpSound.Fill = AYSound;
+ GameExpSound.HiFill = AYSoundHQ;
+ if (FSettings.SndRate)
+ switch (sndcmd) {
+ case 0:
+ case 1:
+ case 8: if (FSettings.soundq >= 1) DoAYSQHQ(0); else DoAYSQ(0); break;
+ case 2:
+ case 3:
+ case 9: if (FSettings.soundq >= 1) DoAYSQHQ(1); else DoAYSQ(1); break;
+ case 4:
+ case 5:
+ case 10: if (FSettings.soundq >= 1) DoAYSQHQ(2); else DoAYSQ(2); break;
+ case 7:
+ for (x = 0; x < 2; x++)
+ if (FSettings.soundq >= 1) DoAYSQHQ(x); else DoAYSQ(x);
+ break;
+ }
+ sreg[sndcmd] = V;
+}
+
+static void DoAYSQ(int x) {
+ int32 freq = ((sreg[x << 1] | ((sreg[(x << 1) + 1] & 15) << 8)) + 1) << (4 + 17);
+ int32 amp = (sreg[0x8 + x] & 15) << 2;
+ int32 start, end;
+ int V;
+
+ amp += amp >> 1;
+
+ start = CAYBC[x];
+ end = (SOUNDTS << 16) / soundtsinc;
+ if (end <= start) return;
+ CAYBC[x] = end;
+
+ if (amp && !(sreg[0x7] & (1 << x)))
+ for (V = start; V < end; V++) {
+ if (dcount[x])
+ Wave[V >> 4] += amp;
+ vcount[x] -= nesincsize;
+ while (vcount[x] <= 0) {
+ dcount[x] ^= 1;
+ vcount[x] += freq;
+ }
+ }
+}
+
+static void DoAYSQHQ(int x) {
+ uint32 V;
+ int32 freq = ((sreg[x << 1] | ((sreg[(x << 1) + 1] & 15) << 8)) + 1) << 4;
+ int32 amp = (sreg[0x8 + x] & 15) << 6;
+
+ amp += amp >> 1;
+
+ if (!(sreg[0x7] & (1 << x))) {
+ for (V = CAYBC[x]; V < SOUNDTS; V++) {
+ if (dcount[x])
+ WaveHi[V] += amp;
+ vcount[x]--;
+ if (vcount[x] <= 0) {
+ dcount[x] ^= 1;
+ vcount[x] = freq;
+ }
+ }
+ }
+ CAYBC[x] = SOUNDTS;
+}
+
+static void AYSound(int Count) {
+ int x;
+ DoAYSQ(0);
+ DoAYSQ(1);
+ DoAYSQ(2);
+ for (x = 0; x < 3; x++)
+ CAYBC[x] = Count;
+}
+
+static void AYSoundHQ(void) {
+ DoAYSQHQ(0);
+ DoAYSQHQ(1);
+ DoAYSQHQ(2);
+}
+
+static void AYHiSync(int32 ts) {
+ int x;
+
+ for (x = 0; x < 3; x++)
+ CAYBC[x] = ts;
+}
+
+void Mapper69_ESI(void) {
+ GameExpSound.RChange = Mapper69_ESI;
+ GameExpSound.HiSync = AYHiSync;
+ memset(dcount, 0, sizeof(dcount));
+ memset(vcount, 0, sizeof(vcount));
+ memset(CAYBC, 0, sizeof(CAYBC));
+ AddExState(&SStateRegs, ~0, 0, 0);
+}
+
+// SUNSOFT-5/FME-7 Sound
+
+static void M69Power(void) {
+ cmdreg = sndcmd = 0;
+ IRQCount = 0xFFFF;
+ IRQa = 0;
+ Sync();
+ SetReadHandler(0x6000, 0x7FFF, M69WRAMRead);
+ SetWriteHandler(0x6000, 0x7FFF, M69WRAMWrite);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0x9FFF, M69Write0);
+ SetWriteHandler(0xA000, 0xBFFF, M69Write1);
+ SetWriteHandler(0xC000, 0xDFFF, M69SWrite0);
+ SetWriteHandler(0xE000, 0xFFFF, M69SWrite1);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M69Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void M69IRQHook(int a) {
+ if (IRQa) {
+ IRQCount -= a;
+ if (IRQCount <= 0) {
+ X6502_IRQBegin(FCEU_IQEXT); IRQa = 0; IRQCount = 0xFFFF;
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper69_Init(CartInfo *info) {
+ info->Power = M69Power;
+ info->Close = M69Close;
+ MapIRQHook = M69IRQHook;
+ if(info->ines2)
+ WRAMSIZE = info->wram_size + info->battery_wram_size;
+ else
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ GameStateRestore = StateRestore;
+ Mapper69_ESI();
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+void NSFAY_Init(void) {
+ sndcmd = 0;
+ SetWriteHandler(0xC000, 0xDFFF, M69SWrite0);
+ SetWriteHandler(0xE000, 0xFFFF, M69SWrite1);
+ Mapper69_ESI();
+}
diff --git a/source/fceux/boards/71.cpp b/source/fceux/boards/71.cpp
new file mode 100644
index 0000000..37c05aa
--- /dev/null
+++ b/source/fceux/boards/71.cpp
@@ -0,0 +1,64 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg, mirr;
+
+static SFORMAT StateRegs[] =
+{
+ { &preg, 1, "PREG" },
+ { &mirr, 1, "MIRR" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg16(0x8000, preg);
+ setprg16(0xC000, ~0);
+ setchr8(0);
+ if(mirr)
+ setmirror(mirr);
+}
+
+static DECLFW(M71Write) {
+ if ((A & 0xF000) == 0x9000)
+ mirr = MI_0 + ((V >> 4) & 1); // 2-in-1, some carts are normal hardwire V/H mirror, some uses mapper selectable 0/1 mirror
+ else
+ preg = V;
+ Sync();
+}
+
+static void M71Power(void) {
+ mirr = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M71Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper71_Init(CartInfo *info) {
+ info->Power = M71Power;
+ GameStateRestore = StateRestore;
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/72.cpp b/source/fceux/boards/72.cpp
new file mode 100644
index 0000000..de5ec91
--- /dev/null
+++ b/source/fceux/boards/72.cpp
@@ -0,0 +1,64 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Moero!! Pro Tennis have ADPCM codec on-board, PROM isn't dumped, emulation isn't
+ * possible just now.
+ */
+
+#include "mapinc.h"
+
+static uint8 preg, creg;
+
+static SFORMAT StateRegs[] =
+{
+ { &preg, 1, "PREG" },
+ { &creg, 1, "CREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg16(0x8000, preg);
+ setprg16(0xC000, ~0);
+ setchr8(creg);
+}
+
+static DECLFW(M72Write) {
+ if (V & 0x80)
+ preg = V & 0xF;
+ if (V & 0x40)
+ creg = V & 0xF;
+ Sync();
+}
+
+static void M72Power(void) {
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0xFFFF, M72Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper72_Init(CartInfo *info) {
+ info->Power = M72Power;
+ GameStateRestore = StateRestore;
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/77.cpp b/source/fceux/boards/77.cpp
new file mode 100644
index 0000000..bbba3e8
--- /dev/null
+++ b/source/fceux/boards/77.cpp
@@ -0,0 +1,75 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 latche;
+
+static uint8 *CHRRAM=NULL;
+static uint32 CHRRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { &latche, 1, "LATC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, latche & 7);
+ setchr2(0x0000, latche >> 4);
+ setchr2r(0x10, 0x0800, 2);
+ setchr4r(0x10, 0x1000, 0);
+}
+
+static DECLFW(M77Write) {
+ latche = V;
+ Sync();
+}
+
+static void M77Power(void) {
+ latche = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M77Write);
+}
+
+static void M77Close(void)
+{
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ CHRRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper77_Init(CartInfo *info) {
+ info->Power = M77Power;
+ info->Close = M77Close;
+ GameStateRestore = StateRestore;
+
+ CHRRAMSIZE = 6 * 1024;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
+
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/79.cpp b/source/fceux/boards/79.cpp
new file mode 100644
index 0000000..14d9ac7
--- /dev/null
+++ b/source/fceux/boards/79.cpp
@@ -0,0 +1,61 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 creg, preg;
+static SFORMAT StateRegs[] =
+{
+ { &creg, 1, "CREG" },
+ { &preg, 1, "PREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg32(0x8000, preg);
+ setchr8(creg);
+}
+
+static DECLFW(M79Write) {
+ if ((A < 0x8000) && ((A ^ 0x4100) == 0)) {
+ preg = (V >> 3) & 1;
+ }
+ creg = V & 7;
+ Sync();
+}
+
+static void M79Power(void) {
+ preg = ~0;
+ Sync();
+ SetWriteHandler(0x4100, 0x5FFF, M79Write);
+ SetWriteHandler(0x8000, 0xFFFF, M79Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper79_Init(CartInfo *info) {
+ info->Power = M79Power;
+ AddExState(&StateRegs, ~0, 0, 0);
+ GameStateRestore = StateRestore;
+}
diff --git a/source/fceux/boards/80.cpp b/source/fceux/boards/80.cpp
new file mode 100644
index 0000000..b99132c
--- /dev/null
+++ b/source/fceux/boards/80.cpp
@@ -0,0 +1,193 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ * Copyright (C) 2002 Xodnizel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 preg[3], creg[6], isExMirr;
+static uint8 mirr, cmd, wram_enable, wram[256];
+static uint8 mcache[8];
+static uint32 lastppu;
+
+static SFORMAT StateRegs80[] =
+{
+ { preg, 3, "PREG" },
+ { creg, 6, "CREG" },
+ { wram, 256, "WRAM" },
+ { &mirr, 1, "MIRR" },
+ { &wram_enable, 1, "WRME" },
+ { 0 }
+};
+
+static SFORMAT StateRegs95[] =
+{
+ { &cmd, 1, "CMDR" },
+ { preg, 3, "PREG" },
+ { creg, 6, "CREG" },
+ { mcache, 8, "MCCH" },
+ { &lastppu, 4, "LPPU" },
+ { 0 }
+};
+
+static SFORMAT StateRegs207[] =
+{
+ { preg, 3, "PREG" },
+ { creg, 6, "CREG" },
+ { mcache, 8, "MCCH" },
+ { &lastppu, 4, "LPPU" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x8000, preg[0]);
+ setprg8(0xA000, preg[1]);
+ setprg8(0xC000, preg[2]);
+ setprg8(0xE000, ~0);
+ setchr2(0x0000, (creg[0] >> 1) & 0x3F);
+ setchr2(0x0800, (creg[1] >> 1) & 0x3F);
+ setchr1(0x1000, creg[2]);
+ setchr1(0x1400, creg[3]);
+ setchr1(0x1800, creg[4]);
+ setchr1(0x1C00, creg[5]);
+ if (isExMirr) {
+ setmirror(MI_0 + mcache[lastppu]);
+ } else
+ setmirror(mirr);
+}
+
+static DECLFW(M80RamWrite) {
+ if(wram_enable == 0xA3)
+ wram[A & 0xFF] = V;
+}
+
+static DECLFR(M80RamRead) {
+ if(wram_enable == 0xA3)
+ return wram[A & 0xFF];
+ else
+ return 0xFF;
+}
+
+static DECLFW(M80Write) {
+ switch (A) {
+ case 0x7EF0: creg[0] = V; mcache[0] = mcache[1] = V >> 7; Sync(); break;
+ case 0x7EF1: creg[1] = V; mcache[2] = mcache[3] = V >> 7; Sync(); break;
+ case 0x7EF2: creg[2] = V; mcache[4] = V >> 7; Sync(); break;
+ case 0x7EF3: creg[3] = V; mcache[5] = V >> 7; Sync(); break;
+ case 0x7EF4: creg[4] = V; mcache[6] = V >> 7; Sync(); break;
+ case 0x7EF5: creg[5] = V; mcache[7] = V >> 7; Sync(); break;
+ case 0x7EF6: mirr = V & 1; Sync(); break;
+ case 0x7EF8: wram_enable = V; break;
+ case 0x7EFA:
+ case 0x7EFB: preg[0] = V; Sync(); break;
+ case 0x7EFC:
+ case 0x7EFD: preg[1] = V; Sync(); break;
+ case 0x7EFE:
+ case 0x7EFF: preg[2] = V; Sync(); break;
+ }
+}
+
+static DECLFW(M95Write) {
+ switch (A & 0xF001) {
+ case 0x8000: cmd = V; break;
+ case 0x8001:
+ switch (cmd & 0x07) {
+ case 0: creg[0] = V & 0x1F; mcache[0] = mcache[1] = (V >> 5) & 1; Sync(); break;
+ case 1: creg[1] = V & 0x1F; mcache[2] = mcache[3] = (V >> 5) & 1; Sync(); break;
+ case 2: creg[2] = V & 0x1F; mcache[4] = (V >> 5) & 1; Sync(); break;
+ case 3: creg[3] = V & 0x1F; mcache[5] = (V >> 5) & 1; Sync(); break;
+ case 4: creg[4] = V & 0x1F; mcache[6] = (V >> 5) & 1; Sync(); break;
+ case 5: creg[5] = V & 0x1F; mcache[7] = (V >> 5) & 1; Sync(); break;
+ case 6: preg[0] = V; Sync(); break;
+ case 7: preg[1] = V; Sync(); break;
+ }
+ Sync();
+ }
+}
+
+static void MExMirrPPU(uint32 A) {
+ static int8 lastmirr = -1, curmirr;
+ if (A < 0x2000) {
+ lastppu = A >> 10;
+ curmirr = mcache[lastppu];
+ if (curmirr != lastmirr) {
+ setmirror(MI_0 + curmirr);
+ lastmirr = curmirr;
+ }
+ }
+}
+
+static void M80Power(void) {
+ wram_enable = 0xFF;
+ Sync();
+ SetReadHandler(0x7F00, 0x7FFF, M80RamRead);
+ SetWriteHandler(0x7F00, 0x7FFF, M80RamWrite);
+ SetWriteHandler(0x7EF0, 0x7EFF, M80Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void M207Power(void) {
+ mcache[0] = mcache[1] = mcache[2] = mcache[3] = 0;
+ mcache[4] = mcache[5] = mcache[6] = mcache[7] = 0;
+ Sync();
+ SetWriteHandler(0x7EF0, 0x7EFF, M80Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void M95Power(void) {
+ preg[2] = ~1;
+ mcache[0] = mcache[1] = mcache[2] = mcache[3] = 0;
+ mcache[4] = mcache[5] = mcache[6] = mcache[7] = 0;
+ Sync();
+ SetWriteHandler(0x8000, 0xFFFF, M95Write);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper80_Init(CartInfo *info) {
+ isExMirr = 0;
+ info->Power = M80Power;
+ GameStateRestore = StateRestore;
+
+ if (info->battery) {
+ info->SaveGame[0] = wram;
+ info->SaveGameLen[0] = 256;
+ }
+
+ AddExState(&StateRegs80, ~0, 0, 0);
+}
+
+void Mapper95_Init(CartInfo *info) {
+ isExMirr = 1;
+ info->Power = M95Power;
+ PPU_hook = MExMirrPPU;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs95, ~0, 0, 0);
+}
+
+void Mapper207_Init(CartInfo *info) {
+ isExMirr = 1;
+ info->Power = M207Power;
+ PPU_hook = MExMirrPPU;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs207, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/80013-B.cpp b/source/fceux/boards/80013-B.cpp
new file mode 100644
index 0000000..1f376ea
--- /dev/null
+++ b/source/fceux/boards/80013-B.cpp
@@ -0,0 +1,76 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2017 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 bios_prg, rom_prg, rom_mode, mirror;
+
+static SFORMAT StateRegs[] =
+{
+ { &bios_prg, 1, "BREG" },
+ { &rom_prg, 1, "RREG" },
+ { &rom_mode, 1, "RMODE" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8(0);
+ if(rom_mode&2) {
+ setprg16r(0,0x8000,(bios_prg&0xF)|(rom_prg&0x70));
+ } else {
+ setprg16r(1,0x8000,bios_prg&3);
+ }
+ setprg16r(0,0xC000,rom_prg&0x7F);
+ setmirror(((bios_prg>>4)&1)^1);
+}
+
+static DECLFW(BMC80013BWrite) {
+ uint8 reg = (A>>13)&3;
+ if(reg == 0) {
+ bios_prg = V;
+ } else {
+ rom_prg = V;
+ rom_mode = reg;
+ }
+ Sync();
+}
+
+static void BMC80013BPower(void) {
+ bios_prg=rom_prg=rom_mode=mirror=0;
+ Sync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, BMC80013BWrite);
+}
+
+static void BMC80013BReset(void) {
+ bios_prg=rom_prg=rom_mode=mirror=0;
+ Sync();
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void BMC80013B_Init(CartInfo *info) {
+ info->Reset = BMC80013BReset;
+ info->Power = BMC80013BPower;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/8157.cpp b/source/fceux/boards/8157.cpp
new file mode 100644
index 0000000..287be08
--- /dev/null
+++ b/source/fceux/boards/8157.cpp
@@ -0,0 +1,85 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * GG1 boards, similar to T-262, with no Data latch
+ *
+ */
+
+#include "mapinc.h"
+
+static uint16 cmdreg;
+static uint8 reset;
+static SFORMAT StateRegs[] =
+{
+ { &reset, 1, "REST" },
+ { &cmdreg, 2, "CREG" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint32 base = ((cmdreg & 0x060) | ((cmdreg & 0x100) >> 1)) >> 2;
+ uint32 bank = (cmdreg & 0x01C) >> 2;
+ uint32 lbank = (cmdreg & 0x200) ? 7 : ((cmdreg & 0x80) ? bank : 0);
+ if (PRGptr[1]) {
+ setprg16r(base >> 3, 0x8000, bank); // for versions with split ROMs
+ setprg16r(base >> 3, 0xC000, lbank);
+ } else {
+ setprg16(0x8000, base | bank);
+ setprg16(0xC000, base | lbank);
+ }
+ setmirror(((cmdreg & 2) >> 1) ^ 1);
+}
+
+static DECLFR(UNL8157Read) {
+ if ((cmdreg & 0x100) && (PRGsize[0] < (1024 * 1024))) {
+ A = (A & 0xFFF0) + reset;
+ }
+ return CartBR(A);
+}
+
+static DECLFW(UNL8157Write) {
+ cmdreg = A;
+ Sync();
+}
+
+static void UNL8157Power(void) {
+ setchr8(0);
+ SetWriteHandler(0x8000, 0xFFFF, UNL8157Write);
+ SetReadHandler(0x8000, 0xFFFF, UNL8157Read);
+ cmdreg = reset = 0;
+ Sync();
+}
+
+static void UNL8157Reset(void) {
+ cmdreg = reset = 0;
+ reset++;
+ reset &= 0x1F;
+ Sync();
+}
+
+static void UNL8157Restore(int version) {
+ Sync();
+}
+
+void UNL8157_Init(CartInfo *info) {
+ info->Power = UNL8157Power;
+ info->Reset = UNL8157Reset;
+ GameStateRestore = UNL8157Restore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/82.cpp b/source/fceux/boards/82.cpp
new file mode 100644
index 0000000..a1a68b6
--- /dev/null
+++ b/source/fceux/boards/82.cpp
@@ -0,0 +1,98 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Taito X1-017 board, battery backed
+ *
+ */
+
+#include "mapinc.h"
+
+static uint8 regs[9], ctrl;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+
+static SFORMAT StateRegs[] =
+{
+ { regs, 9, "REGS" },
+ { &ctrl, 1, "CTRL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ uint32 swap = ((ctrl & 2) << 11);
+ setchr2(0x0000 ^ swap, regs[0] >> 1);
+ setchr2(0x0800 ^ swap, regs[1] >> 1);
+ setchr1(0x1000 ^ swap, regs[2]);
+ setchr1(0x1400 ^ swap, regs[3]);
+ setchr1(0x1800 ^ swap, regs[4]);
+ setchr1(0x1c00 ^ swap, regs[5]);
+ setprg8r(0x10, 0x6000, 0);
+ setprg8(0x8000, regs[6]);
+ setprg8(0xA000, regs[7]);
+ setprg8(0xC000, regs[8]);
+ setprg8(0xE000, ~0);
+ setmirror(ctrl & 1);
+}
+
+static DECLFW(M82Write) {
+ if (A <= 0x7ef5)
+ regs[A & 7] = V;
+ else
+ switch (A) {
+ case 0x7ef6: ctrl = V & 3; break;
+ case 0x7efa: regs[6] = V >> 2; break;
+ case 0x7efb: regs[7] = V >> 2; break;
+ case 0x7efc: regs[8] = V >> 2; break;
+ }
+ Sync();
+}
+
+static void M82Power(void) {
+ Sync();
+ SetReadHandler(0x6000, 0xffff, CartBR);
+ SetWriteHandler(0x6000, 0x7fff, CartBW);
+ SetWriteHandler(0x7ef0, 0x7efc, M82Write); // external WRAM might end at $73FF
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M82Close(void) {
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper82_Init(CartInfo *info) {
+ info->Power = M82Power;
+ info->Close = M82Close;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/8237.cpp b/source/fceux/boards/8237.cpp
new file mode 100644
index 0000000..3807769
--- /dev/null
+++ b/source/fceux/boards/8237.cpp
@@ -0,0 +1,173 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2011 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Super Game (Sugar Softec) protected mapper
+ * Pocahontas 2 (Unl) [U][!], etc.
+ * TODO: 9in1 LION KING HANGS!
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static uint8 cmdin;
+
+static uint8 regperm[8][8] =
+{
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 0, 2, 6, 1, 7, 3, 4, 5 },
+ { 0, 5, 4, 1, 7, 2, 6, 3 }, // unused
+ { 0, 6, 3, 7, 5, 2, 4, 1 },
+ { 0, 2, 5, 3, 6, 1, 7, 4 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+};
+
+static uint8 adrperm[8][8] =
+{
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 3, 2, 0, 4, 1, 5, 6, 7 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // unused
+ { 5, 0, 1, 2, 3, 7, 6, 4 },
+ { 3, 1, 0, 5, 2, 4, 6, 7 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+ { 0, 1, 2, 3, 4, 5, 6, 7 }, // empty
+};
+
+static void UNL8237CW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x40)
+ setchr1(A, ((EXPREGS[1] & 0xc) << 6) | (V & 0x7F) | ((EXPREGS[1] & 0x20) << 2));
+ else
+ setchr1(A, ((EXPREGS[1] & 0xc) << 6) | V);
+}
+
+static void UNL8237PW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x40) {
+ uint8 sbank = (EXPREGS[1] & 0x10);
+ if (EXPREGS[0] & 0x80) {
+ uint8 bank = ((EXPREGS[1] & 3) << 4) | (EXPREGS[0] & 0x7) | (sbank >> 1);
+ if (EXPREGS[0] & 0x20)
+ setprg32(0x8000, bank >> 1);
+ else{
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else
+ setprg8(A, ((EXPREGS[1] & 3) << 5) | (V & 0x0F) | sbank);
+ } else {
+ if (EXPREGS[0] & 0x80) {
+ uint8 bank = ((EXPREGS[1] & 3) << 4) | (EXPREGS[0] & 0xF);
+ if (EXPREGS[0] & 0x20)
+ setprg32(0x8000, bank >> 1);
+ else{
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else
+ setprg8(A, ((EXPREGS[1] & 3) << 5) | (V & 0x1F));
+ }
+}
+
+static void UNL8237ACW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x40)
+ setchr1(A, ((EXPREGS[1] & 0xE) << 7) | (V & 0x7F) | ((EXPREGS[1] & 0x20) << 2));
+ else
+ setchr1(A, ((EXPREGS[1] & 0xE) << 7) | V);
+}
+
+static void UNL8237APW(uint32 A, uint8 V) {
+ if (EXPREGS[0] & 0x40) {
+ uint8 sbank = (EXPREGS[1] & 0x10);
+ if (EXPREGS[0] & 0x80) {
+ uint8 bank = ((EXPREGS[1] & 3) << 4) | ((EXPREGS[1] & 8) << 3) | (EXPREGS[0] & 0x7) | (sbank >> 1);
+ if (EXPREGS[0] & 0x20) {
+// FCEU_printf("8000:%02X\n",bank>>1);
+ setprg32(0x8000, bank >> 1);
+ } else {
+// FCEU_printf("8000-C000:%02X\n",bank);
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else {
+// FCEU_printf("%04x:%02X\n",A,((EXPREGS[1]&3)<<5)|((EXPREGS[1]&8)<<4)|(V&0x0F)|sbank);
+ setprg8(A, ((EXPREGS[1] & 3) << 5) | ((EXPREGS[1] & 8) << 4) | (V & 0x0F) | sbank);
+ }
+ } else {
+ if (EXPREGS[0] & 0x80) {
+ uint8 bank = ((EXPREGS[1] & 3) << 4) | ((EXPREGS[1] & 8) << 3) | (EXPREGS[0] & 0xF);
+ if (EXPREGS[0] & 0x20) {
+// FCEU_printf("8000:%02X\n",(bank>>1)&0x07);
+ setprg32(0x8000, bank >> 1);
+ } else {
+// FCEU_printf("8000-C000:%02X\n",bank&0x0F);
+ setprg16(0x8000, bank);
+ setprg16(0xC000, bank);
+ }
+ } else {
+// FCEU_printf("%04X:%02X\n",A,(((EXPREGS[1]&3)<<5)|((EXPREGS[1]&8)<<4)|(V&0x1F))&0x1F);
+ setprg8(A, ((EXPREGS[1] & 3) << 5) | ((EXPREGS[1] & 8) << 4) | (V & 0x1F));
+ }
+ }
+}
+static DECLFW(UNL8237Write) {
+ uint8 dat = V;
+ uint8 adr = adrperm[EXPREGS[2]][((A >> 12) & 6) | (A & 1)];
+ uint16 addr = (adr & 1) | ((adr & 6) << 12) | 0x8000;
+ if (adr < 4) {
+ if (!adr)
+ dat = (dat & 0xC0) | (regperm[EXPREGS[2]][dat & 7]);
+ MMC3_CMDWrite(addr, dat);
+ } else
+ MMC3_IRQWrite(addr, dat);
+}
+
+static DECLFW(UNL8237ExWrite) {
+ switch (A) {
+ case 0x5000: EXPREGS[0] = V; FixMMC3PRG(MMC3_cmd); break;
+ case 0x5001: EXPREGS[1] = V; FixMMC3PRG(MMC3_cmd); FixMMC3CHR(MMC3_cmd); break;
+ case 0x5007: EXPREGS[2] = V; break;
+ }
+}
+
+static void UNL8237Power(void) {
+ EXPREGS[0] = EXPREGS[2] = 0;
+ EXPREGS[1] = 3;
+ GenMMC3Power();
+ SetWriteHandler(0x8000, 0xFFFF, UNL8237Write);
+ SetWriteHandler(0x5000, 0x7FFF, UNL8237ExWrite);
+}
+
+void UNL8237_Init(CartInfo *info) {
+ GenMMC3_Init(info, 256, 256, 0, 0);
+ cwrap = UNL8237CW;
+ pwrap = UNL8237PW;
+ info->Power = UNL8237Power;
+ AddExState(EXPREGS, 3, 0, "EXPR");
+ AddExState(&cmdin, 1, 0, "CMDI");
+}
+
+void UNL8237A_Init(CartInfo *info) {
+ GenMMC3_Init(info, 256, 256, 0, 0);
+ cwrap = UNL8237ACW;
+ pwrap = UNL8237APW;
+ info->Power = UNL8237Power;
+ AddExState(EXPREGS, 3, 0, "EXPR");
+ AddExState(&cmdin, 1, 0, "CMDI");
+}
diff --git a/source/fceux/boards/88.cpp b/source/fceux/boards/88.cpp
new file mode 100644
index 0000000..7341f25
--- /dev/null
+++ b/source/fceux/boards/88.cpp
@@ -0,0 +1,83 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[8];
+static uint8 mirror, cmd, is154;
+
+static SFORMAT StateRegs[] =
+{
+ { &cmd, 1, "CMD" },
+ { &mirror, 1, "MIRR" },
+ { reg, 8, "REGS" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr2(0x0000, reg[0] >> 1);
+ setchr2(0x0800, reg[1] >> 1);
+ setchr1(0x1000, reg[2] | 0x40);
+ setchr1(0x1400, reg[3] | 0x40);
+ setchr1(0x1800, reg[4] | 0x40);
+ setchr1(0x1C00, reg[5] | 0x40);
+ setprg8(0x8000, reg[6]);
+ setprg8(0xA000, reg[7]);
+ setprg8(0xC000, ~1);
+ setprg8(0xE000, ~0);
+}
+
+static void MSync(void) {
+ if (is154) setmirror(MI_0 + (mirror & 1));
+}
+
+static DECLFW(M88Write) {
+ switch (A & 0x8001) {
+ case 0x8000: cmd = V & 7; mirror = V >> 6; MSync(); break;
+ case 0x8001: reg[cmd] = V; Sync(); break;
+ }
+}
+
+static void M88Power(void) {
+ reg[0] = reg[1] = reg[2] = reg[3] = reg[4] = reg[5] = reg[6] = reg[7] = 0;
+ Sync();
+ MSync();
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, M88Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+ MSync();
+}
+
+void Mapper88_Init(CartInfo *info) {
+ is154 = 0;
+ info->Power = M88Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
+void Mapper154_Init(CartInfo *info) {
+ is154 = 1;
+ info->Power = M88Power;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/8in1.cpp b/source/fceux/boards/8in1.cpp
new file mode 100644
index 0000000..3e2f964
--- /dev/null
+++ b/source/fceux/boards/8in1.cpp
@@ -0,0 +1,67 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2016 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * 8-in-1 Rockin' Kats, Snake, (PCB marked as "8 in 1"), similar to 12IN1,
+ * but with MMC3 on board, all games are hacked the same, Snake is buggy too!
+ *
+ * no reset-citcuit, so selected game can be reset, but to change it you must use power
+ *
+ */
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+static void BMC8IN1CW(uint32 A, uint8 V) {
+ setchr1(A, ((EXPREGS[0] & 0xC) << 5) | (V & 0x7F));
+}
+
+static void BMC8IN1PW(uint32 A, uint8 V) {
+ if(EXPREGS[0] & 0x10) { // MMC3 mode
+ setprg8(A, ((EXPREGS[0] & 0xC) << 2) | (V & 0xF));
+ } else {
+ setprg32(0x8000, EXPREGS[0] & 0xF);
+ }
+}
+
+static DECLFW(BMC8IN1Write) {
+ if(A & 0x1000) {
+ EXPREGS[0] = V;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+ } else {
+ if(A < 0xC000)
+ MMC3_CMDWrite(A, V);
+ else
+ MMC3_IRQWrite(A, V);
+ }
+}
+
+static void BMC8IN1Power(void) {
+ EXPREGS[0] = 0;
+ GenMMC3Power();
+ SetWriteHandler(0x8000, 0xFFFF, BMC8IN1Write);
+}
+
+void BMC8IN1_Init(CartInfo *info) {
+ GenMMC3_Init(info, 128, 128, 0, 0);
+ cwrap = BMC8IN1CW;
+ pwrap = BMC8IN1PW;
+ info->Power = BMC8IN1Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
diff --git a/source/fceux/boards/90.cpp b/source/fceux/boards/90.cpp
new file mode 100644
index 0000000..7c873d2
--- /dev/null
+++ b/source/fceux/boards/90.cpp
@@ -0,0 +1,507 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Xodnizel
+ * Copyright (C) 2005 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+//#define DEBUG90
+
+// Mapper 090 is simpliest mapper hardware and have not extended nametable control and latched chr banks in 4k mode
+// Mapper 209 much compicated hardware with decribed above features disabled by default and switchable by command
+// Mapper 211 the same mapper 209 but with forced nametable control
+
+static int is209;
+static int is211;
+
+static uint8 IRQMode; // from $c001
+static uint8 IRQPre; // from $c004
+static uint8 IRQPreSize; // from $c007
+static uint8 IRQCount; // from $c005
+static uint8 IRQXOR; // Loaded from $C006
+static uint8 IRQa; // $c002, $c003, and $c000
+
+static uint8 mul[2];
+static uint8 regie;
+
+static uint8 tkcom[4];
+static uint8 prgb[4];
+static uint8 chrlow[8];
+static uint8 chrhigh[8];
+
+static uint8 chr[2];
+
+static uint16 names[4];
+static uint8 tekker;
+
+static SFORMAT Tek_StateRegs[] = {
+ { &IRQMode, 1, "IRQM" },
+ { &IRQPre, 1, "IRQP" },
+ { &IRQPreSize, 1, "IRQR" },
+ { &IRQCount, 1, "IRQC" },
+ { &IRQXOR, 1, "IRQX" },
+ { &IRQa, 1, "IRQA" },
+ { mul, 2, "MUL" },
+ { ®ie, 1, "REGI" },
+ { tkcom, 4, "TKCO" },
+ { prgb, 4, "PRGB" },
+ { chr, 2, "CLTC" },
+ { chrlow, 4, "CHRL" },
+ { chrhigh, 8, "CHRH" },
+ { &names[0], 2 | FCEUSTATE_RLSB, "NMS0" },
+ { &names[1], 2 | FCEUSTATE_RLSB, "NMS1" },
+ { &names[2], 2 | FCEUSTATE_RLSB, "NMS2" },
+ { &names[3], 2 | FCEUSTATE_RLSB, "NMS3" },
+ { &tekker, 1, "TEKR" },
+ { 0 }
+};
+
+static void mira(void)
+{
+ if((tkcom[0]&0x20&&is209)||is211)
+ {
+ int x;
+ if(tkcom[0]&0x40) // Name tables are ROM-only
+ {
+ for(x=0;x<4;x++)
+ setntamem(CHRptr[0]+(((names[x])&CHRmask1[0])<<10),0,x);
+ }
+ else // Name tables can be RAM or ROM.
+ {
+ for(x=0;x<4;x++)
+ {
+ if((tkcom[1]&0x80)==(names[x]&0x80)) // RAM selected.
+ setntamem(NTARAM+((names[x]&0x1)<<10),1,x);
+ else
+ setntamem(CHRptr[0]+(((names[x])&CHRmask1[0])<<10),0,x);
+ }
+ }
+ }
+ else
+ {
+ switch(tkcom[1]&3)
+ {
+ case 0: setmirror(MI_V); break;
+ case 1: setmirror(MI_H); break;
+ case 2: setmirror(MI_0); break;
+ case 3: setmirror(MI_1); break;
+ }
+ }
+}
+
+static void tekprom(void)
+{
+ uint32 bankmode=((tkcom[3]&6)<<5);
+ switch(tkcom[0]&7)
+ {
+ case 00: if(tkcom[0]&0x80)
+ setprg8(0x6000,(((prgb[3]<<2)+3)&0x3F)|bankmode);
+ setprg32(0x8000,0x0F|((tkcom[3]&6)<<3));
+ break;
+ case 01: if(tkcom[0]&0x80)
+ setprg8(0x6000,(((prgb[3]<<1)+1)&0x3F)|bankmode);
+ setprg16(0x8000,(prgb[1]&0x1F)|((tkcom[3]&6)<<4));
+ setprg16(0xC000,0x1F|((tkcom[3]&6)<<4));
+ break;
+ case 03: // bit reversion
+ case 02: if(tkcom[0]&0x80)
+ setprg8(0x6000,(prgb[3]&0x3F)|bankmode);
+ setprg8(0x8000,(prgb[0]&0x3F)|bankmode);
+ setprg8(0xa000,(prgb[1]&0x3F)|bankmode);
+ setprg8(0xc000,(prgb[2]&0x3F)|bankmode);
+ setprg8(0xe000,0x3F|bankmode);
+ break;
+ case 04: if(tkcom[0]&0x80)
+ setprg8(0x6000,(((prgb[3]<<2)+3)&0x3F)|bankmode);
+ setprg32(0x8000,(prgb[3]&0x0F)|((tkcom[3]&6)<<3));
+ break;
+ case 05: if(tkcom[0]&0x80)
+ setprg8(0x6000,(((prgb[3]<<1)+1)&0x3F)|bankmode);
+ setprg16(0x8000,(prgb[1]&0x1F)|((tkcom[3]&6)<<4));
+ setprg16(0xC000,(prgb[3]&0x1F)|((tkcom[3]&6)<<4));
+ break;
+ case 07: // bit reversion
+ case 06: if(tkcom[0]&0x80)
+ setprg8(0x6000,(prgb[3]&0x3F)|bankmode);
+ setprg8(0x8000,(prgb[0]&0x3F)|bankmode);
+ setprg8(0xa000,(prgb[1]&0x3F)|bankmode);
+ setprg8(0xc000,(prgb[2]&0x3F)|bankmode);
+ setprg8(0xe000,(prgb[3]&0x3F)|bankmode);
+ break;
+ }
+}
+
+static void tekvrom(void)
+{
+ int x, bank=0, mask=0xFFFF;
+ if(!(tkcom[3]&0x20))
+ {
+ bank=(tkcom[3]&1)|((tkcom[3]&0x18)>>2);
+ switch (tkcom[0]&0x18)
+ {
+ case 0x00: bank<<=5; mask=0x1F; break;
+ case 0x08: bank<<=6; mask=0x3F; break;
+ case 0x10: bank<<=7; mask=0x7F; break;
+ case 0x18: bank<<=8; mask=0xFF; break;
+ }
+ }
+ switch(tkcom[0]&0x18)
+ {
+ case 0x00: // 8KB
+ setchr8(((chrlow[0]|(chrhigh[0]<<8))&mask)|bank);
+ break;
+ case 0x08: // 4KB
+// for(x=0;x<8;x+=4)
+// setchr4(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
+ setchr4(0x0000,((chrlow[chr[0]]|(chrhigh[chr[0]]<<8))&mask)|bank);
+ setchr4(0x1000,((chrlow[chr[1]]|(chrhigh[chr[1]]<<8))&mask)|bank);
+ break;
+ case 0x10: // 2KB
+ for(x=0;x<8;x+=2)
+ setchr2(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
+ break;
+ case 0x18: // 1KB
+ for(x=0;x<8;x++)
+ setchr1(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank);
+ break;
+ }
+}
+
+static DECLFW(M90TekWrite)
+{
+ switch(A&0x5C03)
+ {
+ case 0x5800: mul[0]=V; break;
+ case 0x5801: mul[1]=V; break;
+ case 0x5803: regie=V; break;
+ }
+}
+
+static DECLFR(M90TekRead)
+{
+ switch(A&0x5C03)
+ {
+ case 0x5800: return (mul[0]*mul[1]);
+ case 0x5801: return((mul[0]*mul[1])>>8);
+ case 0x5803: return (regie);
+ default: return tekker;
+ }
+ return(0xff);
+}
+
+static DECLFW(M90PRGWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ prgb[A&3]=V;
+ tekprom();
+}
+
+static DECLFW(M90CHRlowWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ chrlow[A&7]=V;
+ tekvrom();
+}
+
+static DECLFW(M90CHRhiWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ chrhigh[A&7]=V;
+ tekvrom();
+}
+
+static DECLFW(M90NTWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ if(A&4)
+ {
+ names[A&3]&=0x00FF;
+ names[A&3]|=V<<8;
+ }
+ else
+ {
+ names[A&3]&=0xFF00;
+ names[A&3]|=V;
+ }
+ mira();
+}
+
+static DECLFW(M90IRQWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ switch(A&7)
+ {
+ case 00: //FCEU_printf("%s IRQ (C000)\n",V&1?"Enable":"Disable");
+ IRQa=V&1;if(!(V&1)) X6502_IRQEnd(FCEU_IQEXT);break;
+ case 02: //FCEU_printf("Disable IRQ (C002) scanline=%d\n", scanline);
+ IRQa=0;X6502_IRQEnd(FCEU_IQEXT);break;
+ case 03: //FCEU_printf("Enable IRQ (C003) scanline=%d\n", scanline);
+ IRQa=1;break;
+ case 01: IRQMode=V;
+ // FCEU_printf("IRQ Count method: ");
+ // switch (IRQMode&3)
+ // {
+ // case 00: FCEU_printf("M2 cycles\n");break;
+ // case 01: FCEU_printf("PPU A12 toggles\n");break;
+ // case 02: FCEU_printf("PPU reads\n");break;
+ // case 03: FCEU_printf("Writes to CPU space\n");break;
+ // }
+ // FCEU_printf("Counter prescaler size: %s\n",(IRQMode&4)?"3 bits":"8 bits");
+ // FCEU_printf("Counter prescaler size adjust: %s\n",(IRQMode&8)?"Used C007":"Normal Operation");
+ // if((IRQMode>>6)==2) FCEU_printf("Counter Down\n");
+ // else if((IRQMode>>6)==1) FCEU_printf("Counter Up\n");
+ // else FCEU_printf("Counter Stopped\n");
+ break;
+ case 04: //FCEU_printf("Pre Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR);
+ IRQPre=V^IRQXOR;break;
+ case 05: //FCEU_printf("Main Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR);
+ IRQCount=V^IRQXOR;break;
+ case 06: //FCEU_printf("Xor Value: %d\n",V);
+ IRQXOR=V;break;
+ case 07: //if(!(IRQMode&8)) FCEU_printf("C001 is clear, no effect applied\n");
+ // else if(V==0xFF) FCEU_printf("Prescaler is changed for 12bits\n");
+ // else FCEU_printf("Counter Stopped\n");
+ IRQPreSize=V;break;
+ }
+}
+
+static DECLFW(M90ModeWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ tkcom[A&3]=V;
+ tekprom();
+ tekvrom();
+ mira();
+
+#ifdef DEBUG90
+ switch (A&3)
+ {
+ case 00: FCEU_printf("Main Control Register:\n");
+ FCEU_printf(" PGR Banking mode: %d\n",V&7);
+ FCEU_printf(" CHR Banking mode: %d\n",(V>>3)&3);
+ FCEU_printf(" 6000-7FFF addresses mapping: %s\n",(V&0x80)?"Yes":"No");
+ FCEU_printf(" Nametable control: %s\n",(V&0x20)?"Enabled":"Disabled");
+ if(V&0x20)
+ FCEU_printf(" Nametable can be: %s\n",(V&0x40)?"ROM Only":"RAM or ROM");
+ break;
+ case 01: FCEU_printf("Mirroring mode: ");
+ switch (V&3)
+ {
+ case 0: FCEU_printf("Vertical\n");break;
+ case 1: FCEU_printf("Horizontal\n");break;
+ case 2: FCEU_printf("Nametable 0 only\n");break;
+ case 3: FCEU_printf("Nametable 1 only\n");break;
+ }
+ FCEU_printf("Mirroring flag: %s\n",(V&0x80)?"On":"Off");
+ break;
+ case 02: if((((tkcom[0])>>5)&3)==1)
+ FCEU_printf("Nametable ROM/RAM select mode: %d\n",V>>7);
+ break;
+ case 03:
+ FCEU_printf("CHR Banking mode: %s\n",(V&0x20)?"Entire CHR ROM":"256Kb Switching mode");
+ if(!(V&0x20)) FCEU_printf("256K CHR bank number: %02x\n",(V&1)|((V&0x18)>>2));
+ FCEU_printf("512K PRG bank number: %d\n",(V&6)>>1);
+ FCEU_printf("CHR Bank mirroring: %s\n",(V&0x80)?"Swapped":"Normal operate");
+ }
+#endif
+}
+
+static DECLFW(M90DummyWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+}
+
+static void CCL(void)
+{
+ if((IRQMode>>6) == 1) // Count Up
+ {
+ IRQCount++;
+ if((IRQCount == 0) && IRQa)
+ {
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+ else if((IRQMode>>6) == 2) // Count down
+ {
+ IRQCount--;
+ if((IRQCount == 0xFF) && IRQa)
+ {
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void ClockCounter(void)
+{
+ uint8 premask;
+
+ if(IRQMode & 0x4)
+ premask = 0x7;
+ else
+ premask = 0xFF;
+ if((IRQMode>>6) == 1) // Count up
+ {
+ IRQPre++;
+ if((IRQPre & premask) == 0) CCL();
+ }
+ else if((IRQMode>>6) == 2) // Count down
+ {
+ IRQPre--;
+ if((IRQPre & premask) == premask) CCL();
+ }
+}
+
+void CPUWrap(int a)
+{
+ int x;
+ if((IRQMode&3)==0) for(x=0;x>8;
+ if(h<0x20&&((h&0x0F)==0xF))
+ {
+ l=A&0xF0;
+ if(l==0xD0)
+ {
+ chr[(h&0x10)>>4]=((h&0x10)>>2);
+ tekvrom();
+ }
+ else if(l==0xE0)
+ {
+ chr[(h&0x10)>>4]=((h&0x10)>>2)|2;
+ tekvrom();
+ }
+ }
+ }
+ else
+ {
+ chr[0]=0;
+ chr[1]=4;
+ }
+}
+
+static void togglie()
+{
+ tekker+=0x40;
+ tekker&=0xC0;
+ FCEU_printf("tekker=%02x\n",tekker);
+ memset(tkcom,0x00,sizeof(tkcom));
+ memset(prgb,0xff,sizeof(prgb));
+ tekprom();
+ tekvrom();
+}
+
+static void M90Restore(int version)
+{
+ tekprom();
+ tekvrom();
+ mira();
+}
+
+static void M90Power(void)
+{
+ SetWriteHandler(0x5000,0x5fff,M90TekWrite);
+ SetWriteHandler(0x8000,0x8ff0,M90PRGWrite);
+ SetWriteHandler(0x9000,0x9fff,M90CHRlowWrite);
+ SetWriteHandler(0xA000,0xAfff,M90CHRhiWrite);
+ SetWriteHandler(0xB000,0xBfff,M90NTWrite);
+ SetWriteHandler(0xC000,0xCfff,M90IRQWrite);
+ SetWriteHandler(0xD000,0xD5ff,M90ModeWrite);
+ SetWriteHandler(0xE000,0xFfff,M90DummyWrite);
+
+
+ SetReadHandler(0x5000,0x5fff,M90TekRead);
+ SetReadHandler(0x6000,0xffff,CartBR);
+
+ mul[0]=mul[1]=regie=0xFF;
+
+ memset(tkcom,0x00,sizeof(tkcom));
+ memset(prgb,0xff,sizeof(prgb));
+ memset(chrlow,0xff,sizeof(chrlow));
+ memset(chrhigh,0xff,sizeof(chrhigh));
+ memset(names,0x00,sizeof(names));
+
+ if(is211)
+ tekker=0xC0;
+ else
+ tekker=0x00;
+
+ tekprom();
+ tekvrom();
+}
+
+
+void Mapper90_Init(CartInfo *info)
+{
+ is211=0;
+ is209=0;
+ info->Reset=togglie;
+ info->Power=M90Power;
+ PPU_hook=M90PPU;
+ MapIRQHook=CPUWrap;
+ GameHBIRQHook2=SLWrap;
+ GameStateRestore=M90Restore;
+ AddExState(Tek_StateRegs, ~0, 0, 0);
+}
+
+void Mapper209_Init(CartInfo *info)
+{
+ is211=0;
+ is209=1;
+ info->Reset=togglie;
+ info->Power=M90Power;
+ PPU_hook=M90PPU;
+ MapIRQHook=CPUWrap;
+ GameHBIRQHook2=SLWrap;
+ GameStateRestore=M90Restore;
+ AddExState(Tek_StateRegs, ~0, 0, 0);
+}
+
+void Mapper211_Init(CartInfo *info)
+{
+ is211=1;
+ info->Reset=togglie;
+ info->Power=M90Power;
+ PPU_hook=M90PPU;
+ MapIRQHook=CPUWrap;
+ GameHBIRQHook2=SLWrap;
+ GameStateRestore=M90Restore;
+ AddExState(Tek_StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/91.cpp b/source/fceux/boards/91.cpp
new file mode 100644
index 0000000..d1ed61b
--- /dev/null
+++ b/source/fceux/boards/91.cpp
@@ -0,0 +1,85 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 cregs[4], pregs[2];
+static uint8 IRQCount, IRQa;
+
+static SFORMAT StateRegs[] =
+{
+ { cregs, 4, "CREG" },
+ { pregs, 2, "PREG" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 1, "IRQC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setprg8(0x8000, pregs[0]);
+ setprg8(0xa000, pregs[1]);
+ setprg8(0xc000, ~1);
+ setprg8(0xe000, ~0);
+ setchr2(0x0000, cregs[0]);
+ setchr2(0x0800, cregs[1]);
+ setchr2(0x1000, cregs[2]);
+ setchr2(0x1800, cregs[3]);
+}
+
+static DECLFW(M91Write0) {
+ cregs[A & 3] = V;
+ Sync();
+}
+
+static DECLFW(M91Write1) {
+ switch (A & 3) {
+ case 0:
+ case 1: pregs[A & 1] = V; Sync(); break;
+ case 2: IRQa = IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 3: IRQa = 1; X6502_IRQEnd(FCEU_IQEXT); break;
+ }
+}
+
+static void M91Power(void) {
+ Sync();
+ SetWriteHandler(0x6000, 0x6fff, M91Write0);
+ SetWriteHandler(0x7000, 0x7fff, M91Write1);
+ SetReadHandler(0x8000, 0xffff, CartBR);
+}
+
+static void M91IRQHook(void) {
+ if (IRQCount < 8 && IRQa) {
+ IRQCount++;
+ if (IRQCount >= 8) {
+ X6502_IRQBegin(FCEU_IQEXT);
+ }
+ }
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper91_Init(CartInfo *info) {
+ info->Power = M91Power;
+ GameHBIRQHook = M91IRQHook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/96.cpp b/source/fceux/boards/96.cpp
new file mode 100644
index 0000000..08c42d6
--- /dev/null
+++ b/source/fceux/boards/96.cpp
@@ -0,0 +1,70 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 1998 BERO
+ * Copyright (C) 2002 Xodnizel
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg, ppulatch;
+
+static SFORMAT StateRegs[] =
+{
+ { ®, 1, "REG" },
+ { &ppulatch, 1, "PPUL" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setmirror(MI_0);
+ setprg32(0x8000, reg & 3);
+ setchr4(0x0000, (reg & 4) | ppulatch);
+ setchr4(0x1000, (reg & 4) | 3);
+}
+
+static DECLFW(M96Write) {
+ reg = V;
+ Sync();
+}
+
+static void M96Hook(uint32 A) {
+ if ((A & 0x3000) == 0x2000) {
+ ppulatch = (A >> 8) & 3;
+ Sync();
+ }
+}
+
+static void M96Power(void) {
+ reg = ppulatch = 0;
+ Sync();
+ SetReadHandler(0x8000, 0xffff, CartBR);
+ SetWriteHandler(0x8000, 0xffff, M96Write);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper96_Init(CartInfo *info) {
+ info->Power = M96Power;
+ PPU_hook = M96Hook;
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
+
diff --git a/source/fceux/boards/99.cpp b/source/fceux/boards/99.cpp
new file mode 100644
index 0000000..b9df340
--- /dev/null
+++ b/source/fceux/boards/99.cpp
@@ -0,0 +1,79 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2012 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 latch;
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+static writefunc old4016;
+
+static SFORMAT StateRegs[] =
+{
+ { &latch, 1, "LATC" },
+ { 0 }
+};
+
+static void Sync(void) {
+ setchr8((latch >> 2) & 1);
+ setprg8r(0x10, 0x6000, 0);
+ setprg32(0x8000, 0);
+ setprg8(0x8000, latch & 4); /* Special for VS Gumshoe */
+}
+
+static DECLFW(M99Write) {
+ latch = V;
+ Sync();
+ old4016(A, V);
+}
+
+static void M99Power(void) {
+ latch = 0;
+ Sync();
+ old4016 = GetWriteHandler(0x4016);
+ SetWriteHandler(0x4016, 0x4016, M99Write);
+ SetReadHandler(0x6000, 0xFFFF, CartBR);
+ SetWriteHandler(0x6000, 0x7FFF, CartBW);
+ FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
+}
+
+static void M99Close(void)
+{
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ WRAM = NULL;
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void Mapper99_Init(CartInfo *info) {
+ info->Power = M99Power;
+ info->Close = M99Close;
+
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+
+ GameStateRestore = StateRestore;
+ AddExState(&StateRegs, ~0, 0, 0);
+}
diff --git a/source/fceux/boards/__dummy_mapper.cpp b/source/fceux/boards/__dummy_mapper.cpp
new file mode 100644
index 0000000..505f916
--- /dev/null
+++ b/source/fceux/boards/__dummy_mapper.cpp
@@ -0,0 +1,100 @@
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2013 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mapinc.h"
+
+static uint8 reg[8];
+static uint8 IRQa;
+static int16 IRQCount, IRQLatch;
+/*
+static uint8 *WRAM = NULL;
+static uint32 WRAMSIZE;
+static uint8 *CHRRAM = NULL;
+static uint32 CHRRAMSIZE;
+*/
+
+static SFORMAT StateRegs[] =
+{
+ { reg, 8, "REGS" },
+ { &IRQa, 1, "IRQA" },
+ { &IRQCount, 2, "IRQC" },
+ { &IRQLatch, 2, "IRQL" },
+ { 0 }
+};
+
+static void Sync(void) {
+}
+
+static DECLFW(MNNNWrite) {
+}
+
+static void MNNNPower(void) {
+// SetReadHandler(0x6000, 0x7fff, CartBR);
+// SetWriteHandler(0x6000, 0x7fff, CartBW);
+ SetReadHandler(0x8000, 0xFFFF, CartBR);
+ SetWriteHandler(0x8000, 0xFFFF, MNNNWrite);
+}
+
+static void MNNNReset(void) {
+}
+
+/*
+static void MNNNClose(void)
+{
+ if (WRAM)
+ FCEU_gfree(WRAM);
+ if (CHRRAM)
+ FCEU_gfree(CHRRAM);
+ WRAM = CHRRAM = NULL;
+}
+*/
+
+static void MNNNIRQHook() {
+ X6502_IRQBegin(FCEU_IQEXT);
+}
+
+static void StateRestore(int version) {
+ Sync();
+}
+
+void MapperNNN_Init(CartInfo *info) {
+ info->Reset = MNNNReset;
+ info->Power = MNNNPower;
+// info->Close = MNNNClose;
+ GameHBIRQHook = MNNNIRQHook;
+ GameStateRestore = StateRestore;
+/*
+ CHRRAMSIZE = 8192;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
+ AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
+*/
+/*
+ WRAMSIZE = 8192;
+ WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
+ SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
+ AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+ if (info->battery) {
+ info->SaveGame[0] = WRAM;
+ info->SaveGameLen[0] = WRAMSIZE;
+ }
+*/
+ AddExState(&StateRegs, ~0, 0, 0);
+}