diff options
author | Lars Skovlund | 2010-01-03 17:40:17 +0000 |
---|---|---|
committer | Lars Skovlund | 2010-01-03 17:40:17 +0000 |
commit | 6cc4dacf5ee6919cbd41aa6b0e35b16ba424b4c5 (patch) | |
tree | 5c2d55cb82f0dbe4ea439794f3024a82d23e360d | |
parent | 6a25bd2b8a135dff9760e45ffd0501d3b7c928bc (diff) | |
download | scummvm-rg350-6cc4dacf5ee6919cbd41aa6b0e35b16ba424b4c5.tar.gz scummvm-rg350-6cc4dacf5ee6919cbd41aa6b0e35b16ba424b4c5.tar.bz2 scummvm-rg350-6cc4dacf5ee6919cbd41aa6b0e35b16ba424b4c5.zip |
SCI: Support pointer arithmetics in +ag, +agi, etc. too
svn-id: r46935
-rw-r--r-- | engines/sci/engine/vm.cpp | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 4792454f1b..e5fdbbb145 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -516,7 +516,7 @@ static reg_t pointer_add(EngineState *s, reg_t base, int offset) { default: // Changed this to warning, because iceman does this during dancing with girl - warning("[VM] Error: Attempt to add %d to pointer %04x:%04x: Pointer arithmetics of this type unsupported", offset, PRINT_REG(base)); + warning("[VM] Error: Attempt to add %d to pointer %04x:%04x, type %d: Pointer arithmetics of this type unsupported", offset, PRINT_REG(base), mobj->getType()); return NULL_REG; } @@ -1352,7 +1352,12 @@ void run_vm(EngineState *s, int restoring) { case 0x63: // +ap var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0]; - s->r_acc = make_reg(0, 1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + s->r_acc = pointer_add(s, r_temp, 1); + } else + s->r_acc = make_reg(0, r_temp.offset + 1); WRITE_VAR(var_type, var_number, s->r_acc); break; @@ -1362,7 +1367,12 @@ void run_vm(EngineState *s, int restoring) { case 0x67: // +sp var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0]; - r_temp = make_reg(0, 1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + r_temp = pointer_add(s, r_temp, 1); + } else + r_temp = make_reg(0, r_temp.offset + 1); PUSH32(r_temp); WRITE_VAR(var_type, var_number, r_temp); break; @@ -1373,7 +1383,12 @@ void run_vm(EngineState *s, int restoring) { case 0x6b: // +api var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0] + signed_validate_arithmetic(s->r_acc); - s->r_acc = make_reg(0, 1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + s->r_acc = pointer_add(s, r_temp, 1); + } else + s->r_acc = make_reg(0, r_temp.offset + 1); WRITE_VAR(var_type, var_number, s->r_acc); break; @@ -1383,7 +1398,12 @@ void run_vm(EngineState *s, int restoring) { case 0x6f: // +spi var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0] + signed_validate_arithmetic(s->r_acc); - r_temp = make_reg(0, 1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + r_temp = pointer_add(s, r_temp, 1); + } else + r_temp = make_reg(0, r_temp.offset + 1); PUSH32(r_temp); WRITE_VAR(var_type, var_number, r_temp); break; @@ -1392,19 +1412,30 @@ void run_vm(EngineState *s, int restoring) { case 0x71: // -al case 0x72: // -at case 0x73: // -ap + { var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0]; - s->r_acc = make_reg(0, -1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + s->r_acc = pointer_add(s, r_temp, -1); + } else + s->r_acc = make_reg(0, r_temp.offset - 1); WRITE_VAR(var_type, var_number, s->r_acc); break; - + } case 0x74: // -sg case 0x75: // -sl case 0x76: // -st case 0x77: // -sp var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0]; - r_temp = make_reg(0, -1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + r_temp = pointer_add(s, r_temp, -1); + } else + r_temp = make_reg(0, r_temp.offset - 1); PUSH32(r_temp); WRITE_VAR(var_type, var_number, r_temp); break; @@ -1415,7 +1446,12 @@ void run_vm(EngineState *s, int restoring) { case 0x7b: // -api var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0] + signed_validate_arithmetic(s->r_acc); - s->r_acc = make_reg(0, -1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + s->r_acc = pointer_add(s, r_temp, -1); + } else + s->r_acc = make_reg(0, r_temp.offset - 1); WRITE_VAR(var_type, var_number, s->r_acc); break; @@ -1425,7 +1461,12 @@ void run_vm(EngineState *s, int restoring) { case 0x7f: // -spi var_type = (opcode >> 1) & 0x3; // Gets the variable type: g, l, t or p var_number = opparams[0] + signed_validate_arithmetic(s->r_acc); - r_temp = make_reg(0, -1 + validate_arithmetic(READ_VAR(var_type, var_number, s->r_acc))); + r_temp = READ_VAR(var_type, var_number, s->r_acc); + if (r_temp.segment) { + // Pointer arithmetics! + r_temp = pointer_add(s, r_temp, -1); + } else + r_temp = make_reg(0, r_temp.offset - 1); PUSH32(r_temp); WRITE_VAR(var_type, var_number, r_temp); break; |