Merge pull request #676 from negativeExponent/master

Fix handling of roms with  prg size below 16K
This commit is contained in:
Alexey Cluster 2023-12-09 22:46:54 +04:00 committed by GitHub
commit e806a5a25a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 28 deletions

View File

@ -837,34 +837,36 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
MirroringAs2bits = head.ROM_type & 1; MirroringAs2bits = head.ROM_type & 1;
if (head.ROM_type & 8) MirroringAs2bits |= 2; if (head.ROM_type & 8) MirroringAs2bits |= 2;
int not_round_size; int not_round_size = 0;
int rom_size_bytes = 0;
int vrom_size_bytes = 0;
if (!iNES2) { if (!iNES2) {
not_round_size = head.ROM_size; not_round_size = head.ROM_size << 14;
} }
else { else {
if ((head.Upper_ROM_VROM_size & 0x0F) != 0x0F) if ((head.Upper_ROM_VROM_size & 0x0F) != 0x0F)
// simple notation // simple notation
not_round_size = head.ROM_size | ((head.Upper_ROM_VROM_size & 0x0F) << 8); not_round_size = (head.ROM_size | ((head.Upper_ROM_VROM_size & 0x0F) << 8)) << 14;
else else
// exponent-multiplier notation // exponent-multiplier notation
not_round_size = ((1 << (head.ROM_size >> 2)) * ((head.ROM_size & 0b11) * 2 + 1)) >> 14; not_round_size = ((1 << (head.ROM_size >> 2)) * ((head.ROM_size & 0b11) * 2 + 1));
} }
if (!head.ROM_size && !iNES2) if (!head.ROM_size && !iNES2)
ROM_size = 256; rom_size_bytes = 256 << 14;
else else
ROM_size = uppow2(not_round_size); rom_size_bytes = uppow2(not_round_size);
VROM_size = uppow2(head.VROM_size | (iNES2?((head.Upper_ROM_VROM_size & 0xF0)<<4):0));
if (!iNES2) { if (!iNES2) {
VROM_size = uppow2(head.VROM_size); vrom_size_bytes = uppow2(head.VROM_size << 13);
} }
else { else {
if ((head.Upper_ROM_VROM_size & 0xF0) != 0xF0) if ((head.Upper_ROM_VROM_size & 0xF0) != 0xF0)
// simple notation // simple notation
VROM_size = uppow2(head.VROM_size | ((head.Upper_ROM_VROM_size & 0xF0) << 4)); vrom_size_bytes = uppow2((head.VROM_size | ((head.Upper_ROM_VROM_size & 0xF0) << 4)) << 13);
else else
VROM_size = ((1 << (head.VROM_size >> 2)) * ((head.VROM_size & 0b11) * 2 + 1)) >> 13; vrom_size_bytes = ((1 << (head.VROM_size >> 2)) * ((head.VROM_size & 0b11) * 2 + 1));
} }
int round = true; int round = true;
@ -880,12 +882,15 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
} }
} }
ROM = (uint8*)FCEU_malloc(ROM_size << 14); ROM_size = rom_size_bytes >> 14;
memset(ROM, 0xFF, ROM_size << 14); VROM_size = vrom_size_bytes >> 13;
if (VROM_size) { ROM = (uint8*)FCEU_malloc(rom_size_bytes);
VROM = (uint8*)FCEU_malloc(VROM_size << 13); memset(ROM, 0xFF, rom_size_bytes);
memset(VROM, 0xFF, VROM_size << 13);
if (vrom_size_bytes) {
VROM = (uint8*)FCEU_malloc(vrom_size_bytes);
memset(VROM, 0xFF, vrom_size_bytes);
} }
// Set Vs. System flag if need // Set Vs. System flag if need
@ -946,21 +951,21 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
ResetCartMapping(); ResetCartMapping();
ResetExState(0, 0); ResetExState(0, 0);
SetupCartPRGMapping(0, ROM, ROM_size << 14, 0); SetupCartPRGMapping(0, ROM, rom_size_bytes, 0);
FCEU_fread(ROM, 0x4000, (round) ? ROM_size : not_round_size, fp); FCEU_fread(ROM, 1, (round) ? rom_size_bytes : not_round_size, fp);
if (VROM_size) if (vrom_size_bytes)
FCEU_fread(VROM, 0x2000, VROM_size, fp); FCEU_fread(VROM, 1, vrom_size_bytes, fp);
md5_starts(&md5); md5_starts(&md5);
md5_update(&md5, ROM, ROM_size << 14); md5_update(&md5, ROM, rom_size_bytes);
iNESGameCRC32 = CalcCRC32(0, ROM, ROM_size << 14); iNESGameCRC32 = CalcCRC32(0, ROM, rom_size_bytes);
if (VROM_size) { if (vrom_size_bytes) {
iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, VROM_size << 13); iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, vrom_size_bytes);
md5_update(&md5, VROM, VROM_size << 13); md5_update(&md5, VROM, vrom_size_bytes);
} }
md5_finish(&md5, iNESCart.MD5); md5_finish(&md5, iNESCart.MD5);
memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5));
@ -969,8 +974,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
iNESCart.CRC32 = iNESGameCRC32; iNESCart.CRC32 = iNESGameCRC32;
FCEU_printf(" PRG ROM: %d x 16KiB = %d KiB\n", round ? ROM_size : not_round_size, (round ? ROM_size : not_round_size) * 16); FCEU_printf(" PRG ROM: %d x 16KiB = %d KiB\n", (round ? rom_size_bytes : not_round_size) >> 14, ((round ? rom_size_bytes : not_round_size) >> 14) * 16);
FCEU_printf(" CHR ROM: %d x 8KiB = %d KiB\n", VROM_size, VROM_size * 8); FCEU_printf(" CHR ROM: %d x 8KiB = %d KiB\n", (vrom_size_bytes >> 13), (vrom_size_bytes >> 13) * 8);
FCEU_printf(" ROM CRC32: 0x%08x\n", iNESGameCRC32); FCEU_printf(" ROM CRC32: 0x%08x\n", iNESGameCRC32);
{ {
int x; int x;
@ -1015,8 +1020,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
/* Must remain here because above functions might change value of /* Must remain here because above functions might change value of
VROM_size and free(VROM). VROM_size and free(VROM).
*/ */
if (VROM_size) if (vrom_size_bytes)
SetupCartCHRMapping(0, VROM, VROM_size * 0x2000, 0); SetupCartCHRMapping(0, VROM, vrom_size_bytes, 0);
if (Mirroring == 2) { if (Mirroring == 2) {
ExtraNTARAM = (uint8*)FCEU_gmalloc(2048); ExtraNTARAM = (uint8*)FCEU_gmalloc(2048);