diff options
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 |
commit | 612af8ba64b4aa37a51f5b2f6d895158382ece30 (patch) | |
tree | 596cf2322028254d73d6af70b1012f255423e3f9 | |
parent | f2430a3fdfc8f98abd2bde14b37504bd86ff5344 (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.inc | 36 |
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()) |