summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2015-03-14 14:51:57 +0100
committer yz70s <yz70s@users.noreply.github.com>2015-03-14 14:51:57 +0100
commit612af8ba64b4aa37a51f5b2f6d895158382ece30 (patch)
tree596cf2322028254d73d6af70b1012f255423e3f9
parentf2430a3fdfc8f98abd2bde14b37504bd86ff5344 (diff)
i386.c: new implementation of x87 opcode fprem based on intel manual since curent one gives wrong results (nw)
-rw-r--r--src/emu/cpu/i386/x87ops.inc36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/emu/cpu/i386/x87ops.inc b/src/emu/cpu/i386/x87ops.inc
index 1afd7da0a40..c057138cb44 100644
--- a/src/emu/cpu/i386/x87ops.inc
+++ b/src/emu/cpu/i386/x87ops.inc
@@ -2185,13 +2185,41 @@ void i386_device::x87_fprem(UINT8 modrm)
}
else
{
- floatx80 a = ST(0);
- floatx80 b = ST(1);
+ floatx80 a0 = ST(0);
+ floatx80 b1 = ST(1);
m_x87_sw &= ~X87_SW_C2;
- // TODO: Implement Cx bits
- result = floatx80_rem(a, b);
+ //int d=extractFloatx80Exp(a0)-extractFloatx80Exp(b1);
+ int d = (a0.high & 0x7FFF) - (b1.high & 0x7FFF);
+ if (d < 64) {
+ floatx80 t=floatx80_div(a0, b1);
+ int64 q = floatx80_to_int64_round_to_zero(t);
+ floatx80 qf = int64_to_floatx80(q);
+ floatx80 tt = floatx80_mul(b1, qf);
+ result = floatx80_sub(a0, tt);
+ // C2 already 0
+ m_x87_sw &= ~(X87_SW_C0|X87_SW_C3|X87_SW_C1);
+ if (q & 1)
+ m_x87_sw |= X87_SW_C1;
+ if (q & 2)
+ m_x87_sw |= X87_SW_C3;
+ if (q & 4)
+ m_x87_sw |= X87_SW_C0;
+ }
+ else {
+ m_x87_sw |= X87_SW_C2;
+ int n = 63;
+ int e = 1 << (d - n);
+ floatx80 ef = int32_to_floatx80(e);
+ floatx80 t=floatx80_div(a0, b1);
+ floatx80 td = floatx80_div(t, ef);
+ int64 qq = floatx80_to_int64_round_to_zero(td);
+ floatx80 qqf = int64_to_floatx80(qq);
+ floatx80 tt = floatx80_mul(b1, qqf);
+ floatx80 ttt = floatx80_mul(tt, ef);
+ result = floatx80_sub(a0, ttt);
+ }
}
if (x87_check_exceptions())