diff options
author | Walter van Niftrik | 2010-01-27 01:47:41 +0000 |
---|---|---|
committer | Walter van Niftrik | 2010-01-27 01:47:41 +0000 |
commit | 7c0dcf108cf3327525507b7784dbc725bd02b059 (patch) | |
tree | ef8861da8f80c8749abe4892718495d49588e3fe | |
parent | d4f08cbe818f2a7d80df10b468b30cc61975b422 (diff) | |
download | scummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.tar.gz scummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.tar.bz2 scummvm-rg350-7c0dcf108cf3327525507b7784dbc725bd02b059.zip |
SCI: Add pointer comparison support to signed comparison operators.
svn-id: r47585
-rw-r--r-- | engines/sci/engine/vm.cpp | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 974109237c..b993cf84d9 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -848,22 +848,40 @@ void run_vm(EngineState *s, int restoring) { case 0x0f: // gt? s->r_prev = s->r_acc; - s->r_acc = ACC_ARITHMETIC_L((int16)POP() > (int16)/*acc*/); + r_temp = POP32(); + if (r_temp.segment && s->r_acc.segment) { + // Signed pointer comparison. We do unsigned comparison instead, as that is probably what was intended. + // FIXME: Add a warning when pointers in different segments are compared + s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset > s->r_acc.offset); + } else + s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() > (int16)/*acc*/); break; case 0x10: // ge? s->r_prev = s->r_acc; - s->r_acc = ACC_ARITHMETIC_L((int16)POP() >= (int16)/*acc*/); + r_temp = POP32(); + if (r_temp.segment && s->r_acc.segment) + s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset >= s->r_acc.offset); + else + s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() >= (int16)/*acc*/); break; case 0x11: // lt? s->r_prev = s->r_acc; - s->r_acc = ACC_ARITHMETIC_L((int16)POP() < (int16)/*acc*/); + r_temp = POP32(); + if (r_temp.segment && s->r_acc.segment) + s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset < s->r_acc.offset); + else + s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() < (int16)/*acc*/); break; case 0x12: // le? s->r_prev = s->r_acc; - s->r_acc = ACC_ARITHMETIC_L((int16)POP() <= (int16)/*acc*/); + r_temp = POP32(); + if (r_temp.segment && s->r_acc.segment) + s->r_acc = make_reg(0, (r_temp.segment == s->r_acc.segment) && r_temp.offset <= s->r_acc.offset); + else + s->r_acc = ACC_ARITHMETIC_L(r_temp.toSint16() <= (int16)/*acc*/); break; case 0x13: // ugt? |