GBA: Yank support, needs work

This commit is contained in:
Jeffrey Pfau 2015-06-19 01:12:46 -07:00
parent d524148469
commit af4d5d7eb1
7 changed files with 28 additions and 2 deletions

View File

@ -21,6 +21,7 @@ Features:
- Finer control over FPS target - Finer control over FPS target
- Holdable shortcut for rewinding one frame at a time - Holdable shortcut for rewinding one frame at a time
- Ability to boot directly into the BIOS - Ability to boot directly into the BIOS
- Preliminary support for yanking out the game pak while a game is running
Bugfixes: Bugfixes:
- ARM7: Fix SWI and IRQ timings - ARM7: Fix SWI and IRQ timings
- GBA Audio: Force audio FIFOs to 32-bit - GBA Audio: Force audio FIFOs to 32-bit

View File

@ -376,6 +376,7 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char
GBALog(gba, GBA_LOG_WARN, "Couldn't map ROM"); GBALog(gba, GBA_LOG_WARN, "Couldn't map ROM");
return; return;
} }
gba->yankedRomSize = 0;
gba->memory.rom = gba->pristineRom; gba->memory.rom = gba->pristineRom;
gba->activeFile = fname; gba->activeFile = fname;
gba->memory.romSize = gba->pristineRomSize; gba->memory.romSize = gba->pristineRomSize;
@ -385,6 +386,11 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char
// TODO: error check // TODO: error check
} }
void GBAYankROM(struct GBA* gba) {
gba->yankedRomSize = gba->memory.romSize;
gba->memory.romSize = 0;
}
void GBALoadBIOS(struct GBA* gba, struct VFile* vf) { void GBALoadBIOS(struct GBA* gba, struct VFile* vf) {
gba->biosVf = vf; gba->biosVf = vf;
uint32_t* bios = vf->map(vf, SIZE_BIOS, MAP_READ); uint32_t* bios = vf->map(vf, SIZE_BIOS, MAP_READ);

View File

@ -146,6 +146,7 @@ struct GBA {
struct GBARRContext* rr; struct GBARRContext* rr;
void* pristineRom; void* pristineRom;
size_t pristineRomSize; size_t pristineRomSize;
size_t yankedRomSize;
uint32_t romCrc32; uint32_t romCrc32;
struct VFile* romVf; struct VFile* romVf;
struct VFile* biosVf; struct VFile* biosVf;
@ -206,6 +207,7 @@ void GBASetBreakpoint(struct GBA* gba, struct ARMComponent* component, uint32_t
void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mode, uint32_t opcode); void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mode, uint32_t opcode);
void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname); void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname);
void GBAYankROM(struct GBA* gba);
void GBALoadBIOS(struct GBA* gba, struct VFile* vf); void GBALoadBIOS(struct GBA* gba, struct VFile* vf);
void GBAApplyPatch(struct GBA* gba, struct Patch* patch); void GBAApplyPatch(struct GBA* gba, struct Patch* patch);

View File

@ -18,7 +18,7 @@
static uint32_t _popcount32(unsigned bits); static uint32_t _popcount32(unsigned bits);
static void _pristineCow(struct GBA* gba); static void _pristineCow(struct GBA* gba);
static uint32_t _deadbeef[2] = { 0xDEADBEEF, 0xFEEDFACE }; static uint32_t _deadbeef[1] = { 0xF00FC7C8 };
static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region); static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info); static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
@ -273,7 +273,9 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
memory->activeRegion = 0; memory->activeRegion = 0;
cpu->memory.activeRegion = _deadbeef; cpu->memory.activeRegion = _deadbeef;
cpu->memory.activeMask = 0; cpu->memory.activeMask = 0;
GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address"); if (!gba->yankedRomSize) {
GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
}
break; break;
} }
cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion]; cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];

View File

@ -325,6 +325,15 @@ void GameController::loadBIOS(const QString& path) {
} }
} }
void GameController::yankPak() {
if (!m_gameOpen) {
return;
}
threadInterrupt();
GBAYankROM(m_threadContext.gba);
threadContinue();
}
void GameController::loadPatch(const QString& path) { void GameController::loadPatch(const QString& path) {
if (m_gameOpen) { if (m_gameOpen) {
closeGame(); closeGame();

View File

@ -97,6 +97,7 @@ signals:
public slots: public slots:
void loadGame(const QString& path, bool dirmode = false); void loadGame(const QString& path, bool dirmode = false);
void loadBIOS(const QString& path); void loadBIOS(const QString& path);
void yankPak();
void setSkipBIOS(bool); void setSkipBIOS(bool);
void setUseBIOS(bool); void setUseBIOS(bool);
void loadPatch(const QString& path); void loadPatch(const QString& path);

View File

@ -698,6 +698,11 @@ void Window::setupMenu(QMenuBar* menubar) {
connect(shutdown, SIGNAL(triggered()), m_controller, SLOT(closeGame())); connect(shutdown, SIGNAL(triggered()), m_controller, SLOT(closeGame()));
m_gameActions.append(shutdown); m_gameActions.append(shutdown);
addControlledAction(emulationMenu, shutdown, "shutdown"); addControlledAction(emulationMenu, shutdown, "shutdown");
QAction* yank = new QAction(tr("Yank game pak"), emulationMenu);
connect(yank, SIGNAL(triggered()), m_controller, SLOT(yankPak()));
m_gameActions.append(yank);
addControlledAction(emulationMenu, yank, "yank");
emulationMenu->addSeparator(); emulationMenu->addSeparator();
QAction* pause = new QAction(tr("&Pause"), emulationMenu); QAction* pause = new QAction(tr("&Pause"), emulationMenu);