From aeeefebf3169ccbdab14cfe2bb12c6834d2e2782 Mon Sep 17 00:00:00 2001 From: cracyc Date: Mon, 30 Dec 2019 09:56:24 -0600 Subject: [PATCH] i386: fix over/underflow result and zero div (nw) --- src/devices/cpu/i386/i386.h | 2 +- src/devices/cpu/i386/x87ops.hxx | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index 5f3053f7571..e6fda6278bc 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -1357,7 +1357,7 @@ protected: inline void x87_set_stack_overflow(); int x87_inc_stack(); int x87_dec_stack(); - int x87_check_exceptions(); + int x87_check_exceptions(bool store = false); int x87_mf_fault(); inline void x87_write_cw(uint16_t cw); void x87_reset(); diff --git a/src/devices/cpu/i386/x87ops.hxx b/src/devices/cpu/i386/x87ops.hxx index cce3bc712a2..5ed9fcaf62d 100644 --- a/src/devices/cpu/i386/x87ops.hxx +++ b/src/devices/cpu/i386/x87ops.hxx @@ -150,7 +150,7 @@ uint32_t i386_device::Getx87EA(uint8_t modrm, int rwn) return ret; } -int i386_device::x87_check_exceptions() +int i386_device::x87_check_exceptions(bool store) { m_x87_cs = m_sreg[CS].selector; if (PROTECTED_MODE && !V8086_MODE) @@ -179,7 +179,13 @@ int i386_device::x87_check_exceptions() m_x87_sw |= X87_SW_PE; float_exception_flags &= ~float_flag_inexact; } + if (float_exception_flags & float_flag_divbyzero) + { + m_x87_sw |= X87_SW_ZE; + float_exception_flags &= ~float_flag_divbyzero; + } + uint16_t unmasked = (m_x87_sw & ~m_x87_cw) & 0x3f; if ((m_x87_sw & ~m_x87_cw) & 0x3f) { // m_device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE); @@ -187,6 +193,8 @@ int i386_device::x87_check_exceptions() // interrupt handler m_x87_sw |= X87_SW_ES; m_ferr_handler(1); + if (store || !(unmasked & (X87_SW_OE | X87_SW_UE))) + return 0; } return 1; @@ -2935,7 +2943,7 @@ void i386_device::x87_fst_m32real(uint8_t modrm) value = ST(0); } - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { uint32_t m32real = floatx80_to_float32(value); WRITE32(ea, m32real); @@ -2962,7 +2970,7 @@ void i386_device::x87_fst_m64real(uint8_t modrm) value = ST(0); } - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { uint64_t m64real = floatx80_to_float64(value); WRITE64(ea, m64real); @@ -3016,7 +3024,7 @@ void i386_device::x87_fstp_m32real(uint8_t modrm) value = ST(0); } - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { uint32_t m32real = floatx80_to_float32(value); WRITE32(ea, m32real); @@ -3045,7 +3053,7 @@ void i386_device::x87_fstp_m64real(uint8_t modrm) uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { uint64_t m64real = floatx80_to_float64(value); WRITE64(ea, m64real); @@ -3073,7 +3081,7 @@ void i386_device::x87_fstp_m80real(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE80(ea, value); x87_inc_stack(); @@ -3139,7 +3147,7 @@ void i386_device::x87_fist_m16int(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE16(ea, m16int); } @@ -3174,7 +3182,7 @@ void i386_device::x87_fist_m32int(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE32(ea, m32int); } @@ -3209,7 +3217,7 @@ if (X87_IS_ST_EMPTY(0)) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE16(ea, m16int); x87_inc_stack(); @@ -3245,7 +3253,7 @@ void i386_device::x87_fistp_m32int(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE32(ea, m32int); x87_inc_stack(); @@ -3281,7 +3289,7 @@ void i386_device::x87_fistp_m64int(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE64(ea, m64int); x87_inc_stack(); @@ -3318,7 +3326,7 @@ void i386_device::x87_fbstp(uint8_t modrm) } uint32_t ea = Getx87EA(modrm, 1); - if (x87_check_exceptions()) + if (x87_check_exceptions(true)) { WRITE80(ea, result); x87_inc_stack();