mirror of https://github.com/mgba-emu/mgba.git
GBA, GB: ROM is now unloaded if a patch is applied
This commit is contained in:
parent
af77e5ab62
commit
28a3ac50a6
|
@ -63,7 +63,7 @@ struct GB {
|
|||
|
||||
uint8_t* keySource;
|
||||
|
||||
void* pristineRom;
|
||||
bool isPristine;
|
||||
size_t pristineRomSize;
|
||||
size_t yankedRomSize;
|
||||
uint32_t romCrc32;
|
||||
|
|
|
@ -17,7 +17,7 @@ mLOG_DECLARE_CATEGORY(GB_MBC);
|
|||
struct GB;
|
||||
struct GBMemory;
|
||||
void GBMBCInit(struct GB* gb);
|
||||
void GBMBCSwitchBank(struct GBMemory* memory, int bank);
|
||||
void GBMBCSwitchBank(struct GB* gb, int bank);
|
||||
void GBMBCSwitchSramBank(struct GB* gb, int bank);
|
||||
|
||||
struct GBMBCRTCSaveBuffer {
|
||||
|
|
|
@ -90,7 +90,7 @@ struct GBA {
|
|||
struct mRumble* rumble;
|
||||
|
||||
struct GBARRContext* rr;
|
||||
void* pristineRom;
|
||||
bool isPristine;
|
||||
size_t pristineRomSize;
|
||||
size_t yankedRomSize;
|
||||
uint32_t romCrc32;
|
||||
|
|
52
src/gb/gb.c
52
src/gb/gb.c
|
@ -79,7 +79,7 @@ static void GBInit(void* cpu, struct mCPUComponent* component) {
|
|||
gb->sramVf = NULL;
|
||||
gb->sramRealVf = NULL;
|
||||
|
||||
gb->pristineRom = 0;
|
||||
gb->isPristine = false;
|
||||
gb->pristineRomSize = 0;
|
||||
gb->yankedRomSize = 0;
|
||||
|
||||
|
@ -108,24 +108,23 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf) {
|
|||
gb->romVf = vf;
|
||||
gb->pristineRomSize = vf->size(vf);
|
||||
vf->seek(vf, 0, SEEK_SET);
|
||||
gb->isPristine = true;
|
||||
#ifdef _3DS
|
||||
gb->pristineRom = 0;
|
||||
if (gb->pristineRomSize <= romBufferSize) {
|
||||
gb->pristineRom = romBuffer;
|
||||
gb->memory.rom = romBuffer;
|
||||
vf->read(vf, romBuffer, gb->pristineRomSize);
|
||||
}
|
||||
#else
|
||||
gb->pristineRom = vf->map(vf, gb->pristineRomSize, MAP_READ);
|
||||
gb->memory.rom = vf->map(vf, gb->pristineRomSize, MAP_READ);
|
||||
#endif
|
||||
if (!gb->pristineRom) {
|
||||
if (!gb->memory.rom) {
|
||||
return false;
|
||||
}
|
||||
gb->yankedRomSize = 0;
|
||||
gb->memory.rom = gb->pristineRom;
|
||||
gb->memory.romBase = gb->memory.rom;
|
||||
gb->memory.romSize = gb->pristineRomSize;
|
||||
gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
|
||||
GBMBCSwitchBank(&gb->memory, gb->memory.currentBank);
|
||||
GBMBCSwitchBank(gb, gb->memory.currentBank);
|
||||
|
||||
if (gb->cpu) {
|
||||
struct LR35902Core* cpu = gb->cpu;
|
||||
|
@ -263,26 +262,25 @@ void GBSavedataUnmask(struct GB* gb) {
|
|||
|
||||
void GBUnloadROM(struct GB* gb) {
|
||||
// TODO: Share with GBAUnloadROM
|
||||
if (gb->memory.rom && gb->memory.romBase != gb->memory.rom && gb->memory.romBase != gb->pristineRom) {
|
||||
if (gb->memory.rom && gb->memory.romBase != gb->memory.rom && !gb->isPristine) {
|
||||
free(gb->memory.romBase);
|
||||
}
|
||||
if (gb->memory.rom && gb->pristineRom != gb->memory.rom) {
|
||||
if (gb->memory.rom && !gb->isPristine) {
|
||||
if (gb->yankedRomSize) {
|
||||
gb->yankedRomSize = 0;
|
||||
}
|
||||
mappedMemoryFree(gb->memory.rom, GB_SIZE_CART_MAX);
|
||||
gb->memory.rom = gb->pristineRom;
|
||||
}
|
||||
gb->memory.rom = 0;
|
||||
|
||||
if (gb->romVf) {
|
||||
#ifndef _3DS
|
||||
gb->romVf->unmap(gb->romVf, gb->pristineRom, gb->pristineRomSize);
|
||||
gb->romVf->unmap(gb->romVf, gb->memory.rom, gb->pristineRomSize);
|
||||
#endif
|
||||
gb->romVf->close(gb->romVf);
|
||||
gb->romVf = 0;
|
||||
gb->romVf = NULL;
|
||||
}
|
||||
gb->pristineRom = 0;
|
||||
gb->memory.rom = NULL;
|
||||
gb->isPristine = false;
|
||||
|
||||
GBSavedataUnmask(gb);
|
||||
GBSramDeinit(gb);
|
||||
|
@ -317,14 +315,26 @@ void GBApplyPatch(struct GB* gb, struct Patch* patch) {
|
|||
if (patchedSize > GB_SIZE_CART_MAX) {
|
||||
patchedSize = GB_SIZE_CART_MAX;
|
||||
}
|
||||
gb->memory.rom = anonymousMemoryMap(GB_SIZE_CART_MAX);
|
||||
if (!patch->applyPatch(patch, gb->pristineRom, gb->pristineRomSize, gb->memory.rom, patchedSize)) {
|
||||
mappedMemoryFree(gb->memory.rom, patchedSize);
|
||||
gb->memory.rom = gb->pristineRom;
|
||||
void* newRom = anonymousMemoryMap(GB_SIZE_CART_MAX);
|
||||
if (!patch->applyPatch(patch, gb->memory.rom, gb->pristineRomSize, newRom, patchedSize)) {
|
||||
mappedMemoryFree(newRom, GB_SIZE_CART_MAX);
|
||||
return;
|
||||
}
|
||||
if (gb->romVf) {
|
||||
#ifndef _3DS
|
||||
gb->romVf->unmap(gb->romVf, gb->memory.rom, gb->pristineRomSize);
|
||||
#endif
|
||||
gb->romVf->close(gb->romVf);
|
||||
gb->romVf = NULL;
|
||||
}
|
||||
gb->isPristine = false;
|
||||
if (gb->memory.romBase == gb->memory.rom) {
|
||||
gb->memory.romBase = newRom;
|
||||
}
|
||||
gb->memory.rom = newRom;
|
||||
gb->memory.romSize = patchedSize;
|
||||
gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
|
||||
gb->cpu->memory.setActiveRegion(gb->cpu, gb->cpu->pc);
|
||||
}
|
||||
|
||||
void GBDestroy(struct GB* gb) {
|
||||
|
@ -652,9 +662,6 @@ void GBGetGameTitle(const struct GB* gb, char* out) {
|
|||
if (gb->memory.rom) {
|
||||
cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
||||
}
|
||||
if (gb->pristineRom) {
|
||||
cart = (const struct GBCartridge*) &((uint8_t*) gb->pristineRom)[0x100];
|
||||
}
|
||||
if (!cart) {
|
||||
return;
|
||||
}
|
||||
|
@ -671,9 +678,6 @@ void GBGetGameCode(const struct GB* gb, char* out) {
|
|||
if (gb->memory.rom) {
|
||||
cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
||||
}
|
||||
if (gb->pristineRom) {
|
||||
cart = (const struct GBCartridge*) &((uint8_t*) gb->pristineRom)[0x100];
|
||||
}
|
||||
if (!cart) {
|
||||
return;
|
||||
}
|
||||
|
|
33
src/gb/mbc.c
33
src/gb/mbc.c
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/internal/gb/mbc.h>
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
#include <mgba/internal/lr35902/lr35902.h>
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gb/memory.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
@ -28,18 +29,21 @@ static void _GBMBC6(struct GB*, uint16_t address, uint8_t value);
|
|||
static void _GBMBC7(struct GB*, uint16_t address, uint8_t value);
|
||||
static void _GBHuC3(struct GB*, uint16_t address, uint8_t value);
|
||||
|
||||
void GBMBCSwitchBank(struct GBMemory* memory, int bank) {
|
||||
void GBMBCSwitchBank(struct GB* gb, int bank) {
|
||||
size_t bankStart = bank * GB_SIZE_CART_BANK0;
|
||||
if (bankStart + GB_SIZE_CART_BANK0 > memory->romSize) {
|
||||
if (bankStart + GB_SIZE_CART_BANK0 > gb->memory.romSize) {
|
||||
mLOG(GB_MBC, GAME_ERROR, "Attempting to switch to an invalid ROM bank: %0X", bank);
|
||||
bankStart &= (memory->romSize - 1);
|
||||
bankStart &= (gb->memory.romSize - 1);
|
||||
bank = bankStart / GB_SIZE_CART_BANK0;
|
||||
if (!bank) {
|
||||
++bank;
|
||||
}
|
||||
}
|
||||
memory->romBank = &memory->rom[bankStart];
|
||||
memory->currentBank = bank;
|
||||
gb->memory.romBank = &gb->memory.rom[bankStart];
|
||||
gb->memory.currentBank = bank;
|
||||
if (gb->cpu->pc < GB_BASE_VRAM) {
|
||||
gb->cpu->memory.setActiveRegion(gb->cpu, gb->cpu->pc);
|
||||
}
|
||||
}
|
||||
|
||||
void GBMBCSwitchSramBank(struct GB* gb, int bank) {
|
||||
|
@ -249,12 +253,12 @@ void _GBMBC1(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
if (!bank) {
|
||||
++bank;
|
||||
}
|
||||
GBMBCSwitchBank(memory, bank | (memory->currentBank & 0x60));
|
||||
GBMBCSwitchBank(gb, bank | (memory->currentBank & 0x60));
|
||||
break;
|
||||
case 0x2:
|
||||
bank &= 3;
|
||||
if (!memory->mbcState.mbc1.mode) {
|
||||
GBMBCSwitchBank(memory, (bank << 5) | (memory->currentBank & 0x1F));
|
||||
GBMBCSwitchBank(gb, (bank << 5) | (memory->currentBank & 0x1F));
|
||||
} else {
|
||||
GBMBCSwitchSramBank(gb, bank);
|
||||
}
|
||||
|
@ -262,7 +266,7 @@ void _GBMBC1(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
case 0x3:
|
||||
memory->mbcState.mbc1.mode = value & 1;
|
||||
if (memory->mbcState.mbc1.mode) {
|
||||
GBMBCSwitchBank(memory, memory->currentBank & 0x1F);
|
||||
GBMBCSwitchBank(gb, memory->currentBank & 0x1F);
|
||||
} else {
|
||||
GBMBCSwitchSramBank(gb, 0);
|
||||
}
|
||||
|
@ -297,7 +301,7 @@ void _GBMBC2(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
if (!bank) {
|
||||
++bank;
|
||||
}
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
default:
|
||||
// TODO
|
||||
|
@ -328,7 +332,7 @@ void _GBMBC3(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
if (!bank) {
|
||||
++bank;
|
||||
}
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
case 0x2:
|
||||
if (value < 4) {
|
||||
|
@ -372,11 +376,11 @@ void _GBMBC5(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
break;
|
||||
case 0x2:
|
||||
bank = (memory->currentBank & 0x100) | value;
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
case 0x3:
|
||||
bank = (memory->currentBank & 0xFF) | ((value & 1) << 8);
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
|
@ -402,11 +406,10 @@ void _GBMBC6(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
}
|
||||
|
||||
void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
|
||||
struct GBMemory* memory = &gb->memory;
|
||||
int bank = value & 0x7F;
|
||||
switch (address >> 13) {
|
||||
case 0x1:
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
case 0x2:
|
||||
if (value < 0x10) {
|
||||
|
@ -616,7 +619,7 @@ void _GBHuC3(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
}
|
||||
break;
|
||||
case 0x1:
|
||||
GBMBCSwitchBank(memory, bank);
|
||||
GBMBCSwitchBank(gb, bank);
|
||||
break;
|
||||
case 0x2:
|
||||
GBMBCSwitchSramBank(gb, bank);
|
||||
|
|
|
@ -614,7 +614,7 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
memory->wramCurrentBank = state->memory.wramCurrentBank;
|
||||
memory->sramCurrentBank = state->memory.sramCurrentBank;
|
||||
|
||||
GBMBCSwitchBank(memory, memory->currentBank);
|
||||
GBMBCSwitchBank(gb, memory->currentBank);
|
||||
GBMemorySwitchWramBank(memory, memory->wramCurrentBank);
|
||||
GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
|
||||
|
||||
|
@ -651,14 +651,15 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
}
|
||||
|
||||
void _pristineCow(struct GB* gb) {
|
||||
if (gb->memory.rom != gb->pristineRom) {
|
||||
if (!gb->isPristine) {
|
||||
return;
|
||||
}
|
||||
gb->memory.rom = anonymousMemoryMap(GB_SIZE_CART_MAX);
|
||||
memcpy(gb->memory.rom, gb->pristineRom, gb->memory.romSize);
|
||||
memset(((uint8_t*) gb->memory.rom) + gb->memory.romSize, 0xFF, GB_SIZE_CART_MAX - gb->memory.romSize);
|
||||
if (gb->pristineRom == gb->memory.romBase) {
|
||||
gb->memory.romBase = gb->memory.rom;
|
||||
void* newRom = anonymousMemoryMap(GB_SIZE_CART_MAX);
|
||||
memcpy(newRom, gb->memory.rom, gb->memory.romSize);
|
||||
memset(((uint8_t*) newRom) + gb->memory.romSize, 0xFF, GB_SIZE_CART_MAX - gb->memory.romSize);
|
||||
if (gb->memory.rom == gb->memory.romBase) {
|
||||
gb->memory.romBase = newRom;
|
||||
}
|
||||
GBMBCSwitchBank(&gb->memory, gb->memory.currentBank);
|
||||
gb->memory.rom = newRom;
|
||||
GBMBCSwitchBank(gb, gb->memory.currentBank);
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ static void _GBACoreReset(struct mCore* core) {
|
|||
#endif
|
||||
|
||||
ARMReset(core->cpu);
|
||||
if (core->opts.skipBios && gba->pristineRom) {
|
||||
if (core->opts.skipBios && gba->isPristine) {
|
||||
GBASkipBIOS(core->board);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) {
|
|||
|
||||
gba->performingDMA = false;
|
||||
|
||||
gba->pristineRom = 0;
|
||||
gba->isPristine = false;
|
||||
gba->pristineRomSize = 0;
|
||||
gba->yankedRomSize = 0;
|
||||
|
||||
|
@ -112,22 +112,22 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) {
|
|||
}
|
||||
|
||||
void GBAUnloadROM(struct GBA* gba) {
|
||||
if (gba->memory.rom && gba->pristineRom != gba->memory.rom) {
|
||||
if (gba->memory.rom && !gba->isPristine) {
|
||||
if (gba->yankedRomSize) {
|
||||
gba->yankedRomSize = 0;
|
||||
}
|
||||
mappedMemoryFree(gba->memory.rom, SIZE_CART0);
|
||||
}
|
||||
gba->memory.rom = 0;
|
||||
|
||||
if (gba->romVf) {
|
||||
#ifndef _3DS
|
||||
gba->romVf->unmap(gba->romVf, gba->pristineRom, gba->pristineRomSize);
|
||||
gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize);
|
||||
#endif
|
||||
gba->romVf->close(gba->romVf);
|
||||
gba->romVf = 0;
|
||||
gba->romVf = NULL;
|
||||
}
|
||||
gba->pristineRom = 0;
|
||||
gba->memory.rom = NULL;
|
||||
gba->isPristine = false;
|
||||
|
||||
GBASavedataDeinit(&gba->memory.savedata);
|
||||
if (gba->memory.savedata.realVf) {
|
||||
|
@ -291,23 +291,23 @@ bool GBALoadMB(struct GBA* gba, struct VFile* vf) {
|
|||
if (gba->pristineRomSize > SIZE_WORKING_RAM) {
|
||||
gba->pristineRomSize = SIZE_WORKING_RAM;
|
||||
}
|
||||
gba->isPristine = true;
|
||||
#ifdef _3DS
|
||||
gba->pristineRom = 0;
|
||||
if (gba->pristineRomSize <= romBufferSize) {
|
||||
gba->pristineRom = romBuffer;
|
||||
gba->memory.wram = romBuffer;
|
||||
vf->read(vf, romBuffer, gba->pristineRomSize);
|
||||
}
|
||||
#else
|
||||
gba->pristineRom = vf->map(vf, gba->pristineRomSize, MAP_READ);
|
||||
gba->memory.wram = vf->map(vf, gba->pristineRomSize, MAP_READ);
|
||||
#endif
|
||||
if (!gba->pristineRom) {
|
||||
if (!gba->memory.wram) {
|
||||
mLOG(GBA, WARN, "Couldn't map ROM");
|
||||
return false;
|
||||
}
|
||||
gba->yankedRomSize = 0;
|
||||
gba->memory.romSize = 0;
|
||||
gba->memory.romMask = 0;
|
||||
gba->romCrc32 = doCrc32(gba->pristineRom, gba->pristineRomSize);
|
||||
gba->romCrc32 = doCrc32(gba->memory.wram, gba->pristineRomSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -322,21 +322,20 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
|
|||
if (gba->pristineRomSize > SIZE_CART0) {
|
||||
gba->pristineRomSize = SIZE_CART0;
|
||||
}
|
||||
gba->isPristine = true;
|
||||
#ifdef _3DS
|
||||
gba->pristineRom = 0;
|
||||
if (gba->pristineRomSize <= romBufferSize) {
|
||||
gba->pristineRom = romBuffer;
|
||||
gba->memory.rom = romBuffer;
|
||||
vf->read(vf, romBuffer, gba->pristineRomSize);
|
||||
}
|
||||
#else
|
||||
gba->pristineRom = vf->map(vf, gba->pristineRomSize, MAP_READ);
|
||||
gba->memory.rom = vf->map(vf, gba->pristineRomSize, MAP_READ);
|
||||
#endif
|
||||
if (!gba->pristineRom) {
|
||||
if (!gba->memory.rom) {
|
||||
mLOG(GBA, WARN, "Couldn't map ROM");
|
||||
return false;
|
||||
}
|
||||
gba->yankedRomSize = 0;
|
||||
gba->memory.rom = gba->pristineRom;
|
||||
gba->memory.romSize = gba->pristineRomSize;
|
||||
gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
|
||||
gba->memory.mirroring = false;
|
||||
|
@ -389,12 +388,21 @@ void GBAApplyPatch(struct GBA* gba, struct Patch* patch) {
|
|||
if (!patchedSize || patchedSize > SIZE_CART0) {
|
||||
return;
|
||||
}
|
||||
gba->memory.rom = anonymousMemoryMap(SIZE_CART0);
|
||||
if (!patch->applyPatch(patch, gba->pristineRom, gba->pristineRomSize, gba->memory.rom, patchedSize)) {
|
||||
mappedMemoryFree(gba->memory.rom, patchedSize);
|
||||
gba->memory.rom = gba->pristineRom;
|
||||
void* newRom = anonymousMemoryMap(SIZE_CART0);
|
||||
if (!patch->applyPatch(patch, gba->memory.rom, gba->pristineRomSize, newRom, patchedSize)) {
|
||||
mappedMemoryFree(newRom, SIZE_CART0);
|
||||
return;
|
||||
}
|
||||
if (gba->romVf) {
|
||||
#ifndef _3DS
|
||||
gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize);
|
||||
#endif
|
||||
gba->romVf->close(gba->romVf);
|
||||
gba->romVf = NULL;
|
||||
}
|
||||
gba->isPristine = false;
|
||||
gba->memory.rom = newRom;
|
||||
gba->memory.hw.gpioBase = &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1];
|
||||
gba->memory.romSize = patchedSize;
|
||||
gba->memory.romMask = SIZE_CART0 - 1;
|
||||
gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
|
||||
|
@ -540,8 +548,8 @@ void GBAGetGameTitle(const struct GBA* gba, char* out) {
|
|||
memcpy(out, &((struct GBACartridge*) gba->memory.rom)->title, 12);
|
||||
return;
|
||||
}
|
||||
if (gba->pristineRom) {
|
||||
memcpy(out, &((struct GBACartridge*) gba->pristineRom)->title, 12);
|
||||
if (gba->isPristine && gba->memory.wram) {
|
||||
memcpy(out, &((struct GBACartridge*) gba->memory.wram)->title, 12);
|
||||
return;
|
||||
}
|
||||
strncpy(out, "(BIOS)", 12);
|
||||
|
|
|
@ -102,13 +102,12 @@ void GBAMemoryDeinit(struct GBA* gba) {
|
|||
}
|
||||
|
||||
void GBAMemoryReset(struct GBA* gba) {
|
||||
if (gba->memory.wram) {
|
||||
mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
|
||||
}
|
||||
gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
|
||||
if (gba->pristineRom && !gba->memory.rom) {
|
||||
// Multiboot
|
||||
memcpy(gba->memory.wram, gba->pristineRom, gba->pristineRomSize);
|
||||
if (gba->memory.rom || gb->fullBios) {
|
||||
// Not multiboot
|
||||
if (gba->memory.wram) {
|
||||
mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
|
||||
}
|
||||
gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
|
||||
}
|
||||
|
||||
if (gba->memory.iwram) {
|
||||
|
@ -1541,10 +1540,19 @@ void GBAMemoryDeserialize(struct GBAMemory* memory, const struct GBASerializedSt
|
|||
}
|
||||
|
||||
void _pristineCow(struct GBA* gba) {
|
||||
if (gba->memory.rom != gba->pristineRom) {
|
||||
if (!gba->isPristine) {
|
||||
return;
|
||||
}
|
||||
gba->memory.rom = anonymousMemoryMap(SIZE_CART0);
|
||||
memcpy(gba->memory.rom, gba->pristineRom, gba->memory.romSize);
|
||||
memset(((uint8_t*) gba->memory.rom) + gba->memory.romSize, 0xFF, SIZE_CART0 - gba->memory.romSize);
|
||||
void* newRom = anonymousMemoryMap(SIZE_CART0);
|
||||
memcpy(newRom, gba->memory.rom, gba->memory.romSize);
|
||||
memset(((uint8_t*) newRom) + gba->memory.romSize, 0xFF, SIZE_CART0 - gba->memory.romSize);
|
||||
if (gba->romVf) {
|
||||
#ifndef _3DS
|
||||
gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->memory.romSize);
|
||||
#endif
|
||||
gba->romVf->close(gba->romVf);
|
||||
gba->romVf = NULL;
|
||||
}
|
||||
gba->memory.rom = newRom;
|
||||
gba->memory.hw.gpioBase = &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue