From e8597862f1f35b8c5d4f8570f256750395a7716b Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 2 May 2020 00:20:44 -0400 Subject: [PATCH 1/2] CHR size < 1k allows NES program to corrupt memory because VPage is 1k granularity returning 0 from iNES_Init is not ideal, error is "unsupported mapper" but at least it's an error also adding CHRmask1/2/4/8 fallback, not sure if needed but looks suspicious for <8k --- src/cart.cpp | 5 +++++ src/ines.cpp | 1 + 2 files changed, 6 insertions(+) diff --git a/src/cart.cpp b/src/cart.cpp index 4646eabd..26f7627c 100644 --- a/src/cart.cpp +++ b/src/cart.cpp @@ -132,6 +132,11 @@ void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram) { CHRmask4[chip] = (size >> 12) - 1; CHRmask8[chip] = (size >> 13) - 1; + if (CHRmask1[chip] >= (unsigned int)(-1)) CHRmask1[chip] = 0; + if (CHRmask2[chip] >= (unsigned int)(-1)) CHRmask2[chip] = 0; + if (CHRmask4[chip] >= (unsigned int)(-1)) CHRmask4[chip] = 0; + if (CHRmask8[chip] >= (unsigned int)(-1)) CHRmask8[chip] = 0; + CHRram[chip] = ram; } diff --git a/src/ines.cpp b/src/ines.cpp index 5111f481..70245a71 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -1017,6 +1017,7 @@ static int iNES_Init(int num) { { CHRRAMSize = iNESCart.battery_vram_size + iNESCart.vram_size; } + if (CHRRAMSize < 1024) return 0; // unsupported size, VPage only goes down to 1k banks, NES program can corrupt memory if used if ((VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 0; FCEU_MemoryRand(VROM, CHRRAMSize); From 2cdb283a64413fc0aee283433cc02092cce4dc69 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 2 May 2020 00:42:44 -0400 Subject: [PATCH 2/2] iNES_Init error reporting --- src/ines.cpp | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/ines.cpp b/src/ines.cpp index 70245a71..790c8725 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -892,8 +892,31 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { iNESCart.battery = (head.ROM_type & 2) ? 1 : 0; iNESCart.mirror = Mirroring; - if (!iNES_Init(MapperNo)) + int result = iNES_Init(MapperNo); + switch(result) + { + case 0: + goto init_ok; + case 1: FCEU_PrintError("iNES mapper #%d is not supported at all.", MapperNo); + goto init_ok; // this error is still allowed to run as NROM? + case 2: + FCEU_PrintError("Unable to allocate CHR-RAM."); + break; + case 3: + FCEU_PrintError("CHR-RAM size < 1k is not supported."); + break; + } + if (ROM) free(ROM); + if (VROM) free(VROM); + if (trainerpoo) free(trainerpoo); + if (ExtraNTARAM) free(ExtraNTARAM); + ROM = NULL; + VROM = NULL; + trainerpoo = NULL; + ExtraNTARAM = NULL; + return 0; +init_ok: GameInfo->mappernum = MapperNo; FCEU_LoadGameSave(&iNESCart); @@ -1017,8 +1040,8 @@ static int iNES_Init(int num) { { CHRRAMSize = iNESCart.battery_vram_size + iNESCart.vram_size; } - if (CHRRAMSize < 1024) return 0; // unsupported size, VPage only goes down to 1k banks, NES program can corrupt memory if used - if ((VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 0; + if (CHRRAMSize < 1024) return 3; // unsupported size, VPage only goes down to 1k banks, NES program can corrupt memory if used + if ((VROM = (uint8*)FCEU_dmalloc(CHRRAMSize)) == NULL) return 2; FCEU_MemoryRand(VROM, CHRRAMSize); UNIFchrrama = VROM; @@ -1038,9 +1061,9 @@ static int iNES_Init(int num) { if (head.ROM_type & 8) AddExState(ExtraNTARAM, 2048, 0, "EXNR"); tmp->init(&iNESCart); - return 1; + return 0; } tmp++; } - return 0; + return 1; }