diff options
-rw-r--r-- | subx/013direct_addressing.cc | 28 | ||||
-rw-r--r-- | subx/015immediate_addressing.cc | 10 |
2 files changed, 27 insertions, 11 deletions
diff --git a/subx/013direct_addressing.cc b/subx/013direct_addressing.cc index 3f7d40d6..9c314b02 100644 --- a/subx/013direct_addressing.cc +++ b/subx/013direct_addressing.cc @@ -279,6 +279,8 @@ case 0xf7: { Reg[EAX].u = result & 0xffffffff; Reg[EDX].u = result >> 32; OF = (Reg[EDX].u != 0); + CF = OF; + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << Reg[EAX].u << end(); break; } @@ -360,11 +362,14 @@ case 3: { // negate r/m32 OF = true; break; } - *arg1 = -(*arg1); - trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); - SF = (*arg1 >> 31); - ZF = (*arg1 == 0); + int32_t result = -(*arg1); + SF = (result >> 31); + ZF = (result == 0); OF = false; + CF = (*arg1 != 0); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -518,9 +523,12 @@ case 0xd3: { bool pnsb = (*arg1 & 0x40000000); OF = (msb != pnsb); } - *arg1 = (*arg1 << count); - ZF = (*arg1 == 0); - SF = (*arg1 < 0); + int32_t result = (*arg1 << count); + ZF = (result == 0); + SF = (result < 0); + CF = (*arg1 << (count-1)) & 0x80000000; + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -561,6 +569,7 @@ case 7: { // shift right r/m32 by CL, preserving sign SF = (*arg1 < 0); // OF is only defined if count is 1 if (count == 1) OF = false; + // CF undefined trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -638,6 +647,7 @@ case 5: { // shift right r/m32 by CL, padding zeroes ZF = (*uarg1 == 0); // result is always positive by definition SF = false; + // CF undefined trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -822,9 +832,7 @@ case 2: { // not r/m32 trace(Callstack_depth+1, "run") << "subop: not" << end(); *arg1 = ~(*arg1); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); - SF = (*arg1 >> 31); - ZF = (*arg1 == 0); - OF = false; + // no flags affected break; } diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index bfedac21..478e3592 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -449,6 +449,8 @@ case 0xc1: { *arg1 = (*arg1 << count); ZF = (*arg1 == 0); SF = (*arg1 < 0); + // CF undefined + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -483,11 +485,15 @@ void test_shift_right_arithmetic_r32_with_imm8() { case 7: { // shift right r/m32 by CL, preserving sign trace(Callstack_depth+1, "run") << "subop: shift right by CL bits, while preserving sign" << end(); uint8_t count = next() & 0x1f; - *arg1 = (*arg1 >> count); + int32_t result = (*arg1 >> count); ZF = (*arg1 == 0); SF = (*arg1 < 0); // OF is only defined if count is 1 if (count == 1) OF = false; + // CF + CF = ((*arg1 >> (count-1)) & 0x1); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); + *arg1 = result; trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -562,6 +568,8 @@ case 5: { // shift right r/m32 by CL, preserving sign ZF = (*uarg1 == 0); // result is always positive by definition SF = false; + // CF undefined + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } |