From fca059aaf49d46338b93d685ad1beffe61c7e102 Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 16 Oct 2020 13:02:06 -0400 Subject: [PATCH] mmc5 was making no virtually no effort to clear data on power-on, creating nondeterminisms on movie plays. I revised all that.. and it's making me think fceux fundamentally doesn't work well with this. In particular I'm not sure about the timing of the loaded save data. If we get called in the order: mapper_init, loadsavedata, mapper_power -- then we will clobber the WRAM in mapper_power (at least, the way I have it now in mmc5) which will lose the save data. save data should really be loaded AFTER a power-on command. but I don't think fceux ever through through any of this very well. well, at least this fixes my case of a deterministic fm2. --- src/boards/mmc5.cpp | 77 +++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/src/boards/mmc5.cpp b/src/boards/mmc5.cpp index 6fa9a243..0099e409 100644 --- a/src/boards/mmc5.cpp +++ b/src/boards/mmc5.cpp @@ -22,6 +22,8 @@ #include "mapinc.h" +#include + #define ABANKS MMC5SPRVPage #define BBANKS MMC5BGVPage #define SpriteON (PPU[1] & 0x10) //Show Sprite @@ -81,10 +83,11 @@ static INLINE void MMC5BGVROM_BANK8(uint32 V) { } } -static uint8 PRGBanks[4]; +static std::array PRGBanks; static uint8 WRAMPage; -static uint16 CHRBanksA[8], CHRBanksB[4]; -static uint8 WRAMMaskEnable[2]; +static std::array CHRBanksA; +static std::array CHRBanksB; +static std::array WRAMMaskEnable; uint8 mmc5ABMode; /* A=0, B=1 */ static uint8 IRQScanline, IRQEnable; @@ -93,7 +96,7 @@ static uint8 CHRMode, NTAMirroring, NTFill, ATFill; static uint8 MMC5IRQR; static uint8 MMC5LineCounter; static uint8 mmc5psize, mmc5vsize; -static uint8 mul[2]; +static std::array mul; static uint32 WRAMSIZE = 0; static uint8 *WRAM = NULL; @@ -104,8 +107,8 @@ const int MMC5WRAMMAX = 1<<7; // 7 bits in register interface (real MMC5 has onl static uint8 MMC5WRAMsize; //configuration, not state static uint8 MMC5WRAMIndex[MMC5WRAMMAX]; //configuration, not state -static uint8 MMC5ROMWrProtect[4]; -static uint8 MMC5MemIn[5]; +static std::array MMC5ROMWrProtect; +static std::array MMC5MemIn; static void MMC5CHRA(void); static void MMC5CHRB(void); @@ -895,18 +898,35 @@ void NSFMMC5_Close(void) { ExRAM = NULL; } -static void GenMMC5Reset(void) { - int x; +static void GenMMC5Power(void) { - for (x = 0; x < 4; x++) PRGBanks[x] = ~0; - for (x = 0; x < 8; x++) CHRBanksA[x] = ~0; - for (x = 0; x < 4; x++) CHRBanksB[x] = ~0; - WRAMMaskEnable[0] = WRAMMaskEnable[1] = ~0; - - mmc5psize = mmc5vsize = 3; + PRGBanks.fill(0xFF); + WRAMPage = 0; + CHRBanksA.fill(0xFF); + CHRBanksB.fill(0xFF); + WRAMMaskEnable.fill(0xFF); + mmc5ABMode = 0; + IRQScanline = 0; + IRQEnable = 0; CHRMode = 0; - NTAMirroring = NTFill = ATFill = 0xFF; + MMC5IRQR = 0; + MMC5LineCounter = 0; + mmc5psize = mmc5vsize = 3; + mul.fill(0); + + MMC5ROMWrProtect.fill(0); + MMC5MemIn.fill(0); + + // MMC5fill is and 8-bit tile index, and a 2-bit attribute implented as a mirrored nametable + u8 nval = MMC5fill[0x000]; + u8 aval = MMC5fill[0x3C0] & 3; aval = aval | (aval << 2) | (aval << 4) | (aval << 6); + FCEU_dwmemset(MMC5fill + 0x000, nval | (nval<<8) | (nval<<16) | (nval<<24), 0x3C0); + FCEU_dwmemset(MMC5fill + 0x3C0, aval | (aval<<8) | (aval<<16) | (aval<<24), 0x040); + + FCEU_MemoryRand(WRAM, MMC5WRAMsize * 8 * 1024); + FCEU_MemoryRand(MMC5fill,1024); + FCEU_MemoryRand(ExRAM,1024); MMC5Synco(); @@ -929,11 +949,11 @@ static void GenMMC5Reset(void) { } static SFORMAT MMC5_StateRegs[] = { - { PRGBanks, 4, "PRGB" }, - { CHRBanksA, 16, "CHRA" }, - { CHRBanksB, 8, "CHRB" }, + { &PRGBanks, 4, "PRGB" }, + { &CHRBanksA, 16, "CHRA" }, + { &CHRBanksB, 8, "CHRB" }, { &WRAMPage, 1, "WRMP" }, - { WRAMMaskEnable, 2, "WRME" }, + { &WRAMMaskEnable, 2, "WRME" }, { &mmc5ABMode, 1, "ABMD" }, { &IRQScanline, 1, "IRQS" }, { &IRQEnable, 1, "IRQE" }, @@ -947,9 +967,9 @@ static SFORMAT MMC5_StateRegs[] = { { &MMC5LineCounter, 1, "LCTR" }, { &mmc5psize, 1, "PSIZ" }, { &mmc5vsize, 1, "VSIZ" }, - { mul, 2, "MUL2" }, - { MMC5ROMWrProtect, 4, "WRPR" }, - { MMC5MemIn, 5, "MEMI" }, + { &mul, 2, "MUL2" }, + { &MMC5ROMWrProtect, 4, "WRPR" }, + { &MMC5MemIn, 5, "MEMI" }, { &MMC5Sound.wl[0], 2 | FCEUSTATE_RLSB, "SDW0" }, { &MMC5Sound.wl[1], 2 | FCEUSTATE_RLSB, "SDW1" }, @@ -972,19 +992,14 @@ static SFORMAT MMC5_StateRegs[] = { static void GenMMC5_Init(CartInfo *info, int wsize, int battery) { if (wsize) { - WRAM = (uint8*)FCEU_gmalloc(wsize * 1024); + WRAM = (uint8*)FCEU_malloc(wsize * 1024); SetupCartPRGMapping(0x10, WRAM, wsize * 1024, 1); AddExState(WRAM, wsize * 1024, 0, "WRAM"); } - MMC5fill = (uint8*)FCEU_gmalloc(1024); - ExRAM = (uint8*)FCEU_gmalloc(1024); + MMC5fill = (uint8*)FCEU_malloc(1024); + ExRAM = (uint8*)FCEU_malloc(1024); - // MMC5fill is and 8-bit tile index, and a 2-bit attribute implented as a mirrored nametable - u8 nval = MMC5fill[0x000]; - u8 aval = MMC5fill[0x3C0] & 3; aval = aval | (aval << 2) | (aval << 4) | (aval << 6); - FCEU_dwmemset(MMC5fill + 0x000, nval | (nval<<8) | (nval<<16) | (nval<<24), 0x3C0); - FCEU_dwmemset(MMC5fill + 0x3C0, aval | (aval<<8) | (aval<<16) | (aval<<24), 0x040); AddExState(ExRAM, 1024, 0, "ERAM"); AddExState(&MMC5HackSPMode, 1, 0, "SPLM"); @@ -996,7 +1011,7 @@ static void GenMMC5_Init(CartInfo *info, int wsize, int battery) { MMC5WRAMsize = wsize / 8; BuildWRAMSizeTable(); GameStateRestore = MMC5_StateRestore; - info->Power = GenMMC5Reset; + info->Power = GenMMC5Power; if (battery) { info->SaveGame[0] = WRAM;