GBA: Fix 1 MiB ROM mirroring to only mirror 4 times

This commit is contained in:
Vicki Pfau 2022-09-07 20:26:35 -07:00
parent e0b07a6446
commit 4b0ea00ba1
4 changed files with 15 additions and 20 deletions

View File

@ -33,6 +33,7 @@ Emulation fixes:
- GBA: Improve timing when not booting from BIOS
- GBA: Fix expected entry point for multiboot ELFs (fixes mgba.io/i/2450)
- GBA: Fix booting multiboot ROMs with no JOY entrypoint
- GBA: Fix 1 MiB ROM mirroring to only mirror 4 times
- GBA Audio: Adjust PSG sampling rate with SOUNDBIAS
- GBA Audio: Sample FIFOs at SOUNDBIAS-set frequency
- GBA BIOS: Work around IRQ handling hiccup in Mario & Luigi (fixes mgba.io/i/1059)

View File

@ -364,7 +364,6 @@ bool GBALoadNull(struct GBA* gba) {
gba->yankedRomSize = 0;
gba->memory.romSize = SIZE_CART0;
gba->memory.romMask = SIZE_CART0 - 1;
gba->memory.mirroring = false;
gba->romCrc32 = 0;
if (gba->cpu) {
@ -419,6 +418,19 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
gba->memory.romSize = SIZE_CART0;
}
gba->pristineRomSize = SIZE_CART0;
} else if (gba->pristineRomSize == 0x00100000) {
// 1 MiB ROMs (e.g. Classic NES) all appear as 4x mirrored, but not more
gba->isPristine = false;
gba->memory.romSize = 0x00400000;
#ifdef FIXED_ROM_BUFFER
gba->memory.rom = romBuffer;
#else
gba->memory.rom = anonymousMemoryMap(SIZE_CART0);
#endif
vf->read(vf, gba->memory.rom, gba->pristineRomSize);
memcpy(&gba->memory.rom[0x40000], gba->memory.rom, 0x00100000);
memcpy(&gba->memory.rom[0x80000], gba->memory.rom, 0x00100000);
memcpy(&gba->memory.rom[0xC0000], gba->memory.rom, 0x00100000);
} else {
gba->memory.rom = vf->map(vf, gba->pristineRomSize, MAP_READ);
gba->memory.romSize = gba->pristineRomSize;
@ -430,8 +442,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
}
gba->yankedRomSize = 0;
gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
gba->memory.mirroring = false;
gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
gba->romCrc32 = doCrc32(gba->memory.rom, gba->pristineRomSize);
if (popcount32(gba->memory.romSize) != 1) {
// This ROM is either a bad dump or homebrew. Emulate flash cart behavior.
#ifndef FIXED_ROM_BUFFER

View File

@ -83,7 +83,6 @@ void GBAMemoryInit(struct GBA* gba) {
cpu->memory.activeNonseqCycles32 = 0;
cpu->memory.activeNonseqCycles16 = 0;
gba->memory.biosPrefetch = 0;
gba->memory.mirroring = false;
gba->memory.agbPrintProtect = 0;
memset(&gba->memory.agbPrintCtx, 0, sizeof(gba->memory.agbPrintCtx));
@ -277,9 +276,6 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
if (newRegion < REGION_CART0 || (address & (SIZE_CART0 - 1)) < memory->romSize) {
return;
}
if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
return;
}
}
if (memory->activeRegion == REGION_BIOS) {
@ -411,8 +407,6 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
wait += waitstatesRegion[address >> BASE_OFFSET]; \
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) { \
LOAD_32(value, address & memory->romMask & -4, memory->rom); \
} else if (memory->vfame.cartType) { \
value = GBAVFameGetPatternValue(address, 32); \
} else { \
@ -578,8 +572,6 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
LOAD_16(value, address & memory->romMask, memory->rom);
} else if (memory->vfame.cartType) {
value = GBAVFameGetPatternValue(address, 16);
} else if ((address & (SIZE_CART0 - 1)) >= AGB_PRINT_BASE) {
@ -605,8 +597,6 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
value = GBACartEReaderRead(&memory->ereader, address);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
LOAD_16(value, address & memory->romMask, memory->rom);
} else if (memory->vfame.cartType) {
value = GBAVFameGetPatternValue(address, 16);
} else {
@ -698,8 +688,6 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
value = ((uint8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
value = ((uint8_t*) memory->rom)[address & memory->romMask];
} else if (memory->vfame.cartType) {
value = GBAVFameGetPatternValue(address, 8);
} else {

View File

@ -229,7 +229,6 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver
if (!found && override->id[0] == 'F') {
// Classic NES Series
override->savetype = SAVEDATA_EEPROM;
override->mirroring = true;
found = true;
}
@ -377,10 +376,6 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri
gba->idleOptimization = IDLE_LOOP_REMOVE;
}
}
if (override->mirroring) {
gba->memory.mirroring = true;
}
}
void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overrides) {