all repos — mgba @ a44a8f668f6a54a4b4ee3e5853d504b2708f8458

mGBA Game Boy Advance Emulator

GB: Add yanking
Vicki Pfau vi@endrift.com
Sat, 07 Sep 2019 18:32:37 -0700
commit

a44a8f668f6a54a4b4ee3e5853d504b2708f8458

parent

7c8d253123733d667e271668f00bacceb390175d

M CHANGESCHANGES

@@ -20,6 +20,7 @@ - GBA Cheats: Add support for loading EZ Flash-style cht files

- Support for unlicensed Wisdom Tree Game Boy mapper - Qt: Add export button for tile view (closes mgba.io/i/1507) - Qt: Add recent game list clearing (closes mgba.io/i/1380) + - GB: Yanking gamepak now supported Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs
M include/mgba/internal/gb/gb.hinclude/mgba/internal/gb/gb.h

@@ -94,6 +94,7 @@

bool isPristine; size_t pristineRomSize; size_t yankedRomSize; + enum GBMemoryBankControllerType yankedMbc; uint32_t romCrc32; struct VFile* romVf; struct VFile* biosVf;

@@ -163,6 +164,7 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf);

bool GBLoadSave(struct GB* gb, struct VFile* vf); void GBUnloadROM(struct GB* gb); void GBSynthesizeROM(struct VFile* vf); +void GBYankROM(struct GB* gb); void GBLoadBIOS(struct GB* gb, struct VFile* vf);
M src/gb/gb.csrc/gb/gb.c

@@ -127,6 +127,19 @@ // TODO: error check

return true; } +void GBYankROM(struct GB* gb) { + gb->yankedRomSize = gb->memory.romSize; + gb->yankedMbc = gb->memory.mbcType; + gb->memory.romSize = 0; + gb->memory.mbcType = GB_MBC_NONE; + gb->memory.sramAccess = false; + + if (gb->cpu) { + struct LR35902Core* cpu = gb->cpu; + cpu->memory.setActiveRegion(cpu, cpu->pc); + } +} + static void GBSramDeinit(struct GB* gb) { if (gb->sramVf) { gb->sramVf->unmap(gb->sramVf, gb->memory.sram, gb->sramSize);

@@ -430,6 +443,7 @@ gb->doubleSpeed = 0;

if (gb->yankedRomSize) { gb->memory.romSize = gb->yankedRomSize; + gb->memory.mbcType = gb->yankedMbc; gb->yankedRomSize = 0; }
M src/gb/io.csrc/gb/io.c

@@ -458,6 +458,9 @@ GBVideoWriteSTAT(&gb->video, value);

value = gb->video.stat; break; case 0x50: + if (gb->memory.io[0x50] != 0xFF) { + break; + } GBUnmapBIOS(gb); if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_UNK4C] < 0x80) { gb->model = GB_MODEL_DMG;
M src/gb/memory.csrc/gb/memory.c

@@ -16,6 +16,8 @@ #include <mgba-util/memory.h>

mLOG_DEFINE_CATEGORY(GB_MEM, "GB Memory", "gb.memory"); +static const uint8_t _yankBuffer[] = { 0xFF }; + enum GBBus { GB_BUS_CPU, GB_BUS_MAIN,

@@ -69,6 +71,14 @@ cpu->memory.cpuLoad8 = GBFastLoad8;

cpu->memory.activeRegion = memory->romBase; cpu->memory.activeRegionEnd = GB_BASE_CART_BANK1; cpu->memory.activeMask = GB_SIZE_CART_BANK0 - 1; + if (gb->memory.romSize < GB_SIZE_CART_BANK0) { + if (address >= gb->memory.romSize) { + cpu->memory.activeRegion = _yankBuffer; + cpu->memory.activeMask = 0; + } else { + cpu->memory.activeRegionEnd = gb->memory.romSize; + } + } break; case GB_REGION_CART_BANK1: case GB_REGION_CART_BANK1 + 1:

@@ -87,6 +97,14 @@ cpu->memory.activeRegionEnd = GB_BASE_VRAM;

} else { cpu->memory.activeRegion = memory->romBank; cpu->memory.activeRegionEnd = GB_BASE_CART_BANK1 + 0x2000; + } + } + if (gb->memory.romSize < GB_SIZE_CART_BANK0 * 2) { + if (address >= gb->memory.romSize) { + cpu->memory.activeRegion = _yankBuffer; + cpu->memory.activeMask = 0; + } else { + cpu->memory.activeRegionEnd = gb->memory.romSize; } } break;

@@ -243,6 +261,9 @@ case GB_REGION_CART_BANK0:

case GB_REGION_CART_BANK0 + 1: case GB_REGION_CART_BANK0 + 2: case GB_REGION_CART_BANK0 + 3: + if (address >= memory->romSize) { + return 0xFF; + } return memory->romBase[address & (GB_SIZE_CART_BANK0 - 1)]; case GB_REGION_CART_BANK1 + 2: case GB_REGION_CART_BANK1 + 3:

@@ -252,6 +273,9 @@ }

// Fall through case GB_REGION_CART_BANK1: case GB_REGION_CART_BANK1 + 1: + if (address >= memory->romSize) { + return 0xFF; + } return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)]; case GB_REGION_VRAM: case GB_REGION_VRAM + 1:
M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -628,13 +628,16 @@ mCoreLoadFile(m_threadContext.core, fname.toUtf8().constData());

} void CoreController::yankPak() { -#ifdef M_CORE_GBA - if (platform() != PLATFORM_GBA) { - return; + Interrupter interrupter(this); + + switch (platform()) { + case PLATFORM_GBA: + GBAYankROM(static_cast<GBA*>(m_threadContext.core->board)); + break; + case PLATFORM_GB: + GBYankROM(static_cast<GB*>(m_threadContext.core->board)); + break; } - Interrupter interrupter(this); - GBAYankROM(static_cast<GBA*>(m_threadContext.core->board)); -#endif } void CoreController::addKey(int key) {
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -1212,12 +1212,10 @@ addGameAction(tr("Sh&utdown"), "shutdown", [this]() {

m_controller->stop(); }, "emu"); -#ifdef M_CORE_GBA Action* yank = addGameAction(tr("Yank game pak"), "yank", [this]() { m_controller->yankPak(); }, "emu"); - m_platformActions.insert(PLATFORM_GBA, yank); -#endif + m_actions.addSeparator("emu"); Action* pause = m_actions.addBooleanAction(tr("&Pause"), "pause", [this](bool paused) {