GBA Memory: Fix mirroring on non-overdumped Classic NES games

This commit is contained in:
Jeffrey Pfau 2016-02-21 12:01:54 -08:00
parent 2adc03bcbd
commit aa0ee743b3
6 changed files with 114 additions and 89 deletions

View File

@ -13,6 +13,7 @@ Bugfixes:
- SDL: Fix axes being mapped wrong - SDL: Fix axes being mapped wrong
- Qt: Fix initial state of key mapping - Qt: Fix initial state of key mapping
- Shaders: Fix AGS-001 shader with some bad drivers - Shaders: Fix AGS-001 shader with some bad drivers
- GBA Memory: Fix mirror on non-overdumped Classic NES games
Misc: Misc:
- GBA: Slightly optimize GBAProcessEvents - GBA: Slightly optimize GBAProcessEvents
- Qt: Add preset for DualShock 4 - Qt: Add preset for DualShock 4

View File

@ -12,167 +12,169 @@
static const struct GBACartridgeOverride _overrides[] = { static const struct GBACartridgeOverride _overrides[] = {
// Advance Wars // Advance Wars
{ "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, { "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false },
{ "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, { "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false },
// Advance Wars 2: Black Hole Rising // Advance Wars 2: Black Hole Rising
{ "AW2E", SAVEDATA_FLASH512, HW_NONE, 0x8036E08 }, { "AW2E", SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false },
{ "AW2P", SAVEDATA_FLASH512, HW_NONE, 0x803719C }, { "AW2P", SAVEDATA_FLASH512, HW_NONE, 0x803719C, false },
// Boktai: The Sun is in Your Hand // Boktai: The Sun is in Your Hand
{ "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U3IP", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IP", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Boktai 2: Solar Boy Django // Boktai 2: Solar Boy Django
{ "U32J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U32J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U32E", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U32E", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U32P", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U32P", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Dragon Ball Z - The Legacy of Goku // Dragon Ball Z - The Legacy of Goku
{ "ALGP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "ALGP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Dragon Ball Z - Taiketsu // Dragon Ball Z - Taiketsu
{ "BDBE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "BDBE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "BDBP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "BDBP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Drill Dozer // Drill Dozer
{ "V49J", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE }, { "V49J", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
{ "V49E", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE }, { "V49E", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
// Final Fantasy Tactics Advance // Final Fantasy Tactics Advance
{ "AFXE", SAVEDATA_FLASH512, HW_NONE, 0x8000428 }, { "AFXE", SAVEDATA_FLASH512, HW_NONE, 0x8000428, false },
// F-Zero - Climax // F-Zero - Climax
{ "BFTJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BFTJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Iridion II // Iridion II
{ "AI2E", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE }, { "AI2E", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
{ "AI2P", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE }, { "AI2P", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
// Golden Sun: The Lost Age // Golden Sun: The Lost Age
{ "AGFE", SAVEDATA_FLASH512, HW_NONE, 0x801353A }, { "AGFE", SAVEDATA_FLASH512, HW_NONE, 0x801353A, false },
// Koro Koro Puzzle - Happy Panechu! // Koro Koro Puzzle - Happy Panechu!
{ "KHPJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE }, { "KHPJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
// Mega Man Battle Network // Mega Man Battle Network
{ "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E }, { "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E, false },
// Mega Man Zero // Mega Man Zero
{ "AZCE", SAVEDATA_SRAM, HW_NONE, 0x80004E8 }, { "AZCE", SAVEDATA_SRAM, HW_NONE, 0x80004E8, false },
// Metal Slug Advance // Metal Slug Advance
{ "BSME", SAVEDATA_EEPROM, HW_NONE, 0x8000290 }, { "BSME", SAVEDATA_EEPROM, HW_NONE, 0x8000290, false },
// Pokemon Ruby // Pokemon Ruby
{ "AXVJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXVF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Pokemon Sapphire // Pokemon Sapphire
{ "AXPJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "AXPF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Pokemon Emerald // Pokemon Emerald
{ "BPEJ", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEJ", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEE", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEE", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEP", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEP", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEI", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEI", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPES", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPES", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPED", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPED", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEF", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEF", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
// Pokemon Mystery Dungeon // Pokemon Mystery Dungeon
{ "B24J", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "B24J", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "B24E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "B24E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "B24P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "B24P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "B24U", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "B24U", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Pokemon FireRed // Pokemon FireRed
{ "BPRJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPRF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Pokemon LeafGreen // Pokemon LeafGreen
{ "BPGJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, { "BPGF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// RockMan EXE 4.5 - Real Operation // RockMan EXE 4.5 - Real Operation
{ "BR4J", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE }, { "BR4J", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
// Rocky // Rocky
{ "AR8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "AR8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "AROP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "AROP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Sennen Kazoku // Sennen Kazoku
{ "BKAJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, { "BKAJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Shin Bokura no Taiyou: Gyakushuu no Sabata // Shin Bokura no Taiyou: Gyakushuu no Sabata
{ "U33J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U33J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Super Mario Advance 2 // Super Mario Advance 2
{ "AA2J", SAVEDATA_EEPROM, HW_NONE, 0x800052E }, { "AA2J", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false },
{ "AA2E", SAVEDATA_EEPROM, HW_NONE, 0x800052E }, { "AA2E", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false },
{ "AA2P", SAVEDATA_AUTODETECT, HW_NONE, 0x800052E }, { "AA2P", SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false },
// Super Mario Advance 3 // Super Mario Advance 3
{ "A3AJ", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, { "A3AJ", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
{ "A3AE", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, { "A3AE", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
{ "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, { "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
// Super Mario Advance 4 // Super Mario Advance 4
{ "AX4J", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, { "AX4J", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
{ "AX4E", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, { "AX4E", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
{ "AX4P", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, { "AX4P", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
// Super Monkey Ball Jr. // Super Monkey Ball Jr.
{ "ALUE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "ALUE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "ALUP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE }, { "ALUP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Top Gun - Combat Zones // Top Gun - Combat Zones
{ "A2YE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE }, { "A2YE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
// Wario Ware Twisted // Wario Ware Twisted
{ "RZWJ", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE }, { "RZWJ", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
{ "RZWE", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE }, { "RZWE", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
{ "RZWP", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE }, { "RZWP", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
// Yoshi's Universal Gravitation // Yoshi's Universal Gravitation
{ "KYGJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE }, { "KYGJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
{ "KYGE", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE }, { "KYGE", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
{ "KYGP", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE }, { "KYGP", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
{ { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE } { { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE, false }
}; };
bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) { bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) {
override->savetype = SAVEDATA_AUTODETECT; override->savetype = SAVEDATA_AUTODETECT;
override->hardware = HW_NONE; override->hardware = HW_NONE;
override->idleLoop = IDLE_LOOP_NONE; override->idleLoop = IDLE_LOOP_NONE;
override->mirroring = false;
bool found = false; bool found = false;
if (override->id[0] == 'F') { if (override->id[0] == 'F') {
// Classic NES Series // Classic NES Series
override->savetype = SAVEDATA_EEPROM; override->savetype = SAVEDATA_EEPROM;
override->mirroring = true;
found = true; found = true;
} else { } else {
int i; int i;
@ -311,6 +313,10 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri
gba->idleOptimization = IDLE_LOOP_REMOVE; gba->idleOptimization = IDLE_LOOP_REMOVE;
} }
} }
if (override->mirroring) {
gba->memory.mirroring = true;
}
} }
void GBAOverrideApplyDefaults(struct GBA* gba) { void GBAOverrideApplyDefaults(struct GBA* gba) {

View File

@ -17,6 +17,7 @@ struct GBACartridgeOverride {
enum SavedataType savetype; enum SavedataType savetype;
int hardware; int hardware;
uint32_t idleLoop; uint32_t idleLoop;
bool mirroring;
}; };
struct Configuration; struct Configuration;

View File

@ -469,6 +469,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
gba->memory.rom = gba->pristineRom; gba->memory.rom = gba->pristineRom;
gba->memory.romSize = gba->pristineRomSize; gba->memory.romSize = gba->pristineRomSize;
gba->memory.romMask = toPow2(gba->memory.romSize) - 1; 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->memory.romSize);
GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]);
// TODO: error check // TODO: error check

View File

@ -82,6 +82,7 @@ void GBAMemoryInit(struct GBA* gba) {
cpu->memory.activeNonseqCycles32 = 0; cpu->memory.activeNonseqCycles32 = 0;
cpu->memory.activeNonseqCycles16 = 0; cpu->memory.activeNonseqCycles16 = 0;
gba->memory.biosPrefetch = 0; gba->memory.biosPrefetch = 0;
gba->memory.mirroring = false;
} }
void GBAMemoryDeinit(struct GBA* gba) { void GBAMemoryDeinit(struct GBA* gba) {
@ -244,8 +245,13 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
gba->lastJump = address; gba->lastJump = address;
memory->lastPrefetchedPc = 0; memory->lastPrefetchedPc = 0;
memory->lastPrefetchedLoads = 0; memory->lastPrefetchedLoads = 0;
if (newRegion == memory->activeRegion && (newRegion < REGION_CART0 || (address & (SIZE_CART0 - 1)) < memory->romSize)) { if (newRegion == memory->activeRegion) {
return; 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) { if (memory->activeRegion == REGION_BIOS) {
@ -372,6 +378,8 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
wait += waitstatesRegion[address >> BASE_OFFSET]; \ wait += waitstatesRegion[address >> BASE_OFFSET]; \
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \ if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \ LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) { \
LOAD_32(value, address & memory->romMask, memory->rom); \
} else { \ } else { \
mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \ mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
value = ((address & ~3) >> 1) & 0xFFFF; \ value = ((address & ~3) >> 1) & 0xFFFF; \
@ -502,6 +510,8 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom); 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 { } else {
mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address); mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; value = (address >> 1) & 0xFFFF;
@ -513,6 +523,8 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
value = GBASavedataReadEEPROM(&memory->savedata); value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) { } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom); 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 { } else {
mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address); mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
value = (address >> 1) & 0xFFFF; value = (address >> 1) & 0xFFFF;
@ -596,6 +608,8 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if ((address & (SIZE_CART0 - 1)) < memory->romSize) { if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
value = ((uint8_t*) memory->rom)[address & (SIZE_CART0 - 1)]; 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 { } else {
mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address); mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address);
value = (address >> 1) & 0xFF; value = (address >> 1) & 0xFF;

View File

@ -142,6 +142,8 @@ struct GBAMemory {
int activeDMA; int activeDMA;
int32_t nextDMA; int32_t nextDMA;
int32_t eventDiff; int32_t eventDiff;
bool mirroring;
}; };
void GBAMemoryInit(struct GBA* gba); void GBAMemoryInit(struct GBA* gba);