mirror of https://github.com/mgba-emu/mgba.git
GBA Unlicensed Carts: Improve bank swapping behavior
This commit is contained in:
parent
bdb0057fb3
commit
822a2c8df5
|
@ -10,7 +10,7 @@
|
||||||
#include <mgba/internal/gba/serialize.h>
|
#include <mgba/internal/gba/serialize.h>
|
||||||
#include <mgba-util/vfs.h>
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
#define MULTI_SETTLE 512
|
#define MULTI_SETTLE 300
|
||||||
#define MULTI_BLOCK 0x80000
|
#define MULTI_BLOCK 0x80000
|
||||||
#define MULTI_BANK 0x2000000
|
#define MULTI_BANK 0x2000000
|
||||||
|
|
||||||
|
@ -94,18 +94,24 @@ void GBAUnlCartWriteSRAM(struct GBA* gba, uint32_t address, uint8_t value) {
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case GBA_MULTICART_CFG_BANK:
|
case GBA_MULTICART_CFG_BANK:
|
||||||
unl->multi.bank = value >> 4;
|
unl->multi.bank = value >> 4;
|
||||||
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
if (!(unl->multi.offset & 0x80)) {
|
||||||
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
||||||
|
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GBA_MULTICART_CFG_OFFSET:
|
case GBA_MULTICART_CFG_OFFSET:
|
||||||
unl->multi.offset = value & 0x3F;
|
unl->multi.offset = value;
|
||||||
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
if (!(unl->multi.offset & 0x80)) {
|
||||||
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
||||||
|
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GBA_MULTICART_CFG_SIZE:
|
case GBA_MULTICART_CFG_SIZE:
|
||||||
unl->multi.size = 0x40 - (value & 0x3F);
|
unl->multi.size = 0x40 - (value & 0x3F);
|
||||||
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
if (!(unl->multi.offset & 0x80)) {
|
||||||
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
mTimingDeschedule(&gba->timing, &unl->multi.settle);
|
||||||
|
mTimingSchedule(&gba->timing, &unl->multi.settle, MULTI_SETTLE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GBA_MULTICART_CFG_SRAM:
|
case GBA_MULTICART_CFG_SRAM:
|
||||||
if (value == 0 && unl->multi.sramActive) {
|
if (value == 0 && unl->multi.sramActive) {
|
||||||
|
@ -147,8 +153,8 @@ static void _multicartSettle(struct mTiming* timing, void* context, uint32_t cyc
|
||||||
UNUSED(cyclesLate);
|
UNUSED(cyclesLate);
|
||||||
struct GBA* gba = context;
|
struct GBA* gba = context;
|
||||||
mLOG(GBA_MEM, INFO, "Switching to bank %i offset %i, size %i",
|
mLOG(GBA_MEM, INFO, "Switching to bank %i offset %i, size %i",
|
||||||
gba->memory.unl.multi.bank, gba->memory.unl.multi.offset, gba->memory.unl.multi.size);
|
gba->memory.unl.multi.bank, gba->memory.unl.multi.offset & 0x3F, gba->memory.unl.multi.size);
|
||||||
size_t offset = gba->memory.unl.multi.bank * (MULTI_BANK >> 2) + gba->memory.unl.multi.offset * (MULTI_BLOCK >> 2);
|
size_t offset = gba->memory.unl.multi.bank * (MULTI_BANK >> 2) + (gba->memory.unl.multi.offset & 0x3F) * (MULTI_BLOCK >> 2);
|
||||||
size_t size = gba->memory.unl.multi.size * MULTI_BLOCK;
|
size_t size = gba->memory.unl.multi.size * MULTI_BLOCK;
|
||||||
if (offset * 4 >= gba->memory.unl.multi.fullSize || offset * 4 + size > gba->memory.unl.multi.fullSize) {
|
if (offset * 4 >= gba->memory.unl.multi.fullSize || offset * 4 + size > gba->memory.unl.multi.fullSize) {
|
||||||
mLOG(GBA_MEM, GAME_ERROR, "Bank switch was out of bounds, %07" PRIz "X + %" PRIz "X > %07" PRIz "X",
|
mLOG(GBA_MEM, GAME_ERROR, "Bank switch was out of bounds, %07" PRIz "X + %" PRIz "X > %07" PRIz "X",
|
||||||
|
|
Loading…
Reference in New Issue