mirror of https://github.com/mgba-emu/mgba.git
Add ability to run code indefinitely (or at least until we crash)
This commit is contained in:
parent
dbe9796b34
commit
e5379c99e0
|
@ -28,6 +28,7 @@ static const char* ERROR_MISSING_ARGS = "Arguments missing";
|
||||||
typedef void (DebuggerComamnd)(struct ARMDebugger*, struct DebugVector*);
|
typedef void (DebuggerComamnd)(struct ARMDebugger*, struct DebugVector*);
|
||||||
|
|
||||||
static void _breakInto(struct ARMDebugger*, struct DebugVector*);
|
static void _breakInto(struct ARMDebugger*, struct DebugVector*);
|
||||||
|
static void _continue(struct ARMDebugger*, struct DebugVector*);
|
||||||
static void _print(struct ARMDebugger*, struct DebugVector*);
|
static void _print(struct ARMDebugger*, struct DebugVector*);
|
||||||
static void _printHex(struct ARMDebugger*, struct DebugVector*);
|
static void _printHex(struct ARMDebugger*, struct DebugVector*);
|
||||||
static void _printStatus(struct ARMDebugger*, struct DebugVector*);
|
static void _printStatus(struct ARMDebugger*, struct DebugVector*);
|
||||||
|
@ -40,6 +41,8 @@ struct {
|
||||||
const char* name;
|
const char* name;
|
||||||
DebuggerComamnd* command;
|
DebuggerComamnd* command;
|
||||||
} debuggerCommands[] = {
|
} debuggerCommands[] = {
|
||||||
|
{ "c", _continue },
|
||||||
|
{ "continue", _continue },
|
||||||
{ "i", _printStatus },
|
{ "i", _printStatus },
|
||||||
{ "info", _printStatus },
|
{ "info", _printStatus },
|
||||||
{ "p", _print },
|
{ "p", _print },
|
||||||
|
@ -80,6 +83,11 @@ static void _breakInto(struct ARMDebugger* debugger, struct DebugVector* dv) {
|
||||||
signal(SIGTRAP, oldSignal);
|
signal(SIGTRAP, oldSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _continue(struct ARMDebugger* debugger, struct DebugVector* dv) {
|
||||||
|
(void)(dv);
|
||||||
|
debugger->state = DEBUGGER_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
static void _print(struct ARMDebugger* debugger, struct DebugVector* dv) {
|
static void _print(struct ARMDebugger* debugger, struct DebugVector* dv) {
|
||||||
(void)(debugger);
|
(void)(debugger);
|
||||||
for ( ; dv; dv = dv->next) {
|
for ( ; dv; dv = dv->next) {
|
||||||
|
@ -441,19 +449,37 @@ static void _parse(struct ARMDebugger* debugger, const char* line) {
|
||||||
|
|
||||||
void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
|
void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
|
||||||
debugger->cpu = cpu;
|
debugger->cpu = cpu;
|
||||||
|
debugger->state = DEBUGGER_PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMDebuggerRun(struct ARMDebugger* debugger) {
|
||||||
|
while (debugger->state != DEBUGGER_EXITING) {
|
||||||
|
while (debugger->state == DEBUGGER_RUNNING) {
|
||||||
|
ARMRun(debugger->cpu);
|
||||||
|
}
|
||||||
|
switch (debugger->state) {
|
||||||
|
case DEBUGGER_PAUSED:
|
||||||
|
ARMDebuggerEnter(debugger);
|
||||||
|
break;
|
||||||
|
case DEBUGGER_EXITING:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
// Should never be reached
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMDebuggerEnter(struct ARMDebugger* debugger) {
|
void ARMDebuggerEnter(struct ARMDebugger* debugger) {
|
||||||
char* line;
|
char* line;
|
||||||
_printStatus(debugger, 0);
|
_printStatus(debugger, 0);
|
||||||
while ((line = linenoise("> "))) {
|
while (debugger->state == DEBUGGER_PAUSED) {
|
||||||
|
line = linenoise("> ");
|
||||||
|
if (!line) {
|
||||||
|
debugger->state = DEBUGGER_EXITING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
_parse(debugger, line);
|
_parse(debugger, line);
|
||||||
free(line);
|
free(line);
|
||||||
switch (debugger->state) {
|
|
||||||
case DEBUGGER_EXITING:
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct ARMDebugger {
|
||||||
};
|
};
|
||||||
|
|
||||||
void ARMDebuggerInit(struct ARMDebugger*, struct ARMCore*);
|
void ARMDebuggerInit(struct ARMDebugger*, struct ARMCore*);
|
||||||
|
void ARMDebuggerRun(struct ARMDebugger*);
|
||||||
void ARMDebuggerEnter(struct ARMDebugger*);
|
void ARMDebuggerEnter(struct ARMDebugger*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "gba.h"
|
#include "gba.h"
|
||||||
|
|
||||||
|
#include "debugger.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -76,6 +79,11 @@ void GBABoardReset(struct ARMBoard* board) {
|
||||||
cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
|
cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger) {
|
||||||
|
ARMDebuggerInit(debugger, &gba->cpu);
|
||||||
|
gba->debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
void GBALoadROM(struct GBA* gba, int fd) {
|
void GBALoadROM(struct GBA* gba, int fd) {
|
||||||
gba->memory.rom = mmap(0, SIZE_CART0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
|
gba->memory.rom = mmap(0, SIZE_CART0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
|
||||||
// TODO: error check
|
// TODO: error check
|
||||||
|
@ -382,4 +390,5 @@ void GBALog(int level, const char* format, ...) {
|
||||||
|
|
||||||
void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
|
void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
|
||||||
GBALog(GBA_LOG_STUB, "Stub opcode: %08x", opcode);
|
GBALog(GBA_LOG_STUB, "Stub opcode: %08x", opcode);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,8 @@ struct GBA {
|
||||||
struct GBABoard board;
|
struct GBABoard board;
|
||||||
struct GBAMemory memory;
|
struct GBAMemory memory;
|
||||||
|
|
||||||
|
struct ARMDebugger* debugger;
|
||||||
|
|
||||||
enum GBAError errno;
|
enum GBAError errno;
|
||||||
const char* errstr;
|
const char* errstr;
|
||||||
};
|
};
|
||||||
|
@ -105,6 +107,8 @@ void GBAMemoryDeinit(struct GBAMemory* memory);
|
||||||
void GBABoardInit(struct GBABoard* board);
|
void GBABoardInit(struct GBABoard* board);
|
||||||
void GBABoardReset(struct ARMBoard* board);
|
void GBABoardReset(struct ARMBoard* board);
|
||||||
|
|
||||||
|
void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);
|
||||||
|
|
||||||
void GBALoadROM(struct GBA* gba, int fd);
|
void GBALoadROM(struct GBA* gba, int fd);
|
||||||
|
|
||||||
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address);
|
int32_t GBALoad32(struct ARMMemory* memory, uint32_t address);
|
||||||
|
|
|
@ -14,8 +14,8 @@ int main(int argc, char** argv) {
|
||||||
GBALoadROM(&gba, fd);
|
GBALoadROM(&gba, fd);
|
||||||
gba.cpu.gprs[ARM_PC] = 0x08000004;
|
gba.cpu.gprs[ARM_PC] = 0x08000004;
|
||||||
gba.memory.d.setActiveRegion(&gba.memory.d, gba.cpu.gprs[ARM_PC]);
|
gba.memory.d.setActiveRegion(&gba.memory.d, gba.cpu.gprs[ARM_PC]);
|
||||||
ARMDebuggerInit(&debugger, &gba.cpu);
|
GBAAttachDebugger(&gba, &debugger);
|
||||||
ARMDebuggerEnter(&debugger);
|
ARMDebuggerRun(&debugger);
|
||||||
GBADeinit(&gba);
|
GBADeinit(&gba);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue