SAGA2: Add more debug output for scripts

This commit is contained in:
a/ 2021-08-15 07:00:42 +09:00
parent 62ea348ea0
commit 73d5d7d82f

View File

@ -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;
}