aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorLars Skovlund2010-01-03 17:40:17 +0000
committerLars Skovlund2010-01-03 17:40:17 +0000
commit6cc4dacf5ee6919cbd41aa6b0e35b16ba424b4c5 (patch)
tree5c2d55cb82f0dbe4ea439794f3024a82d23e360d /engines
parent6a25bd2b8a135dff9760e45ffd0501d3b7c928bc (diff)
downloadscummvm-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
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/vm.cpp61
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;