GBA Core: Export reduced GBA ROM region size if the ROM is less than 32 MiB

This commit is contained in:
Vicki Pfau 2023-09-12 00:17:17 -07:00
parent 022e009a75
commit b2dd7611ea
1 changed files with 60 additions and 16 deletions

View File

@ -187,8 +187,29 @@ struct GBACore {
struct mDebuggerPlatform* debuggerPlatform; struct mDebuggerPlatform* debuggerPlatform;
struct mCheatDevice* cheatDevice; struct mCheatDevice* cheatDevice;
struct GBAAudioMixer* audioMixer; struct GBAAudioMixer* audioMixer;
struct mCoreMemoryBlock memoryBlocks[12];
size_t nMemoryBlocks;
int memoryBlockType;
}; };
#define _MAX(A, B) ((A > B) ? (A) : (B))
static_assert(sizeof(((struct GBACore*) 0)->memoryBlocks) >=
_MAX(
_MAX(
sizeof(_GBAMemoryBlocksSRAM),
_MAX(
sizeof(_GBAMemoryBlocksFlash512),
sizeof(_GBAMemoryBlocksFlash1M)
)
),
_MAX(
sizeof(_GBAMemoryBlocksEEPROM),
sizeof(_GBAMemoryBlocks)
)
),
"GBACore memoryBlocks sized too small");
#undef _MAX
static bool _GBACoreInit(struct mCore* core) { static bool _GBACoreInit(struct mCore* core) {
struct GBACore* gbacore = (struct GBACore*) core; struct GBACore* gbacore = (struct GBACore*) core;
@ -548,6 +569,7 @@ static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
} }
static bool _GBACoreLoadROM(struct mCore* core, struct VFile* vf) { static bool _GBACoreLoadROM(struct mCore* core, struct VFile* vf) {
struct GBACore* gbacore = (struct GBACore*) core;
#ifdef USE_ELF #ifdef USE_ELF
struct ELF* elf = ELFOpen(vf); struct ELF* elf = ELFOpen(vf);
if (elf) { if (elf) {
@ -565,6 +587,7 @@ static bool _GBACoreLoadROM(struct mCore* core, struct VFile* vf) {
if (GBAIsMB(vf)) { if (GBAIsMB(vf)) {
return GBALoadMB(core->board, vf); return GBALoadMB(core->board, vf);
} }
gbacore->memoryBlockType = -2;
return GBALoadROM(core->board, vf); return GBALoadROM(core->board, vf);
} }
@ -698,6 +721,7 @@ static void _GBACoreReset(struct mCore* core) {
if (!vbaBugCompat) { if (!vbaBugCompat) {
gba->vbaBugCompat = false; gba->vbaBugCompat = false;
} }
gbacore->memoryBlockType = -2;
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
if (!gba->biosVf && core->opts.useBios) { if (!gba->biosVf && core->opts.useBios) {
@ -940,23 +964,43 @@ static void _GBACoreRawWrite32(struct mCore* core, uint32_t address, int segment
size_t _GBACoreListMemoryBlocks(const struct mCore* core, const struct mCoreMemoryBlock** blocks) { size_t _GBACoreListMemoryBlocks(const struct mCore* core, const struct mCoreMemoryBlock** blocks) {
const struct GBA* gba = core->board; const struct GBA* gba = core->board;
switch (gba->memory.savedata.type) { struct GBACore* gbacore = (struct GBACore*) core;
case SAVEDATA_SRAM:
*blocks = _GBAMemoryBlocksSRAM; if (gbacore->memoryBlockType != gba->memory.savedata.type) {
return sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM); switch (gba->memory.savedata.type) {
case SAVEDATA_FLASH512: case SAVEDATA_SRAM:
*blocks = _GBAMemoryBlocksFlash512; memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM, sizeof(_GBAMemoryBlocksSRAM));
return sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM);
case SAVEDATA_FLASH1M: break;
*blocks = _GBAMemoryBlocksFlash1M; case SAVEDATA_FLASH512:
return sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash512, sizeof(_GBAMemoryBlocksFlash512));
case SAVEDATA_EEPROM: gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512);
*blocks = _GBAMemoryBlocksEEPROM; break;
return sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM); case SAVEDATA_FLASH1M:
default: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash1M, sizeof(_GBAMemoryBlocksFlash1M));
*blocks = _GBAMemoryBlocks; gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M);
return sizeof(_GBAMemoryBlocks) / sizeof(*_GBAMemoryBlocks); break;
case SAVEDATA_EEPROM:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM, sizeof(_GBAMemoryBlocksEEPROM));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM);
break;
default:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocks, sizeof(_GBAMemoryBlocks));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocks) / sizeof(*_GBAMemoryBlocks);
break;
}
size_t i;
for (i = 0; i < gbacore->nMemoryBlocks; ++i) {
if (gbacore->memoryBlocks[i].id == GBA_REGION_ROM0 || gbacore->memoryBlocks[i].id == GBA_REGION_ROM1 || gbacore->memoryBlocks[i].id == GBA_REGION_ROM2) {
gbacore->memoryBlocks[i].size = gba->memory.romSize;
}
}
gbacore->memoryBlockType = gba->memory.savedata.type;
} }
*blocks = gbacore->memoryBlocks;
return gbacore->nMemoryBlocks;
} }
void* _GBACoreGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) { void* _GBACoreGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) {