From 706ee282943209c6e818f122c30c132a3803df06 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Sun, 23 Jun 2019 20:04:11 +0800 Subject: [PATCH 01/20] UNIF: Allow mirroring override (removes hard mirroring in vertical/horizontal modes) - A few multi-cart UNIF carts are incorrectly using vertical/horizontal mirroring but the mapper used has mapper-controlled mirroring which does not work when using previous hard-mirroring. - This PR allows overriding the initial mirroring set (vertical/horizontal) when cart requests a mirroring change for multi-cart games. --- src/unif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unif.c b/src/unif.c index 2ff053e..c969909 100644 --- a/src/unif.c +++ b/src/unif.c @@ -113,7 +113,8 @@ static uint8 exntar[2048]; static void MooMirroring(void) { if (mirrortodo < 0x4) - SetupCartMirroring(mirrortodo, 1, 0); + /* 06-22-19 Allow override when using vertical/horizontal mirroring. */ + SetupCartMirroring(mirrortodo, (mirrortodo >> 1) & 1, 0); else if (mirrortodo == 0x4) { SetupCartMirroring(4, 1, exntar); AddExState(exntar, 2048, 0, "EXNR"); From 130580d70eb55d69ad28899f4ee3ebda9cb8e4dc Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Sun, 23 Jun 2019 20:15:32 +0800 Subject: [PATCH 02/20] BMC-830425C-4391T: Update cpu banking - Fixes loading Mermaid game. --- src/boards/bmc830425C4391t.c | 52 +++++++++++------------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/src/boards/bmc830425C4391t.c b/src/boards/bmc830425C4391t.c index db18618..ce64fd2 100644 --- a/src/boards/bmc830425C4391t.c +++ b/src/boards/bmc830425C4391t.c @@ -26,66 +26,46 @@ #include "mapinc.h" -static uint8 regs[2]; -static uint8 isMermaid = 0; +static uint8 bank_size; +static uint8 inner_bank; +static uint8 outer_bank; static SFORMAT StateRegs[] = { - { regs, 2, "REGS" }, - { &isMermaid, 1, "MERM" }, + { &inner_bank, 1, "INNB" }, + { &outer_bank, 1, "OUTB" }, + { &bank_size, 1, "SIZE" }, { 0 } }; static void Sync(void) { - uint8 bank_size = (regs[0] & 0x80) ? 0x07: 0x0F; - uint8 outer_bank = !isMermaid ? (regs[0] & 0x78) : 0x04; - uint8 inner_bank = regs[1]; - uint8 game_block = regs[0] & 0x78; - - /* TODO: Hacky and forced mapping of outer banks(game block)... */ - if (!isMermaid) { - switch(game_block) { - case 0x00: /* botb outerbank=0 */ - case 0x10: /* rocketeer outerbank=1 */ - case 0x20: /* contra outerbank=2 */ - case 0x28: /* ducktales outerbank=3 */ - case 0x38: /* school fight outerbank=5 */ - outer_bank = (game_block >> 4) + ((game_block & 0x08) ? 0x01 : 0x00); - outer_bank |= (game_block >> 3) & 1; - break; - case 0x30: - /* Mermaid game block is tricky (to me at least). Aim here is - * when this register is selected, ignore any other outer bank reg changes */ - isMermaid = 1; - outer_bank = 0x04; - break; - } - } - setprg16r(outer_bank, 0x8000, (inner_bank & bank_size)); setprg16r(outer_bank, 0xC000, bank_size); setchr8(0); } static DECLFW(M320Write) { - if ((A & 0xF0E0) == 0xF0E0) { - regs[0] = (A & 0x1F) << 3; + const uint8 chip[] = { 0, 0, 1, 0, 2, 3, 4, 5 }; + /* address mask is inconsistent with that is in the wiki. Mask should be + * 0xFFE0 or Mermaid game will not work. */ + if ((A & 0xFFE0) == 0xF0E0) { + outer_bank = chip[(A & 0x0F)]; + bank_size = (A & 0x10) ? 0x07 : 0x0F; } - regs[1] = V & 0x0F; + inner_bank = (V & 0x0F); Sync(); } static void M320Power(void) { - regs[0] = regs[1] = 0; - isMermaid = 0; + bank_size = 0x0F; Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); SetWriteHandler(0x8000, 0xFFFF, M320Write); } static void M320Reset(void) { - regs[0] = regs[1] = 0; - isMermaid = 0; + inner_bank = outer_bank = 0; + bank_size = 0x0F; Sync(); } From e89bcbfb0d0763127d01213ce391bab90af6554c Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Sun, 23 Jun 2019 20:51:46 +0800 Subject: [PATCH 03/20] UNIF: Update mirroring on some boards based on last commit --- src/boards/addrlatch.c | 4 ++-- src/boards/bmc60311c.c | 2 +- src/boards/bmc80013b.c | 2 +- src/boards/bmcctc09.c | 2 +- src/boards/bmck3036.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index ee18af9..473559e 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -553,7 +553,7 @@ static void BMCTJ03Sync(void) { setchr8(bank); if (bank == 3) mirr ^= 1; /* Twin Bee has incorrect mirroring */ - SetupCartMirroring(mirr, 1, NULL); + setmirror(mirr); } void BMCTJ03_Init(CartInfo *info) { @@ -568,7 +568,7 @@ static void BMCSA005ASync(void) { setprg16(0x8000, latche & 0x0F); setprg16(0xC000, latche & 0x0F); setchr8(latche & 0x0F); - SetupCartMirroring((latche >> 3) & 1, 1, NULL); + setmirror((latche >> 3) & 1); } void BMCSA005A_Init(CartInfo *info) { diff --git a/src/boards/bmc60311c.c b/src/boards/bmc60311c.c index 8f313ee..03eaf11 100644 --- a/src/boards/bmc60311c.c +++ b/src/boards/bmc60311c.c @@ -66,7 +66,7 @@ static void Sync(void) { setchr8(0); setprg16(0x8000, preg[0]); setprg16(0xC000, preg[1]); - SetupCartMirroring(((mode & 8) >> 3) ^ 1, 1, NULL); + setmirror(((mode & 8) >> 3) ^ 1); } static DECLFW(Write0) { diff --git a/src/boards/bmc80013b.c b/src/boards/bmc80013b.c index 51fb150..82dc4cf 100644 --- a/src/boards/bmc80013b.c +++ b/src/boards/bmc80013b.c @@ -39,7 +39,7 @@ static void Sync(void) { else setprg16r(1, 0x8000, regs[0] & 0x03); setprg16(0xC000, regs[1]); - SetupCartMirroring(((regs[0] >> 4) & 1) ^ 1, 1, NULL); + setmirror(((regs[0] >> 4) & 1) ^ 1); } static DECLFW(BMC80013BWrite) { diff --git a/src/boards/bmcctc09.c b/src/boards/bmcctc09.c index 185576c..8651ad9 100644 --- a/src/boards/bmcctc09.c +++ b/src/boards/bmcctc09.c @@ -43,7 +43,7 @@ static void Sync(void) { setprg32(0x8000, regs[PRG] & 0x07); setchr8(regs[CHR] & 0x0F); - SetupCartMirroring(((regs[PRG] >> 5) & 1) ^ 1, 1, NULL); + setmirror(((regs[PRG] >> 5) & 1) ^ 1); } static DECLFW(WritePRG) { diff --git a/src/boards/bmck3036.c b/src/boards/bmck3036.c index 2e716e0..c013579 100644 --- a/src/boards/bmck3036.c +++ b/src/boards/bmck3036.c @@ -43,7 +43,7 @@ static void Sync(void) { setprg16(0xC000, regs[0] & 0x1F | 0x07); } setchr8(0); - SetupCartMirroring(((regs[0] & 0x25) == 0x25 ? MI_H : MI_V), 1, NULL); + setmirror(((regs[0] & 0x25) == 0x25) ? MI_H : MI_V); } static DECLFW(M340Write) { From 503dd5249b97d460d92160a3b9df1328af8e4ba5 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 24 Jun 2019 06:26:44 +0800 Subject: [PATCH 04/20] Add BMC-JC-016-2 --- src/boards/mmc3.c | 21 +++++++++++++++------ src/unif.c | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 9ac6f86..90a34b4 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -1169,20 +1169,29 @@ void Mapper198_Init(CartInfo *info) { } /* ---------------------------- Mapper 205 ------------------------------ */ -/* https://wiki.nesdev.com/w/index.php/INES_Mapper_205 */ +/* UNIF boardname BMC-JC-016-2 +https://wiki.nesdev.com/w/index.php/INES_Mapper_205 */ +static uint8 block[] = {0, 0, 1, 2}; static void M205PW(uint32 A, uint8 V) { - setprg8(A, EXPREGS[0] & 0x30 | (V & (!(EXPREGS[0] & 0xC0) ? 0x1F : 0x0F))); + uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x0F : 0x1F); + if (PRGptr[1]) + setprg8r(block[EXPREGS[0]], A, bank); + else + setprg8(A, EXPREGS[0] << 4 | bank); } static void M205CW(uint32 A, uint8 V) { - uint16 reg = (uint16)EXPREGS[0] & 0x30; - setchr1(A, (reg << 3) | V); + uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x7F : 0xFF); + if (PRGptr[1]) + setchr1r(block[EXPREGS[0]], A, bank); + else + setchr1(A, (EXPREGS[0] << 7) | bank); } static DECLFW(M205Write0) { if (EXPREGS[1] == 0) { - EXPREGS[0] = (V << 4) & 0x30; + EXPREGS[0] = V & 0x03; EXPREGS[1] = A & 0x80; FixMMC3PRG(MMC3_cmd); FixMMC3CHR(MMC3_cmd); @@ -1212,7 +1221,7 @@ static void M205Power(void) { } void Mapper205_Init(CartInfo *info) { - GenMMC3_Init(info, 128, 128, 8, 0); + GenMMC3_Init(info, 256, 128, 8, 0); pwrap = M205PW; cwrap = M205CW; info->Power = M205Power; diff --git a/src/unif.c b/src/unif.c index c969909..68403a6 100644 --- a/src/unif.c +++ b/src/unif.c @@ -493,6 +493,8 @@ static BMAPPING bmap[] = { { "KS106C", BMCKS106C_Init, 0 }, { "900218", BTL900218_Init, 0 }, + { "JC-016-2", Mapper205_Init, 0 }, + #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, { "COPYFAMI", MapperCopyFami_Init, 0 }, From c9b3dfb8d590041e5e187c687a2d06183002c41e Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 24 Jun 2019 07:00:29 +0800 Subject: [PATCH 05/20] Add BMC-T-262 --- src/boards/t-262.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/boards/t-262.c b/src/boards/t-262.c index ae8c818..d887ef6 100644 --- a/src/boards/t-262.c +++ b/src/boards/t-262.c @@ -33,8 +33,13 @@ static SFORMAT StateRegs[] = static void Sync(void) { setchr8(0); - setprg16(0x8000, base | bank); - setprg16(0xC000, base | (mode ? bank : 7)); + if (PRGptr[1]) { + setprg16r(base >> 3, 0x8000, bank); + setprg16r(base >> 3, 0xC000, (mode ? bank : 7)); + } else { + setprg16(0x8000, base | bank); + setprg16(0xC000, base | (mode ? bank : 7)); + } setmirror(mirr); } From db8a5ab2c99bbe9b7baf5df7798cf03e6612756e Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 24 Jun 2019 18:03:18 +0800 Subject: [PATCH 06/20] Add UNL-AX-40G --- src/boards/ax40g.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 1 + src/unif.h | 1 + 3 files changed, 96 insertions(+) create mode 100644 src/boards/ax40g.c diff --git a/src/boards/ax40g.c b/src/boards/ax40g.c new file mode 100644 index 0000000..87be2a7 --- /dev/null +++ b/src/boards/ax40g.c @@ -0,0 +1,94 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * + * 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 + */ + +/* NES 2.0 Mapper 527 is used for a bootleg version of + * Taito's 不動明王伝 (Fudō Myōō Den). + * Its UNIF board name is UNL-AX-40G. The original INES Mapper 207 is + * replaced with a VRC2 clone (A0/A1, i.e. VRC2b) while retaining + * Mapper 207's extended mirroring. + */ + +#include "mapinc.h" + +static uint8 preg[2], creg[8], NT[2]; + +static SFORMAT StateRegs[] = +{ + { preg, 2, "PREG" }, + { creg, 8, "CREG" }, + { NT, 2, "NMT" }, + { 0 } +}; + +static void Sync(void) { + uint8 i; + setprg8(0x8000, preg[0]); + setprg8(0xA000, preg[1]); + setprg8(0xC000, 0x1E); + setprg8(0xE000, 0x1F); + for (i = 0; i < 8; i++) + setchr1(i << 10, creg[i]); + setmirrorw(NT[0], NT[0], NT[1], NT[1]); +} + +static DECLFW(UNLAX40GWrite8) { + A &= 0xF003; + preg[0] = V & 0x1F; + Sync(); +} + +static DECLFW(UNLAX40GWriteA) { + A &= 0xF003; + preg[1] = V & 0x1F; + Sync(); +} + +static DECLFW(UNLAX40GWriteB) { + uint16 i, shift; + A &= 0xF003; + i = ((A >> 1) & 1) | ((A - 0xB000) >> 11); + shift = ((A & 1) << 2); + creg[i] = (creg[i] & (0xF0 >> shift)) | ((V & 0xF) << shift); + if (i < 2) + NT[i] = (creg[i] & 0x80) >> 7; + Sync(); +} + +static void UNLAX40GPower(void) { + Sync(); + SetReadHandler(0x8000, 0xFFFF, CartBR); + SetWriteHandler(0x8000, 0x8FFF, UNLAX40GWrite8); + SetWriteHandler(0xA000, 0xAFFF, UNLAX40GWriteA); + SetWriteHandler(0xB000, 0xEFFF, UNLAX40GWriteB); +} + +static void StateRestore(int version) { + Sync(); +} + +void UNLAX40G_Init(CartInfo *info) { + info->Power = UNLAX40GPower; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} + +/*void UNLAX40G_Init(CartInfo *info); // m527 +{ "AX-40G", UNLAX40G_Init, 0 }, +{ "JC-016-2", Mapper205_Init, 0 }, +*/ diff --git a/src/unif.c b/src/unif.c index 68403a6..ebd60fa 100644 --- a/src/unif.c +++ b/src/unif.c @@ -494,6 +494,7 @@ static BMAPPING bmap[] = { { "900218", BTL900218_Init, 0 }, { "JC-016-2", Mapper205_Init, 0 }, + { "AX-40G", UNLAX40G_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 93b3df8..6181f3b 100644 --- a/src/unif.h +++ b/src/unif.h @@ -179,6 +179,7 @@ void BMCK3036_Init(CartInfo *info); /* m340 */ void MINDKIDS_Init(CartInfo *info); /* m268 */ void UNLKS7021A_Init(CartInfo *info); /* m525 */ void BTL900218_Init(CartInfo *info); /* m524 */ +void UNLAX40G_Init(CartInfo *info); /* m527 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 78c0cb422e9d4757f57efa6ebafe2c9f1ed75395 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 24 Jun 2019 18:24:22 +0800 Subject: [PATCH 07/20] BMC-K-3088: move to its own mapper for better compatibility. --- src/boards/bmck3088.c | 72 +++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 2 +- src/unif.h | 1 + 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/boards/bmck3088.c diff --git a/src/boards/bmck3088.c b/src/boards/bmck3088.c new file mode 100644 index 0000000..e59c38c --- /dev/null +++ b/src/boards/bmck3088.c @@ -0,0 +1,72 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 287 + * similar to BMC-411120-C but without jumper or dipswitch */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMCK3088CW(uint32 A, uint8 V) { + if (CHRptr[EXPREGS[0] & 7]) + setchr1r(EXPREGS[0] & 7, A, V); + else + setchr1(A, V | ((EXPREGS[0] & 3) << 7)); +} + +static void BMCK3088PW(uint32 A, uint8 V) { + if (PRGptr[EXPREGS[0] & 7]) { + uint8 chip = EXPREGS[0] & 7; + if (EXPREGS[0] & 8) + setprg32r(chip, 0x8000, ((EXPREGS[0] >> 4) & 3)); + else + setprg8r(chip, A, (V & 0x0F)); + } else { + if (EXPREGS[0] & 8) + setprg32(0x8000, ((EXPREGS[0] >> 4) & 3) | (0x0C)); + else + setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 3) << 4)); + } +} + +static DECLFW(BMCK3088LoWrite) { + EXPREGS[0] = A; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void BMCK3088Reset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMCK3088Power(void) { + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BMCK3088LoWrite); +} + +void BMCK3088_Init(CartInfo *info) { + GenMMC3_Init(info, 128, 128, 8, 0); + pwrap = BMCK3088PW; + cwrap = BMCK3088CW; + info->Power = BMCK3088Power; + info->Reset = BMCK3088Reset; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/unif.c b/src/unif.c index ebd60fa..9e8cc07 100644 --- a/src/unif.c +++ b/src/unif.c @@ -479,7 +479,7 @@ static BMAPPING bmap[] = { { "RESETNROM-XIN1", BMCRESETNROMXIN1_Init, 0 }, { " BMC-RESET-TXROM", BMCRESETTXROM_Init, 0 }, { "RESET-TXROM", BMCRESETTXROM_Init, 0 }, - { "K-3088", BMC411120C_Init, 0 }, + { "K-3088", BMCK3088_Init, 0 }, { "FARID_SLROM_8-IN-1", FARIDSLROM8IN1_Init, 0 }, { "830425C-4391T", BMC830425C4391T_Init, 0 }, { "TJ-03", BMCTJ03_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 6181f3b..2c9f269 100644 --- a/src/unif.h +++ b/src/unif.h @@ -180,6 +180,7 @@ void MINDKIDS_Init(CartInfo *info); /* m268 */ void UNLKS7021A_Init(CartInfo *info); /* m525 */ void BTL900218_Init(CartInfo *info); /* m524 */ void UNLAX40G_Init(CartInfo *info); /* m527 */ +void BMCK3088_Init(CartInfo *info); /* m287 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 42ae290d46c0b6473eb269200b89b315adbb9389 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 24 Jun 2019 18:45:20 +0800 Subject: [PATCH 08/20] Add BMC-STREETFIGTER-GAME4IN1 --- src/boards/mmc3.c | 20 +++++++++++++++++++- src/unif.c | 1 + src/unif.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 90a34b4..083aa4e 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -599,6 +599,12 @@ void Mapper47_Init(CartInfo *info) { } /* ---------------------------- Mapper 49 ------------------------------- */ +/* -------------------- BMC-STREETFIGTER-GAME4IN1 ----------------------- */ +/* added 6-24-19: + * BMC-STREETFIGTER-GAME4IN1 - Sic. $6000 set to $41 rather than $00 on power-up. + */ + +static uint8 isUNIF = 0; static void M49PW(uint32 A, uint8 V) { if (EXPREGS[0] & 1) { @@ -625,11 +631,12 @@ static DECLFW(M49Write) { } static void M49Reset(void) { - EXPREGS[0] = 0; + EXPREGS[0] = isUNIF ? 0x41 : 0; MMC3RegReset(); } static void M49Power(void) { + EXPREGS[0] = isUNIF ? 0x41 : 0; M49Reset(); GenMMC3Power(); SetWriteHandler(0x6000, 0x7FFF, M49Write); @@ -637,6 +644,7 @@ static void M49Power(void) { } void Mapper49_Init(CartInfo *info) { + isUNIF = 0; GenMMC3_Init(info, 512, 256, 0, 0); cwrap = M49CW; pwrap = M49PW; @@ -645,6 +653,16 @@ void Mapper49_Init(CartInfo *info) { AddExState(EXPREGS, 1, 0, "EXPR"); } +void BMCSFGAME4IN1_Init(CartInfo *info) { + isUNIF = 1; + GenMMC3_Init(info, 512, 512, 0, 0); + cwrap = M49CW; + pwrap = M49PW; + info->Reset = M49Reset; + info->Power = M49Power; + AddExState(EXPREGS, 1, 0, "EXPR"); +} + /* ---------------------------- Mapper 52 ------------------------------- */ static void M52PW(uint32 A, uint8 V) { uint32 mask = 0x1F ^ ((EXPREGS[0] & 8) << 1); diff --git a/src/unif.c b/src/unif.c index 9e8cc07..3e482e7 100644 --- a/src/unif.c +++ b/src/unif.c @@ -495,6 +495,7 @@ static BMAPPING bmap[] = { { "JC-016-2", Mapper205_Init, 0 }, { "AX-40G", UNLAX40G_Init, 0 }, + { " BMC-STREETFIGTER-GAME4IN1", BMCSFGAME4IN1_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 2c9f269..9bcf745 100644 --- a/src/unif.h +++ b/src/unif.h @@ -181,6 +181,7 @@ void UNLKS7021A_Init(CartInfo *info); /* m525 */ void BTL900218_Init(CartInfo *info); /* m524 */ void UNLAX40G_Init(CartInfo *info); /* m527 */ void BMCK3088_Init(CartInfo *info); /* m287 */ +void BMCSFGAME4IN1_Init(CartInfo *info); /* m049 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 177cd68d9922d01e6a2b07c7699f091f8cd31a73 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 25 Jun 2019 08:10:36 +0800 Subject: [PATCH 09/20] Add support for UNL-BJ-56 and BMC-G631 (probably a Ghostbuster63in1 mislabel) --- src/boards/bj56.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 2 + src/unif.h | 1 + 3 files changed, 122 insertions(+) create mode 100644 src/boards/bj56.c diff --git a/src/boards/bj56.c b/src/boards/bj56.c new file mode 100644 index 0000000..a73a2ce --- /dev/null +++ b/src/boards/bj56.c @@ -0,0 +1,119 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 526 is used for a bootleg version of Namco's 三国志: 中原の覇者 (Sangokushi: Chūgen no Hasha). + * Its UNIF board name is UNL-BJ-56. + * Mirroring seems to be hard-wired (to vertical). + * https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_526 + */ + +#include "mapinc.h" + +static uint8 preg[4], creg[8]; +static uint32 IRQCount; +static uint8 *WRAM = NULL; +static uint32 WRAMSIZE; + +static SFORMAT StateRegs[] = +{ + { preg, 4, "PREG" }, + { creg, 8, "CREG" }, + { &IRQCount, 4, "IRQC" }, + { 0 } +}; + +static void Sync(void) { + uint8 i; + setprg8r(0x10, 0x6000, 0); + setprg8(0x8000, preg[0]); + setprg8(0xA000, preg[1]); + setprg8(0xC000, preg[2]); + setprg8(0xE000, preg[3]); + for (i = 0; i < 8; i++) + setchr1((i << 10), creg[i]); + setmirror(MI_V); +} + +static DECLFW(UNLBJ56Write) { +/* FCEU_printf("Wr: A:%04x V:%02x\n", A, V); */ + A &= 0xF00F; + if (A <= 0x8007) { + creg[A & 0x07] = V; + Sync(); + } else if (A <= 0x800B) { + preg[A & 0x03] = V; + Sync(); + } else { + switch (A & 0x0F) { + case 0x0D: + case 0x0F: + /* One of these two acknowledges a pending IRQ, and the other + * resets to IRQ counter to zero. Because they are always written + * to one after the other, it's not clear which one does which. */ + X6502_IRQEnd(FCEU_IQEXT); + IRQCount = 0; + break; + } + } +} + +static void FP_FASTAPASS(1) UNLBJ56IRQHook(int a) { + IRQCount += a; + if (IRQCount & 4096) + X6502_IRQBegin(FCEU_IQEXT); +} + +static void UNLBJ56Close(void) { + if (WRAM) + FCEU_gfree(WRAM); + WRAM = NULL; +} + +static void UNLBJ56Power(void) { + preg[0] = ~3; + preg[1] = ~2; + preg[2] = ~1; + preg[3] = ~0; + Sync(); + SetReadHandler(0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, CartBW); + SetWriteHandler(0x8000, 0x800F, UNLBJ56Write); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); +} + +static void StateRestore(int version) { + Sync(); +} + +void UNLBJ56_Init(CartInfo *info) { + info->Power = UNLBJ56Power; + info->Close = UNLBJ56Close; + MapIRQHook = UNLBJ56IRQHook; + 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/src/unif.c b/src/unif.c index 3e482e7..c2f4b89 100644 --- a/src/unif.c +++ b/src/unif.c @@ -496,6 +496,8 @@ static BMAPPING bmap[] = { { "JC-016-2", Mapper205_Init, 0 }, { "AX-40G", UNLAX40G_Init, 0 }, { " BMC-STREETFIGTER-GAME4IN1", BMCSFGAME4IN1_Init, 0 }, + { "G631", BMCGhostbusters63in1_Init, 0 }, + { "BJ-56", UNLBJ56_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 9bcf745..d2111b3 100644 --- a/src/unif.h +++ b/src/unif.h @@ -182,6 +182,7 @@ void BTL900218_Init(CartInfo *info); /* m524 */ void UNLAX40G_Init(CartInfo *info); /* m527 */ void BMCK3088_Init(CartInfo *info); /* m287 */ void BMCSFGAME4IN1_Init(CartInfo *info); /* m049 */ +void UNLBJ56_Init(CartInfo *info); /* m526 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 6ff34f4c7ae6a0ce52c2a1a7985db543cd1b37af Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 25 Jun 2019 10:48:42 +0800 Subject: [PATCH 10/20] Add support for BMC-L6IN1 --- src/boards/bmcl6in1.c | 74 +++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 1 + src/unif.h | 1 + 3 files changed, 76 insertions(+) create mode 100644 src/boards/bmcl6in1.c diff --git a/src/boards/bmcl6in1.c b/src/boards/bmcl6in1.c new file mode 100644 index 0000000..f788537 --- /dev/null +++ b/src/boards/bmcl6in1.c @@ -0,0 +1,74 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 345 + * BMC-L6IN1 + * New Star 6-in-1 Game Cartridge + * https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_345 + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMCL6IN1CW(uint32 A, uint8 V) { + setchr8(V); +} + +static void BMCL6IN1PW(uint32 A, uint8 V) { + if (EXPREGS[0] & 0x0C) + setprg8(A, (V & 0x0F) | (EXPREGS[0] & 0xC0) >> 2); + else + setprg32(0x8000, ((EXPREGS[0] & 0xC0) >> 4) | (EXPREGS[0] & 0x03)); +} + +static void BMCL6IN1MW(uint8 V) { + if (EXPREGS[0] & 0x20) + setmirror(MI_0 + ((EXPREGS[0] & 0x10) >> 1)); + else { + A000B = V; + setmirror((V & 1) ^ 1); + } +} + +static DECLFW(BMCL6IN1Write) { + EXPREGS[0] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void BMCL6IN1Reset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMCL6IN1Power(void) { + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BMCL6IN1Write); +} + +void BMCL6IN1_Init(CartInfo *info) { + GenMMC3_Init(info, 512, 0, 1, 0); + pwrap = BMCL6IN1PW; + cwrap = BMCL6IN1CW; + mwrap = BMCL6IN1MW; + info->Power = BMCL6IN1Power; + info->Reset = BMCL6IN1Reset; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/unif.c b/src/unif.c index c2f4b89..a918888 100644 --- a/src/unif.c +++ b/src/unif.c @@ -498,6 +498,7 @@ static BMAPPING bmap[] = { { " BMC-STREETFIGTER-GAME4IN1", BMCSFGAME4IN1_Init, 0 }, { "G631", BMCGhostbusters63in1_Init, 0 }, { "BJ-56", UNLBJ56_Init, 0 }, + { "L6IN1", BMCL6IN1_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index d2111b3..a378f12 100644 --- a/src/unif.h +++ b/src/unif.h @@ -183,6 +183,7 @@ void UNLAX40G_Init(CartInfo *info); /* m527 */ void BMCK3088_Init(CartInfo *info); /* m287 */ void BMCSFGAME4IN1_Init(CartInfo *info); /* m049 */ void UNLBJ56_Init(CartInfo *info); /* m526 */ +void BMCL6IN1_Init(CartInfo *info); /* m345 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From afaa5eab6ce1eebd4cb526a896df2c54852e14e5 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 25 Jun 2019 16:47:18 +0800 Subject: [PATCH 11/20] Add support for BMC-CTC-12IN1 and BMC-891227 --- src/boards/bmcgamecard.c | 95 ++++++++++++++++++++++++++++++++++++++++ src/unif.c | 4 +- src/unif.h | 3 ++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/boards/bmcgamecard.c diff --git a/src/boards/bmcgamecard.c b/src/boards/bmcgamecard.c new file mode 100644 index 0000000..e634abd --- /dev/null +++ b/src/boards/bmcgamecard.c @@ -0,0 +1,95 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 337 - BMC-CTC-12IN1 + * 12-in-1 Game Card multicart + * https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_337 + + * NES 2.0 Mapper 350 - BMC-891227 + * Super 15-in-1 Game Card + * https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_350 + */ + +#include "mapinc.h" + +static uint8 latche, m350; + +static SFORMAT StateRegs[] = +{ + { &latche, 1, "LATC" }, + { &m350, 1, "M350" }, + { 0 } +}; + +static void Sync(void) { + uint8 mirroring = m350 ? ((latche >> 7) & 1) : ((latche >> 5) & 1); + uint8 mode = m350 ? ((latche >> 5) & 0x03) : ((latche >> 6) & 0x03); + uint8 chip = m350 ? ((mode & 2) ? ((latche >> 5) & 1) : 0) : 0; + + setchr8(0); + setprg8(0x6000, 1); + setprg16r(PRGptr[1] ? chip : 0, 0x8000, (latche & 0x1F)); + setprg16r(PRGptr[1] ? chip : 0, 0xC000, (latche & 0x1F) | ((mode & 2) ? 0x07 : (mode & 1))); + setmirror(mirroring ^ 1); +} + +static DECLFW(BMCCTC12IN1Write8) { + latche = (latche & 7) | (V & ~7); + Sync(); +} + +static DECLFW(BMCCTC12IN1WriteC) { + latche = (latche & ~7) | (V & 7); + Sync(); +} + +static void BMCCTC12IN1Power(void) { + Sync(); + SetReadHandler(0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x8000, 0xBFFF, BMCCTC12IN1Write8); + SetWriteHandler(0xC000, 0xFFFF, BMCCTC12IN1WriteC); +} + +static void BMCCTC12IN1Reset(void) { + latche = 0; + Sync(); +} + +static void StateRestore(int version) { + Sync(); +} + +/* Mapper 337 - BMC-CTC-12IN1 */ +void BMCCTC12IN1_Init(CartInfo *info) { + m350 = 0; + info->Power = BMCCTC12IN1Power; + info->Reset = BMCCTC12IN1Reset; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} + +/* Mapper 350 - BMC-891227 */ +void BMC891227_Init(CartInfo *info) { + m350 = 1; + info->Power = BMCCTC12IN1Power; + info->Reset = BMCCTC12IN1Reset; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/unif.c b/src/unif.c index a918888..1d8159c 100644 --- a/src/unif.c +++ b/src/unif.c @@ -473,7 +473,6 @@ static BMAPPING bmap[] = { { "WAIXING-FW01", Mapper227_Init, 0 }, /* https://wiki.nesdev.com/w/index.php/Talk:INES_Mapper_242 */ { "WAIXING-FS005", BMCFK23C_Init, 0 }, /* https://wiki.nesdev.com/w/index.php/INES_Mapper_176 */ { "80013-B", BMC80013B_Init, 0 }, - { "TH2131-1", UNLTH21311_Init, 0 }, { "LH51", LH51_Init, 0 }, { "RESETNROM-XIN1", BMCRESETNROMXIN1_Init, 0 }, @@ -492,13 +491,14 @@ static BMAPPING bmap[] = { { "KS7021A", UNLKS7021A_Init, 0 }, { "KS106C", BMCKS106C_Init, 0 }, { "900218", BTL900218_Init, 0 }, - { "JC-016-2", Mapper205_Init, 0 }, { "AX-40G", UNLAX40G_Init, 0 }, { " BMC-STREETFIGTER-GAME4IN1", BMCSFGAME4IN1_Init, 0 }, { "G631", BMCGhostbusters63in1_Init, 0 }, { "BJ-56", UNLBJ56_Init, 0 }, { "L6IN1", BMCL6IN1_Init, 0 }, + { "CTC-12IN1", BMCCTC12IN1_Init, 0 }, + { "891227", BMC891227_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index a378f12..98bb3b1 100644 --- a/src/unif.h +++ b/src/unif.h @@ -185,6 +185,9 @@ void BMCSFGAME4IN1_Init(CartInfo *info); /* m049 */ void UNLBJ56_Init(CartInfo *info); /* m526 */ void BMCL6IN1_Init(CartInfo *info); /* m345 */ +void BMCCTC12IN1_Init(CartInfo *info); /* m337 */ +void BMC891227_Init(CartInfo *info); /* m350 */ + #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); void MapperCopyFami_Init(CartInfo *info); From 0cb1c866a17657a7a08c97760e385048714f4b35 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 25 Jun 2019 16:56:05 +0800 Subject: [PATCH 12/20] Silence clang warnings --- src/boards/90.c | 4 ++-- src/boards/bmc80013b.c | 2 +- src/boards/bmck3036.c | 4 ++-- src/boards/mmc1.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/boards/90.c b/src/boards/90.c index 2bc867a..ff2b0b4 100644 --- a/src/boards/90.c +++ b/src/boards/90.c @@ -130,13 +130,13 @@ static void tekprom(void) { case 0x00: if (tkcom[0] & 0x80) setprg8(0x6000, (((prgb[3] << 2) + 3) & 0x3F) | bankmode); - setprg32(0x8000, last_bank & prgmask | bankmode); + setprg32(0x8000, (last_bank & prgmask) | bankmode); break; case 0x01: if (tkcom[0] & 0x80) setprg8(0x6000, (((prgb[3] << 1) + 1) & 0x3F) | bankmode); setprg16(0x8000, (prgb[1] & prgmask) | bankmode); - setprg16(0xC000, last_bank & prgmask | bankmode); + setprg16(0xC000, (last_bank & prgmask) | bankmode); break; case 0x02: case 0x03: diff --git a/src/boards/bmc80013b.c b/src/boards/bmc80013b.c index 82dc4cf..bfe6b27 100644 --- a/src/boards/bmc80013b.c +++ b/src/boards/bmc80013b.c @@ -35,7 +35,7 @@ static SFORMAT StateRegs[] = static void Sync(void) { if (mode & 0x02) - setprg16(0x8000, regs[0] & 0x0F | regs[1] & 0x70); + setprg16(0x8000, (regs[0] & 0x0F) | (regs[1] & 0x70)); else setprg16r(1, 0x8000, regs[0] & 0x03); setprg16(0xC000, regs[1]); diff --git a/src/boards/bmck3036.c b/src/boards/bmck3036.c index c013579..77ced85 100644 --- a/src/boards/bmck3036.c +++ b/src/boards/bmck3036.c @@ -39,8 +39,8 @@ static void Sync(void) { setprg16(0x8000, regs[0] & 0x1F); setprg16(0xC000, regs[0] & 0x1F); } else { /* UNROM */ - setprg16(0x8000, regs[0] & 0x1F | regs[1] & 0x07); - setprg16(0xC000, regs[0] & 0x1F | 0x07); + setprg16(0x8000, (regs[0] & 0x1F) | (regs[1] & 0x07)); + setprg16(0xC000, (regs[0] & 0x1F) | 0x07); } setchr8(0); setmirror(((regs[0] & 0x25) == 0x25) ? MI_H : MI_V); diff --git a/src/boards/mmc1.c b/src/boards/mmc1.c index 4dc4f69..f3ef3c1 100644 --- a/src/boards/mmc1.c +++ b/src/boards/mmc1.c @@ -440,6 +440,6 @@ void FARIDSLROM8IN1_Init(CartInfo *info) { MMC1PRGHook16 = FARIDSLROM8IN1PRGHook; info->Power = FARIDSLROM8IN1Power; info->Reset = FARIDSLROM8IN1Reset; - AddExState(lock, 1, 0, "LOCK"); - AddExState(reg, 1, 0, "REG6"); + AddExState(&lock, 1, 0, "LOCK"); + AddExState(®, 1, 0, "REG6"); } From 3666962090e5cd3747ec678badc71a9a2ebdc2eb Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 25 Jun 2019 18:23:23 +0800 Subject: [PATCH 13/20] UNL-KS7017: Smoother state loading... - Smoother states loading by using the the register value used during call to Sync() instead of the last value written since write and sync are called at different times. - (reg value written @ $4A000, sync happens $5100) --- src/boards/KS7017.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/boards/KS7017.c b/src/boards/KS7017.c index 64812a4..b1c9d87 100644 --- a/src/boards/KS7017.c +++ b/src/boards/KS7017.c @@ -23,7 +23,7 @@ #include "mapinc.h" -static uint8 reg, mirr; +static uint8 latche, reg, mirr; static int32 IRQa, IRQCount, IRQLatch; static uint8 *WRAM = NULL; static uint32 WRAMSIZE; @@ -35,6 +35,7 @@ static SFORMAT StateRegs[] = { &IRQa, 4, "IRQA" }, { &IRQCount, 4, "IRQC" }, { &IRQLatch, 4, "IRQL" }, + { &latche, 1, "LATC" }, { 0 } }; @@ -47,8 +48,9 @@ static void Sync(void) { static DECLFW(UNLKS7017Write) { /* FCEU_printf("bs %04x %02x\n",A,V); */ if ((A & 0xFF00) == 0x4A00) { - reg = ((A >> 2) & 3) | ((A >> 4) & 4); + latche = ((A >> 2) & 3) | ((A >> 4) & 4); } else if ((A & 0xFF00) == 0x5100) { + reg = latche; Sync(); } else if (A == 0x4020) { X6502_IRQEnd(FCEU_IQEXT); From 024a2f904eed22414140d6ffa7c05afcf16d1c7d Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 00:11:14 +0800 Subject: [PATCH 14/20] Add support for FARID_UNROM_8-IN-1 and NEWSTAR-GRM070-8IN1 --- src/boards/faridunrom.c | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/boards/faridunrom.c diff --git a/src/boards/faridunrom.c b/src/boards/faridunrom.c new file mode 100644 index 0000000..219b8d7 --- /dev/null +++ b/src/boards/faridunrom.c @@ -0,0 +1,70 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 324 + * FARID_UNROM_8-IN-1 + * https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_324 + */ + +#include "mapinc.h" + +static uint8 latch; + +static SFORMAT StateRegs[] = +{ + { &latch, 1, "LATC" }, + { 0 } +}; + +static void Sync(void) { + setchr8(0); + setprg16(0x8000, ((latch & 0x70) >> 1) | (latch & 0x07)); + setprg16(0xC000, ((latch & 0x70) >> 1) | 0x07 ); +} + +static DECLFW(FARIDUNROMWrite) { + V &= CartBR(A); + if ((V & 0x80) && !(latch & 0x80) && !(latch & 0x08)) + latch = (latch & 0x87) | (V & 0x78); + latch = (latch & 0x78) | (V & 0x87); + Sync(); +} + +static void FARIDUNROMPower(void) { + Sync(); + SetReadHandler(0x8000, 0xFFFF, CartBR); + SetWriteHandler(0x8000, 0xFFFF, FARIDUNROMWrite); +} + +static void FARIDUNROMReset(void) { + latch &= ~0x78; + Sync(); +} + +static void StateRestore(int version) { + Sync(); +} + +void FARIDUNROM_Init(CartInfo *info) { + info->Power = FARIDUNROMPower; + info->Reset = FARIDUNROMReset; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} From 93986604acb5905894826a67d4d4879edcc48333 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 09:03:01 +0800 Subject: [PATCH 15/20] Add support for BMC-K-3033 --- src/boards/bcmk3033.c | 89 +++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 3 ++ src/unif.h | 2 + 3 files changed, 94 insertions(+) create mode 100644 src/boards/bcmk3033.c diff --git a/src/boards/bcmk3033.c b/src/boards/bcmk3033.c new file mode 100644 index 0000000..90ff0af --- /dev/null +++ b/src/boards/bcmk3033.c @@ -0,0 +1,89 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 322 + * BMC-K-3033 + * 35-in-1 (K-3033) + * http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_322 + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMCK3033CW(uint32 A, uint8 V) { + if (EXPREGS[2]) { + if (EXPREGS[3]) { // MMC3-256 + setchr1r(EXPREGS[1] & ~0x01, A, (V & 0xFF)); + } else { // MMC3-128 + setchr1r(EXPREGS[1], A, (V & 0x7F)); + } + } else { // NROM + setchr1r(EXPREGS[1], A, (V & 0x7F)); + } +} + +static void BMCK3033PW(uint32 A, uint8 V) { + if (EXPREGS[2]) { + if (EXPREGS[3] ) { +/* FCEU_printf("MMC3-256 A:%04x V:%02x chip:%02x\n", A, V, EXPREGS[1] & ~0x01); */ + setprg8r((EXPREGS[1] & ~0x01), A, (V & 0x1F)); + } else { +/* FCEU_printf("MMC3-128 A:%04x V:%02x chip:%02x\n", A, V, EXPREGS[1]); */ + setprg8r(EXPREGS[1], A, (V & 0x0F)); + } + } else { + if (EXPREGS[0] & 0x03) { +/* FCEU_printf("NROM-256 base:%02x chip:%02x\n", EXPREGS[0] >> 1, EXPREGS[1]); */ + setprg32r(EXPREGS[1], 0x8000, EXPREGS[0] >> 1); + } else { +/* FCEU_printf("NROM-128 base:%02x chip:%02x\n", EXPREGS[0], EXPREGS[1]); */ + setprg16r(EXPREGS[1], 0x8000, EXPREGS[0]); + setprg16r(EXPREGS[1], 0xC000, EXPREGS[0]); + } + } +} + +static DECLFW(BMCK3033Write) { + EXPREGS[0] = (A & 0x07); + EXPREGS[1] = ((A & 0x18) >> 3) | ((A & 0x40) >> 4); + EXPREGS[2] = (A & 0x20); + EXPREGS[3] = (A & 0x80); + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void BMCK3033Power(void) { + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BMCK3033Write); +} + +static void BMCK3033Reset(void) { + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + MMC3RegReset(); +} + +void BMCK3033_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 1, 0); + pwrap = BMCK3033PW; + cwrap = BMCK3033CW; + info->Power = BMCK3033Power; + info->Reset = BMCK3033Reset; + AddExState(EXPREGS, 4, 0, "EXPR"); +} diff --git a/src/unif.c b/src/unif.c index 1d8159c..9772d75 100644 --- a/src/unif.c +++ b/src/unif.c @@ -499,6 +499,9 @@ static BMAPPING bmap[] = { { "L6IN1", BMCL6IN1_Init, 0 }, { "CTC-12IN1", BMCCTC12IN1_Init, 0 }, { "891227", BMC891227_Init, 0 }, + { "NEWSTAR-GRM070-8IN1", BMC8IN1_Init, 0 }, + { "FARID_UNROM_8-IN-1", FARIDUNROM_Init, 0 }, + { "K-3033", BMCK3033_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 98bb3b1..5bc341d 100644 --- a/src/unif.h +++ b/src/unif.h @@ -187,6 +187,8 @@ void BMCL6IN1_Init(CartInfo *info); /* m345 */ void BMCCTC12IN1_Init(CartInfo *info); /* m337 */ void BMC891227_Init(CartInfo *info); /* m350 */ +void FARIDUNROM_Init(CartInfo *info); /* m324 */ +void BMCK3033_Init(CartInfo *info); /* mm22 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 38a560df82ef44ecdc6dbaf03bbb09ccc7fdad1a Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 11:04:42 +0800 Subject: [PATCH 16/20] A few unif board fixes - RESET-NROM-XIN1 - fix MD5 mismatch due to uninitialized variable - RESET-TXROM - improve compatibility with some rom types --- src/boards/resetnromxin1.c | 2 +- src/boards/resettxrom.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/boards/resetnromxin1.c b/src/boards/resetnromxin1.c index c97837d..d17bc81 100644 --- a/src/boards/resetnromxin1.c +++ b/src/boards/resetnromxin1.c @@ -59,7 +59,7 @@ static void StateRestore(int version) { void BMCRESETNROMXIN1_Init(CartInfo *info) { uint8 x; - uint64 partialmd5; + uint64 partialmd5 = 0; for (x = 0; x < 8; x++) partialmd5 |= (uint64)info->MD5[15 - x] << (x * 8); diff --git a/src/boards/resettxrom.c b/src/boards/resettxrom.c index fdf1d1b..e4bced0 100644 --- a/src/boards/resettxrom.c +++ b/src/boards/resettxrom.c @@ -28,11 +28,11 @@ #include "mmc3.h" static void M313CW(uint32 A, uint8 V) { - setchr1r(EXPREGS[0], A, V & 0x7F); + setchr1r(CHRptr[1] ? EXPREGS[0] : 0, A, (EXPREGS[0] << 7) | (V & 0x7F)); } static void M313PW(uint32 A, uint8 V) { - setprg8r(EXPREGS[0], A, V & 0x0F); + setprg8r(PRGptr[1] ? EXPREGS[0] : 0, A, (EXPREGS[0] << 4) | (V & 0x0F)); } static void M313Reset(void) { @@ -48,7 +48,7 @@ static void M313Power(void) { /* NES 2.0 313, UNIF BMC-RESET-TXROM */ void BMCRESETTXROM_Init(CartInfo *info) { - GenMMC3_Init(info, 512, 256, 0, 0); + GenMMC3_Init(info, 128, 128, 0, 0); cwrap = M313CW; pwrap = M313PW; info->Power = M313Power; From 6653f4028a8a1d2a3790a9674a2f8f49b0e2f765 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 16:45:08 +0800 Subject: [PATCH 17/20] Add support for BMC-830134C --- src/boards/830134C.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 1 + src/unif.h | 1 + 3 files changed, 74 insertions(+) create mode 100644 src/boards/830134C.c diff --git a/src/boards/830134C.c b/src/boards/830134C.c new file mode 100644 index 0000000..7d546d5 --- /dev/null +++ b/src/boards/830134C.c @@ -0,0 +1,72 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 + */ + +/* NES 2.0 Mapper 315 + * BMC-830134C + * Used for multicarts using 820732C- and 830134C-numbered PCBs such as 4-in-1 Street Blaster 5 + * http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_315 + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMC830134CCW(uint32 A, uint8 V) { + uint32 chip = (EXPREGS[0] & 0x03) & ~((EXPREGS[0] & 0x02) >> 1); + setchr1r(chip, A, (V & 0xFF) | ((EXPREGS[0] & 0x01) << 8) | ((EXPREGS[0] & 0x02) << 6) | ((EXPREGS[0] & 0x08) << 3)); +} + +static void BMC830134CPW(uint32 A, uint8 V) { + uint32 chip = (EXPREGS[0] & 0x06) >> 1; + if ((EXPREGS[0] & 0x06) == 0x06) { + if (A == 0x8000) { + setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); + setprg8r(chip, 0xC000, (V & 0x0F) | 0x32); + } else if (A == 0xA000) { + setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); + setprg8r(chip, 0xE000, (V & 0x0F) | 0x32); + } + } else + setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); +} + +static DECLFW(BMC830134CWrite) { + EXPREGS[0] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void BMC830134CReset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMC830134CPower(void) { + GenMMC3Power(); + SetWriteHandler(0x6800, 0x68FF, BMC830134CWrite); +} + +void BMC830134C_Init(CartInfo *info) { + GenMMC3_Init(info, 128, 256, 1, 0); + pwrap = BMC830134CPW; + cwrap = BMC830134CCW; + info->Power = BMC830134CPower; + info->Reset = BMC830134CReset; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/unif.c b/src/unif.c index 9772d75..d58c1d4 100644 --- a/src/unif.c +++ b/src/unif.c @@ -502,6 +502,7 @@ static BMAPPING bmap[] = { { "NEWSTAR-GRM070-8IN1", BMC8IN1_Init, 0 }, { "FARID_UNROM_8-IN-1", FARIDUNROM_Init, 0 }, { "K-3033", BMCK3033_Init, 0 }, + { "830134C", BMC830134C_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 5bc341d..b35c250 100644 --- a/src/unif.h +++ b/src/unif.h @@ -189,6 +189,7 @@ void BMCCTC12IN1_Init(CartInfo *info); /* m337 */ void BMC891227_Init(CartInfo *info); /* m350 */ void FARIDUNROM_Init(CartInfo *info); /* m324 */ void BMCK3033_Init(CartInfo *info); /* mm22 */ +void BMC830134C_Init(CartInfo *info); /* m315 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From 6d26ce4f9f4207b02a3539d74be19824a1b8806d Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 22:14:48 +0800 Subject: [PATCH 18/20] BMC-K-3036: Fix incorrect write address range --- src/boards/{bcmk3006.c => bmck3006.c} | 0 src/boards/{bcmk3033.c => bmck3033.c} | 0 src/boards/bmck3036.c | 28 +++++++++++++++------------ 3 files changed, 16 insertions(+), 12 deletions(-) rename src/boards/{bcmk3006.c => bmck3006.c} (100%) rename src/boards/{bcmk3033.c => bmck3033.c} (100%) diff --git a/src/boards/bcmk3006.c b/src/boards/bmck3006.c similarity index 100% rename from src/boards/bcmk3006.c rename to src/boards/bmck3006.c diff --git a/src/boards/bcmk3033.c b/src/boards/bmck3033.c similarity index 100% rename from src/boards/bcmk3033.c rename to src/boards/bmck3033.c diff --git a/src/boards/bmck3036.c b/src/boards/bmck3036.c index 77ced85..bd72ca3 100644 --- a/src/boards/bmck3036.c +++ b/src/boards/bmck3036.c @@ -26,40 +26,44 @@ #include "mapinc.h" -static uint8 regs[2]; +static uint8 regs[2], mirr, mode; static SFORMAT StateRegs[] = { - { regs, 2, "REGS" }, + { regs, 2, "REGS" }, + { &mode, 1, "MODE" }, + { &mirr, 1, "MIRR" }, { 0 } }; static void Sync(void) { - if (regs[0] & 0x20) { /* NROM-128 */ - setprg16(0x8000, regs[0] & 0x1F); - setprg16(0xC000, regs[0] & 0x1F); + if (mode) { /* NROM-128 */ + setprg16(0x8000, regs[0]); + setprg16(0xC000, regs[0]); } else { /* UNROM */ - setprg16(0x8000, (regs[0] & 0x1F) | (regs[1] & 0x07)); - setprg16(0xC000, (regs[0] & 0x1F) | 0x07); + setprg16(0x8000, regs[0] | regs[1]); + setprg16(0xC000, regs[0] | 0x07); } setchr8(0); - setmirror(((regs[0] & 0x25) == 0x25) ? MI_H : MI_V); + setmirror(mirr); } static DECLFW(M340Write) { - regs[0] = A & 0xFF; - regs[1] = V & 0xFF; + regs[0] = A & 0x1F; + regs[1] = V & 0x07; + mode = A & 0x20; + mirr = ((A & 0x25) == 0x25) ? 0 : 1; Sync(); } static void BMCK3036Power(void) { Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x8000, 0xBFFF, M340Write); + SetWriteHandler(0x8000, 0xFFFF, M340Write); } static void BMCK3036Reset(void) { - regs[0] = regs[1] = 0; + regs[0] = regs[1] = mode = mirr = 0; Sync(); } From e734fa87965c272391fce046923123af875bf096 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 26 Jun 2019 23:51:19 +0800 Subject: [PATCH 19/20] Add support for BMC-GN-26 --- src/boards/gn26.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 1 + src/unif.h | 1 + 3 files changed, 70 insertions(+) create mode 100644 src/boards/gn26.c diff --git a/src/boards/gn26.c b/src/boards/gn26.c new file mode 100644 index 0000000..a712cc2 --- /dev/null +++ b/src/boards/gn26.c @@ -0,0 +1,68 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * + * + * 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 + */ + +/* NES 2.0 Mapper 344 + * BMC-GN-26 + * Kuai Da Jin Ka Zhong Ji Tiao Zhan 3-in-1 (3-in-1,6-in-1,Unl) + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMCGN26CW(uint32 A, uint8 V) { + uint32 chip = (EXPREGS[0] & 0x03); + if (chip) chip -= 1; + setchr1r(chip, A, (V & 0xFF)); +} + +static void BMCGN26PW(uint32 A, uint8 V) { + uint32 chip = (EXPREGS[0] & 0x03); + if (chip) chip -= 1; /* Re-ordered -> 0:SF4 1:Contra Force 2:Revolution Hero */ + if (EXPREGS[0] & 4) { + if (A == 0x8000) + setprg32r(chip, 0x8000, (V >> 2)); + } else + setprg8r(chip, A, (V & 0x0F)); +} + +static DECLFW(BMCGN26Write) { + EXPREGS[0] = A & 0x0F; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void BMCGN26Reset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMCGN26Power(void) { + GenMMC3Power(); + SetWriteHandler(0x6800, 0x68FF, BMCGN26Write); +} + +void BMCGN26_Init(CartInfo *info) { + GenMMC3_Init(info, 128, 256, 1, 0); + pwrap = BMCGN26PW; + cwrap = BMCGN26CW; + info->Power = BMCGN26Power; + info->Reset = BMCGN26Reset; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/unif.c b/src/unif.c index d58c1d4..567ba59 100644 --- a/src/unif.c +++ b/src/unif.c @@ -503,6 +503,7 @@ static BMAPPING bmap[] = { { "FARID_UNROM_8-IN-1", FARIDUNROM_Init, 0 }, { "K-3033", BMCK3033_Init, 0 }, { "830134C", BMC830134C_Init, 0 }, + { "GN-26", BMCGN26_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index b35c250..661fff3 100644 --- a/src/unif.h +++ b/src/unif.h @@ -190,6 +190,7 @@ void BMC891227_Init(CartInfo *info); /* m350 */ void FARIDUNROM_Init(CartInfo *info); /* m324 */ void BMCK3033_Init(CartInfo *info); /* mm22 */ void BMC830134C_Init(CartInfo *info); /* m315 */ +void BMCGN26_Init(CartInfo *info); /* m344 */ #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From fa21e91ef5eebdbc334e4995054c7f2dd9f2973f Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Thu, 27 Jun 2019 00:56:24 +0800 Subject: [PATCH 20/20] UNL-EH8813A: Update based on latest wiki --- src/boards/ax40g.c | 1 + src/boards/eh8813a.c | 30 +++++++++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/boards/ax40g.c b/src/boards/ax40g.c index 87be2a7..f3fe1d1 100644 --- a/src/boards/ax40g.c +++ b/src/boards/ax40g.c @@ -1,6 +1,7 @@ /* FCEUmm - NES/Famicom Emulator * * Copyright notice for this file: + * Copyright (C) 2019 Libretro 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 diff --git a/src/boards/eh8813a.c b/src/boards/eh8813a.c index ab15b39..d8998a3 100644 --- a/src/boards/eh8813a.c +++ b/src/boards/eh8813a.c @@ -18,36 +18,40 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + /* Updated 6-27-19 */ + #include "mapinc.h" -static uint16 addrlatch; -static uint8 datalatch, hw_mode; +static uint8 datalatch, addrlatch, lock, hw_mode; static SFORMAT StateRegs[] = { - { &addrlatch, 2, "ADRL" }, + { &addrlatch, 1, "ADRL" }, { &datalatch, 1, "DATL" }, - { &hw_mode, 1, "HWMO" }, + { &hw_mode, 1, "HWMO" }, + { &lock, 1, "LOCK" }, { 0 } }; static void Sync(void) { - uint8 prg = (addrlatch & 7); + uint8 prg = (addrlatch & 0x3F); setchr8(datalatch); - if(addrlatch & 0x80) { + if (addrlatch & 0x80) { setprg16(0x8000,prg); setprg16(0xC000,prg); } else { setprg32(0x8000,prg >> 1); } - setmirror(MI_V); + setmirror(((datalatch >> 7) & 1) ^ 1); } static DECLFW(EH8813AWrite) { - if((addrlatch & 0x100) == 0) { - addrlatch = A & 0x1FF; - datalatch = V & 0xF; + if (lock == 0) { + addrlatch = A & 0xFF; + datalatch = V & 0xFC; + lock = (A & 0x100) >> 8; } + datalatch = (datalatch & ~0x03) | (V & 0x03); Sync(); } @@ -56,16 +60,16 @@ static DECLFR(EH8813ARead) { A= (A & 0xFFF0) + hw_mode; return CartBR(A); } - + static void EH8813APower(void) { - addrlatch = datalatch = hw_mode = 0; + addrlatch = datalatch = hw_mode = lock = 0; Sync(); SetReadHandler(0x8000, 0xFFFF, EH8813ARead); SetWriteHandler(0x8000, 0xFFFF, EH8813AWrite); } static void EH8813AReset(void) { - addrlatch = datalatch = 0; + addrlatch = datalatch = lock = 0; hw_mode = (hw_mode + 1) & 0xF; FCEU_printf("Hardware Switch is %01X\n", hw_mode); Sync();