mirror of https://github.com/mgba-emu/mgba.git
GBA: Yank support, needs work
This commit is contained in:
parent
d524148469
commit
af4d5d7eb1
1
CHANGES
1
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue