aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2016-11-05 17:56:15 -0500
committerColin Snover2016-11-20 12:31:43 -0600
commit9380b541204e2ec446d75627b8fad1b78850f356 (patch)
tree16340e97cc926cd44332c7bad5b1cb74c9467055 /engines
parent1af7fe8b9616c5ade0af00b7720db0b4967471ff (diff)
downloadscummvm-rg350-9380b541204e2ec446d75627b8fad1b78850f356.tar.gz
scummvm-rg350-9380b541204e2ec446d75627b8fad1b78850f356.tar.bz2
scummvm-rg350-9380b541204e2ec446d75627b8fad1b78850f356.zip
SCI: Add code-address breakpoints to debugger
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/console.cpp30
-rw-r--r--engines/sci/console.h1
-rw-r--r--engines/sci/debug.h8
-rw-r--r--engines/sci/engine/scriptdebug.cpp16
-rw-r--r--engines/sci/engine/vm.cpp2
-rw-r--r--engines/sci/sci.h1
6 files changed, 56 insertions, 2 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 83f1271252..4028974c83 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -201,6 +201,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
registerCmd("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
registerCmd("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
registerCmd("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
+ registerCmd("bp_address", WRAP_METHOD(Console, cmdBreakpointAddress));
+ registerCmd("bpa", WRAP_METHOD(Console, cmdBreakpointAddress)); // alias
registerCmd("bp_method", WRAP_METHOD(Console, cmdBreakpointMethod));
registerCmd("bpx", WRAP_METHOD(Console, cmdBreakpointMethod)); // alias
registerCmd("bp_read", WRAP_METHOD(Console, cmdBreakpointRead));
@@ -435,6 +437,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
debugPrintf("Breakpoints:\n");
debugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
debugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
+ debugPrintf(" bp_address / bpa - Sets a breakpoint on a script address\n");
debugPrintf(" bp_method / bpx - Sets a breakpoint on the execution of a specified method/selector\n");
debugPrintf(" bp_read / bpr - Sets a breakpoint on reading of a specified selector\n");
debugPrintf(" bp_write / bpw - Sets a breakpoint on writing to a specified selector\n");
@@ -3738,6 +3741,8 @@ bool Console::cmdBreakpointList(int argc, const char **argv) {
bpdata = bp->address;
debugPrintf("Execute script %d, export %d\n", bpdata >> 16, bpdata & 0xFFFF);
break;
+ case BREAK_ADDRESS:
+ debugPrintf("Execute address %04x:%04x\n", PRINT_REG(bp->regAddress));
}
i++;
@@ -3894,6 +3899,31 @@ bool Console::cmdBreakpointFunction(int argc, const char **argv) {
return true;
}
+bool Console::cmdBreakpointAddress(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Sets a breakpoint on the execution of the specified code address.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ return true;
+ }
+
+ reg_t addr;
+
+ if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ Breakpoint bp;
+ bp.type = BREAK_ADDRESS;
+ bp.regAddress = make_reg32(addr.getSegment(), addr.getOffset());
+
+ _debugState._breakpoints.push_back(bp);
+ _debugState._activeBreakpointTypes |= BREAK_ADDRESS;
+
+ return true;
+}
+
bool Console::cmdSfx01Header(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Dumps the header of a SCI01 song\n");
diff --git a/engines/sci/console.h b/engines/sci/console.h
index d4b17ee802..7dd1572340 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -152,6 +152,7 @@ private:
bool cmdBreakpointWrite(int argc, const char **argv);
bool cmdBreakpointKernel(int argc, const char **argv);
bool cmdBreakpointFunction(int argc, const char **argv);
+ bool cmdBreakpointAddress(int argc, const char **argv);
// VM
bool cmdScriptSteps(int argc, const char **argv);
bool cmdScriptObjects(int argc, const char **argv);
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index 4fcb757c10..60fad26671 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -42,12 +42,16 @@ enum BreakpointType {
* Break when an exported function is called. Data contains
* script_no << 16 | export_no.
*/
- BREAK_EXPORT = 1 << 3
+ BREAK_EXPORT = 1 << 3,
+ BREAK_ADDRESS = 1 << 4 // break when pc is at this address
};
struct Breakpoint {
BreakpointType type;
- uint32 address; ///< Breakpoints on exports
+ union {
+ uint32 address; ///< Breakpoints on exports
+ reg32_t regAddress; ///< Breakpoints on addresses
+ };
Common::String name; ///< Breakpoints on selector names
};
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index b017e62df7..47b360d13b 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -631,6 +631,22 @@ bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
return false;
}
+bool SciEngine::checkAddressBreakpoint(const reg32_t &address) {
+ if (_debugState._activeBreakpointTypes & BREAK_ADDRESS) {
+ Common::List<Breakpoint>::const_iterator bp;
+ for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
+ if (bp->type == BREAK_ADDRESS && bp->regAddress == address) {
+ _console->debugPrintf("Break at %04x:%04x\n", PRINT_REG(address));
+ _debugState.debugging = true;
+ _debugState.breakpointWasHit = true;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType) {
int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
const char *objectName = segMan->getObjectName(send_obj);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index ac15aebf3a..e82128ebad 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -634,6 +634,8 @@ void run_vm(EngineState *s) {
if (s->abortScriptProcessing != kAbortNone)
return; // Stop processing
+ g_sci->checkAddressBreakpoint(s->xs->addr.pc);
+
// Debug if this has been requested:
// TODO: re-implement sci_debug_flags
if (g_sci->_debugState.debugging /* sci_debug_flags*/) {
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 61dccb4aba..7d248906cf 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -334,6 +334,7 @@ public:
void scriptDebug();
bool checkExportBreakpoint(uint16 script, uint16 pubfunct);
bool checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector);
+ bool checkAddressBreakpoint(const reg32_t &address);
void patchGameSaveRestore();