Merge pull request #323 from negativeExponent/add_new_mappers
add, update and fix mappers
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
/* 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
|
||||
*
|
||||
* 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-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 0
|
||||
if(reg[3])
|
||||
return reg[2];
|
||||
else
|
||||
return X.DB;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
89
src/boards/269.c
Normal file
89
src/boards/269.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 269
|
||||
* Games Xplosion 121-in-1
|
||||
* 15000-in-1
|
||||
* 18000-in-1
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static uint8 *CHRROM;
|
||||
static uint32 CHRROMSIZE;
|
||||
|
||||
static void M269CW(uint32 A, uint8 V) {
|
||||
uint32 NV = V;
|
||||
if (EXPREGS[2] & 8)
|
||||
NV &= (1 << ((EXPREGS[2] & 7) + 1)) - 1;
|
||||
NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4);
|
||||
setchr1(A, NV);
|
||||
}
|
||||
|
||||
static void M269PW(uint32 A, uint8 V) {
|
||||
uint32 MV = V & ((EXPREGS[3] & 0x3F) ^ 0x3F);
|
||||
MV |= EXPREGS[1];
|
||||
MV |= ((EXPREGS[3] & 0x40) << 2);
|
||||
setprg8(A, MV);
|
||||
}
|
||||
|
||||
static DECLFW(M269Write5) {
|
||||
if (!(EXPREGS[3] & 0x80)) {
|
||||
EXPREGS[EXPREGS[4]] = V;
|
||||
EXPREGS[4] = (EXPREGS[4] + 1) & 3;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void M269Reset(void) {
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
MMC3RegReset();
|
||||
}
|
||||
|
||||
static void M269Power(void) {
|
||||
uint32 i;
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
GenMMC3Power();
|
||||
SetWriteHandler(0x5000, 0x5FFF, M269Write5);
|
||||
|
||||
CHRROMSIZE = PRGsize[0];
|
||||
CHRROM = (uint8*)FCEU_gmalloc(CHRROMSIZE);
|
||||
/* Decrypt CHR data */
|
||||
for (i = 0; i < CHRROMSIZE; i++) {
|
||||
uint8_t Val = PRGptr[0][i];
|
||||
Val = ((Val & 1) << 6) | ((Val & 2) << 3) | ((Val & 4) << 0) | ((Val & 8) >> 3) | ((Val & 16) >> 3) | ((Val & 32) >> 2) | ((Val & 64) >> 1) | ((Val & 128) << 0);
|
||||
CHRROM[i] = Val;
|
||||
}
|
||||
SetupCartCHRMapping(0, CHRROM, CHRROMSIZE, 0);
|
||||
AddExState(CHRROM, CHRROMSIZE, 0, "_CHR");
|
||||
}
|
||||
|
||||
void Mapper269_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 512, 0, 8, 0);
|
||||
cwrap = M269CW;
|
||||
pwrap = M269PW;
|
||||
info->Power = M269Power;
|
||||
info->Reset = M269Reset;
|
||||
AddExState(EXPREGS, 5, 0, "EXPR");
|
||||
}
|
||||
@@ -56,8 +56,8 @@ void Mirror(uint8 value)
|
||||
|
||||
|
||||
static void Sync() {
|
||||
uint8 prglo;
|
||||
uint8 prghi;
|
||||
uint8 prglo = 0;
|
||||
uint8 prghi = 0;
|
||||
|
||||
uint8 outb = outer << 1;
|
||||
|
||||
|
||||
130
src/boards/353.c
Normal file
130
src/boards/353.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 353 is used for the 92 Super Mario Family multicart,
|
||||
* consisting of an MMC3 clone ASIC together with a PAL.
|
||||
* The PCB code is 81-03-05-C.
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static uint8* CHRRAM = NULL;
|
||||
static uint32 CHRRAMSIZE;
|
||||
static uint8 PPUCHRBus;
|
||||
static uint8 MIR[8];
|
||||
|
||||
static void M353PPU(uint32 A) {
|
||||
A &= 0x1FFF;
|
||||
A >>= 10;
|
||||
PPUCHRBus = A;
|
||||
if (EXPREGS[0] == 0)
|
||||
setmirror(MI_0 + MIR[A]);
|
||||
}
|
||||
|
||||
static void M353PW(uint32 A, uint8 V) {
|
||||
uint32 bank = V;
|
||||
|
||||
if (EXPREGS[0] == 2) {
|
||||
bank &= 0x0F;
|
||||
bank |= (DRegBuf[0] & 0x80) ? 0x10 : 0x00;
|
||||
bank |= (EXPREGS[0] << 5);
|
||||
} else {
|
||||
if ((EXPREGS[0] == 3) && !(DRegBuf[0] & 0x80)) {
|
||||
switch (A & 0xF000) {
|
||||
case 0xC000:
|
||||
case 0xE000:
|
||||
bank = DRegBuf[6 + ((A >> 13) & 1)] | 0x70;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bank &= 0x1F;
|
||||
bank |= (EXPREGS[0] << 5);
|
||||
}
|
||||
}
|
||||
|
||||
setprg8(A, bank);
|
||||
}
|
||||
|
||||
static void M353CW(uint32 A, uint8 V) {
|
||||
if ((EXPREGS[0] == 2) && (DRegBuf[0] & 0x80))
|
||||
setchr8r(0x10, 0);
|
||||
else
|
||||
setchr1(A, (V & 0x7F) | ((EXPREGS[0]) << 7));
|
||||
|
||||
MIR[A >> 10] = V >> 7;
|
||||
if ((EXPREGS[0] == 0) && (PPUCHRBus == (A >> 10)))
|
||||
setmirror(MI_0 + (V >> 7));
|
||||
}
|
||||
|
||||
static void M353MW(uint8 V) {
|
||||
if (EXPREGS[0] != 0) {
|
||||
A000B = V;
|
||||
setmirror((V & 1) ^ 1);
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M353Write) {
|
||||
if (A & 0x80) {
|
||||
EXPREGS[0] = (A >> 13) & 0x03;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
} else {
|
||||
if (A < 0xC000) {
|
||||
MMC3_CMDWrite(A, V);
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
} else
|
||||
MMC3_IRQWrite(A, V);
|
||||
}
|
||||
}
|
||||
|
||||
static void M353Power(void) {
|
||||
EXPREGS[0] = 0;
|
||||
GenMMC3Power();
|
||||
SetWriteHandler(0x8000, 0xFFFF, M353Write);
|
||||
}
|
||||
|
||||
static void M353Reset(void) {
|
||||
EXPREGS[0] = 0;
|
||||
MMC3RegReset();
|
||||
}
|
||||
|
||||
static void M353Close(void) {
|
||||
if (CHRRAM)
|
||||
FCEU_gfree(CHRRAM);
|
||||
CHRRAM = NULL;
|
||||
}
|
||||
|
||||
void Mapper353_Init(CartInfo* info) {
|
||||
GenMMC3_Init(info, 256, 128, 8, info->battery);
|
||||
cwrap = M353CW;
|
||||
pwrap = M353PW;
|
||||
mwrap = M353MW;
|
||||
PPU_hook = M353PPU;
|
||||
info->Power = M353Power;
|
||||
info->Close = M353Close;
|
||||
info->Reset = M353Reset;
|
||||
AddExState(EXPREGS, 1, 0, "EXPR");
|
||||
|
||||
CHRRAMSIZE = 8192;
|
||||
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
|
||||
AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
|
||||
}
|
||||
103
src/boards/356.c
Normal file
103
src/boards/356.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 356 - J.Y. Company's 7-in-1 Rockman (JY-208)
|
||||
* All registers work as INES Mapper 045, except $6000 sequential register 2 (third write):
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static uint8* CHRRAM = NULL;
|
||||
static uint32 CHRRAMSIZE = 0;
|
||||
|
||||
static void M356CW(uint32 A, uint8 V) {
|
||||
if (EXPREGS[2] & 0x20) {
|
||||
uint32 NV = V;
|
||||
if (EXPREGS[2] & 8)
|
||||
NV &= (1 << ((EXPREGS[2] & 7) + 1)) - 1;
|
||||
else
|
||||
if (EXPREGS[2])
|
||||
NV &= 0; /* hack ;( don't know exactly how it should be */
|
||||
NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4);
|
||||
setchr1(A, NV);
|
||||
} else
|
||||
setchr8r(0x10, 0);
|
||||
}
|
||||
|
||||
static void M356PW(uint32 A, uint8 V) {
|
||||
uint32 MV = V & ((EXPREGS[3] & 0x3F) ^ 0x3F);
|
||||
MV |= EXPREGS[1];
|
||||
if (UNIFchrrama)
|
||||
MV |= ((EXPREGS[2] & 0x40) << 2);
|
||||
setprg8(A, MV);
|
||||
}
|
||||
|
||||
static void M356MW(uint8 V) {
|
||||
if (EXPREGS[2] & 0x40)
|
||||
SetupCartMirroring(4, 1, CHRRAM);
|
||||
else
|
||||
setmirror((V & 1) ^ 1);
|
||||
}
|
||||
|
||||
static DECLFW(M356Write) {
|
||||
if (!(EXPREGS[3] & 0x40)) {
|
||||
EXPREGS[EXPREGS[4]] = V;
|
||||
EXPREGS[4] = (EXPREGS[4] + 1) & 3;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void M356Close(void) {
|
||||
if (CHRRAM)
|
||||
FCEU_free(CHRRAM);
|
||||
CHRRAM = NULL;
|
||||
}
|
||||
|
||||
static void M356Reset(void) {
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
MMC3RegReset();
|
||||
}
|
||||
|
||||
static void M356Power(void) {
|
||||
EXPREGS[4] = 0;
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
GenMMC3Power();
|
||||
SetWriteHandler(0x6000, 0x7FFF, M356Write);
|
||||
}
|
||||
|
||||
void Mapper356_Init(CartInfo* info) {
|
||||
GenMMC3_Init(info, 128, 128, 0, 0);
|
||||
cwrap = M356CW;
|
||||
pwrap = M356PW;
|
||||
mwrap = M356MW;
|
||||
info->Reset = M356Reset;
|
||||
info->Power = M356Power;
|
||||
info->Close = M356Close;
|
||||
AddExState(EXPREGS, 5, 0, "EXPR");
|
||||
|
||||
CHRRAMSIZE = 8192;
|
||||
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
|
||||
AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
|
||||
}
|
||||
193
src/boards/359.c
Normal file
193
src/boards/359.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 359 - BMC-SB-5013
|
||||
* NES 2.0 Mapper 540 - UNL-82112C
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint32 mapperNum;
|
||||
static uint8 preg[4];
|
||||
static uint8 creg[8];
|
||||
static uint8 exRegs[4];
|
||||
static uint8 IRQReload;
|
||||
static uint8 IRQa;
|
||||
static uint8 irqPA12;
|
||||
static uint8 IRQAutoEnable;
|
||||
static uint8 IRQLatch;
|
||||
static uint8 IRQCount;
|
||||
static int16 IRQCount16;
|
||||
|
||||
static SFORMAT StateRegs[] = {
|
||||
{ preg, 4, "PREG" },
|
||||
{ creg, 8, "CREG" },
|
||||
{ exRegs, 4, "EXPR" },
|
||||
{ &IRQReload, 1, "IRQL" },
|
||||
{ &IRQa, 1, "IRQa" },
|
||||
{ &irqPA12, 1, "IRQp" },
|
||||
{ &IRQAutoEnable, 1, "IRQe" },
|
||||
{ &IRQLatch, 1, "IRQl" },
|
||||
{ &IRQCount, 1, "IRQ8" },
|
||||
{ &IRQCount16, 2 | FCEUSTATE_RLSB, "IRQC" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
uint32 prgMask = 0x3F;
|
||||
uint32 prgOuterBank = (exRegs[0] & 0x38) << 1;
|
||||
|
||||
switch (exRegs[1] & 3) {
|
||||
case 0: prgMask = 0x3F; break;
|
||||
case 1: prgMask = 0x1F; break;
|
||||
case 2: prgMask = 0x2F; break;
|
||||
case 3: prgMask = 0x0F; break;
|
||||
}
|
||||
|
||||
setprg8(0x6000, (preg[3] & prgMask) | prgOuterBank);
|
||||
setprg8(0x8000, (preg[0] & prgMask) | prgOuterBank);
|
||||
setprg8(0xA000, (preg[1] & prgMask) | prgOuterBank);
|
||||
setprg8(0xC000, (preg[2] & prgMask) | prgOuterBank);
|
||||
setprg8(0xE000, ( ~0 & prgMask) | prgOuterBank);
|
||||
|
||||
if (!UNIFchrrama) {
|
||||
switch (mapperNum) {
|
||||
case 359: {
|
||||
uint32 chrMask = (exRegs[1] & 0x40) ? 0xFF : 0x7F;
|
||||
uint32 chrOuterBank = (exRegs[3] << 7);
|
||||
uint32 i;
|
||||
for (i = 0; i < 8; i++)
|
||||
setchr1(i << 10, (creg[i] & chrMask) | chrOuterBank);
|
||||
} break;
|
||||
case 540:
|
||||
setchr2(0x0000, creg[0]);
|
||||
setchr2(0x0800, creg[1]);
|
||||
setchr2(0x1000, creg[6]);
|
||||
setchr2(0x1800, creg[7]);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
setchr8(0);
|
||||
|
||||
if (exRegs[2] & 2)
|
||||
setmirror(MI_0 + (exRegs[2] & 1));
|
||||
else
|
||||
setmirror((exRegs[2] & 1) ^ 1);
|
||||
}
|
||||
|
||||
static DECLFW(M359WriteIRQ) {
|
||||
switch (A & 0xF003) {
|
||||
case 0xC000:
|
||||
if (IRQAutoEnable) IRQa = 0;
|
||||
IRQCount16 &= 0xFF00;
|
||||
IRQCount16 |= V;
|
||||
IRQReload = 1;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
break;
|
||||
case 0xC001:
|
||||
if (IRQAutoEnable) IRQa = 1;
|
||||
IRQCount16 &= 0x00FF;
|
||||
IRQCount16 |= (V << 8);
|
||||
IRQLatch = V;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
break;
|
||||
case 0xC002:
|
||||
IRQa = (V & 1);
|
||||
irqPA12 = (V & 2) >> 1;
|
||||
IRQAutoEnable = (V & 4) >> 2;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
break;
|
||||
case 0xC003:
|
||||
IRQa = (V & 1);
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M359WritePRG) {
|
||||
uint32 i = A & 3;
|
||||
preg[i] = V;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static DECLFW(M359WriteCHR) {
|
||||
uint32 i = ((A >> 10) & 4) | (A & 3);
|
||||
creg[i] = V;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static DECLFW(M359WriteEx) {
|
||||
uint32 i = A & 3;
|
||||
exRegs[i] = V;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M359Power(void) {
|
||||
Sync();
|
||||
SetReadHandler(0x6000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x8000, 0x8FFF, M359WritePRG);
|
||||
SetWriteHandler(0x9000, 0x9FFF, M359WriteEx);
|
||||
SetWriteHandler(0xA000, 0xBFFF, M359WriteCHR);
|
||||
SetWriteHandler(0xC000, 0xCFFF, M359WriteIRQ);
|
||||
}
|
||||
|
||||
static void FP_FASTAPASS(1) M359CPUHook(int a) {
|
||||
if (!irqPA12) {
|
||||
if (IRQa && IRQCount16) {
|
||||
IRQCount16 -= a;
|
||||
if (IRQCount16 <= 0)
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M359IRQHook(void) {
|
||||
if (irqPA12) {
|
||||
if (!IRQCount || IRQReload) {
|
||||
IRQCount = IRQLatch;
|
||||
IRQReload = 0;
|
||||
} else
|
||||
IRQCount--;
|
||||
if (!IRQCount && IRQa)
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
}
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper359_Init(CartInfo* info) {
|
||||
mapperNum = 359;
|
||||
info->Power = M359Power;
|
||||
MapIRQHook = M359CPUHook;
|
||||
GameHBIRQHook = M359IRQHook;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
|
||||
void Mapper540_Init(CartInfo* info) {
|
||||
mapperNum = 540;
|
||||
info->Power = M359Power;
|
||||
MapIRQHook = M359CPUHook;
|
||||
GameHBIRQHook = M359IRQHook;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2012 CaH4e3
|
||||
* 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
|
||||
*
|
||||
* TXC/Micro Genius simplified mapper
|
||||
* updated 06-2019 http://wiki.nesdev.com/w/index.php/INES_Mapper_036
|
||||
*
|
||||
* Known games:
|
||||
* - Strike Wolf (Asia) (Unl)
|
||||
* - Policeman (Gluk Video) (unl)
|
||||
* - F-15 City War (Spain) (Gluk Video) (Unl)
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 regs[5];
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ regs, 5, "REGS" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
setprg32(0x8000, regs[0] >> 4);
|
||||
setchr8(regs[4] & 0x0F);
|
||||
}
|
||||
|
||||
static DECLFW(M36Write4100) {
|
||||
switch(A & 0xE103) {
|
||||
case 0x4100:
|
||||
if(regs[3] & 0x10)
|
||||
regs[0]++;
|
||||
else
|
||||
regs[0] = regs[2];
|
||||
break;
|
||||
case 0x4101:
|
||||
case 0x4102:
|
||||
case 0x4103:
|
||||
regs[A & 0x03] = V;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M36Write4200) {
|
||||
regs[4] = V;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static DECLFW(M36WriteHi) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
static DECLFR(M36Read) {
|
||||
return ((X.DB & 0xCF) | (regs[0] & 0x30));
|
||||
}
|
||||
|
||||
static void M36Power(void) {
|
||||
Sync();
|
||||
SetReadHandler(0x4100, 0x4100, M36Read);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x4100, 0x4103, M36Write4100);
|
||||
SetWriteHandler(0x4200, 0x4200, M36Write4200);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M36WriteHi);
|
||||
}
|
||||
|
||||
static void M36Restore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper36_Init(CartInfo *info) {
|
||||
info->Power = M36Power;
|
||||
GameStateRestore = M36Restore;
|
||||
AddExState(StateRegs, ~0, 0, 0);
|
||||
}
|
||||
67
src/boards/360.c
Normal file
67
src/boards/360.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 360 - Bit Corp's 31-in-1 multicart (3150) */
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 dipswitch;
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ &dipswitch, 1, "DPSW" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
/* dip 0 and 1 is the same game SMB) */
|
||||
if (dipswitch < 2)
|
||||
setprg32(0x8000, dipswitch >> 1);
|
||||
else {
|
||||
setprg16(0x8000, dipswitch);
|
||||
setprg16(0xC000, dipswitch);
|
||||
}
|
||||
setchr8(dipswitch);
|
||||
setmirror(((dipswitch & 0x10) >> 4) ^ 1);
|
||||
}
|
||||
|
||||
static void M360Power(void) {
|
||||
dipswitch = 0;
|
||||
Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x8000, 0XFFFF, CartBW);
|
||||
}
|
||||
|
||||
static void M360Reset(void) {
|
||||
dipswitch = (dipswitch + 1) & 31;
|
||||
Sync();
|
||||
FCEU_printf("dipswitch = %d\n", dipswitch);
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper360_Init(CartInfo *info) {
|
||||
info->Reset = M360Reset;
|
||||
info->Power = M360Power;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
98
src/boards/382.c
Normal file
98
src/boards/382.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 382 - denotes the 830928C circuit board,
|
||||
* used on a 512 KiB 5-in-1 and a 1 MiB 9-in-1 multicart containing
|
||||
* the BNROM game Journey to the West and Capcom/Konami UNROM games.
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 preg[2];
|
||||
static uint8 mode;
|
||||
static uint8 mirr;
|
||||
static uint8 lock;
|
||||
|
||||
static SFORMAT StateRegs[] = {
|
||||
{ &preg[0], 1, "PRG0" },
|
||||
{ &preg[1], 1, "PRG1" },
|
||||
{ &mode, 1, "MODE" },
|
||||
{ &mirr, 1, "MIRR" },
|
||||
{ &lock, 1, "LOCK" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
switch (mode) {
|
||||
case 1:
|
||||
/* bnrom */
|
||||
setprg32(0x8000, (preg[1] << 2) | (preg[0] & 3));
|
||||
break;
|
||||
default:
|
||||
/* unrom */
|
||||
setprg16(0x8000, (preg[1] << 3) | (preg[0] & 7));
|
||||
setprg16(0xC000, (preg[1] << 3) | 7);
|
||||
break;
|
||||
}
|
||||
setchr8(0);
|
||||
setmirror(mirr ^ 1);
|
||||
/* FCEU_printf("inB[0]:%02x outB[1]:%02x mode:%02x mirr:%02x lock:%02x\n", preg[0], preg[1], mode, mirr, lock); */
|
||||
}
|
||||
|
||||
static DECLFW(M382Write) {
|
||||
if (!lock) {
|
||||
preg[1] = (A & 0x07);
|
||||
mode = (A & 0x08) >> 3;
|
||||
mirr = (A & 0x10) >> 4;
|
||||
lock = (A & 0x20) >> 5;
|
||||
}
|
||||
/* inner bank subject to bus conflicts */
|
||||
preg[0] = V & CartBR(A);
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M382Power(void) {
|
||||
preg[0] = preg[1] = 0;
|
||||
mode = 0;
|
||||
mirr = 0;
|
||||
lock = 0;
|
||||
Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M382Write);
|
||||
}
|
||||
|
||||
static void M382Reset(void) {
|
||||
preg[1] = 0;
|
||||
mode = 0;
|
||||
mirr = 0;
|
||||
lock = 0;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper382_Init(CartInfo* info) {
|
||||
info->Power = M382Power;
|
||||
info->Reset = M382Reset;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
58
src/boards/516.c
Normal file
58
src/boards/516.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 516 - Brilliant Com Cocoma Pack */
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static void M516CW(uint32 A, uint8 V) {
|
||||
/* FCEU_printf("CHR: A:%04x V:%02x R0:%02x\n", A, V, EXPREGS[0]); */
|
||||
setchr1(A, (V & 0x7F) | ((EXPREGS[0] << 5) & 0x180));
|
||||
}
|
||||
|
||||
static void M516PW(uint32 A, uint8 V) {
|
||||
/* FCEU_printf("PRG: A:%04x V:%02x R0:%02x\n", A, V, EXPREGS[0]); */
|
||||
setprg8(A, (V & 0x0F) | ((EXPREGS[0] << 4) & 0x30));
|
||||
}
|
||||
|
||||
static DECLFW(M516Write) {
|
||||
/* FCEU_printf("Wr: A:%04x V:%02x R0:%02x\n", A, V, EXPREGS[0]); */
|
||||
if (A & 0x10) {
|
||||
EXPREGS[0] = A & 0xF;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
MMC3_CMDWrite(A, V);
|
||||
}
|
||||
|
||||
static void M516Power(void) {
|
||||
EXPREGS[0] = 0;
|
||||
GenMMC3Power();
|
||||
SetWriteHandler(0x8000, 0xFFFF, M516Write);
|
||||
}
|
||||
|
||||
void Mapper516_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 128, 128, 0, 0);
|
||||
cwrap = M516CW;
|
||||
pwrap = M516PW;
|
||||
info->Power = M516Power;
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
}
|
||||
66
src/boards/533.c
Normal file
66
src/boards/533.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 533 is used for the Sachen 3014 board, used for the game
|
||||
* 動動腦 II: 國中英文(一) (Dòngdòngnǎo II: Guózhōng Yīngwén (I),
|
||||
* also known as Middle School English II, SA-003).
|
||||
* It's a CNROM-like board with the added ability to read back
|
||||
* the latch content for protection purposes.
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 latche;
|
||||
|
||||
static SFORMAT StateRegs[] = {
|
||||
{ &latche, 1, "LATC" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
setprg32(0x8000, 0);
|
||||
setchr8((latche >> 4) & 1);
|
||||
}
|
||||
|
||||
static DECLFR(M533Read) {
|
||||
return ((PRGptr[0][A] & 0xF0) | (latche >> 4));
|
||||
}
|
||||
|
||||
static DECLFW(M533Write) {
|
||||
latche = (V & CartBR(A));
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M533Power(void) {
|
||||
Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBROB);
|
||||
SetReadHandler(0xE000, 0xEFFF, M533Read);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M533Write);
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper533_Init(CartInfo* info) {
|
||||
info->Power = M533Power;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
92
src/boards/534.c
Normal file
92
src/boards/534.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 534 - 2-in-1 数独/五子棋 (Sudoku/Gomoku, NJ064) */
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static uint32 GetPRGBank(uint32 bank)
|
||||
{
|
||||
if (~bank & 1 && (MMC3_cmd & 0x40)) bank ^= 2;
|
||||
return (bank & 2) ? (0xFE | (bank & 1)) : DRegBuf[6 | (bank & 1)];
|
||||
}
|
||||
|
||||
void SyncPRG_GNROM(int A14, int AND, int OR) {
|
||||
setprg8(0x8000, ((GetPRGBank(0) & ~A14) & AND) | OR);
|
||||
setprg8(0xA000, ((GetPRGBank(1) & ~A14) & AND) | OR);
|
||||
setprg8(0xC000, ((GetPRGBank(0) | A14) & AND) | OR);
|
||||
setprg8(0xE000, ((GetPRGBank(1) | A14) & AND) | OR);
|
||||
}
|
||||
|
||||
static void M534PW(uint32 A, uint8 V) {
|
||||
if (EXPREGS[0] & 0x40)
|
||||
SyncPRG_GNROM(EXPREGS[3] & 0x02, 0x0F, ((EXPREGS[0] & 3) << 4));
|
||||
else
|
||||
setprg8(A, (V & 0x1F) | ((EXPREGS[0] & 0x2) << 4));
|
||||
}
|
||||
|
||||
static void M534CW(uint32 A, uint8 V) {
|
||||
setchr1(A, (V & 0xFF) | ((EXPREGS[2] & 0x0F) << 3) | ((EXPREGS[0] & 0x18) << 4));
|
||||
}
|
||||
|
||||
static DECLFW(M534IRQWrite) {
|
||||
MMC3_IRQWrite(0xC000 | (A & 1), V ^ 0xFF);
|
||||
}
|
||||
|
||||
static DECLFW(M534WriteLo) {
|
||||
if ((A & 0x800) && (!(EXPREGS[3] & 0x80) || (A & 3) == 2)) {
|
||||
EXPREGS[A & 3] = V;
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void M534Power(void) {
|
||||
EXPREGS[0] = 0x00;
|
||||
EXPREGS[1] = 0x00;
|
||||
EXPREGS[2] = 0x00;
|
||||
EXPREGS[3] = 0x00;
|
||||
GenMMC3Power();
|
||||
SetWriteHandler(0x6000, 0x6FFF, M534WriteLo);
|
||||
SetWriteHandler(0xC000, 0xDFFF, M534IRQWrite);
|
||||
}
|
||||
|
||||
static void M534Reset(void) {
|
||||
EXPREGS[0] = 0x00;
|
||||
EXPREGS[1] = 0x00;
|
||||
EXPREGS[2] = 0x00;
|
||||
EXPREGS[3] = 0x00;
|
||||
EXPREGS[4] = (EXPREGS[4] + 1) & 7;
|
||||
FCEU_printf("dipswitch = %d\n", EXPREGS[4]);
|
||||
MMC3RegReset();
|
||||
}
|
||||
static void M534Close(void) {
|
||||
}
|
||||
|
||||
void Mapper534_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 512, 512, 0, 0);
|
||||
pwrap = M534PW;
|
||||
cwrap = M534CW;
|
||||
info->Power = M534Power;
|
||||
info->Reset = M534Reset;
|
||||
info->Close = M534Close;
|
||||
AddExState(EXPREGS, 5, 0, "EXPR");
|
||||
}
|
||||
101
src/boards/539.c
Normal file
101
src/boards/539.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 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 preg;
|
||||
static uint8 mirr;
|
||||
static uint8 WRAM[8192];
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ &preg, 1, "PREG" },
|
||||
{ &mirr, 1, "MIRR" }
|
||||
};
|
||||
|
||||
static uint32 GetWRAMAddress(uint32 A) {
|
||||
return ((A & 0x1FFF) |
|
||||
((A < 0xC000) ? 0x1000 : 0x0000) |
|
||||
((A < 0x8000) ? 0x0800 : 0x000));
|
||||
}
|
||||
|
||||
static void Sync(void) {
|
||||
setprg8(0x6000, 13);
|
||||
setprg8(0x8000, 12);
|
||||
setprg8(0xA000, preg);
|
||||
setprg8(0xC000, 14);
|
||||
setprg8(0xE000, 15);
|
||||
setchr8(0);
|
||||
setmirror(((mirr & 8) >> 3) ^ 1);
|
||||
}
|
||||
|
||||
static DECLFR(M539Read) {
|
||||
switch (A >> 8) {
|
||||
case 0x60: case 0x62: case 0x64: case 0x65: case 0x82: case 0xC0: case 0xC1: case 0xC2:
|
||||
case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA:
|
||||
case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xDF:
|
||||
return WRAM[GetWRAMAddress(A)];
|
||||
default:
|
||||
return CartBR(A);
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M539Write) {
|
||||
switch (A >> 8) {
|
||||
case 0x60: case 0x62: case 0x64: case 0x65: case 0x82: case 0xC0: case 0xC1: case 0xC2:
|
||||
case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA:
|
||||
case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xDF:
|
||||
WRAM[GetWRAMAddress(A)] = V;
|
||||
break;
|
||||
default:
|
||||
switch (A & 0xF000) {
|
||||
case 0xA000:
|
||||
preg = V;
|
||||
Sync();
|
||||
break;
|
||||
case 0xF000:
|
||||
if ((A & 0x25) == 0x25) {
|
||||
mirr = V;
|
||||
Sync();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void M539Power(void) {
|
||||
preg = 0;
|
||||
mirr = 0;
|
||||
Sync();
|
||||
SetReadHandler(0x6000, 0xFFFF, M539Read);
|
||||
SetWriteHandler(0x6000, 0xFFFF, M539Write);
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper539_Init(CartInfo *info) {
|
||||
info->Power = M539Power;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(WRAM, 8192, 0, "WRAM");
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2012 CaH4e3
|
||||
* Copyright (C) 2020 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
|
||||
@@ -18,10 +19,20 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* added 2020-2-15
|
||||
* Street Fighter 3, Mortal Kombat II, Dragon Ball Z 2, Mario & Sonic 2 (JY-016)
|
||||
* 1995 Super HIK 4-in-1 (JY-016), 1995 Super HiK 4-in-1 (JY-017)
|
||||
* submapper 1 - Super Fighter III
|
||||
* NOTE: nesdev's notes for IRQ is different that whats implemented here
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 cregs[4], pregs[2];
|
||||
static uint8 IRQCount, IRQa;
|
||||
static uint8 submapper;
|
||||
static uint8 outerbank;
|
||||
static uint8 mirr;
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
@@ -29,23 +40,36 @@ static SFORMAT StateRegs[] =
|
||||
{ pregs, 2, "PREG" },
|
||||
{ &IRQa, 1, "IRQA" },
|
||||
{ &IRQCount, 1, "IRQC" },
|
||||
{ &outerbank, 1, "BLOK" },
|
||||
{ &mirr, 1, "MIRR" },
|
||||
{ 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]);
|
||||
/* FCEU_printf("P0:%02x P1:%02x outerbank:%02x\n", pregs[0], pregs[1], outerbank);*/
|
||||
setprg8(0x8000, pregs[0] | (outerbank & 6) << 3);
|
||||
setprg8(0xa000, pregs[1] | (outerbank & 6) << 3);
|
||||
setprg8(0xc000, 0xE | (outerbank & 6) << 3);
|
||||
setprg8(0xe000, 0xF | (outerbank & 6) << 3);
|
||||
setchr2(0x0000, cregs[0] | (outerbank & 1) << 8);
|
||||
setchr2(0x0800, cregs[1] | (outerbank & 1) << 8);
|
||||
setchr2(0x1000, cregs[2] | (outerbank & 1) << 8);
|
||||
setchr2(0x1800, cregs[3] | (outerbank & 1) << 8);
|
||||
|
||||
if (submapper == 1)
|
||||
setmirror(mirr ^ 1);
|
||||
}
|
||||
|
||||
static DECLFW(M91Write0) {
|
||||
cregs[A & 3] = V;
|
||||
Sync();
|
||||
switch (A & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: cregs[A & 3] = V; Sync(); break;
|
||||
case 4:
|
||||
case 5: mirr = V & 1; Sync(); break;
|
||||
default: /*FCEU_printf("A:%04x V:%02x\n", A, V);*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M91Write1) {
|
||||
@@ -57,11 +81,17 @@ static DECLFW(M91Write1) {
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M91Write2) {
|
||||
outerbank = A & 7;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M91Power(void) {
|
||||
Sync();
|
||||
SetReadHandler(0x8000, 0xffff, CartBR);
|
||||
SetWriteHandler(0x6000, 0x6fff, M91Write0);
|
||||
SetWriteHandler(0x7000, 0x7fff, M91Write1);
|
||||
SetReadHandler(0x8000, 0xffff, CartBR);
|
||||
SetWriteHandler(0x8000, 0x9fff, M91Write2);
|
||||
}
|
||||
|
||||
static void M91IRQHook(void) {
|
||||
@@ -78,6 +108,12 @@ static void StateRestore(int version) {
|
||||
}
|
||||
|
||||
void Mapper91_Init(CartInfo *info) {
|
||||
submapper = 0;
|
||||
if (info->CRC32 == 0x082778e6) /* Super Fighter III */
|
||||
submapper = 1;
|
||||
else if (info->iNES2)
|
||||
submapper = info->submapper;
|
||||
|
||||
info->Power = M91Power;
|
||||
GameHBIRQHook = M91IRQHook;
|
||||
GameStateRestore = StateRestore;
|
||||
|
||||
@@ -52,6 +52,8 @@ static void Sync(void) {
|
||||
*/
|
||||
|
||||
preg[0] = bank;
|
||||
preg[1] = 0;
|
||||
|
||||
switch (mode & 3) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
|
||||
269
src/boards/cheapocabra.c
Normal file
269
src/boards/cheapocabra.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* mapper 111 - Cheapocabra board by Memblers
|
||||
* http://forums.nesdev.com/viewtopic.php?p=146039
|
||||
*
|
||||
* 512k PRG-ROM in 32k pages (flashable if battery backed is specified)
|
||||
* 32k CHR-RAM used as:
|
||||
* 2 x 8k pattern pages
|
||||
* 2 x 8k nametable pages
|
||||
*
|
||||
* Notes:
|
||||
* - CHR-RAM for nametables maps to $3000-3FFF as well, but FCEUX internally mirrors to 4k?
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "../ines.h"
|
||||
|
||||
static uint8 reg;
|
||||
static uint8 *CHRRAM = NULL;
|
||||
static uint32 CHRRAMSIZE;
|
||||
|
||||
static uint8 flash = 0;
|
||||
static uint8 flash_mode;
|
||||
static uint8 flash_sequence;
|
||||
static uint8 flash_id;
|
||||
static uint8 *FLASHROM = NULL;
|
||||
static uint32 FLASHROMSIZE;
|
||||
|
||||
static SFORMAT StateRegs[] = {
|
||||
{ ®, 1, "REG" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static SFORMAT FlashRegs[] = {
|
||||
{ &flash_mode, 1, "FMOD" },
|
||||
{ &flash_sequence, 1, "FSEQ" },
|
||||
{ &flash_id, 1, "FMID" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
/* bit 7 controls green LED */
|
||||
/* bit 6 controls red LED */
|
||||
uint32 prg_chip = flash ? 0x10 : 0;
|
||||
int nt = (reg & 0x20) ? 8192 : 0; /* bit 5 controls 8k nametable page */
|
||||
int chr = (reg & 0x10) ? 1 : 0; /* bit 4 selects 8k CHR page */
|
||||
int prg = (reg & 0x0F); /* bits 0-3 select 32k PRG page */
|
||||
int n = 0;
|
||||
|
||||
nt += (16 * 1024);
|
||||
for (n = 0; n < 4; ++n) {
|
||||
setntamem(CHRRAM + nt + (1024 * n), 1, n);
|
||||
}
|
||||
setchr8r(0x10, chr);
|
||||
setprg32r(prg_chip, 0x8000, prg);
|
||||
}
|
||||
|
||||
static DECLFW(M111Write) {
|
||||
if ((A >= 0x5000 && A <= 0x5FFF) || (A >= 0x7000 && A <= 0x7FFF)) {
|
||||
reg = V;
|
||||
Sync();
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFR(M111FlashID) {
|
||||
/* Software ID mode is undefined by the datasheet for all but the lowest 2 addressable bytes,
|
||||
* but some tests of the chip currently being used found it repeats in 512-byte patterns.
|
||||
* http://forums.nesdev.com/viewtopic.php?p=178728#p178728
|
||||
*/
|
||||
|
||||
uint32 aid = A & 0x1FF;
|
||||
switch (aid) {
|
||||
case 0:
|
||||
return 0xBF;
|
||||
case 1:
|
||||
return 0xB7;
|
||||
default:
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void M111FlashIDEnter() {
|
||||
if (flash_id)
|
||||
return;
|
||||
flash_id = 1;
|
||||
SetReadHandler(0x8000, 0xFFFF, M111FlashID);
|
||||
}
|
||||
|
||||
void M111FlashIDExit() {
|
||||
if (!flash_id)
|
||||
return;
|
||||
flash_id = 0;
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
}
|
||||
|
||||
enum {
|
||||
FLASH_MODE_READY = 0,
|
||||
FLASH_MODE_COMMAND,
|
||||
FLASH_MODE_BYTE_WRITE,
|
||||
FLASH_MODE_ERASE,
|
||||
};
|
||||
|
||||
static DECLFW(M111Flash) {
|
||||
uint32 flash_addr = 0;
|
||||
uint32 command_addr = 0;
|
||||
|
||||
if (A < 0x8000 || A > 0xFFFF)
|
||||
return;
|
||||
|
||||
flash_addr = ((reg & 0x0F) << 15) | (A & 0x7FFF);
|
||||
command_addr = flash_addr & 0x7FFF;
|
||||
|
||||
switch (flash_mode) {
|
||||
default:
|
||||
case FLASH_MODE_READY:
|
||||
if (command_addr == 0x5555 && V == 0xAA) {
|
||||
flash_mode = FLASH_MODE_COMMAND;
|
||||
flash_sequence = 0;
|
||||
} else if (V == 0xF0) {
|
||||
M111FlashIDExit();
|
||||
}
|
||||
break;
|
||||
case FLASH_MODE_COMMAND:
|
||||
if (flash_sequence == 0) {
|
||||
if (command_addr == 0x2AAA && V == 0x55)
|
||||
flash_sequence = 1;
|
||||
else
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
} else if (flash_sequence == 1) {
|
||||
if (command_addr == 0x5555) {
|
||||
flash_sequence = 0;
|
||||
switch (V) {
|
||||
default:
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
break;
|
||||
case 0xA0:
|
||||
flash_mode = FLASH_MODE_BYTE_WRITE;
|
||||
break;
|
||||
case 0x80:
|
||||
flash_mode = FLASH_MODE_ERASE;
|
||||
break;
|
||||
case 0x90:
|
||||
M111FlashIDEnter();
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
break;
|
||||
case 0xF0:
|
||||
M111FlashIDExit();
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
} else
|
||||
flash_mode = FLASH_MODE_READY; /* should be unreachable */
|
||||
break;
|
||||
case FLASH_MODE_BYTE_WRITE:
|
||||
FLASHROM[flash_addr] &= V;
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
break;
|
||||
case FLASH_MODE_ERASE:
|
||||
if (flash_sequence == 0) {
|
||||
if (command_addr == 0x5555 && V == 0xAA)
|
||||
flash_sequence = 1;
|
||||
else
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
} else if (flash_sequence == 1) {
|
||||
if (command_addr == 0x2AAA && V == 0x55)
|
||||
flash_sequence = 2;
|
||||
else
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
} else if (flash_sequence == 2) {
|
||||
if (command_addr == 0x5555 && V == 0x10) /* erase chip */
|
||||
{
|
||||
memset(FLASHROM, 0xFF, FLASHROMSIZE);
|
||||
} else if (V == 0x30) /* erase 4k sector */
|
||||
{
|
||||
uint32 sector = flash_addr & 0x7F000;
|
||||
memset(FLASHROM + sector, 0xFF, 1024 * 4);
|
||||
}
|
||||
flash_mode = FLASH_MODE_READY;
|
||||
} else
|
||||
flash_mode = FLASH_MODE_READY; /* should be unreachable */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void M111Power(void) {
|
||||
reg = 0xFF;
|
||||
Sync();
|
||||
SetReadHandler(0x8000, 0xffff, CartBR);
|
||||
SetWriteHandler(0x5000, 0x5fff, M111Write);
|
||||
SetWriteHandler(0x7000, 0x7fff, M111Write);
|
||||
|
||||
if (flash) {
|
||||
flash_mode = 0;
|
||||
flash_sequence = 0;
|
||||
flash_id = 0;
|
||||
SetWriteHandler(0x8000, 0xFFFF, M111Flash);
|
||||
}
|
||||
}
|
||||
|
||||
static void M111Close(void) {
|
||||
if (CHRRAM)
|
||||
FCEU_gfree(CHRRAM);
|
||||
CHRRAM = NULL;
|
||||
|
||||
if (FLASHROM)
|
||||
FCEU_gfree(FLASHROM);
|
||||
FLASHROM = NULL;
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Sync();
|
||||
}
|
||||
|
||||
void Mapper111_Init(CartInfo* info) {
|
||||
info->Power = M111Power;
|
||||
info->Close = M111Close;
|
||||
|
||||
CHRRAMSIZE = 1024 * 32;
|
||||
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
|
||||
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
|
||||
|
||||
flash = (info->battery != 0);
|
||||
if (flash) {
|
||||
uint32 PRGSIZE = 0;
|
||||
uint32 w = 0;
|
||||
uint32 r = 0;
|
||||
|
||||
FLASHROMSIZE = 1024 * 512;
|
||||
FLASHROM = (uint8*)FCEU_gmalloc(FLASHROMSIZE);
|
||||
info->SaveGame[0] = FLASHROM;
|
||||
info->SaveGameLen[0] = FLASHROMSIZE;
|
||||
AddExState(FLASHROM, FLASHROMSIZE, 0, "FROM");
|
||||
AddExState(&FlashRegs, ~0, 0, 0);
|
||||
|
||||
/* copy PRG ROM into FLASHROM, use it instead of PRG ROM */
|
||||
PRGSIZE = ROM_size * 16 * 1024;
|
||||
for (w = 0, r = 0; w < FLASHROMSIZE; ++w) {
|
||||
FLASHROM[w] = ROM[r];
|
||||
++r;
|
||||
if (r >= PRGSIZE)
|
||||
r = 0;
|
||||
}
|
||||
SetupCartPRGMapping(0x10, FLASHROM, FLASHROMSIZE, 0);
|
||||
}
|
||||
}
|
||||
@@ -22,20 +22,35 @@
|
||||
#include "mapinc.h"
|
||||
|
||||
static void GenMMC1Power(void);
|
||||
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery);
|
||||
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int saveram);
|
||||
|
||||
static uint8 DRegs[4];
|
||||
static uint8 Buffer, BufferShift;
|
||||
|
||||
static int mmc1opts;
|
||||
static uint32 WRAMSIZE = 0;
|
||||
|
||||
/* size of non-battery-backed portion of WRAM */
|
||||
/* serves as starting offset for actual save ram from total wram size */
|
||||
/* returns 0 if entire work ram is battery backed ram */
|
||||
static uint32 NONSaveRAMSIZE = 0;
|
||||
|
||||
static void (*MMC1CHRHook4)(uint32 A, uint8 V);
|
||||
static void (*MMC1PRGHook16)(uint32 A, uint8 V);
|
||||
/* Used to override default wram behavior */
|
||||
/* NULL uses default MMC1 wram. Set after GenMMC1Init() is called to override */
|
||||
static void (*MMC1WRAMHook8)(void);
|
||||
|
||||
static uint8 *WRAM = NULL;
|
||||
static uint8 *CHRRAM = NULL;
|
||||
static int is155, is171;
|
||||
|
||||
static uint32 MMC1GetCHRBank (uint32 bank) {
|
||||
if (DRegs[0] & 0x10) /* 4 KiB mode */
|
||||
return (DRegs[1 + bank]);
|
||||
else /* 8 KiB mode */
|
||||
return ((DRegs[1] & ~1) | bank);
|
||||
}
|
||||
|
||||
static uint8 MMC1WRAMEnabled(void) {
|
||||
return !(DRegs[3] & 0x10);
|
||||
}
|
||||
@@ -51,14 +66,26 @@ static DECLFR(MAWRAM) {
|
||||
return(Page[A >> 11][A]);
|
||||
}
|
||||
|
||||
static void MMC1CHR(void) {
|
||||
if (mmc1opts & 4) {
|
||||
if (DRegs[0] & 0x10)
|
||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 4) & 1);
|
||||
static void MMC1WRAM(void) {
|
||||
if (WRAMSIZE > 8192) {
|
||||
if (WRAMSIZE > 16384)
|
||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 2) & 3);
|
||||
else
|
||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 3) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void MMC1CHR(void) {
|
||||
if (MMC1WRAMHook8) /* Use custom wram hook, currently used for M543 */
|
||||
MMC1WRAMHook8();
|
||||
else { /* Use default MMC1 wram behavior */
|
||||
if (WRAMSIZE > 8192) {
|
||||
if (WRAMSIZE > 16384)
|
||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 2) & 3);
|
||||
else
|
||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 3) & 1);
|
||||
}
|
||||
}
|
||||
if (MMC1CHRHook4) {
|
||||
if (DRegs[0] & 0x10) {
|
||||
MMC1CHRHook4(0x0000, DRegs[1]);
|
||||
@@ -183,24 +210,44 @@ static void MMC1CMReset(void) {
|
||||
MMC1PRG();
|
||||
}
|
||||
|
||||
static int DetectMMC1WRAMSize(uint32 crc32) {
|
||||
switch (crc32) {
|
||||
case 0xc6182024: /* Romance of the 3 Kingdoms */
|
||||
case 0x2225c20f: /* Genghis Khan */
|
||||
case 0x4642dda6: /* Nobunaga's Ambition */
|
||||
case 0x29449ba9: /* "" "" (J) */
|
||||
case 0x2b11e0b0: /* "" "" (J) */
|
||||
case 0xb8747abf: /* Best Play Pro Yakyuu Special (J) */
|
||||
case 0xc9556b36: /* Final Fantasy I & II (J) [!] */
|
||||
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
||||
return(16);
|
||||
static int DetectMMC1WRAMSize(CartInfo *info, int *saveRAM) {
|
||||
int workRAM = 8;
|
||||
switch (info->CRC32) {
|
||||
case 0xc6182024: /* Romance of the 3 Kingdoms */
|
||||
case 0xabbf7217: /* "" "" (J) (PRG0) */
|
||||
case 0xccf35c02: /* "" "" (J) (PRG1) */
|
||||
case 0x2225c20f: /* Genghis Khan */
|
||||
case 0xfb69743a: /* "" "" (J) */
|
||||
case 0x4642dda6: /* Nobunaga's Ambition */
|
||||
case 0x3f7ad415: /* "" "" (J) (PRG0) */
|
||||
case 0x2b11e0b0: /* "" "" (J) (PRG1) */
|
||||
*saveRAM = 8;
|
||||
workRAM = 16;
|
||||
break;
|
||||
case 0xb8747abf: /* Best Play Pro Yakyuu Special (J) (PRG0) */
|
||||
case 0xc3de7c69: /* "" "" (J) (PRG1) */
|
||||
case 0xc9556b36: /* Final Fantasy I & II (J) [!] */
|
||||
*saveRAM = 32;
|
||||
workRAM = 32;
|
||||
break;
|
||||
default:
|
||||
if (info->iNES2) {
|
||||
workRAM = (info->PRGRamSize + info->PRGRamSaveSize) / 1024;
|
||||
*saveRAM = info->PRGRamSaveSize / 1024;
|
||||
/* we only support sizes between 8K and 32K */
|
||||
if (workRAM > 0 && workRAM < 8)
|
||||
workRAM = 8;
|
||||
if (workRAM > 32)
|
||||
workRAM = 32;
|
||||
if (*saveRAM > workRAM)
|
||||
*saveRAM = workRAM;
|
||||
}
|
||||
break;
|
||||
case 0xd1e50064: /* Dezaemon */
|
||||
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
||||
return(32);
|
||||
break;
|
||||
default: return(8);
|
||||
}
|
||||
}
|
||||
if (workRAM > 8)
|
||||
FCEU_printf(" >8KB external WRAM present. Use NES 2.0 if you hack the ROM image.\n");
|
||||
|
||||
return workRAM;
|
||||
}
|
||||
|
||||
static uint32 NWCIRQCount;
|
||||
@@ -258,17 +305,16 @@ void Mapper105_Init(CartInfo *info) {
|
||||
|
||||
static void GenMMC1Power(void) {
|
||||
lreset = 0;
|
||||
if (mmc1opts & 1) {
|
||||
FCEU_CheatAddRAM(8, 0x6000, WRAM);
|
||||
if (mmc1opts & 4)
|
||||
FCEU_dwmemset(WRAM, 0, 8192)
|
||||
else if (!(mmc1opts & 2))
|
||||
FCEU_dwmemset(WRAM, 0, 8192);
|
||||
}
|
||||
SetWriteHandler(0x8000, 0xFFFF, MMC1_write);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
|
||||
if (mmc1opts & 1) {
|
||||
if (WRAMSIZE) {
|
||||
FCEU_CheatAddRAM(8, 0x6000, WRAM);
|
||||
|
||||
/* clear non-battery-backed portion of WRAM */
|
||||
if (NONSaveRAMSIZE)
|
||||
FCEU_dwmemset(WRAM, 0, NONSaveRAMSIZE);
|
||||
|
||||
SetReadHandler(0x6000, 0x7FFF, MAWRAM);
|
||||
SetWriteHandler(0x6000, 0x7FFF, MBWRAM);
|
||||
setprg8r(0x10, 0x6000, 0);
|
||||
@@ -285,26 +331,25 @@ static void GenMMC1Close(void) {
|
||||
CHRRAM = WRAM = NULL;
|
||||
}
|
||||
|
||||
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery) {
|
||||
static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int saveram) {
|
||||
is155 = 0;
|
||||
|
||||
info->Close = GenMMC1Close;
|
||||
MMC1PRGHook16 = MMC1CHRHook4 = 0;
|
||||
mmc1opts = 0;
|
||||
MMC1WRAMHook8 = 0;
|
||||
WRAMSIZE = wram * 1024;
|
||||
NONSaveRAMSIZE = (wram - saveram) * 1024;
|
||||
PRGmask16[0] &= (prg >> 14) - 1;
|
||||
CHRmask4[0] &= (chr >> 12) - 1;
|
||||
CHRmask8[0] &= (chr >> 13) - 1;
|
||||
|
||||
if (wram) {
|
||||
WRAM = (uint8*)FCEU_gmalloc(wram * 1024);
|
||||
mmc1opts |= 1;
|
||||
if (wram > 8) mmc1opts |= 4;
|
||||
SetupCartPRGMapping(0x10, WRAM, wram * 1024, 1);
|
||||
AddExState(WRAM, wram * 1024, 0, "WRAM");
|
||||
if (battery) {
|
||||
mmc1opts |= 2;
|
||||
info->SaveGame[0] = WRAM + ((mmc1opts & 4) ? 8192 : 0);
|
||||
info->SaveGameLen[0] = 8192;
|
||||
if (WRAMSIZE) {
|
||||
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
|
||||
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
|
||||
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
|
||||
if (saveram) {
|
||||
info->SaveGame[0] = WRAM + NONSaveRAMSIZE;
|
||||
info->SaveGameLen[0] = saveram * 1024;
|
||||
}
|
||||
}
|
||||
if (!chr) {
|
||||
@@ -322,13 +367,14 @@ static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
||||
}
|
||||
|
||||
void Mapper1_Init(CartInfo *info) {
|
||||
int ws = DetectMMC1WRAMSize(info->CRC32);
|
||||
GenMMC1Init(info, 512, 256, ws, info->battery);
|
||||
int bs = info->battery ? 8 : 0;
|
||||
int ws = DetectMMC1WRAMSize(info, &bs);
|
||||
GenMMC1Init(info, 512, 256, ws, bs);
|
||||
}
|
||||
|
||||
/* Same as mapper 1, without respect for WRAM enable bit. */
|
||||
void Mapper155_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 512, 256, 8, info->battery);
|
||||
GenMMC1Init(info, 512, 256, 8, info->battery ? 8 : 0);
|
||||
is155 = 1;
|
||||
}
|
||||
|
||||
@@ -340,7 +386,7 @@ void Mapper171_Init(CartInfo *info) {
|
||||
}
|
||||
|
||||
void SAROM_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 128, 64, 8, info->battery);
|
||||
GenMMC1Init(info, 128, 64, 8, info->battery ? 8 : 0);
|
||||
}
|
||||
|
||||
void SBROM_Init(CartInfo *info) {
|
||||
@@ -360,7 +406,7 @@ void SGROM_Init(CartInfo *info) {
|
||||
}
|
||||
|
||||
void SKROM_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 256, 64, 8, info->battery);
|
||||
GenMMC1Init(info, 256, 64, 8, info->battery ? 8 : 0);
|
||||
}
|
||||
|
||||
void SLROM_Init(CartInfo *info) {
|
||||
@@ -392,11 +438,11 @@ void SHROM_Init(CartInfo *info) {
|
||||
/* */
|
||||
|
||||
void SNROM_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 256, 0, 8, info->battery);
|
||||
GenMMC1Init(info, 256, 0, 8, info->battery ? 8 : 0);
|
||||
}
|
||||
|
||||
void SOROM_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 256, 0, 16, info->battery);
|
||||
GenMMC1Init(info, 256, 0, 16, info->battery ? 8 : 0);
|
||||
}
|
||||
|
||||
/* ----------------------- FARID_SLROM_8-IN-1 -----------------------*/
|
||||
@@ -490,7 +536,7 @@ static void Sync(void) {
|
||||
MMC1PRG();
|
||||
MMC1CHR();
|
||||
MMC1MIRROR();
|
||||
} else {
|
||||
} else {
|
||||
/* Mapper 70 */
|
||||
setprg16(0x8000, ((mode & 2) << 1) | ((latch >> 4) & 3));
|
||||
setprg16(0xC000, ((mode & 2) << 1) | 3);
|
||||
@@ -532,3 +578,127 @@ void Mapper297_Init(CartInfo *info) {
|
||||
AddExState(&latch, 1, 0, "LATC");
|
||||
AddExState(&mode, 1, 0, "MODE");
|
||||
}
|
||||
|
||||
/* ---------------------------- Mapper 543 -------------------------------- */
|
||||
|
||||
/* NES 2.0 Mapper 543 - 1996 無敵智カ卡 5-in-1 (CH-501) */
|
||||
|
||||
static uint8_t outerBank;
|
||||
static uint8_t bits;
|
||||
static uint8_t shift;
|
||||
|
||||
static void M543PRG16(uint32 A, uint8 V) {
|
||||
setprg16(A, (V & 0x0F) | (outerBank << 4));
|
||||
}
|
||||
|
||||
static void M543CHR4(uint32 A, uint8 V) {
|
||||
setchr4(A, (V & 7));
|
||||
}
|
||||
|
||||
static void M543WRAM8(void) {
|
||||
uint32 wramBank;
|
||||
if (outerBank & 2)
|
||||
wramBank = 4 | ((outerBank >> 1) & 2) | (outerBank & 1) ;
|
||||
else
|
||||
wramBank = ((outerBank << 1) & 2) | ((MMC1GetCHRBank(0) >> 3) & 1);
|
||||
setprg8r(0x10, 0x6000, wramBank);
|
||||
}
|
||||
|
||||
static DECLFW(M543Write) {
|
||||
bits |= ((V >> 3) & 1) << shift++;
|
||||
if (shift == 4) {
|
||||
outerBank = bits;
|
||||
bits = shift = 0;
|
||||
MMC1PRG();
|
||||
MMC1CHR();
|
||||
}
|
||||
}
|
||||
|
||||
static void M543Reset(void) {
|
||||
bits = 0;
|
||||
shift = 0;
|
||||
outerBank = 0;
|
||||
MMC1CMReset();
|
||||
}
|
||||
|
||||
static void M543Power(void) {
|
||||
bits = 0;
|
||||
shift = 0;
|
||||
outerBank = 0;
|
||||
GenMMC1Power();
|
||||
SetWriteHandler(0x5000, 0x5FFF, M543Write);
|
||||
}
|
||||
|
||||
void Mapper543_Init(CartInfo *info) {
|
||||
/* M543 has 32K CHR RAM but only uses 8K, so its safe to set this chr to 0 */
|
||||
GenMMC1Init(info, 2048, 32, 64, info->battery ? 64 : 0);
|
||||
info->Power = M543Power;
|
||||
info->Reset = M543Reset;
|
||||
MMC1CHRHook4 = M543CHR4;
|
||||
MMC1PRGHook16 = M543PRG16;
|
||||
MMC1WRAMHook8 = M543WRAM8;
|
||||
AddExState(&bits, 1, 0, "BITS");
|
||||
AddExState(&shift, 1, 0, "SHFT");
|
||||
AddExState(&outerBank, 1, 0, "BANK");
|
||||
}
|
||||
|
||||
/* ---------------------------- Mapper 550 -------------------------------- */
|
||||
|
||||
/* NES 2.0 Mapper 550 - 7-in-1 1993 Chess Series (JY-015) */
|
||||
|
||||
static uint8_t latch;
|
||||
static uint8_t outerBank;
|
||||
|
||||
static void M550PRG16(uint32 A, uint8 V) {
|
||||
if ((outerBank & 6) == 6)
|
||||
setprg16(A, (V & 7) | (outerBank << 2));
|
||||
else
|
||||
setprg32(0x8000, (latch >> 4) | (outerBank << 1));
|
||||
}
|
||||
|
||||
static void M550CHR4(uint32 A, uint8 V) {
|
||||
if ((outerBank & 6) == 6)
|
||||
setchr4(A, (V & 7) | ((outerBank << 2) & 0x18));
|
||||
else
|
||||
setchr8((latch & 3) | ((outerBank << 1) & 0x0C));
|
||||
}
|
||||
|
||||
static DECLFW(M550Write7) {
|
||||
if (!(outerBank & 8)) {
|
||||
outerBank = A & 15;
|
||||
MMC1PRG();
|
||||
MMC1CHR();
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(M550Write8) {
|
||||
latch = V;
|
||||
if ((outerBank & 6) == 6)
|
||||
MMC1_write(A, V);
|
||||
MMC1PRG();
|
||||
MMC1CHR();
|
||||
}
|
||||
|
||||
static void M550Reset(void) {
|
||||
latch = 0;
|
||||
outerBank = 0;
|
||||
MMC1CMReset();
|
||||
}
|
||||
|
||||
static void M550Power(void) {
|
||||
latch = 0;
|
||||
outerBank = 0;
|
||||
GenMMC1Power();
|
||||
SetWriteHandler(0x7000, 0x7FFF, M550Write7);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M550Write8);
|
||||
}
|
||||
|
||||
void Mapper550_Init(CartInfo *info) {
|
||||
GenMMC1Init(info, 512, 128, 8, 0);
|
||||
info->Power = M550Power;
|
||||
info->Reset = M550Reset;
|
||||
MMC1CHRHook4 = M550CHR4;
|
||||
MMC1PRGHook16 = M550PRG16;
|
||||
AddExState(&latch, 1, 0, "LATC");
|
||||
AddExState(&outerBank, 1, 0, "BANK");
|
||||
}
|
||||
|
||||
@@ -540,7 +540,8 @@ static DECLFR(M45Read) {
|
||||
}
|
||||
|
||||
static void M45Reset(void) {
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
EXPREGS[5]++;
|
||||
EXPREGS[5] &= 7;
|
||||
MMC3RegReset();
|
||||
@@ -548,8 +549,9 @@ static void M45Reset(void) {
|
||||
|
||||
static void M45Power(void) {
|
||||
GenMMC3Power();
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = EXPREGS[4] = EXPREGS[5] = 0;
|
||||
SetWriteHandler(0x5000, 0x7FFF, M45Write);
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[3] = EXPREGS[4] = EXPREGS[5] = 0;
|
||||
EXPREGS[2] = 0x0F;
|
||||
SetWriteHandler(0x6000, 0x7FFF, M45Write);
|
||||
SetReadHandler(0x5000, 0x5FFF, M45Read);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
* Copyright (C) 2020 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
|
||||
@@ -18,10 +19,13 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* 2020-2-3 - updated mapper 150/243 */
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 cmd, dip;
|
||||
static uint8 latch[8];
|
||||
static uint8 mapperNum;
|
||||
|
||||
static void S74LS374MSync(uint8 mirr) {
|
||||
switch (mirr & 3) {
|
||||
@@ -32,7 +36,8 @@ static void S74LS374MSync(uint8 mirr) {
|
||||
}
|
||||
}
|
||||
|
||||
static void S74LS374NSynco(void) {
|
||||
/* old mapper 150 and 243 */
|
||||
/* static void S74LS374NSynco(void) {
|
||||
setprg32(0x8000, latch[0]);
|
||||
setchr8(latch[1] | latch[3] | latch[4]);
|
||||
S74LS374MSync(latch[2]);
|
||||
@@ -57,7 +62,7 @@ static DECLFW(S74LS374NWrite) {
|
||||
static DECLFR(S74LS374NRead) {
|
||||
uint8 ret;
|
||||
if ((A & 0x4100) == 0x4100)
|
||||
/* ret=(X.DB&0xC0)|((~cmd)&0x3F); */
|
||||
// ret=(X.DB&0xC0)|((~cmd)&0x3F);
|
||||
ret = ((~cmd) & 0x3F) ^ dip;
|
||||
else
|
||||
ret = X.DB;
|
||||
@@ -128,7 +133,7 @@ void S74LS374NA_Init(CartInfo *info) {
|
||||
GameStateRestore = S74LS374NRestore;
|
||||
AddExState(latch, 5, 0, "LATC");
|
||||
AddExState(&cmd, 1, 0, "CMD");
|
||||
}
|
||||
}*/
|
||||
|
||||
static int type;
|
||||
static void S8259Synco(void) {
|
||||
@@ -317,73 +322,6 @@ void SA0037_Init(CartInfo *info) {
|
||||
AddExState(&latch[0], 1, 0, "LATC");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
|
||||
static void TCU01Synco() {
|
||||
setprg32(0x8000, ((latch[0] & 0x80) >> 6) | ((latch[0] >> 2) & 1));
|
||||
setchr8((latch[0] >> 3) & 0xF);
|
||||
}
|
||||
|
||||
static DECLFW(TCU01Write) {
|
||||
if ((A & 0x103) == 0x102) {
|
||||
latch[0] = V;
|
||||
TCU01Synco();
|
||||
}
|
||||
}
|
||||
|
||||
static void TCU01Power(void) {
|
||||
latch[0] = 0;
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x4100, 0xFFFF, TCU01Write);
|
||||
TCU01Synco();
|
||||
}
|
||||
|
||||
static void TCU01Restore(int version) {
|
||||
TCU01Synco();
|
||||
}
|
||||
|
||||
void TCU01_Init(CartInfo *info) {
|
||||
GameStateRestore = TCU01Restore;
|
||||
info->Power = TCU01Power;
|
||||
AddExState(&latch[0], 1, 0, "LATC");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
|
||||
static void TCU02Synco() {
|
||||
setprg32(0x8000, 0);
|
||||
setchr8(latch[0] & 3);
|
||||
}
|
||||
|
||||
static DECLFW(TCU02Write) {
|
||||
if ((A & 0x103) == 0x102) {
|
||||
latch[0] = V + 3;
|
||||
TCU02Synco();
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFR(TCU02Read) {
|
||||
return (latch[0] & 0x3F) | (X.DB & 0xC0);
|
||||
}
|
||||
|
||||
static void TCU02Power(void) {
|
||||
latch[0] = 0;
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x4100, TCU02Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, TCU02Write);
|
||||
TCU02Synco();
|
||||
}
|
||||
|
||||
static void TCU02Restore(int version) {
|
||||
TCU02Synco();
|
||||
}
|
||||
|
||||
void TCU02_Init(CartInfo *info) {
|
||||
GameStateRestore = TCU02Restore;
|
||||
info->Power = TCU02Power;
|
||||
AddExState(&latch[0], 1, 0, "LATC");
|
||||
}
|
||||
|
||||
/* --------------------------------------------- */
|
||||
|
||||
static DECLFR(TCA01Read) {
|
||||
@@ -407,3 +345,84 @@ void TCA01_Init(CartInfo *info) {
|
||||
info->Power = TCA01Power;
|
||||
}
|
||||
|
||||
/* ------------------ Mapper 150 --------------------- */
|
||||
/* ------------------ Mapper 243 --------------------- */
|
||||
|
||||
/* Mapper 150 - SA-015 / SA-630 / Unif UNL-Sachen-74LS374N */
|
||||
/* Mapper 243 - SA-020A */
|
||||
|
||||
static void S74LS374NSynco(void) {
|
||||
uint32 chrBank;
|
||||
if (mapperNum == 150)
|
||||
chrBank = (latch[6] & 3) | ((latch[4] << 2) & 4) | (latch[2] << 3);
|
||||
else
|
||||
chrBank = (latch[2] & 1) | ((latch[4] << 1) & 2) | (latch[6] << 2);
|
||||
|
||||
setprg32(0x8000, (latch[2] & 1) | latch[5]);
|
||||
setchr8(chrBank);
|
||||
|
||||
switch ((latch[7] >> 1) & 3) {
|
||||
case 0: setmirrorw(0, 1, 1, 1); break;
|
||||
case 1: setmirror(MI_H); break;
|
||||
case 2: setmirror(MI_V); break;
|
||||
case 3: setmirror(MI_0); break;
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFR(S74LS374NRead) {
|
||||
uint8 ret;
|
||||
if ((A & 0xC101) == 0x4101) {
|
||||
if (dip & 1)
|
||||
ret = (latch[cmd] & 3) | (X.DB & 0xFC);
|
||||
else
|
||||
ret = (latch[cmd] & 7) | (X.DB & 0xF8);
|
||||
} else {
|
||||
ret = X.DB;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DECLFW(S74LS374NWrite) {
|
||||
if (dip & 1)
|
||||
V |= 4;
|
||||
switch (A & 0xC101) {
|
||||
case 0x4100:
|
||||
cmd = V & 7;
|
||||
break;
|
||||
case 0x4101:
|
||||
latch[cmd] = V & 7;
|
||||
S74LS374NSynco();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void S74LS374NRestore(int version) {
|
||||
S74LS374NSynco();
|
||||
}
|
||||
|
||||
static void S74LS374NReset(void) {
|
||||
dip ^= 1;
|
||||
latch[0] = latch[1] = latch[2] = latch[3] = 0;
|
||||
latch[4] = latch[5] = latch[6] = latch[7] = 0;
|
||||
S74LS374NSynco();
|
||||
}
|
||||
|
||||
static void S74LS374NPower(void) {
|
||||
dip = 0;
|
||||
latch[0] = latch[1] = latch[2] = latch[3] = 0;
|
||||
latch[4] = latch[5] = latch[6] = latch[7] = 0;
|
||||
S74LS374NSynco();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x4100, 0x7FFF, S74LS374NWrite);
|
||||
if (mapperNum == 150)
|
||||
SetReadHandler(0x4100, 0x7FFF, S74LS374NRead);
|
||||
}
|
||||
|
||||
void S74LS374N_Init(CartInfo *info) {
|
||||
mapperNum = info->mapper;
|
||||
info->Power = S74LS374NPower;
|
||||
info->Reset = S74LS374NReset;
|
||||
GameStateRestore = S74LS374NRestore;
|
||||
AddExState(latch, 8, 0, "LATC");
|
||||
AddExState(&cmd, 1, 0, "CMD");
|
||||
}
|
||||
|
||||
404
src/boards/txcchip.c
Normal file
404
src/boards/txcchip.c
Normal file
@@ -0,0 +1,404 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2012 CaH4e3
|
||||
* Copyright (C) 2019 Libretro Team
|
||||
* Copyright (C) 2020 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
|
||||
*
|
||||
* TXC/Micro Genius simplified mapper
|
||||
* updated 06-2019 http://wiki.nesdev.com/w/index.php/INES_Mapper_036
|
||||
*
|
||||
* Known games:
|
||||
* - Strike Wolf (Asia) (Unl)
|
||||
* - Policeman (Gluk Video) (unl)
|
||||
* - F-15 City War (Spain) (Gluk Video) (Unl)
|
||||
*
|
||||
* TXC mappers, originally much complex banksitching
|
||||
*
|
||||
* 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-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
|
||||
*
|
||||
*/
|
||||
|
||||
/* added 2020-2-16
|
||||
* Updated based on latest source
|
||||
* Mappers 36, 132, 173
|
||||
* Mappers 136, 147, 172
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 mask;
|
||||
uint8 isJV001;
|
||||
uint8 accumulator;
|
||||
uint8 inverter;
|
||||
uint8 staging;
|
||||
uint8 output;
|
||||
uint8 increase;
|
||||
uint8 Y;
|
||||
uint8 invert;
|
||||
} TXC;
|
||||
|
||||
static TXC txc;
|
||||
|
||||
static void (*WSync)(void);
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ &txc.accumulator, 1, "ACC0" },
|
||||
{ &txc.inverter, 1, "INVR" },
|
||||
{ &txc.staging, 1, "STG0" },
|
||||
{ &txc.output, 1, "OUT0" },
|
||||
{ &txc.increase, 1, "INC0" },
|
||||
{ &txc.Y, 1, "YFLG" },
|
||||
{ &txc.invert, 1, "INVT" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static uint8 TXC_CMDRead(void) {
|
||||
uint8 ret = ((txc.accumulator & txc.mask) | ((txc.inverter ^ txc.invert) & ~txc.mask));
|
||||
txc.Y = !txc.invert || ((ret & 0x10) != 0);
|
||||
WSync();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DECLFW(TXC_CMDWrite) {
|
||||
if (A & 0x8000) {
|
||||
if (txc.isJV001)
|
||||
txc.output = (txc.accumulator & 0x0F) | (txc.inverter & 0xF0);
|
||||
else
|
||||
txc.output = (txc.accumulator & 0x0F) | ((txc.inverter << 1) & 0x10);
|
||||
} else {
|
||||
switch (A & 0x103) {
|
||||
case 0x100:
|
||||
if (txc.increase)
|
||||
txc.accumulator++;
|
||||
else
|
||||
txc.accumulator = ((txc.accumulator & ~txc.mask) | ((txc.staging ^ txc.invert) & txc.mask));
|
||||
break;
|
||||
case 0x101:
|
||||
txc.invert = (V & 0x01) ? 0xFF : 0x00;
|
||||
break;
|
||||
case 0x102:
|
||||
txc.staging = V & txc.mask;
|
||||
txc.inverter = V & ~txc.mask;
|
||||
break;
|
||||
case 0x103:
|
||||
txc.increase = ((V & 0x01) != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
txc.Y = !txc.invert || ((V & 0x10) != 0);
|
||||
WSync();
|
||||
}
|
||||
|
||||
static void TXCRegReset(void) {
|
||||
txc.output = 0;
|
||||
txc.accumulator = 0;
|
||||
txc.inverter = 0;
|
||||
txc.staging = 0;
|
||||
txc.increase = 0;
|
||||
txc.Y = 0;
|
||||
txc.mask = txc.isJV001 ? 0x0F : 0x07;
|
||||
txc.invert = txc.isJV001 ? 0xFF : 0x00;
|
||||
|
||||
WSync();
|
||||
}
|
||||
|
||||
static void GenTXCPower(void) {
|
||||
TXCRegReset();
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
WSync();
|
||||
}
|
||||
|
||||
static void GenTXC_Init(CartInfo *info, void (*proc)(void), uint32 jv001) {
|
||||
txc.isJV001 = jv001;
|
||||
WSync = proc;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(StateRegs, ~0, 0, 0);
|
||||
}
|
||||
|
||||
static int CheckHash(CartInfo *info) {
|
||||
int x = 0;
|
||||
uint64 partialmd5 = 0;
|
||||
|
||||
/* These carts do not work with new mapper implementation.
|
||||
* This is a hack to use previous mapper implementation for such carts. */
|
||||
for (x = 0; x < 8; x++)
|
||||
partialmd5 |= (uint64)info->MD5[15 - x] << (x * 8);
|
||||
switch (partialmd5) {
|
||||
case 0x2dd8f958850f21f4LL: /* Jin Gwok Sei Chuen Saang (Ch) [U][!] */
|
||||
FCEU_printf(" WARNING: Using alternate mapper implementation.\n");
|
||||
UNL22211_Init(info);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------- Mapper 36 --------------- */
|
||||
|
||||
static uint8 creg = 0;
|
||||
|
||||
static void M36Sync(void) {
|
||||
setprg32(0x8000, txc.output & 0x03);
|
||||
setchr8(creg & 0x0F);
|
||||
}
|
||||
|
||||
static DECLFW(M36Write) {
|
||||
if ((A & 0xF200) == 0x4200) creg = V;
|
||||
TXC_CMDWrite(A, (V >> 4) & 0x03);
|
||||
}
|
||||
|
||||
static DECLFR(M36Read) {
|
||||
uint8 ret = X.DB;
|
||||
if ((A & 0x103) == 0x100)
|
||||
ret = (X.DB & 0xCF) | ((TXC_CMDRead() << 4) & 0x30);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void M36Power(void) {
|
||||
creg = 0;
|
||||
GenTXCPower();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x5FFF, M36Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, M36Write);
|
||||
}
|
||||
|
||||
void Mapper36_Init(CartInfo *info) {
|
||||
GenTXC_Init(info, M36Sync, 0);
|
||||
info->Power = M36Power;
|
||||
AddExState(&creg, 1, 0, "CREG");
|
||||
}
|
||||
|
||||
/* --------------- Mapper 132 --------------- */
|
||||
|
||||
static void M132Sync(void) {
|
||||
setprg32(0x8000, (txc.output >> 2) & 0x01);
|
||||
setchr8(txc.output & 0x03);
|
||||
}
|
||||
|
||||
static DECLFW(M132Write) {
|
||||
TXC_CMDWrite(A, V & 0x0F);
|
||||
}
|
||||
|
||||
static DECLFR(M132Read) {
|
||||
uint8 ret = X.DB;
|
||||
if ((A & 0x103) == 0x100)
|
||||
ret = ((X.DB & 0xF0) | (TXC_CMDRead() & 0x0F));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void M132Power(void) {
|
||||
GenTXCPower();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x5FFF, M132Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, M132Write);
|
||||
}
|
||||
|
||||
void Mapper132_Init(CartInfo *info) {
|
||||
if (CheckHash(info) != 0) return;
|
||||
GenTXC_Init(info, M132Sync, 0);
|
||||
info->Power = M132Power;
|
||||
}
|
||||
|
||||
/* --------------- Mapper 173 --------------- */
|
||||
|
||||
static void M173Sync(void) {
|
||||
setprg32(0x8000, 0);
|
||||
if (CHRsize[0] > 0x2000)
|
||||
setchr8(((txc.output & 0x01) | (txc.Y ? 0x02 : 0x00) | ((txc.output & 2) << 0x01)));
|
||||
else
|
||||
setchr8(0);
|
||||
}
|
||||
|
||||
void Mapper173_Init(CartInfo *info) {
|
||||
GenTXC_Init(info, M173Sync, 0);
|
||||
info->Power = M132Power;
|
||||
}
|
||||
|
||||
/* ---------------- Joy/Van ----------------- */
|
||||
|
||||
/* --------------- Mapper 136 --------------- */
|
||||
|
||||
static void M136Sync(void) {
|
||||
setprg32(0x8000, (txc.output >> 4) & 0x01);
|
||||
setchr8(txc.output & 0x07);
|
||||
}
|
||||
|
||||
static DECLFW(M136Write) {
|
||||
TXC_CMDWrite(A, V & 0x3F);
|
||||
}
|
||||
|
||||
static DECLFR(M136Read) {
|
||||
uint8 ret = X.DB;
|
||||
if ((A & 0x103) == 0x100)
|
||||
ret = ((X.DB & 0xC0) | (TXC_CMDRead() & 0x3F));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void M136Power(void) {
|
||||
GenTXCPower();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x5FFF, M136Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, M136Write);
|
||||
}
|
||||
|
||||
void Mapper136_Init(CartInfo *info) {
|
||||
GenTXC_Init(info, M136Sync, 1);
|
||||
info->Power = M136Power;
|
||||
}
|
||||
|
||||
/* --------------- Mapper 147 --------------- */
|
||||
|
||||
static void M147Sync(void) {
|
||||
setprg32(0x8000, ((txc.output >> 4) & 0x02) | (txc.output & 0x01));
|
||||
setchr8((txc.output >> 1) & 0x0F);
|
||||
}
|
||||
|
||||
static DECLFW(M147Write) {
|
||||
TXC_CMDWrite(A, ((V >> 2) & 0x3F) | ((V << 6) & 0xC0));
|
||||
}
|
||||
|
||||
static DECLFR(M147Read) {
|
||||
uint8 ret = X.DB;
|
||||
if ((A & 0x103) == 0x100) {
|
||||
uint8 value = TXC_CMDRead();
|
||||
ret = ((value << 2) & 0xFC) | ((value >> 6) & 0x03);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void M147Power(void) {
|
||||
GenTXCPower();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x5FFF, M147Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, M147Write);
|
||||
}
|
||||
|
||||
void Mapper147_Init(CartInfo *info) {
|
||||
GenTXC_Init(info, M147Sync, 1);
|
||||
info->Power = M147Power;
|
||||
}
|
||||
|
||||
/* --------------- Mapper 172 --------------- */
|
||||
|
||||
static void M172Sync(void) {
|
||||
setprg32(0x8000, 0);
|
||||
setchr8(txc.output);
|
||||
setmirror(txc.invert ? 1 : 0);
|
||||
}
|
||||
|
||||
static uint8 GetValue(uint8 value) {
|
||||
return (((value << 5) & 0x20) | ((value << 3) & 0x10) | ((value << 1) & 0x08) |
|
||||
((value >> 1) & 0x04) | ((value >> 3) & 0x02) | ((value >> 5) & 0x01));
|
||||
}
|
||||
|
||||
static DECLFW(M172Write) {
|
||||
TXC_CMDWrite(A, GetValue(V));
|
||||
}
|
||||
|
||||
static DECLFR(M172Read) {
|
||||
uint8 ret = X.DB;
|
||||
if ((A & 0x103) == 0x100)
|
||||
ret = (X.DB & 0xC0) | GetValue(TXC_CMDRead());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void M172Power(void) {
|
||||
GenTXCPower();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x5FFF, M172Read);
|
||||
SetWriteHandler(0x4100, 0xFFFF, M172Write);
|
||||
}
|
||||
|
||||
void Mapper172_Init(CartInfo *info) {
|
||||
GenTXC_Init(info, M172Sync, 1);
|
||||
info->Power = M172Power;
|
||||
}
|
||||
|
||||
/* === LEGACY MAPPER IMPLEMENTATION === */
|
||||
|
||||
static uint8 reg[4], cmd, is172, is173;
|
||||
|
||||
static SFORMAT UNL22211StateRegs[] =
|
||||
{
|
||||
{ reg, 4, "REGS" },
|
||||
{ &cmd, 1, "CMD" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void UNL22211Sync(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;
|
||||
UNL22211Sync();
|
||||
}
|
||||
|
||||
static DECLFR(UNL22211ReadLo) {
|
||||
return (reg[1] ^ reg[2]) | (is173 ? 0x01 : 0x40);
|
||||
#if 0
|
||||
if(reg[3])
|
||||
return reg[2];
|
||||
else
|
||||
return X.DB;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void UNL22211Power(void) {
|
||||
UNL22211Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x4100, 0x4100, UNL22211ReadLo);
|
||||
SetWriteHandler(0x4100, 0x4103, UNL22211WriteLo);
|
||||
SetWriteHandler(0x8000, 0xFFFF, UNL22211WriteHi);
|
||||
}
|
||||
|
||||
static void UNL22211StateRestore(int version) {
|
||||
UNL22211Sync();
|
||||
}
|
||||
|
||||
void UNL22211_Init(CartInfo *info) {
|
||||
is172 = 0;
|
||||
is173 = 0;
|
||||
info->Power = UNL22211Power;
|
||||
GameStateRestore = UNL22211StateRestore;
|
||||
AddExState(&UNL22211StateRegs, ~0, 0, 0);
|
||||
}
|
||||
@@ -81,7 +81,6 @@ static unsigned turbo_delay = 0;
|
||||
static unsigned input_type[MAX_PLAYERS + 1] = {0}; /* 4-players + famicom expansion */
|
||||
enum RetroZapperInputModes{RetroLightgun, RetroMouse, RetroPointer};
|
||||
static enum RetroZapperInputModes zappermode = RetroLightgun;
|
||||
static unsigned show_advance_sound_options;
|
||||
|
||||
/* emulator-specific variables */
|
||||
|
||||
@@ -2215,7 +2214,7 @@ bool retro_load_game(const struct retro_game_info *game)
|
||||
FCEU_printf(" Loading custom palette: %s%cnes.pal\n", dir, slash);
|
||||
|
||||
/* Save region and dendy mode for region-auto detect */
|
||||
systemRegion = (dendy << 1) | retro_get_region() & 1;
|
||||
systemRegion = (dendy << 1) | (retro_get_region() & 1);
|
||||
|
||||
retro_set_custom_palette();
|
||||
FCEUD_SoundToggle();
|
||||
|
||||
@@ -396,7 +396,7 @@ void FCEU_MemoryRand(uint8 *ptr, uint32 size)
|
||||
*ptr = (x & 1) ? 0x55 : 0xAA; /* F-15 Sity War HISCORE is screwed... */
|
||||
/* 1942 SCORE/HISCORE is screwed... */
|
||||
#endif
|
||||
uint8_t v;
|
||||
uint8_t v = 0;
|
||||
switch (option_ramstate)
|
||||
{
|
||||
case 0: v = 0xff; break;
|
||||
|
||||
@@ -359,6 +359,14 @@
|
||||
{0xa3ac0095, 189, -1}, /* Street Fighter II - The World Warrior (Unl) [a2].nes */
|
||||
{0xeced5899, 121, -1}, /* Ultimate Mortal Kombat 4 (Unl) [!].nes */
|
||||
|
||||
/* TXC / Sachen / JoyVan */
|
||||
|
||||
/* This cart does not work anymore with latest mapper implementation.
|
||||
* This will be run using alternate mapper using override in m132 */
|
||||
{0x2a5f4c5a, 132, -1}, /* /Zhan Guo Si Chuan Sheng (C&E) (Unl).nes */
|
||||
|
||||
{0x0acfc3cd, 132, -1}, /* Mahjong Block (MGC-008) (Unl) [!].nes */
|
||||
|
||||
/* ines mappers that uses iNes 2.0 numbers */
|
||||
|
||||
{0xf6bd8e31, 281, 0}, /* 1997 Super HIK 4-in-1 (JY-052) [p1][!] */
|
||||
|
||||
32
src/ines.c
32
src/ines.c
@@ -505,7 +505,7 @@ static BMAPPINGLocal bmap[] = {
|
||||
{(uint8_t*)"FDS UNROM BOARD", 108, Mapper108_Init},
|
||||
/* {(uint8_t*)"", 109, Mapper109_Init}, */
|
||||
/* {(uint8_t*)"", 110, Mapper110_Init}, */
|
||||
/* {(uint8_t*)"", 111, Mapper111_Init}, */
|
||||
{(uint8_t*)"Cheapocabra", 111, Mapper111_Init},
|
||||
{(uint8_t*)"ASDER/NTDEC BOARD", 112, Mapper112_Init},
|
||||
{(uint8_t*)"HACKER/SACHEN BOARD", 113, Mapper113_Init},
|
||||
{(uint8_t*)"MMC3 SG PROT. A", 114, Mapper114_Init},
|
||||
@@ -526,12 +526,12 @@ static BMAPPINGLocal bmap[] = {
|
||||
/* {(uint8_t*)"", 129, Mapper129_Init}, */
|
||||
/* {(uint8_t*)"", 130, Mapper130_Init}, */
|
||||
/* {(uint8_t*)"", 131, Mapper131_Init}, */
|
||||
{(uint8_t*)"TXC/MGENIUS 22111", 132, UNL22211_Init},
|
||||
{(uint8_t*)"TXC/UNL-22211", 132, Mapper132_Init},
|
||||
{(uint8_t*)"SA72008", 133, SA72008_Init},
|
||||
/* {(uint8_t*)"MMC3 BMC PIRATE", 134, Mapper134_Init}, */
|
||||
{(uint8_t*)"MMC3 BMC PIRATE", 134, Bs5652_Init},
|
||||
/* {(uint8_t*)"", 135, Mapper135_Init}, */
|
||||
{(uint8_t*)"TCU02", 136, TCU02_Init},
|
||||
{(uint8_t*)"Sachen 3011", 136, Mapper136_Init},
|
||||
{(uint8_t*)"S8259D", 137, S8259D_Init},
|
||||
{(uint8_t*)"S8259B", 138, S8259B_Init},
|
||||
{(uint8_t*)"S8259C", 139, S8259C_Init},
|
||||
@@ -542,10 +542,10 @@ static BMAPPINGLocal bmap[] = {
|
||||
{(uint8_t*)"AGCI 50282", 144, Mapper144_Init},
|
||||
{(uint8_t*)"SA72007", 145, SA72007_Init},
|
||||
{(uint8_t*)"SA0161M", 146, SA0161M_Init},
|
||||
{(uint8_t*)"TCU01", 147, TCU01_Init},
|
||||
{(uint8_t*)"Sachen 3018 board", 147, Mapper147_Init},
|
||||
{(uint8_t*)"SA0037", 148, SA0037_Init},
|
||||
{(uint8_t*)"SA0036", 149, SA0036_Init},
|
||||
{(uint8_t*)"S74LS374N", 150, S74LS374N_Init},
|
||||
{(uint8_t*)"SA-015/SA-630", 150, S74LS374N_Init},
|
||||
{(uint8_t*)"", 151, Mapper151_Init},
|
||||
{(uint8_t*)"", 152, Mapper152_Init},
|
||||
{(uint8_t*)"BANDAI SRAM", 153, Mapper153_Init}, /* Bandai board 16 with SRAM instead of EEPROM */
|
||||
@@ -567,8 +567,8 @@ static BMAPPINGLocal bmap[] = {
|
||||
/* {(uint8_t*)"", 169, Mapper169_Init}, */
|
||||
{(uint8_t*)"", 170, Mapper170_Init},
|
||||
{(uint8_t*)"", 171, Mapper171_Init},
|
||||
{(uint8_t*)"", 172, Mapper172_Init},
|
||||
{(uint8_t*)"", 173, Mapper173_Init},
|
||||
{(uint8_t*)"Super Mega P-4070", 172, Mapper172_Init},
|
||||
{(uint8_t*)"Idea-Tek ET.xx", 173, Mapper173_Init},
|
||||
/* {(uint8_t*)"", 174, Mapper174_Init}, */
|
||||
{(uint8_t*)"", 175, Mapper175_Init},
|
||||
{(uint8_t*)"BMCFK23C", 176, BMCFK23C_Init}, /* zero 26-may-2012 - well, i have some WXN junk games that use 176 for instance ????. i dont know what game uses this BMCFK23C as mapper 176. we'll have to make a note when we find it. */
|
||||
@@ -638,7 +638,7 @@ static BMAPPINGLocal bmap[] = {
|
||||
{(uint8_t*)"", 240, Mapper240_Init},
|
||||
{(uint8_t*)"", 241, Mapper241_Init},
|
||||
{(uint8_t*)"", 242, Mapper242_Init},
|
||||
{(uint8_t*)"S74LS374NA", 243, S74LS374NA_Init},
|
||||
{(uint8_t*)"SA-020A", 243, S74LS374N_Init},
|
||||
{(uint8_t*)"DECATHLON", 244, Mapper244_Init},
|
||||
{(uint8_t*)"", 245, Mapper245_Init},
|
||||
{(uint8_t*)"FONG SHEN BANG", 246, Mapper246_Init},
|
||||
@@ -668,9 +668,22 @@ static BMAPPINGLocal bmap[] = {
|
||||
{(uint8_t*)"Realtec 8031", 390, Mapper390_Init },
|
||||
{(uint8_t*)"60-1064-16L (FDS)", 538, Mapper538_Init },
|
||||
{(uint8_t*)"LittleCom 160-in-1", 541, Mapper541_Init },
|
||||
{(uint8_t*)"8-in-1 JY-119", 267, Mapper267_Init },
|
||||
{(uint8_t*)"8-in-1 JY-119", 267, Mapper267_Init },
|
||||
{(uint8_t*)"MMC3 BMC PIRATE", 294, Bs5652_Init}, /* nesdev redirects this as mapper 134 */
|
||||
{(uint8_t*)"TXC 01-22110-000", 297, Mapper297_Init},
|
||||
{(uint8_t*)"Bitcorp 31-in-1", 360, Mapper360_Init},
|
||||
{(uint8_t*)"Sachen 3014", 533, Mapper533_Init},
|
||||
{(uint8_t*)"830928C", 382, Mapper382_Init},
|
||||
{(uint8_t*)"NJ064", 534, Mapper534_Init},
|
||||
{(uint8_t*)"Kid Ikarus (FDS)", 539, Mapper539_Init},
|
||||
{(uint8_t*)"5-in-1 (CH-501)", 543, Mapper543_Init},
|
||||
{(uint8_t*)"", 550, Mapper550_Init},
|
||||
{(uint8_t*)"Brilliant Com Cocoma Pack", 516, Mapper516_Init},
|
||||
{(uint8_t*)"SB-5013/GCL8050/841242C", 359, Mapper359_Init},
|
||||
{(uint8_t*)"82112C", 540, Mapper540_Init},
|
||||
{(uint8_t*)"7-in-1 Rockman (JY-208)", 356, Mapper356_Init},
|
||||
{(uint8_t*)"Games Xplosion 121-in-1", 269, Mapper269_Init},
|
||||
{(uint8_t*)"Super Mario Family", 353, Mapper353_Init},
|
||||
|
||||
/* UNIF to NES 2.0 BOARDS */
|
||||
|
||||
@@ -1036,6 +1049,7 @@ static int iNES_Init(int num) {
|
||||
SetupCartCHRMapping(0, VROM, CHRRAMSize, 1);
|
||||
AddExState(VROM, CHRRAMSize, 0, "CHRR");
|
||||
}
|
||||
FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024);
|
||||
}
|
||||
if (head.ROM_type & 8)
|
||||
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
|
||||
|
||||
17
src/ines.h
17
src/ines.h
@@ -136,6 +136,7 @@ void Mapper105_Init(CartInfo *);
|
||||
void Mapper106_Init(CartInfo *);
|
||||
void Mapper107_Init(CartInfo *);
|
||||
void Mapper108_Init(CartInfo *);
|
||||
void Mapper111_Init(CartInfo *);
|
||||
void Mapper112_Init(CartInfo *);
|
||||
void Mapper113_Init(CartInfo *);
|
||||
void Mapper114_Init(CartInfo *);
|
||||
@@ -147,9 +148,12 @@ void Mapper120_Init(CartInfo *);
|
||||
void Mapper121_Init(CartInfo *);
|
||||
void Mapper125_Init(CartInfo *);
|
||||
void Mapper126_Init(CartInfo *);
|
||||
void Mapper132_Init(CartInfo *);
|
||||
void Mapper134_Init(CartInfo *);
|
||||
void Mapper136_Init(CartInfo *);
|
||||
void Mapper140_Init(CartInfo *);
|
||||
void Mapper144_Init(CartInfo *);
|
||||
void Mapper147_Init(CartInfo *);
|
||||
void Mapper151_Init(CartInfo *);
|
||||
void Mapper152_Init(CartInfo *);
|
||||
void Mapper153_Init(CartInfo *);
|
||||
@@ -244,14 +248,27 @@ void NC7000M_Init(CartInfo *);
|
||||
void J2282_Init(CartInfo *);
|
||||
|
||||
void Mapper267_Init(CartInfo *);
|
||||
void Mapper269_Init(CartInfo *);
|
||||
void Mapper288_Init(CartInfo *);
|
||||
void Mapper297_Init(CartInfo *);
|
||||
void Mapper353_Init(CartInfo *);
|
||||
void Mapper356_Init(CartInfo *);
|
||||
void Mapper357_Init(CartInfo *);
|
||||
void Mapper359_Init(CartInfo *);
|
||||
void Mapper360_Init(CartInfo *);
|
||||
void Mapper372_Init(CartInfo *);
|
||||
void Mapper374_Init(CartInfo *);
|
||||
void Mapper382_Init(CartInfo *);
|
||||
void Mapper381_Init(CartInfo *);
|
||||
void Mapper390_Init(CartInfo *);
|
||||
void Mapper516_Init(CartInfo *);
|
||||
void Mapper533_Init(CartInfo *);
|
||||
void Mapper534_Init(CartInfo *);
|
||||
void Mapper538_Init(CartInfo *);
|
||||
void Mapper539_Init(CartInfo *);
|
||||
void Mapper540_Init(CartInfo *);
|
||||
void Mapper541_Init(CartInfo *);
|
||||
void Mapper543_Init(CartInfo *);
|
||||
void Mapper550_Init(CartInfo *);
|
||||
|
||||
#endif
|
||||
|
||||
18
src/unif.c
18
src/unif.c
@@ -39,6 +39,7 @@
|
||||
#include "fceu-memory.h"
|
||||
#include "input.h"
|
||||
#include "md5.h"
|
||||
#include "crc32.h"
|
||||
|
||||
#include "string/stdstring.h"
|
||||
|
||||
@@ -311,7 +312,7 @@ static int SetBoardName(FCEUFILE *fp) {
|
||||
FCEU_fread(boardname, 1, uchead.info, fp);
|
||||
boardname[uchead.info] = 0;
|
||||
/* strip whitespaces */
|
||||
boardname = string_trim_whitespace(boardname);
|
||||
boardname = string_trim_whitespace((char const*)boardname);
|
||||
FCEU_printf(" Board name: %s\n", boardname);
|
||||
sboardname = boardname;
|
||||
if (!memcmp(boardname, "NES-", 4) || !memcmp(boardname, "UNL-", 4) ||
|
||||
@@ -418,7 +419,7 @@ static BMAPPING bmap[] = {
|
||||
{ "12-IN-1", 331, BMC12IN1_Init, 0 },
|
||||
{ "13in1JY110", 295, BMC13in1JY110_Init, 0 },
|
||||
{ "190in1", 300, BMC190in1_Init, 0 },
|
||||
{ "22211", 132, UNL22211_Init, 0 },
|
||||
{ "22211", 132, Mapper132_Init, 0 },
|
||||
{ "3D-BLOCK", 355, UNL3DBlock_Init, 0 },
|
||||
{ "411120-C", 287, BMC411120C_Init, 0 },
|
||||
{ "42in1ResetSwitch", 233, Mapper233_Init, 0 },
|
||||
@@ -493,7 +494,7 @@ static BMAPPING bmap[] = {
|
||||
{ "PEC-586", NO_INES, UNLPEC586Init, 0 },
|
||||
{ "RROM", 0, NROM_Init, 0 },
|
||||
{ "RROM-128", 0, NROM_Init, 0 },
|
||||
{ "SA-002", 136, TCU02_Init, 0 },
|
||||
{ "SA-002", 136, Mapper136_Init, 0 },
|
||||
{ "SA-0036", 149, SA0036_Init, 0 },
|
||||
{ "SA-0037", 148, SA0037_Init, 0 },
|
||||
{ "SA-009", 160, SA009_Init, 0 },
|
||||
@@ -520,7 +521,7 @@ static BMAPPING bmap[] = {
|
||||
{ "SSS-NROM-256", NO_INES, SSSNROM_Init, 0 },
|
||||
{ "SUNSOFT_UNROM", 93, SUNSOFT_UNROM_Init, 0 }, /* fix me, real pcb name, real pcb type */
|
||||
{ "Sachen-74LS374N", 150, S74LS374N_Init, 0 },
|
||||
{ "Sachen-74LS374NA", 243, S74LS374NA_Init, 0 }, /* seems to be custom mapper */
|
||||
{ "Sachen-74LS374NA", 243, S74LS374N_Init, 0 }, /* seems to be custom mapper */
|
||||
{ "Sachen-8259A", 141, S8259A_Init, 0 },
|
||||
{ "Sachen-8259B", 138, S8259B_Init, 0 },
|
||||
{ "Sachen-8259C", 139, S8259C_Init, 0 },
|
||||
@@ -532,7 +533,7 @@ static BMAPPING bmap[] = {
|
||||
{ "T-230", 529, UNLT230_Init, 0 },
|
||||
{ "T-262", 265, BMCT262_Init, 0 },
|
||||
{ "TBROM", 4, TBROM_Init, 0 },
|
||||
{ "TC-U01-1.5M", 147, TCU01_Init, 0 },
|
||||
{ "TC-U01-1.5M", 147, Mapper147_Init, 0 },
|
||||
{ "TEK90", 90, Mapper90_Init, 0 },
|
||||
{ "TEROM", 4, TEROM_Init, 0 },
|
||||
{ "TF1201", 298, UNLTF1201_Init, 0 },
|
||||
@@ -605,6 +606,9 @@ static BMAPPING bmap[] = {
|
||||
{ "GN-26", 344, BMCGN26_Init, 0 },
|
||||
{ "KG256", NO_INES,KG256_Init, 0 },
|
||||
{ "T4A54A", 134, Bs5652_Init, 0 },
|
||||
{ "WX-KB4K", 134, Bs5652_Init, 0 },
|
||||
{ "SB-5013", 359, Mapper359_Init, 0 },
|
||||
{ "82112C", 540, Mapper540_Init, 0 },
|
||||
|
||||
#ifdef COPYFAMI
|
||||
{ "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 },
|
||||
@@ -797,8 +801,8 @@ int UNIFLoad(const char *name, FCEUFILE *fp) {
|
||||
if (UNIFCart.mapper)
|
||||
FCEU_printf(" [Unif] Mapper: %d\n", UNIFCart.mapper);
|
||||
FCEU_printf(" [Unif] SubMapper: %d\n", UNIFCart.submapper);
|
||||
FCEU_printf(" [Unif] PRG ROM: %ull KiB\n", UNIF_PRGROMSize / 1024);
|
||||
FCEU_printf(" [Unif] CHR ROM: %ull KiB\n", UNIF_CHRROMSize / 1024);
|
||||
FCEU_printf(" [Unif] PRG ROM: %u KiB\n", UNIF_PRGROMSize / 1024);
|
||||
FCEU_printf(" [Unif] CHR ROM: %u KiB\n", UNIF_CHRROMSize / 1024);
|
||||
|
||||
GameInterface = UNIFGI;
|
||||
return 1;
|
||||
|
||||
@@ -94,8 +94,6 @@ void Super24_Init(CartInfo *info);
|
||||
void Supervision16_Init(CartInfo *info);
|
||||
void TBROM_Init(CartInfo *info);
|
||||
void TCA01_Init(CartInfo *info);
|
||||
void TCU01_Init(CartInfo *info);
|
||||
void TCU02_Init(CartInfo *info);
|
||||
void TEROM_Init(CartInfo *info);
|
||||
void TFROM_Init(CartInfo *info);
|
||||
void TGROM_Init(CartInfo *info);
|
||||
|
||||
Reference in New Issue
Block a user