38
src/boards/218.c
Normal file
38
src/boards/218.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* 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"
|
||||||
|
#include "../ines.h"
|
||||||
|
|
||||||
|
static uint8 mirror;
|
||||||
|
static uint8 mask;
|
||||||
|
|
||||||
|
static void M218Power(void) {
|
||||||
|
setchr8(0);
|
||||||
|
setprg32(0x8000, 0);
|
||||||
|
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper218_Init(CartInfo* info) {
|
||||||
|
if (head.ROM_type & 0x08)
|
||||||
|
SetupCartMirroring(MI_0 + (head.ROM_type & 0x01), 1, NULL);
|
||||||
|
SetupCartCHRMapping(0, NTARAM, 2048, 1);
|
||||||
|
info->Power = M218Power;
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ static uint32 WRAMSIZE;
|
|||||||
static uint8 mmc3_reg[8];
|
static uint8 mmc3_reg[8];
|
||||||
static uint8 exRegs[8];
|
static uint8 exRegs[8];
|
||||||
static uint8 pointer;
|
static uint8 pointer;
|
||||||
static uint8 locked;
|
|
||||||
static uint8 readDIP;
|
static uint8 readDIP;
|
||||||
static uint16 prgAND;
|
static uint16 prgAND;
|
||||||
static uint16 chrAND;
|
static uint16 chrAND;
|
||||||
@@ -57,15 +56,15 @@ static SFORMAT BS110_StateRegs[] =
|
|||||||
|
|
||||||
int BS110GetPRGBank(int bank)
|
int BS110GetPRGBank(int bank)
|
||||||
{
|
{
|
||||||
if (~bank & 1 && (pointer & 0x40)) bank ^= 2;
|
if ((~bank & 1) && (pointer & 0x40)) bank ^= 2;
|
||||||
return bank & 2 ? 0xFE | bank & 1 : mmc3_reg[6 | bank & 1];
|
return (bank & 2) ? 0xFE | (bank & 1) : mmc3_reg[6 | (bank & 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void BS110SyncPRG_GNROM(int A14, int AND, int OR) {
|
void BS110SyncPRG_GNROM(int A14, int AND, int OR) {
|
||||||
setprg8(0x8000, (BS110GetPRGBank(0) &~A14) &AND | OR);
|
setprg8(0x8000, ((BS110GetPRGBank(0) &~A14) &AND) | OR);
|
||||||
setprg8(0xA000, (BS110GetPRGBank(1) &~A14) &AND | OR);
|
setprg8(0xA000, ((BS110GetPRGBank(1) &~A14) &AND) | OR);
|
||||||
setprg8(0xC000, (BS110GetPRGBank(0) | A14) &AND | OR);
|
setprg8(0xC000, ((BS110GetPRGBank(0) | A14) &AND) | OR);
|
||||||
setprg8(0xE000, (BS110GetPRGBank(1) | A14) &AND | OR);
|
setprg8(0xE000, ((BS110GetPRGBank(1) | A14) &AND) | OR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BS110CW(uint32 A, uint8 V) {
|
static void BS110CW(uint32 A, uint8 V) {
|
||||||
@@ -83,18 +82,18 @@ static void BS110PW(uint32 A, uint8 V) {
|
|||||||
uint8 block = (exRegs[1] & 3) << 4;
|
uint8 block = (exRegs[1] & 3) << 4;
|
||||||
if ((exRegs[1] >> 3) & 0x01)
|
if ((exRegs[1] >> 3) & 0x01)
|
||||||
{
|
{
|
||||||
setprg8(0x8000, (BS110GetPRGBank(0)) & mask | block);
|
setprg8(0x8000, ((BS110GetPRGBank(0)) & mask) | block);
|
||||||
setprg8(0xA000, (BS110GetPRGBank(1)) & mask | block);
|
setprg8(0xA000, ((BS110GetPRGBank(1)) & mask) | block);
|
||||||
setprg8(0xC000, (BS110GetPRGBank(0)) & mask | block);
|
setprg8(0xC000, ((BS110GetPRGBank(0)) & mask) | block);
|
||||||
setprg8(0xE000, (BS110GetPRGBank(1)) & mask | block);
|
setprg8(0xE000, ((BS110GetPRGBank(1)) & mask) | block);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
setprg8(0x8000, (BS110GetPRGBank(0)) & mask | block);
|
setprg8(0x8000, ((BS110GetPRGBank(0)) & mask) | block);
|
||||||
setprg8(0xA000, (BS110GetPRGBank(1)) & mask | block);
|
setprg8(0xA000, ((BS110GetPRGBank(1)) & mask) | block);
|
||||||
setprg8(0xC000, (BS110GetPRGBank(0) | 2) & mask | block);
|
setprg8(0xC000, ((BS110GetPRGBank(0) | 2) & mask) | block);
|
||||||
setprg8(0xE000, (BS110GetPRGBank(1) | 2) & mask | block);
|
setprg8(0xE000, ((BS110GetPRGBank(1) | 2) & mask) | block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -70,15 +70,15 @@ void Bs5652AnalyzeReg()
|
|||||||
|
|
||||||
int Bs5652GetPRGBank(int bank)
|
int Bs5652GetPRGBank(int bank)
|
||||||
{
|
{
|
||||||
if (~bank & 1 && (pointer & 0x40)) bank ^= 2;
|
if ((~bank & 1) && (pointer & 0x40)) bank ^= 2;
|
||||||
return bank & 2 ? 0xFE | bank & 1 : mmc3_reg[6 | bank & 1];
|
return (bank & 2) ? 0xFE | (bank & 1) : mmc3_reg[6 | (bank & 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bs5652SyncPRG_GNROM(int A14, int AND, int OR) {
|
void Bs5652SyncPRG_GNROM(int A14, int AND, int OR) {
|
||||||
setprg8(0x8000, (Bs5652GetPRGBank(0) &~A14) &AND | OR);
|
setprg8(0x8000, ((Bs5652GetPRGBank(0) &~A14) &AND) | OR);
|
||||||
setprg8(0xA000, (Bs5652GetPRGBank(1) &~A14) &AND | OR);
|
setprg8(0xA000, ((Bs5652GetPRGBank(1) &~A14) &AND) | OR);
|
||||||
setprg8(0xC000, (Bs5652GetPRGBank(0) | A14) &AND | OR);
|
setprg8(0xC000, ((Bs5652GetPRGBank(0) | A14) &AND) | OR);
|
||||||
setprg8(0xE000, (Bs5652GetPRGBank(1) | A14) &AND | OR);
|
setprg8(0xE000, ((Bs5652GetPRGBank(1) | A14) &AND) | OR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Bs5652CW(uint32 A, uint8 V) {
|
static void Bs5652CW(uint32 A, uint8 V) {
|
||||||
|
|||||||
@@ -40,17 +40,17 @@ static void Sync(void)
|
|||||||
r = 1;
|
r = 1;
|
||||||
if ((regs[1] >> 4) & 0x01)
|
if ((regs[1] >> 4) & 0x01)
|
||||||
{
|
{
|
||||||
setprg16(0x8000, regs[1] & 0x07 | (r) << 3);
|
setprg16(0x8000, (regs[1] & 0x07) | (r << 3));
|
||||||
setprg16(0xC000, regs[1] & 0x07 | (r) << 3);
|
setprg16(0xC000, (regs[1] & 0x07) | (r << 3));
|
||||||
setchr8(regs[0] & 0x07 | (r) << 3);
|
setchr8((regs[0] & 0x07) | (r << 3));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setprg32(0x8000, (regs[1] >> 1) & 0x03 | (r) << 2);
|
setprg32(0x8000, ((regs[1] >> 1) & 0x03) | (r << 2));
|
||||||
setchr8(regs[2] & 0x01 | (r) << 3);
|
setchr8((regs[2] & 0x01) | (r << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
mirr = (((regs[0] >> 4 & 0x1)));
|
mirr = (((regs[0] >> 4) & 0x1));
|
||||||
|
|
||||||
if (mirr)
|
if (mirr)
|
||||||
setmirror(0);
|
setmirror(0);
|
||||||
|
|||||||
@@ -64,22 +64,22 @@ void NC7000MAnalyzeReg()
|
|||||||
prgAND = (reg & 0x08 ? 0x0F : 0x1F);
|
prgAND = (reg & 0x08 ? 0x0F : 0x1F);
|
||||||
chrAND = (reg & 0x40 ? 0x7F : 0xFF);
|
chrAND = (reg & 0x40 ? 0x7F : 0xFF);
|
||||||
prgOR = (reg << 4 & 0x30);
|
prgOR = (reg << 4 & 0x30);
|
||||||
chrOR = (reg << 3 & 0x080 | reg & 0x100);
|
chrOR = ((reg << 3) & 0x080) | (reg & 0x100);
|
||||||
nrom = (reg & 0x20);
|
nrom = (reg & 0x20);
|
||||||
nrom256 = (reg & 0x04);
|
nrom256 = (reg & 0x04);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NC7000MGetPRGBank(int bank)
|
int NC7000MGetPRGBank(int bank)
|
||||||
{
|
{
|
||||||
if (~bank & 1 && (pointer & 0x40)) bank ^= 2;
|
if ((~bank & 1) && (pointer & 0x40)) bank ^= 2;
|
||||||
return bank & 2 ? 0xFE | bank & 1 : mmc3_reg[6 | bank & 1];
|
return (bank & 2) ? 0xFE | (bank & 1) : mmc3_reg[6 | (bank & 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NC7000MSyncPRG_GNROM(int A14, int AND, int OR) {
|
void NC7000MSyncPRG_GNROM(int A14, int AND, int OR) {
|
||||||
setprg8(0x8000, (NC7000MGetPRGBank(0) &~A14) &AND | OR);
|
setprg8(0x8000, ((NC7000MGetPRGBank(0) &~A14) &AND) | OR);
|
||||||
setprg8(0xA000, (NC7000MGetPRGBank(1) &~A14) &AND | OR);
|
setprg8(0xA000, ((NC7000MGetPRGBank(1) &~A14) &AND) | OR);
|
||||||
setprg8(0xC000, (NC7000MGetPRGBank(0) | A14) &AND | OR);
|
setprg8(0xC000, ((NC7000MGetPRGBank(0) | A14) &AND) | OR);
|
||||||
setprg8(0xE000, (NC7000MGetPRGBank(1) | A14) &AND | OR);
|
setprg8(0xE000, ((NC7000MGetPRGBank(1) | A14) &AND) | OR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NC7000MCW(uint32 A, uint8 V) {
|
static void NC7000MCW(uint32 A, uint8 V) {
|
||||||
@@ -124,7 +124,7 @@ static DECLFW(NC7000MWriteHi) {
|
|||||||
static DECLFW(NC7000MWriteLo) {
|
static DECLFW(NC7000MWriteLo) {
|
||||||
|
|
||||||
if (!(reg & 0x80)) {
|
if (!(reg & 0x80)) {
|
||||||
reg = V | A & 0x100;
|
reg = V | (A & 0x100);
|
||||||
NC7000MAnalyzeReg();
|
NC7000MAnalyzeReg();
|
||||||
FixMMC3PRG(MMC3_cmd);
|
FixMMC3PRG(MMC3_cmd);
|
||||||
FixMMC3CHR(MMC3_cmd);
|
FixMMC3CHR(MMC3_cmd);
|
||||||
@@ -134,10 +134,6 @@ static DECLFW(NC7000MWriteLo) {
|
|||||||
WRAM[A - 0x6000] = V;
|
WRAM[A - 0x6000] = V;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static DECLFR(NC7000MReadHi)
|
|
||||||
{
|
|
||||||
return CartBR(A);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NC7000MPower(void) {
|
static void NC7000MPower(void) {
|
||||||
mmc3_reg[0] = 0x00; mmc3_reg[1] = 0x02;
|
mmc3_reg[0] = 0x00; mmc3_reg[1] = 0x02;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ static void (*WSync)(void);
|
|||||||
static readfunc defread;
|
static readfunc defread;
|
||||||
static uint8 *WRAM = NULL;
|
static uint8 *WRAM = NULL;
|
||||||
static uint32 WRAMSIZE;
|
static uint32 WRAMSIZE;
|
||||||
|
static uint32 hasBattery;
|
||||||
|
|
||||||
static DECLFW(LatchWrite) {
|
static DECLFW(LatchWrite) {
|
||||||
latche = A;
|
latche = A;
|
||||||
@@ -65,6 +66,7 @@ static void Latch_Init(CartInfo *info, void (*proc)(void), readfunc func, uint16
|
|||||||
addrreg0 = adr0;
|
addrreg0 = adr0;
|
||||||
addrreg1 = adr1;
|
addrreg1 = adr1;
|
||||||
WSync = proc;
|
WSync = proc;
|
||||||
|
hasBattery = 0;
|
||||||
if (func != NULL)
|
if (func != NULL)
|
||||||
defread = func;
|
defread = func;
|
||||||
else
|
else
|
||||||
@@ -77,6 +79,7 @@ static void Latch_Init(CartInfo *info, void (*proc)(void), readfunc func, uint16
|
|||||||
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
|
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
|
||||||
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
|
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
|
||||||
if (info->battery) {
|
if (info->battery) {
|
||||||
|
hasBattery = 1;
|
||||||
info->SaveGame[0] = WRAM;
|
info->SaveGame[0] = WRAM;
|
||||||
info->SaveGameLen[0] = WRAMSIZE;
|
info->SaveGameLen[0] = WRAMSIZE;
|
||||||
}
|
}
|
||||||
@@ -416,6 +419,12 @@ static void M227Sync(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasBattery && (latche & 0x80) == 0x80)
|
||||||
|
/* CHR-RAM write protect hack, needed for some multicarts */
|
||||||
|
SetupCartCHRMapping(0, CHRptr[0], 0x2000, 0);
|
||||||
|
else
|
||||||
|
SetupCartCHRMapping(0, CHRptr[0], 0x2000, 1);
|
||||||
|
|
||||||
setmirror(((latche >> 1) & 1) ^ 1);
|
setmirror(((latche >> 1) & 1) ^ 1);
|
||||||
setchr8(0);
|
setchr8(0);
|
||||||
setprg8r(0x10, 0x6000, 0);
|
setprg8r(0x10, 0x6000, 0);
|
||||||
|
|||||||
@@ -66,15 +66,6 @@ static DECLFR(MAWRAM) {
|
|||||||
return(Page[A >> 11][A]);
|
return(Page[A >> 11][A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
static void MMC1CHR(void) {
|
||||||
if (MMC1WRAMHook8) /* Use custom wram hook, currently used for M543 */
|
if (MMC1WRAMHook8) /* Use custom wram hook, currently used for M543 */
|
||||||
MMC1WRAMHook8();
|
MMC1WRAMHook8();
|
||||||
|
|||||||
@@ -613,7 +613,7 @@ static BMAPPINGLocal bmap[] = {
|
|||||||
{(uint8_t*)"UNL-8237", 215, UNL8237_Init},
|
{(uint8_t*)"UNL-8237", 215, UNL8237_Init},
|
||||||
{(uint8_t*)"", 216, Mapper216_Init},
|
{(uint8_t*)"", 216, Mapper216_Init},
|
||||||
{(uint8_t*)"", 217, Mapper217_Init}, /* Redefined to a new Discrete BMC mapper */
|
{(uint8_t*)"", 217, Mapper217_Init}, /* Redefined to a new Discrete BMC mapper */
|
||||||
/* {(uint8_t*)"", 218, Mapper218_Init}, */
|
{(uint8_t*)"Magic Floor", 218, Mapper218_Init},
|
||||||
{(uint8_t*)"UNLA9746", 219, UNLA9746_Init},
|
{(uint8_t*)"UNLA9746", 219, UNLA9746_Init},
|
||||||
{(uint8_t*)"Debug Mapper", 220, UNLKS7057_Init},
|
{(uint8_t*)"Debug Mapper", 220, UNLKS7057_Init},
|
||||||
{(uint8_t*)"UNLN625092", 221, UNLN625092_Init},
|
{(uint8_t*)"UNLN625092", 221, UNLN625092_Init},
|
||||||
@@ -1040,7 +1040,6 @@ static int iNES_Init(int num) {
|
|||||||
default: CHRRAMSize = 8 * 1024; break;
|
default: CHRRAMSize = 8 * 1024; break;
|
||||||
}
|
}
|
||||||
iNESCart.CHRRamSize = CHRRAMSize;
|
iNESCart.CHRRamSize = CHRRAMSize;
|
||||||
FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024);
|
|
||||||
}
|
}
|
||||||
if (CHRRAMSize) { /* TODO: CHR-RAM are sometimes handled in mappers e.g. MMC1 using submapper 1/2/4 and CHR-RAM can be zero here */
|
if (CHRRAMSize) { /* TODO: CHR-RAM are sometimes handled in mappers e.g. MMC1 using submapper 1/2/4 and CHR-RAM can be zero here */
|
||||||
if ((VROM = (uint8*)malloc(CHRRAMSize)) == NULL) return 0;
|
if ((VROM = (uint8*)malloc(CHRRAMSize)) == NULL) return 0;
|
||||||
@@ -1048,8 +1047,8 @@ static int iNES_Init(int num) {
|
|||||||
UNIFchrrama = VROM;
|
UNIFchrrama = VROM;
|
||||||
SetupCartCHRMapping(0, VROM, CHRRAMSize, 1);
|
SetupCartCHRMapping(0, VROM, CHRRAMSize, 1);
|
||||||
AddExState(VROM, CHRRAMSize, 0, "CHRR");
|
AddExState(VROM, CHRRAMSize, 0, "CHRR");
|
||||||
|
FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024);
|
||||||
}
|
}
|
||||||
FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024);
|
|
||||||
}
|
}
|
||||||
if (head.ROM_type & 8)
|
if (head.ROM_type & 8)
|
||||||
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
|
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ void Mapper213_Init(CartInfo *);
|
|||||||
void Mapper214_Init(CartInfo *);
|
void Mapper214_Init(CartInfo *);
|
||||||
void Mapper216_Init(CartInfo *);
|
void Mapper216_Init(CartInfo *);
|
||||||
void Mapper217_Init(CartInfo *);
|
void Mapper217_Init(CartInfo *);
|
||||||
|
void Mapper218_Init(CartInfo *);
|
||||||
void Mapper220_Init(CartInfo *);
|
void Mapper220_Init(CartInfo *);
|
||||||
void Mapper222_Init(CartInfo *);
|
void Mapper222_Init(CartInfo *);
|
||||||
void Mapper224_Init(CartInfo *);
|
void Mapper224_Init(CartInfo *);
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ static int SetBoardName(FCEUFILE *fp) {
|
|||||||
FCEU_fread(boardname, 1, uchead.info, fp);
|
FCEU_fread(boardname, 1, uchead.info, fp);
|
||||||
boardname[uchead.info] = 0;
|
boardname[uchead.info] = 0;
|
||||||
/* strip whitespaces */
|
/* strip whitespaces */
|
||||||
boardname = string_trim_whitespace((char const*)boardname);
|
boardname = (uint8*)string_trim_whitespace((char *const)boardname);
|
||||||
FCEU_printf(" Board name: %s\n", boardname);
|
FCEU_printf(" Board name: %s\n", boardname);
|
||||||
sboardname = boardname;
|
sboardname = boardname;
|
||||||
if (!memcmp(boardname, "NES-", 4) || !memcmp(boardname, "UNL-", 4) ||
|
if (!memcmp(boardname, "NES-", 4) || !memcmp(boardname, "UNL-", 4) ||
|
||||||
|
|||||||
Reference in New Issue
Block a user