Add mappers 272, 291, 409, 414, 431

Add mapper 272

Add mapper 291

Add mapper 409

Add mapper 414

Add mapper 431
This commit is contained in:
negativeExponent
2022-02-15 16:51:55 +08:00
parent a1ca113b34
commit 324b85f107
7 changed files with 385 additions and 0 deletions

179
src/boards/272.c Normal file
View File

@@ -0,0 +1,179 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2022 negativeExponent
*
* 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 272 is used for a bootleg implementation of
* 悪魔城 Special: ぼくDracula君 (Akumajō Special: Boku Dracula-kun).
*
* as implemented from
* https://forums.nesdev.org/viewtopic.php?f=9&t=15302&start=60#p205862
*
*/
#include "mapinc.h"
static uint8 prg[2];
static uint8 chr[8];
static uint8 mirr;
static uint8 pal_mirr;
static uint8 last_pa13;
static uint8 IRQCount;
static uint8 IRQa;
static SFORMAT StateRegs[] =
{
{ prg, 2, "PRG" },
{ chr, 8, "CHR" },
{ &mirr, 1, "MIRR" },
{ &last_pa13, 1, "PA13" },
{ &IRQCount, 1, "CNTR" },
{ &pal_mirr, 1, "PALM" },
{ &IRQa, 1, "CCLK" },
{ 0 }
};
/* shifts bit from position `bit` into position `pos` of expression `exp` */
#define shi(exp, bit, pos) \
((((exp) & (1 << (bit))) >> (bit)) << (pos))
static uint32 vrc_addr_mix(uint32 A) {
/* this game wires A0 to VRC_A0 and A1 to VRC_A1 */
return (A & 0xf000) | shi(A, 0, 0) | shi(A, 1, 1);
}
static void Sync(void) {
uint8 i;
setprg8(0x8000, prg[0]);
setprg8(0xa000, prg[1]);
setprg16(0xc000, -1);
for (i = 0; i < 8; ++i)
setchr1(0x400 * i, chr[i]);
switch (pal_mirr) {
case 2: setmirror(MI_0); break;
case 3: setmirror(MI_1); break;
default:
switch (mirr) {
case 0: setmirror(MI_V); break;
case 1: setmirror(MI_H); break;
}
}
}
static DECLFW(M272Write) {
/* writes to VRC chip */
switch (vrc_addr_mix(A)) {
case 0x8000:
case 0x8001:
case 0x8002:
case 0x8003:
prg[0] = V;
break;
case 0x9000:
case 0x9001:
case 0x9002:
case 0x9003:
mirr = V & 1;
break;
case 0xA000:
case 0xA001:
case 0xA002:
case 0xA003:
prg[1] = V;
break;
case 0xb000: chr[0] = (chr[0] & 0xF0) | (V & 0xF); break;
case 0xb001: chr[0] = (chr[0] & 0xF) | ((V & 0xF) << 4); break;
case 0xb002: chr[1] = (chr[1] & 0xF0) | (V & 0xF); break;
case 0xb003: chr[1] = (chr[1] & 0xF) | ((V & 0xF) << 4); break;
case 0xc000: chr[2] = (chr[2] & 0xF0) | (V & 0xF); break;
case 0xc001: chr[2] = (chr[2] & 0xF) | ((V & 0xF) << 4); break;
case 0xc002: chr[3] = (chr[3] & 0xF0) | (V & 0xF); break;
case 0xc003: chr[3] = (chr[3] & 0xF) | ((V & 0xF) << 4); break;
case 0xd000: chr[4] = (chr[4] & 0xF0) | (V & 0xF); break;
case 0xd001: chr[4] = (chr[4] & 0xF) | ((V & 0xF) << 4); break;
case 0xd002: chr[5] = (chr[5] & 0xF0) | (V & 0xF); break;
case 0xd003: chr[5] = (chr[5] & 0xF) | ((V & 0xF) << 4); break;
case 0xe000: chr[6] = (chr[6] & 0xF0) | (V & 0xF); break;
case 0xe001: chr[6] = (chr[6] & 0xF) | ((V & 0xF) << 4); break;
case 0xe002: chr[7] = (chr[7] & 0xF0) | (V & 0xF); break;
case 0xe003: chr[7] = (chr[7] & 0xF) | ((V & 0xF) << 4); break;
default:
break;
}
/* writes to PAL chip */
switch (A & 0xC00C) {
case 0x8004: pal_mirr = V & 3; break;
case 0x800c: X6502_IRQBegin(FCEU_IQEXT); break;
case 0xc004: X6502_IRQEnd(FCEU_IQEXT); break;
case 0xc008: IRQa = 1; break;
case 0xc00c: IRQa = 0; IRQCount = 0; X6502_IRQEnd(FCEU_IQEXT); break;
}
Sync();
}
static void M272Power(void) {
prg[0] = prg[1] = 0;
chr[0] = chr[1] = chr[2] = chr[3] = 0;
chr[4] = chr[5] = chr[6] = chr[7] = 0;
mirr = pal_mirr = 0;
last_pa13 = 0;
IRQCount = 0;
IRQa = 0;
Sync();
SetWriteHandler(0x8000, 0xFFFF, M272Write);
SetReadHandler(0x8000, 0xFFFF, CartBR);
}
static void M272Hook(uint32 A) {
uint8 pa13 = (A >> 13) & 1;
if ((last_pa13 == 1) && (pa13 == 0)) {
if (IRQa) {
IRQCount++;
if (IRQCount == 84) {
IRQCount = 0;
X6502_IRQBegin(FCEU_IQEXT);
}
}
}
last_pa13 = pa13;
}
static void M272Reset(void) {
prg[0] = prg[1] = 0;
chr[0] = chr[1] = chr[2] = chr[3] = 0;
chr[4] = chr[5] = chr[6] = chr[7] = 0;
mirr = pal_mirr = 0;
last_pa13 = 0;
IRQCount = 0;
IRQa = 0;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void Mapper272_Init(CartInfo *info) {
info->Power = M272Power;
info->Reset = M272Reset;
PPU_hook = M272Hook;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

59
src/boards/291.c Normal file
View File

@@ -0,0 +1,59 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2022 negativeExponent
*
* 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 M291CW(uint32 A, uint8 V) {
setchr1(A, V | ((EXPREGS[0] << 2) & 0x100));
}
static void M291PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x20)
setprg32(0x8000, ((EXPREGS[0] >> 1) & 3) | ((EXPREGS[0] >> 4) & 4));
else
setprg8(A, (V & 0x0F) | ((EXPREGS[0] >> 2) & 0x10));
}
static DECLFW(M291Write) {
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void M291Reset(void) {
EXPREGS[0] = 0;
MMC3RegReset();
}
static void M291Power(void) {
EXPREGS[0] = 0;
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, M291Write);
}
void Mapper291_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 512, 0, 0);
cwrap = M291CW;
pwrap = M291PW;
info->Power = M291Power;
info->Reset = M291Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

64
src/boards/414.c Normal file
View File

@@ -0,0 +1,64 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2022 negativeExponent
*
* 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_data;
static uint32 latch_addr;
static SFORMAT StateRegs[] =
{
{ &latch_addr, 4, "ADDR" },
{ &latch_data, 1, "DATA" },
{ 0 }
};
static void Sync(void) {
if (latch_addr & 0x2000) { /* NROM-256 */
setprg32(0x8000, latch_addr >> 2);
} else { /* NROM-128 */
setprg16(0x8000, latch_addr >> 1);
setprg16(0xC000, latch_addr >> 1);
}
setchr8(latch_data);
setmirror((latch_data & 1) ^ 1);
}
static DECLFW(M414Write) {
latch_addr = A;
latch_data = V & CartBR(A);
Sync();
}
static void M414Power(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M414Write);
}
static void StateRestore(int version) {
Sync();
}
void Mapper414_Init(CartInfo *info) {
info->Power = M414Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

62
src/boards/431.c Normal file
View File

@@ -0,0 +1,62 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2022 negativeExponent
*
* 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 inner_bank;
static uint8 outer_bank;
static SFORMAT StateRegs[] =
{
{ &outer_bank, 1, "OUTB" },
{ &inner_bank, 1, "INNB" },
{ 0 }
};
static void Sync(void) {
setprg16(0x8000, ((outer_bank >> 2) & ~7) | (inner_bank & 7));
setprg16(0xC000, ((outer_bank >> 2) & ~7) | 7);
setchr8(0);
setmirror((outer_bank & 1) ^ 1);
}
static DECLFW(M431Write) {
if (A < 0xC000) outer_bank = V;
else inner_bank = V;
Sync();
}
static void M431Power(void) {
inner_bank = 0;
outer_bank = 0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M431Write);
}
static void StateRestore(int version) {
Sync();
}
void Mapper431_Init(CartInfo *info) {
info->Power = M431Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -704,3 +704,14 @@ void J2282_Init(CartInfo *info)
{
Latch_Init(info, J2282Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
}
/* -------------- Mapper 409 ------------------------ */
static void M409Sync(void) {
setprg16(0x8000, latche);
setprg16(0xC000, ~0);
setchr8(0);
}
void Mapper409_Init(CartInfo *info) {
Latch_Init(info, M409Sync, NULL, 0x0000, 0xC000, 0xCFFF, 0);
}

View File

@@ -691,6 +691,7 @@ INES_BOARD_BEGIN()
INES_BOARD( "8-in-1 JY-119", 267, Mapper267_Init )
INES_BOARD( "COOLBOY/MINDKIDS", 268, Mapper268_Init ) /* Submapper distinguishes between COOLBOY and MINDKIDS */
INES_BOARD( "Games Xplosion 121-in-1", 269, Mapper269_Init )
INES_BOARD( "Akumajō Special: Boku Dracula-kun", 272, Mapper272_Init )
INES_BOARD( "80013-B", 274, BMC80013B_Init )
INES_BOARD( "YY860417C", 281, Mapper281_Init )
INES_BOARD( "860224C", 282, Mapper282_Init )
@@ -701,6 +702,7 @@ INES_BOARD_BEGIN()
INES_BOARD( "GKCX1", 288, Mapper288_Init )
INES_BOARD( "60311C", 289, BMC60311C_Init )
INES_BOARD( "NTD-03", 290, BMCNTD03_Init )
INES_BOARD( "Kasheng 2-in-1 ", 291, Mapper291_Init )
INES_BOARD( "DRAGONFIGHTER", 292, UNLBMW8544_Init )
INES_BOARD( "NewStar 12-in-1/7-in-1", 293, Mapper293_Init )
INES_BOARD( "MMC3 BMC PIRATE", 294, Bs5652_Init ) /* nesdev redirects this as mapper 134 */
@@ -784,8 +786,10 @@ INES_BOARD_BEGIN()
INES_BOARD( "831019C J-2282", 402, J2282_Init )
INES_BOARD( "89433", 403, Mapper403_Init )
INES_BOARD( "JY012005", 404, Mapper404_Init )
INES_BOARD( "retroUSB DPCMcart", 409, Mapper409_Init )
INES_BOARD( "JY-302", 410, Mapper410_Init )
INES_BOARD( "A88S-1", 411, Mapper411_Init )
INES_BOARD( "9999999-in-1", 414, Mapper414_Init )
INES_BOARD( "0353", 415, Mapper415_Init )
INES_BOARD( "4-in-1/N-32", 416, Mapper416_Init )
INES_BOARD( "", 417, Mapper417_Init )
@@ -793,6 +797,7 @@ INES_BOARD_BEGIN()
INES_BOARD( "BS-400R/BS-4040", 422, Mapper422_Init )
INES_BOARD( "AB-G1L/WELL-NO-DG450", 428, Mapper428_Init )
INES_BOARD( "LIKO BBG-235-8-1B", 429, Mapper429_Init )
INES_BOARD( "Realtek GN-91B", 431, Mapper431_Init )
INES_BOARD( "Realtec 8090", 432, Mapper432_Init )
INES_BOARD( "NC-20MB", 433, Mapper433_Init )
INES_BOARD( "S-009", 434, Mapper434_Init )

View File

@@ -247,9 +247,11 @@ void Mapper254_Init(CartInfo *);
void Mapper255_Init(CartInfo *);
void GN45_Init(CartInfo *info); /* m361, m366 */
void Mapper272_Init(CartInfo *);
void Mapper281_Init(CartInfo *);
void Mapper282_Init(CartInfo *);
void Mapper283_Init(CartInfo *);
void Mapper291_Init(CartInfo *);
void Mapper295_Init(CartInfo *);
void Bs5652_Init(CartInfo *);
@@ -294,8 +296,10 @@ void Mapper397_Init(CartInfo *);
void Mapper401_Init(CartInfo *);
void Mapper403_Init(CartInfo *);
void Mapper404_Init(CartInfo *);
void Mapper409_Init(CartInfo *);
void Mapper410_Init(CartInfo *);
void Mapper411_Init(CartInfo *);
void Mapper414_Init(CartInfo *);
void Mapper415_Init(CartInfo *);
void Mapper416_Init(CartInfo *);
void Mapper417_Init(CartInfo *);
@@ -303,6 +307,7 @@ void Mapper421_Init(CartInfo *);
void Mapper422_Init(CartInfo *);
void Mapper428_Init(CartInfo *);
void Mapper429_Init(CartInfo *);
void Mapper431_Init(CartInfo *);
void Mapper432_Init(CartInfo *);
void Mapper433_Init(CartInfo *);
void Mapper434_Init(CartInfo *);