aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormd52011-03-27 01:43:36 +0200
committermd52011-03-27 01:52:23 +0200
commit6487d05ddf4ae25d49918f9a2f8b70903c8855d3 (patch)
tree26d8e6535b63a07ca0e48fe307a8032c2a84c6c9
parent6501a8609507dbf4f0d0ef976911e2f225ef6f52 (diff)
downloadscummvm-rg350-6487d05ddf4ae25d49918f9a2f8b70903c8855d3.tar.gz
scummvm-rg350-6487d05ddf4ae25d49918f9a2f8b70903c8855d3.tar.bz2
scummvm-rg350-6487d05ddf4ae25d49918f9a2f8b70903c8855d3.zip
SCI: Moved some debug functions from vm.cpp to scriptdebug.cpp
-rw-r--r--engines/sci/engine/scriptdebug.cpp186
-rw-r--r--engines/sci/engine/vm.cpp188
2 files changed, 189 insertions, 185 deletions
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 76490217c3..857b074678 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -281,8 +281,7 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
return retval;
}
-bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget)
-{
+bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);
if (!mobj)
return false;
@@ -571,4 +570,187 @@ void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) {
debugN("Script ends without terminator\n");
}
+bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector) {
+ Common::String methodName = _gamestate->_segMan->getObjectName(send_obj);
+ methodName += ("::" + getKernel()->getSelectorName(selector));
+
+ Common::List<Breakpoint>::const_iterator bpIter;
+ for (bpIter = _debugState._breakpoints.begin(); bpIter != _debugState._breakpoints.end(); ++bpIter) {
+ if ((*bpIter).type == breakpointType && (*bpIter).name == methodName) {
+ _console->DebugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
+ _debugState.debugging = true;
+ _debugState.breakpointWasHit = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
+ if (_debugState._activeBreakpointTypes & BREAK_EXPORT) {
+ uint32 bpaddress = (script << 16 | pubfunct);
+
+ Common::List<Breakpoint>::const_iterator bp;
+ for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
+ if (bp->type == BREAK_EXPORT && bp->address == bpaddress) {
+ _console->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
+ _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);
+ const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();
+ Console *con = g_sci->getSciDebugger();
+
+#ifdef VM_DEBUG_SEND
+ debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
+ s->_segMan->getObjectName(send_obj), selector,
+ g_sci->getKernel()->getSelectorName(selector).c_str());
+#endif // VM_DEBUG_SEND
+
+ switch (selectorType) {
+ case kSelectorNone:
+ break;
+ case kSelectorVariable:
+#ifdef VM_DEBUG_SEND
+ if (argc)
+ debugN("Varselector: Write %04x:%04x\n", PRINT_REG(argp[1]));
+ else
+ debugN("Varselector: Read\n");
+#endif // VM_DEBUG_SEND
+
+ // argc == 0: read selector
+ // argc == 1: write selector
+ // argc can be bigger than 1 in some cases, because of a script bug.
+ // Usually, these aren't fatal.
+ if ((activeBreakpointTypes & BREAK_SELECTORREAD) ||
+ (activeBreakpointTypes & BREAK_SELECTORWRITE) ||
+ argc > 1) {
+
+ reg_t selectorValue = *varp.getPointer(segMan);
+ if (!argc && (activeBreakpointTypes & BREAK_SELECTORREAD)) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
+ con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue));
+ } else if (argc && (activeBreakpointTypes & BREAK_SELECTORWRITE)) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector))
+ con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue), PRINT_REG(argp[1]));
+ }
+
+ if (argc > 1)
+ debug(kDebugLevelScripts, "Write to selector (%s:%s): change %04x:%04x to %04x:%04x, argc == %d\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue), PRINT_REG(argp[1]), argc);
+ }
+ break;
+ case kSelectorMethod:
+#ifndef VM_DEBUG_SEND
+ if (activeBreakpointTypes & BREAK_SELECTOREXEC) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector)) {
+#else
+ if (true) {
+ if (true) {
+#endif
+ con->DebugPrintf("%s::%s(", objectName, selectorName);
+ for (int i = 0; i < argc; i++) {
+ con->DebugPrintf("%04x:%04x", PRINT_REG(argp[i+1]));
+ if (i + 1 < argc)
+ con->DebugPrintf(", ");
+ }
+ con->DebugPrintf(") at %04x:%04x\n", PRINT_REG(funcp));
+ }
+ }
+ break;
+ } // switch
+}
+
+void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result) {
+ Kernel *kernel = g_sci->getKernel();
+ if (!kernelSubCall) {
+ debugN("k%s: ", kernelCall->name);
+ } else {
+ int callNameLen = strlen(kernelCall->name);
+ if (strncmp(kernelCall->name, kernelSubCall->name, callNameLen) == 0) {
+ const char *subCallName = kernelSubCall->name + callNameLen;
+ debugN("k%s(%s): ", kernelCall->name, subCallName);
+ } else {
+ debugN("k%s(%s): ", kernelCall->name, kernelSubCall->name);
+ }
+ }
+ for (int parmNr = 0; parmNr < argc; parmNr++) {
+ if (parmNr)
+ debugN(", ");
+ uint16 regType = kernel->findRegType(argv[parmNr]);
+ if (regType & SIG_TYPE_NULL)
+ debugN("0");
+ else if (regType & SIG_TYPE_UNINITIALIZED)
+ debugN("UNINIT");
+ else if (regType & SIG_IS_INVALID)
+ debugN("INVALID");
+ else if (regType & SIG_TYPE_INTEGER)
+ debugN("%d", argv[parmNr].offset);
+ else {
+ debugN("%04x:%04x", PRINT_REG(argv[parmNr]));
+ switch (regType) {
+ case SIG_TYPE_OBJECT:
+ debugN(" (%s)", s->_segMan->getObjectName(argv[parmNr]));
+ break;
+ case SIG_TYPE_REFERENCE:
+ {
+ SegmentObj *mobj = s->_segMan->getSegmentObj(argv[parmNr].segment);
+ switch (mobj->getType()) {
+ case SEG_TYPE_HUNK:
+ {
+ HunkTable *ht = (HunkTable*)mobj;
+ int index = argv[parmNr].offset;
+ if (ht->isValidEntry(index)) {
+ // NOTE: This ", deleted" isn't as useful as it could
+ // be because it prints the status _after_ the kernel
+ // call.
+ debugN(" ('%s' hunk%s)", ht->_table[index].type, ht->_table[index].mem ? "" : ", deleted");
+ } else
+ debugN(" (INVALID hunk ref)");
+ break;
+ }
+ default:
+ // TODO: Any other segment types which could
+ // use special handling?
+
+ if (kernelCall->function == kSaid) {
+ SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]);
+ if (saidSpec.isRaw) {
+ debugN(" ('");
+ g_sci->getVocabulary()->debugDecipherSaidBlock(saidSpec.raw);
+ debugN("')");
+ } else {
+ debugN(" (non-raw said-spec)");
+ }
+ } else {
+ debugN(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str());
+ }
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ }
+ }
+ if (result.isPointer())
+ debugN(" = %04x:%04x\n", PRINT_REG(result));
+ else
+ debugN(" = %d\n", result.offset);
+}
+
} // End of namespace Sci
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 89e8ed787f..f1e1980064 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -257,112 +257,6 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
return &(s->_executionStack.back());
}
-bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector) {
- Common::String methodName = _gamestate->_segMan->getObjectName(send_obj);
- methodName += ("::" + getKernel()->getSelectorName(selector));
-
- Common::List<Breakpoint>::const_iterator bpIter;
- for (bpIter = _debugState._breakpoints.begin(); bpIter != _debugState._breakpoints.end(); ++bpIter) {
- if ((*bpIter).type == breakpointType && (*bpIter).name == methodName) {
- _console->DebugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
- _debugState.debugging = true;
- _debugState.breakpointWasHit = true;
- return true;
- }
- }
- return false;
-}
-
-bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
- if (_debugState._activeBreakpointTypes & BREAK_EXPORT) {
- uint32 bpaddress = (script << 16 | pubfunct);
-
- Common::List<Breakpoint>::const_iterator bp;
- for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
- if (bp->type == BREAK_EXPORT && bp->address == bpaddress) {
- _console->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
- _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);
- const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();
- Console *con = g_sci->getSciDebugger();
-
-#ifdef VM_DEBUG_SEND
- debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
- s->_segMan->getObjectName(send_obj), selector,
- g_sci->getKernel()->getSelectorName(selector).c_str());
-#endif // VM_DEBUG_SEND
-
- switch (selectorType) {
- case kSelectorNone:
- break;
- case kSelectorVariable:
-#ifdef VM_DEBUG_SEND
- if (argc)
- debugN("Varselector: Write %04x:%04x\n", PRINT_REG(argp[1]));
- else
- debugN("Varselector: Read\n");
-#endif // VM_DEBUG_SEND
-
- // argc == 0: read selector
- // argc == 1: write selector
- // argc can be bigger than 1 in some cases, because of a script bug.
- // Usually, these aren't fatal.
- if ((activeBreakpointTypes & BREAK_SELECTORREAD) ||
- (activeBreakpointTypes & BREAK_SELECTORWRITE) ||
- argc > 1) {
-
- reg_t selectorValue = *varp.getPointer(segMan);
- if (!argc && (activeBreakpointTypes & BREAK_SELECTORREAD)) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
- con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
- objectName, selectorName,
- PRINT_REG(selectorValue));
- } else if (argc && (activeBreakpointTypes & BREAK_SELECTORWRITE)) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector))
- con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
- objectName, selectorName,
- PRINT_REG(selectorValue), PRINT_REG(argp[1]));
- }
-
- if (argc > 1)
- debug(kDebugLevelScripts, "Write to selector (%s:%s): change %04x:%04x to %04x:%04x, argc == %d\n",
- objectName, selectorName,
- PRINT_REG(selectorValue), PRINT_REG(argp[1]), argc);
- }
- break;
- case kSelectorMethod:
-#ifndef VM_DEBUG_SEND
- if (activeBreakpointTypes & BREAK_SELECTOREXEC) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector)) {
-#else
- if (true) {
- if (true) {
-#endif
- con->DebugPrintf("%s::%s(", objectName, selectorName);
- for (int i = 0; i < argc; i++) {
- con->DebugPrintf("%04x:%04x", PRINT_REG(argp[i+1]));
- if (i + 1 < argc)
- con->DebugPrintf(", ");
- }
- con->DebugPrintf(") at %04x:%04x\n", PRINT_REG(funcp));
- }
- }
- break;
- } // switch
-}
-
-
static void _exec_varselectors(EngineState *s) {
// Executes all varselector read/write ops on the TOS
while (!s->_executionStack.empty() && s->_executionStack.back().type == EXEC_STACK_TYPE_VARSELECTOR) {
@@ -382,6 +276,9 @@ static void _exec_varselectors(EngineState *s) {
}
}
+// from scriptdebug.cpp
+extern void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType);
+
ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPtr sp, int framesize, StackPtr argp) {
// send_obj and work_obj are equal for anything but 'super'
// Returns a pointer to the TOS exec_stack element
@@ -453,83 +350,8 @@ static void addKernelCallToExecStack(EngineState *s, int kernelCallNr, int argc,
s->_executionStack.push_back(xstack);
}
-static void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result) {
- Kernel *kernel = g_sci->getKernel();
- if (!kernelSubCall) {
- debugN("k%s: ", kernelCall->name);
- } else {
- int callNameLen = strlen(kernelCall->name);
- if (strncmp(kernelCall->name, kernelSubCall->name, callNameLen) == 0) {
- const char *subCallName = kernelSubCall->name + callNameLen;
- debugN("k%s(%s): ", kernelCall->name, subCallName);
- } else {
- debugN("k%s(%s): ", kernelCall->name, kernelSubCall->name);
- }
- }
- for (int parmNr = 0; parmNr < argc; parmNr++) {
- if (parmNr)
- debugN(", ");
- uint16 regType = kernel->findRegType(argv[parmNr]);
- if (regType & SIG_TYPE_NULL)
- debugN("0");
- else if (regType & SIG_TYPE_UNINITIALIZED)
- debugN("UNINIT");
- else if (regType & SIG_IS_INVALID)
- debugN("INVALID");
- else if (regType & SIG_TYPE_INTEGER)
- debugN("%d", argv[parmNr].offset);
- else {
- debugN("%04x:%04x", PRINT_REG(argv[parmNr]));
- switch (regType) {
- case SIG_TYPE_OBJECT:
- debugN(" (%s)", s->_segMan->getObjectName(argv[parmNr]));
- break;
- case SIG_TYPE_REFERENCE:
- {
- SegmentObj *mobj = s->_segMan->getSegmentObj(argv[parmNr].segment);
- switch (mobj->getType()) {
- case SEG_TYPE_HUNK:
- {
- HunkTable *ht = (HunkTable*)mobj;
- int index = argv[parmNr].offset;
- if (ht->isValidEntry(index)) {
- // NOTE: This ", deleted" isn't as useful as it could
- // be because it prints the status _after_ the kernel
- // call.
- debugN(" ('%s' hunk%s)", ht->_table[index].type, ht->_table[index].mem ? "" : ", deleted");
- } else
- debugN(" (INVALID hunk ref)");
- break;
- }
- default:
- // TODO: Any other segment types which could
- // use special handling?
-
- if (kernelCall->function == kSaid) {
- SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]);
- if (saidSpec.isRaw) {
- debugN(" ('");
- g_sci->getVocabulary()->debugDecipherSaidBlock(saidSpec.raw);
- debugN("')");
- } else {
- debugN(" (non-raw said-spec)");
- }
- } else {
- debugN(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str());
- }
- break;
- }
- }
- default:
- break;
- }
- }
- }
- if (result.isPointer())
- debugN(" = %04x:%04x\n", PRINT_REG(result));
- else
- debugN(" = %d\n", result.offset);
-}
+// from scriptdebug.cpp
+extern void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *kernelSubCall, EngineState *s, int argc, reg_t *argv, reg_t result);
static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
Kernel *kernel = g_sci->getKernel();