MMC1: Better work ram and battery saves support for size greater than 8K
This commit is contained in:
@@ -22,12 +22,17 @@
|
|||||||
#include "mapinc.h"
|
#include "mapinc.h"
|
||||||
|
|
||||||
static void GenMMC1Power(void);
|
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 DRegs[4];
|
||||||
static uint8 Buffer, BufferShift;
|
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 (*MMC1CHRHook4)(uint32 A, uint8 V);
|
||||||
static void (*MMC1PRGHook16)(uint32 A, uint8 V);
|
static void (*MMC1PRGHook16)(uint32 A, uint8 V);
|
||||||
@@ -52,9 +57,9 @@ static DECLFR(MAWRAM) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void MMC1CHR(void) {
|
static void MMC1CHR(void) {
|
||||||
if (mmc1opts & 4) {
|
if (WRAMSIZE > 8192) {
|
||||||
if (DRegs[0] & 0x10)
|
if (WRAMSIZE > 16384)
|
||||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 4) & 1);
|
setprg8r(0x10, 0x6000, (DRegs[1] >> 2) & 3);
|
||||||
else
|
else
|
||||||
setprg8r(0x10, 0x6000, (DRegs[1] >> 3) & 1);
|
setprg8r(0x10, 0x6000, (DRegs[1] >> 3) & 1);
|
||||||
}
|
}
|
||||||
@@ -183,24 +188,44 @@ static void MMC1CMReset(void) {
|
|||||||
MMC1PRG();
|
MMC1PRG();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DetectMMC1WRAMSize(uint32 crc32) {
|
static int DetectMMC1WRAMSize(CartInfo *info, int *saveRAM) {
|
||||||
switch (crc32) {
|
int workRAM = 8;
|
||||||
case 0xc6182024: /* Romance of the 3 Kingdoms */
|
switch (info->CRC32) {
|
||||||
case 0x2225c20f: /* Genghis Khan */
|
case 0xc6182024: /* Romance of the 3 Kingdoms */
|
||||||
case 0x4642dda6: /* Nobunaga's Ambition */
|
case 0xabbf7217: /* "" "" (J) (PRG0) */
|
||||||
case 0x29449ba9: /* "" "" (J) */
|
case 0xccf35c02: /* "" "" (J) (PRG1) */
|
||||||
case 0x2b11e0b0: /* "" "" (J) */
|
case 0x2225c20f: /* Genghis Khan */
|
||||||
case 0xb8747abf: /* Best Play Pro Yakyuu Special (J) */
|
case 0xfb69743a: /* "" "" (J) */
|
||||||
case 0xc9556b36: /* Final Fantasy I & II (J) [!] */
|
case 0x4642dda6: /* Nobunaga's Ambition */
|
||||||
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
case 0x3f7ad415: /* "" "" (J) (PRG0) */
|
||||||
return(16);
|
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->prgRam + info->prgRam_battery) / 1024;
|
||||||
|
*saveRAM = info->prgRam_battery / 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;
|
break;
|
||||||
case 0xd1e50064: /* Dezaemon */
|
}
|
||||||
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
if (workRAM > 8)
|
||||||
return(32);
|
FCEU_printf(" >8KB external WRAM present. Use NES 2.0 if you hack the ROM image.\n");
|
||||||
break;
|
|
||||||
default: return(8);
|
return workRAM;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 NWCIRQCount;
|
static uint32 NWCIRQCount;
|
||||||
@@ -258,17 +283,16 @@ void Mapper105_Init(CartInfo *info) {
|
|||||||
|
|
||||||
static void GenMMC1Power(void) {
|
static void GenMMC1Power(void) {
|
||||||
lreset = 0;
|
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);
|
SetWriteHandler(0x8000, 0xFFFF, MMC1_write);
|
||||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
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);
|
SetReadHandler(0x6000, 0x7FFF, MAWRAM);
|
||||||
SetWriteHandler(0x6000, 0x7FFF, MBWRAM);
|
SetWriteHandler(0x6000, 0x7FFF, MBWRAM);
|
||||||
setprg8r(0x10, 0x6000, 0);
|
setprg8r(0x10, 0x6000, 0);
|
||||||
@@ -285,26 +309,24 @@ static void GenMMC1Close(void) {
|
|||||||
CHRRAM = WRAM = NULL;
|
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;
|
is155 = 0;
|
||||||
|
|
||||||
info->Close = GenMMC1Close;
|
info->Close = GenMMC1Close;
|
||||||
MMC1PRGHook16 = MMC1CHRHook4 = 0;
|
MMC1PRGHook16 = MMC1CHRHook4 = 0;
|
||||||
mmc1opts = 0;
|
WRAMSIZE = wram * 1024;
|
||||||
|
NONSaveRAMSIZE = (wram - saveram) * 1024;
|
||||||
PRGmask16[0] &= (prg >> 14) - 1;
|
PRGmask16[0] &= (prg >> 14) - 1;
|
||||||
CHRmask4[0] &= (chr >> 12) - 1;
|
CHRmask4[0] &= (chr >> 12) - 1;
|
||||||
CHRmask8[0] &= (chr >> 13) - 1;
|
CHRmask8[0] &= (chr >> 13) - 1;
|
||||||
|
|
||||||
if (wram) {
|
if (WRAMSIZE) {
|
||||||
WRAM = (uint8*)FCEU_gmalloc(wram * 1024);
|
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
|
||||||
mmc1opts |= 1;
|
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
|
||||||
if (wram > 8) mmc1opts |= 4;
|
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
|
||||||
SetupCartPRGMapping(0x10, WRAM, wram * 1024, 1);
|
if (saveram) {
|
||||||
AddExState(WRAM, wram * 1024, 0, "WRAM");
|
info->SaveGame[0] = WRAM + NONSaveRAMSIZE;
|
||||||
if (battery) {
|
info->SaveGameLen[0] = saveram * 1024;
|
||||||
mmc1opts |= 2;
|
|
||||||
info->SaveGame[0] = WRAM + ((mmc1opts & 4) ? 8192 : 0);
|
|
||||||
info->SaveGameLen[0] = 8192;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!chr) {
|
if (!chr) {
|
||||||
@@ -322,13 +344,14 @@ static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mapper1_Init(CartInfo *info) {
|
void Mapper1_Init(CartInfo *info) {
|
||||||
int ws = DetectMMC1WRAMSize(info->CRC32);
|
int bs = info->battery ? 8 : 0;
|
||||||
GenMMC1Init(info, 512, 256, ws, info->battery);
|
int ws = DetectMMC1WRAMSize(info, &bs);
|
||||||
|
GenMMC1Init(info, 512, 256, ws, bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as mapper 1, without respect for WRAM enable bit. */
|
/* Same as mapper 1, without respect for WRAM enable bit. */
|
||||||
void Mapper155_Init(CartInfo *info) {
|
void Mapper155_Init(CartInfo *info) {
|
||||||
GenMMC1Init(info, 512, 256, 8, info->battery);
|
GenMMC1Init(info, 512, 256, 8, info->battery ? 8 : 0);
|
||||||
is155 = 1;
|
is155 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +363,7 @@ void Mapper171_Init(CartInfo *info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SAROM_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) {
|
void SBROM_Init(CartInfo *info) {
|
||||||
@@ -360,7 +383,7 @@ void SGROM_Init(CartInfo *info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SKROM_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) {
|
void SLROM_Init(CartInfo *info) {
|
||||||
@@ -392,11 +415,11 @@ void SHROM_Init(CartInfo *info) {
|
|||||||
/* */
|
/* */
|
||||||
|
|
||||||
void SNROM_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) {
|
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 -----------------------*/
|
/* ----------------------- FARID_SLROM_8-IN-1 -----------------------*/
|
||||||
@@ -490,7 +513,7 @@ static void Sync(void) {
|
|||||||
MMC1PRG();
|
MMC1PRG();
|
||||||
MMC1CHR();
|
MMC1CHR();
|
||||||
MMC1MIRROR();
|
MMC1MIRROR();
|
||||||
} else {
|
} else {
|
||||||
/* Mapper 70 */
|
/* Mapper 70 */
|
||||||
setprg16(0x8000, ((mode & 2) << 1) | ((latch >> 4) & 3));
|
setprg16(0x8000, ((mode & 2) << 1) | ((latch >> 4) & 3));
|
||||||
setprg16(0xC000, ((mode & 2) << 1) | 3);
|
setprg16(0xC000, ((mode & 2) << 1) | 3);
|
||||||
|
|||||||
@@ -676,6 +676,7 @@ static BMAPPINGLocal bmap[] = {
|
|||||||
{(uint8_t*)"830928C", 382, Mapper382_Init},
|
{(uint8_t*)"830928C", 382, Mapper382_Init},
|
||||||
{(uint8_t*)"NJ064", 534, Mapper534_Init},
|
{(uint8_t*)"NJ064", 534, Mapper534_Init},
|
||||||
{(uint8_t*)"Kid Ikarus (FDS)", 539, Mapper539_Init},
|
{(uint8_t*)"Kid Ikarus (FDS)", 539, Mapper539_Init},
|
||||||
|
/* {(uint8_t*)"5-in-1 (CH-501)", 543, Mapper543_Init}, */
|
||||||
|
|
||||||
/* UNIF to NES 2.0 BOARDS */
|
/* UNIF to NES 2.0 BOARDS */
|
||||||
|
|
||||||
|
|||||||
@@ -258,5 +258,6 @@ void Mapper534_Init(CartInfo *);
|
|||||||
void Mapper538_Init(CartInfo *);
|
void Mapper538_Init(CartInfo *);
|
||||||
void Mapper539_Init(CartInfo *);
|
void Mapper539_Init(CartInfo *);
|
||||||
void Mapper541_Init(CartInfo *);
|
void Mapper541_Init(CartInfo *);
|
||||||
|
void Mapper543_Init(CartInfo *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user