From 73d5d7d82feb53e70be86ba02bce98c7ec6cbd10 Mon Sep 17 00:00:00 2001 From: a/ Date: Sun, 15 Aug 2021 07:00:42 +0900 Subject: [PATCH] SAGA2: Add more debug output for scripts --- engines/saga2/interp.cpp | 57 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/engines/saga2/interp.cpp b/engines/saga2/interp.cpp index 9383ebd59c1..d080bfc2cd5 100644 --- a/engines/saga2/interp.cpp +++ b/engines/saga2/interp.cpp @@ -37,8 +37,10 @@ namespace Saga2 { -#define IMMED_WORD(w) ((w = *pc++),(w |= (*pc++)<<8)) -#define BRANCH(w) pc = codeSeg + (w) +#define IMMED_WORD(w) ((w = *pc++),(w |= (*pc++)<<8)); \ + debugC(3, kDebugScripts, "IMMED_WORD(%d 0x%04x)", w, w) +#define BRANCH(w) pc = codeSeg + (w); \ + debugC(3, kDebugScripts, "BRANCH(%ld 0x%04lx)", pc - codeSeg, pc - codeSeg) const uint32 sagaID = MKTAG('S', 'A', 'G', 'A'), dataSegID = MKTAG('_', '_', 'D', 'A'), @@ -550,6 +552,9 @@ static void print_stack(int16 *stackBase, int16 *stack) { } #define D_OP(x) debugC(1, kDebugScripts, "[%04ld 0x%04lx]: %s", (pc - codeSeg - 1), (pc - codeSeg - 1), #x) +#define D_OP1(x) debugC(1, kDebugScripts, "[%04ld 0x%04lx]: %s = %d", (pc - codeSeg - 1), (pc - codeSeg - 1), #x, *stack) +#define D_OP2(x) debugC(1, kDebugScripts, "[%04ld 0x%04lx]: %s [%p] = %d", (pc - codeSeg - 1), (pc - codeSeg - 1), #x, (void *)addr, *stack) +#define D_OP3(x) debugC(1, kDebugScripts, "[%04ld 0x%04lx]: %s [%p] %d", (pc - codeSeg - 1), (pc - codeSeg - 1), #x, (void *)addr, *addr) bool Thread::interpret(void) { uint8 *pc, @@ -570,9 +575,9 @@ bool Thread::interpret(void) { switch (op = *pc++) { case op_dup: - D_OP(op_dup); --stack; *stack = stack[1]; // duplicate value on stack + D_OP1(op_dup); break; case op_drop: // drop word on stack @@ -592,27 +597,31 @@ bool Thread::interpret(void) { case op_strlit: // string literal (also pushes word) case op_constint: // constant integer - D_OP(op_strlit); IMMED_WORD(w); // pick up word after opcode *--stack = w; // push integer on stack + + if (op == op_strlit) + D_OP1(op_strlit); + else + D_OP1(op_constint); break; case op_getflag: // get a flag - D_OP(op_getflag); addr = bitAddress(this, &pc, &w); // get address of bit *--stack = ((*addr) & w) ? 1 : 0; // true or false if bit set + D_OP2(op_getflag); break; case op_getint: // read from integer field (mode) - D_OP(op_getint); addr = byteAddress(this, &pc); // get address of integer *--stack = *(uint16 *)addr; // get integer from address + D_OP2(op_getint); break; case op_getbyte: // read from integer field (mode) - D_OP(op_getbyte); addr = byteAddress(this, &pc); // get address of integer *--stack = *addr; // get byte from address + D_OP2(op_getbyte); break; // Note that in the current implementation, "put" ops leave @@ -620,41 +629,41 @@ bool Thread::interpret(void) { // 'vput' which consumes the variable. case op_putflag: // put to flag bit (mode) - D_OP(op_putflag); addr = bitAddress(this, &pc, &w); // get address of bit if (*stack) *addr |= w; // set bit if stack non-zero else *addr &= ~w; // else clear it + D_OP3(op_putflag); break; case op_putflag_v: // put to flag bit (mode) - D_OP(op_putflag_v); addr = bitAddress(this, &pc, &w); // get address of bit if (*stack++) *addr |= w; // set bit if stack non-zero else *addr &= ~w; // else clear it + D_OP3(op_putflag_v); break; case op_putint: // put to integer field (mode) - D_OP(op_putint); addr = byteAddress(this, &pc); // get address of integer *(uint16 *)addr = *stack; // put integer to address + D_OP3(op_putint); break; case op_putint_v: // put to integer field (mode) - D_OP(op_putint_v); addr = byteAddress(this, &pc); // get address of integer *(uint16 *)addr = *stack++; // put integer to address + D_OP3(op_putint_v); break; case op_putbyte: // put to byte field (mode) - D_OP(op_putbyte); addr = byteAddress(this, &pc); // get address of integer *addr = *stack; // put integer to address + D_OP3(op_putbyte); break; case op_putbyte_v: // put to byte field (mode) - D_OP(op_putbyte_v); addr = byteAddress(this, &pc); // get address of integer *addr = *stack++; // put integer to address + D_OP3(op_putbyte_v); break; case op_enter: @@ -887,25 +896,33 @@ bool Thread::interpret(void) { case op_jmp_true_v: D_OP(op_jmp_true_v); IMMED_WORD(w); // pick up word after address - if (*stack++ != 0) BRANCH(w); // if stack is non-zero, jump + if (*stack++ != 0) { + BRANCH(w); // if stack is non-zero, jump + } break; case op_jmp_false_v: D_OP(op_jmp_false_v); IMMED_WORD(w); // pick up word after address - if (*stack++ == 0) BRANCH(w); // if stack is zero, jump + if (*stack++ == 0) { + BRANCH(w); // if stack is zero, jump + } break; case op_jmp_true: D_OP(op_true); IMMED_WORD(w); // pick up word after address - if (*stack != 0) BRANCH(w); // if stack is non-zero. jump + if (*stack != 0) { + BRANCH(w); // if stack is non-zero. jump + } break; case op_jmp_false: D_OP(op_false); IMMED_WORD(w); // pick up word after address - if (*stack == 0) BRANCH(w); // if stack is zero, jump + if (*stack == 0) { + BRANCH(w); // if stack is zero, jump + } break; case op_jmp: @@ -925,6 +942,7 @@ bool Thread::interpret(void) { while (n--) { IMMED_WORD(val); // val = case value IMMED_WORD(jmp); // jmp = address to jump to + debugC(3, kDebugScripts, "Case %d: jmp %d", val, jmp); if (w == val) { // if case values match BRANCH(jmp); // jump to case @@ -1831,10 +1849,10 @@ scriptResult runMethod( th = new Thread(segNum, segOff, args); thisThread = th; if (th == nullptr) { - debugC(4, kDebugScripts, "Couldn't allocate memory for Thread(%d, %d)", segNum, segOff); + debugC(3, kDebugScripts, "Couldn't allocate memory for Thread(%d, %d)", segNum, segOff); return scriptResultNoScript; } else if (!th->_valid) { - debugC(4, kDebugScripts, "Scripts: %d is not valid", lastExport); + debugC(3, kDebugScripts, "Scripts: %d is not valid", lastExport); return scriptResultNoScript; } print_script_name((th->codeSeg) + th->programCounter.offset, objectName(bType, index)); @@ -1846,6 +1864,7 @@ scriptResult runMethod( // Run the thread to completion result = th->run(); args.returnVal = th->returnVal; + debugC(3, kDebugScripts, "return: %d", th->returnVal); if (result != scriptResultAsync) delete th; }