mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add get/set register functions
This commit is contained in:
parent
a2447d09e3
commit
d484c98eba
|
@ -84,6 +84,9 @@ struct mDebuggerPlatform {
|
||||||
void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
|
void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
||||||
void (*trace)(struct mDebuggerPlatform*, char* out, size_t* length);
|
void (*trace)(struct mDebuggerPlatform*, char* out, size_t* length);
|
||||||
|
|
||||||
|
bool (*getRegister)(struct mDebuggerPlatform*, const char* name, int32_t* value);
|
||||||
|
bool (*setRegister)(struct mDebuggerPlatform*, const char* name, int32_t value);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mDebuggerSymbols;
|
struct mDebuggerSymbols;
|
||||||
|
|
|
@ -14,6 +14,7 @@ CXX_GUARD_START
|
||||||
|
|
||||||
extern const char* ERROR_MISSING_ARGS;
|
extern const char* ERROR_MISSING_ARGS;
|
||||||
extern const char* ERROR_OVERFLOW;
|
extern const char* ERROR_OVERFLOW;
|
||||||
|
extern const char* ERROR_INVALID_ARGS;
|
||||||
|
|
||||||
struct CLIDebugger;
|
struct CLIDebugger;
|
||||||
|
|
||||||
|
@ -51,7 +52,6 @@ struct CLIDebuggerSystem {
|
||||||
|
|
||||||
void (*disassemble)(struct CLIDebuggerSystem*, struct CLIDebugVector* dv);
|
void (*disassemble)(struct CLIDebuggerSystem*, struct CLIDebugVector* dv);
|
||||||
uint32_t (*lookupIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
|
uint32_t (*lookupIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
|
||||||
uint32_t (*lookupPlatformIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
|
|
||||||
void (*printStatus)(struct CLIDebuggerSystem*);
|
void (*printStatus)(struct CLIDebuggerSystem*);
|
||||||
|
|
||||||
struct CLIDebuggerCommandSummary* commands;
|
struct CLIDebuggerCommandSummary* commands;
|
||||||
|
|
|
@ -17,7 +17,6 @@ static void _disassembleArm(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _disassembleThumb(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _disassembleThumb(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _setBreakpointARM(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _setBreakpointARM(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _setBreakpointThumb(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _setBreakpointThumb(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _writeRegister(struct CLIDebugger*, struct CLIDebugVector*);
|
|
||||||
|
|
||||||
static void _disassembleMode(struct CLIDebugger*, struct CLIDebugVector*, enum ExecutionMode mode);
|
static void _disassembleMode(struct CLIDebugger*, struct CLIDebugVector*, enum ExecutionMode mode);
|
||||||
static uint32_t _printLine(struct CLIDebugger* debugger, uint32_t address, enum ExecutionMode mode);
|
static uint32_t _printLine(struct CLIDebugger* debugger, uint32_t address, enum ExecutionMode mode);
|
||||||
|
@ -33,7 +32,6 @@ static struct CLIDebuggerCommandSummary _armCommands[] = {
|
||||||
{ "disasm/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" },
|
{ "disasm/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" },
|
||||||
{ "disassemble/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" },
|
{ "disassemble/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" },
|
||||||
{ "disassemble/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" },
|
{ "disassemble/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" },
|
||||||
{ "w/r", _writeRegister, "SI", "Write a register" },
|
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,31 +143,6 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
||||||
_printLine(debugger->p, cpu->gprs[ARM_PC] - instructionLength, mode);
|
_printLine(debugger->p, cpu->gprs[ARM_PC] - instructionLength, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _writeRegister(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
|
||||||
struct CLIDebuggerBackend* be = debugger->backend;
|
|
||||||
struct ARMCore* cpu = debugger->d.core->cpu;
|
|
||||||
if (!dv || dv->type != CLIDV_CHAR_TYPE) {
|
|
||||||
be->printf(be, "%s\n", ERROR_MISSING_ARGS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!dv->next || dv->next->type != CLIDV_INT_TYPE) {
|
|
||||||
be->printf(be, "%s\n", ERROR_MISSING_ARGS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char* end;
|
|
||||||
uint32_t regid = strtoul(&dv->charValue[1], &end, 10);
|
|
||||||
if (dv->charValue[0] != 'r' || (*end && !isspace(*end)) || regid > ARM_PC) {
|
|
||||||
be->printf(be, "%s\n", "Unknown register name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (regid == ARM_PC) {
|
|
||||||
be->printf(be, "%s\n", "Cannot write to program counter");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint32_t value = dv->next->intValue;
|
|
||||||
cpu->gprs[regid] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _setBreakpointARM(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _setBreakpointARM(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
struct CLIDebuggerBackend* be = debugger->backend;
|
struct CLIDebuggerBackend* be = debugger->backend;
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
||||||
|
@ -190,38 +163,9 @@ static void _setBreakpointThumb(struct CLIDebugger* debugger, struct CLIDebugVec
|
||||||
ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_THUMB);
|
ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_THUMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _lookupPlatformIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
|
|
||||||
struct ARMCore* cpu = debugger->p->d.core->cpu;
|
|
||||||
if (strcmp(name, "sp") == 0) {
|
|
||||||
return cpu->gprs[ARM_SP];
|
|
||||||
}
|
|
||||||
if (strcmp(name, "lr") == 0) {
|
|
||||||
return cpu->gprs[ARM_LR];
|
|
||||||
}
|
|
||||||
if (strcmp(name, "pc") == 0) {
|
|
||||||
return cpu->gprs[ARM_PC];
|
|
||||||
}
|
|
||||||
if (strcmp(name, "cpsr") == 0) {
|
|
||||||
return cpu->cpsr.packed;
|
|
||||||
}
|
|
||||||
// TODO: test if mode has SPSR
|
|
||||||
if (strcmp(name, "spsr") == 0) {
|
|
||||||
return cpu->spsr.packed;
|
|
||||||
}
|
|
||||||
if (name[0] == 'r' && name[1] >= '0' && name[1] <= '9') {
|
|
||||||
int reg = atoi(&name[1]);
|
|
||||||
if (reg < 16) {
|
|
||||||
return cpu->gprs[reg];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dv->type = CLIDV_ERROR_TYPE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARMCLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
|
void ARMCLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
|
||||||
debugger->printStatus = _printStatus;
|
debugger->printStatus = _printStatus;
|
||||||
debugger->disassemble = _disassemble;
|
debugger->disassemble = _disassemble;
|
||||||
debugger->lookupPlatformIdentifier = _lookupPlatformIdentifier;
|
|
||||||
debugger->platformName = "ARM";
|
debugger->platformName = "ARM";
|
||||||
debugger->platformCommands = _armCommands;
|
debugger->platformCommands = _armCommands;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t addre
|
||||||
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
||||||
static bool ARMDebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
static bool ARMDebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
||||||
static void ARMDebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
|
static void ARMDebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
|
||||||
|
static bool ARMDebuggerGetRegister(struct mDebuggerPlatform*, const char* name, int32_t* value);
|
||||||
|
static bool ARMDebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value);
|
||||||
|
|
||||||
struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void) {
|
struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void) {
|
||||||
struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct ARMDebugger));
|
struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct ARMDebugger));
|
||||||
|
@ -69,6 +71,8 @@ struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void) {
|
||||||
platform->checkBreakpoints = ARMDebuggerCheckBreakpoints;
|
platform->checkBreakpoints = ARMDebuggerCheckBreakpoints;
|
||||||
platform->hasBreakpoints = ARMDebuggerHasBreakpoints;
|
platform->hasBreakpoints = ARMDebuggerHasBreakpoints;
|
||||||
platform->trace = ARMDebuggerTrace;
|
platform->trace = ARMDebuggerTrace;
|
||||||
|
platform->getRegister = ARMDebuggerGetRegister;
|
||||||
|
platform->setRegister = ARMDebuggerSetRegister;
|
||||||
return platform;
|
return platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,3 +250,81 @@ static void ARMDebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* len
|
||||||
cpu->gprs[12], cpu->gprs[13], cpu->gprs[14], cpu->gprs[15],
|
cpu->gprs[12], cpu->gprs[13], cpu->gprs[14], cpu->gprs[15],
|
||||||
cpu->cpsr.packed, disassembly);
|
cpu->cpsr.packed, disassembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARMDebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, int32_t* value) {
|
||||||
|
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
||||||
|
struct ARMCore* cpu = debugger->cpu;
|
||||||
|
|
||||||
|
if (strcmp(name, "sp") == 0) {
|
||||||
|
*value = cpu->gprs[ARM_SP];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "lr") == 0) {
|
||||||
|
*value = cpu->gprs[ARM_LR];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "pc") == 0) {
|
||||||
|
*value = cpu->gprs[ARM_PC];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "cpsr") == 0) {
|
||||||
|
*value = cpu->cpsr.packed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// TODO: test if mode has SPSR
|
||||||
|
if (strcmp(name, "spsr") == 0) {
|
||||||
|
*value = cpu->spsr.packed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (name[0] == 'r') {
|
||||||
|
char* end;
|
||||||
|
uint32_t reg = strtoul(&name[1], &end, 10);
|
||||||
|
if (reg <= ARM_PC) {
|
||||||
|
*value = cpu->gprs[reg];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32_t value) {
|
||||||
|
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
||||||
|
struct ARMCore* cpu = debugger->cpu;
|
||||||
|
|
||||||
|
if (strcmp(name, "sp") == 0) {
|
||||||
|
cpu->gprs[ARM_SP] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "lr") == 0) {
|
||||||
|
cpu->gprs[ARM_LR] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "pc") == 0) {
|
||||||
|
cpu->gprs[ARM_PC] = value;
|
||||||
|
int32_t currentCycles = 0;
|
||||||
|
if (cpu->executionMode == MODE_ARM) {
|
||||||
|
ARM_WRITE_PC;
|
||||||
|
} else {
|
||||||
|
THUMB_WRITE_PC;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (name[0] == 'r') {
|
||||||
|
char* end;
|
||||||
|
uint32_t reg = strtoul(&name[1], &end, 10);
|
||||||
|
if (reg > ARM_PC) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cpu->gprs[reg] = value;
|
||||||
|
if (reg == ARM_PC) {
|
||||||
|
int32_t currentCycles = 0;
|
||||||
|
if (cpu->executionMode == MODE_ARM) {
|
||||||
|
ARM_WRITE_PC;
|
||||||
|
} else {
|
||||||
|
THUMB_WRITE_PC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
|
const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
|
||||||
const char* ERROR_OVERFLOW = "Arguments overflow";
|
const char* ERROR_OVERFLOW = "Arguments overflow";
|
||||||
|
const char* ERROR_INVALID_ARGS = "Invalid arguments";
|
||||||
|
|
||||||
#if !defined(NDEBUG) && !defined(_WIN32)
|
#if !defined(NDEBUG) && !defined(_WIN32)
|
||||||
static void _breakInto(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _breakInto(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
@ -51,6 +52,7 @@ static void _setWriteWatchpoint(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _trace(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _trace(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _writeByte(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _writeByte(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _writeHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _writeHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
static void _writeRegister(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _writeWord(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _writeWord(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
@ -92,6 +94,7 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = {
|
||||||
{ "w", _setWatchpoint, "I", "Set a watchpoint" },
|
{ "w", _setWatchpoint, "I", "Set a watchpoint" },
|
||||||
{ "w/1", _writeByte, "II", "Write a byte at a specified offset" },
|
{ "w/1", _writeByte, "II", "Write a byte at a specified offset" },
|
||||||
{ "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" },
|
{ "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" },
|
||||||
|
{ "w/r", _writeRegister, "SI", "Write a register" },
|
||||||
{ "w/4", _writeWord, "II", "Write a word at a specified offset" },
|
{ "w/4", _writeWord, "II", "Write a word at a specified offset" },
|
||||||
{ "watch", _setWatchpoint, "I", "Set a watchpoint" },
|
{ "watch", _setWatchpoint, "I", "Set a watchpoint" },
|
||||||
{ "watch/r", _setReadWatchpoint, "I", "Set a read watchpoint" },
|
{ "watch/r", _setReadWatchpoint, "I", "Set a read watchpoint" },
|
||||||
|
@ -273,12 +276,12 @@ static void _readWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _writeByte(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _writeByte(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || !dv->next) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!dv->next || dv->next->type != CLIDV_INT_TYPE) {
|
if (dv->type != CLIDV_INT_TYPE || dv->next->type != CLIDV_INT_TYPE) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t address = dv->intValue;
|
uint32_t address = dv->intValue;
|
||||||
|
@ -295,12 +298,12 @@ static void _writeByte(struct CLIDebugger* debugger, struct CLIDebugVector* dv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _writeHalfword(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _writeHalfword(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || !dv->next) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!dv->next || dv->next->type != CLIDV_INT_TYPE) {
|
if (dv->type != CLIDV_INT_TYPE || dv->next->type != CLIDV_INT_TYPE) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t address = dv->intValue;
|
uint32_t address = dv->intValue;
|
||||||
|
@ -316,15 +319,29 @@ static void _writeHalfword(struct CLIDebugger* debugger, struct CLIDebugVector*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _writeWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _writeRegister(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || !dv->next) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!dv->next || dv->next->type != CLIDV_INT_TYPE) {
|
if (dv->type != CLIDV_CHAR_TYPE || dv->next->type != CLIDV_INT_TYPE) {
|
||||||
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!debugger->d.platform->setRegister(debugger->d.platform, dv->charValue, dv->next->intValue)) {
|
||||||
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _writeWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
|
if (!dv || !dv->next) {
|
||||||
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (dv->type != CLIDV_INT_TYPE || dv->next->type != CLIDV_INT_TYPE) {
|
||||||
|
debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint32_t address = dv->intValue;
|
uint32_t address = dv->intValue;
|
||||||
uint32_t value = dv->next->intValue;
|
uint32_t value = dv->next->intValue;
|
||||||
if (dv->segmentValue >= 0) {
|
if (dv->segmentValue >= 0) {
|
||||||
|
@ -559,12 +576,10 @@ static void _lookupIdentifier(struct mDebugger* debugger, const char* name, stru
|
||||||
if (debugger->core->symbolTable && mDebuggerSymbolLookup(debugger->core->symbolTable, name, &dv->intValue, &dv->segmentValue)) {
|
if (debugger->core->symbolTable && mDebuggerSymbolLookup(debugger->core->symbolTable, name, &dv->intValue, &dv->segmentValue)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value = cliDebugger->system->lookupPlatformIdentifier(cliDebugger->system, name, dv);
|
dv->type = CLIDV_INT_TYPE;
|
||||||
if (dv->type != CLIDV_ERROR_TYPE) {
|
if (debugger->platform->getRegister(debugger->platform, name, &dv->intValue)) {
|
||||||
dv->intValue = value;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dv->type = CLIDV_INT_TYPE;
|
|
||||||
value = cliDebugger->system->lookupIdentifier(cliDebugger->system, name, dv);
|
value = cliDebugger->system->lookupIdentifier(cliDebugger->system, name, dv);
|
||||||
if (dv->type != CLIDV_ERROR_TYPE) {
|
if (dv->type != CLIDV_ERROR_TYPE) {
|
||||||
dv->intValue = value;
|
dv->intValue = value;
|
||||||
|
|
|
@ -100,58 +100,9 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
||||||
_printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc));
|
_printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _lookupPlatformIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
|
|
||||||
struct LR35902Core* cpu = debugger->p->d.core->cpu;
|
|
||||||
if (strcmp(name, "a") == 0) {
|
|
||||||
return cpu->a;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "b") == 0) {
|
|
||||||
return cpu->b;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "c") == 0) {
|
|
||||||
return cpu->c;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "d") == 0) {
|
|
||||||
return cpu->d;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "e") == 0) {
|
|
||||||
return cpu->e;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "h") == 0) {
|
|
||||||
return cpu->h;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "l") == 0) {
|
|
||||||
return cpu->l;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "bc") == 0) {
|
|
||||||
return cpu->bc;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "de") == 0) {
|
|
||||||
return cpu->de;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "hl") == 0) {
|
|
||||||
return cpu->hl;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "af") == 0) {
|
|
||||||
return cpu->af;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "pc") == 0) {
|
|
||||||
return cpu->pc;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "sp") == 0) {
|
|
||||||
return cpu->sp;
|
|
||||||
}
|
|
||||||
if (strcmp(name, "f") == 0) {
|
|
||||||
return cpu->f.packed;
|
|
||||||
}
|
|
||||||
dv->type = CLIDV_ERROR_TYPE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LR35902CLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
|
void LR35902CLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
|
||||||
debugger->printStatus = _printStatus;
|
debugger->printStatus = _printStatus;
|
||||||
debugger->disassemble = _disassemble;
|
debugger->disassemble = _disassemble;
|
||||||
debugger->lookupPlatformIdentifier = _lookupPlatformIdentifier;
|
|
||||||
debugger->platformName = "GB-Z80";
|
debugger->platformName = "GB-Z80";
|
||||||
debugger->platformCommands = _lr35902Commands;
|
debugger->platformCommands = _lr35902Commands;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ static void LR35902DebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t a
|
||||||
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
||||||
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
||||||
static void LR35902DebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
|
static void LR35902DebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
|
||||||
|
static bool LR35902DebuggerGetRegister(struct mDebuggerPlatform*, const char* name, int32_t* value);
|
||||||
|
static bool LR35902DebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value);
|
||||||
|
|
||||||
struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) {
|
struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) {
|
||||||
struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger));
|
struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger));
|
||||||
|
@ -63,6 +65,8 @@ struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) {
|
||||||
platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints;
|
platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints;
|
||||||
platform->hasBreakpoints = LR35902DebuggerHasBreakpoints;
|
platform->hasBreakpoints = LR35902DebuggerHasBreakpoints;
|
||||||
platform->trace = LR35902DebuggerTrace;
|
platform->trace = LR35902DebuggerTrace;
|
||||||
|
platform->getRegister = LR35902DebuggerGetRegister;
|
||||||
|
platform->setRegister = LR35902DebuggerSetRegister;
|
||||||
return platform;
|
return platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,3 +172,131 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t*
|
||||||
cpu->d, cpu->e, cpu->h, cpu->l,
|
cpu->d, cpu->e, cpu->h, cpu->l,
|
||||||
cpu->sp, cpu->pc, disassembly);
|
cpu->sp, cpu->pc, disassembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LR35902DebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, int32_t* value) {
|
||||||
|
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
||||||
|
struct LR35902Core* cpu = debugger->cpu;
|
||||||
|
|
||||||
|
if (strcmp(name, "a") == 0) {
|
||||||
|
*value = cpu->a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "b") == 0) {
|
||||||
|
*value = cpu->b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "c") == 0) {
|
||||||
|
*value = cpu->c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "d") == 0) {
|
||||||
|
*value = cpu->d;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "e") == 0) {
|
||||||
|
*value = cpu->e;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "h") == 0) {
|
||||||
|
*value = cpu->h;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "l") == 0) {
|
||||||
|
*value = cpu->l;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "bc") == 0) {
|
||||||
|
*value = cpu->bc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "de") == 0) {
|
||||||
|
*value = cpu->de;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "hl") == 0) {
|
||||||
|
*value = cpu->hl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "af") == 0) {
|
||||||
|
*value = cpu->af;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "pc") == 0) {
|
||||||
|
*value = cpu->pc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "sp") == 0) {
|
||||||
|
*value = cpu->sp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "f") == 0) {
|
||||||
|
*value = cpu->f.packed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LR35902DebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32_t value) {
|
||||||
|
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
||||||
|
struct LR35902Core* cpu = debugger->cpu;
|
||||||
|
|
||||||
|
if (strcmp(name, "a") == 0) {
|
||||||
|
cpu->a = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "b") == 0) {
|
||||||
|
cpu->b = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "c") == 0) {
|
||||||
|
cpu->c = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "d") == 0) {
|
||||||
|
cpu->d = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "e") == 0) {
|
||||||
|
cpu->e = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "h") == 0) {
|
||||||
|
cpu->h = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "l") == 0) {
|
||||||
|
cpu->l = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "bc") == 0) {
|
||||||
|
cpu->bc = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "de") == 0) {
|
||||||
|
cpu->de = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "hl") == 0) {
|
||||||
|
cpu->hl = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "af") == 0) {
|
||||||
|
cpu->af = value;
|
||||||
|
cpu->f.packed &= 0xF0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "pc") == 0) {
|
||||||
|
cpu->pc = value;
|
||||||
|
cpu->memory.setActiveRegion(cpu, cpu->pc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "sp") == 0) {
|
||||||
|
cpu->sp = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "f") == 0) {
|
||||||
|
cpu->f.packed = value & 0xF0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue