summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2019-12-20 16:31:55 -0600
committer cracyc <cracyc@users.noreply.github.com>2019-12-20 16:31:55 -0600
commite2451e5c6f21308664874613c833d414c424afef (patch)
treeb9b4bf3a7b999faafda0772ebb192ec3ab38eff7
parent8d28138ed527116e4a860ce76e1a39cb678cf83c (diff)
i386: unbreak the x87 and flesh out 486 float exceptions a bit (nw)
-rw-r--r--src/devices/cpu/i386/athlon.cpp4
-rw-r--r--src/devices/cpu/i386/i386.cpp4
-rw-r--r--src/devices/cpu/i386/i386.h11
-rw-r--r--src/devices/cpu/i386/i386ops.h1
-rw-r--r--src/devices/cpu/i386/i486ops.hxx5
-rw-r--r--src/devices/cpu/i386/x87ops.hxx554
-rw-r--r--src/devices/cpu/i386/x87priv.h1
7 files changed, 423 insertions, 157 deletions
diff --git a/src/devices/cpu/i386/athlon.cpp b/src/devices/cpu/i386/athlon.cpp
index a391a476e96..e47f99a2af6 100644
--- a/src/devices/cpu/i386/athlon.cpp
+++ b/src/devices/cpu/i386/athlon.cpp
@@ -477,7 +477,7 @@ uint64_t athlonxp_device::READ64PL(uint32_t ea, uint8_t privilege)
case 0:
default:
value = READ32PL(ea, privilege);
- value |= uint64_t(READ32PL(ea + 2, privilege)) << 32;
+ value |= uint64_t(READ32PL(ea + 4, privilege)) << 32;
break;
case 1:
@@ -610,7 +610,7 @@ void athlonxp_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
{
case 0:
WRITE32PL(ea, privilege, value & 0xffffffff);
- WRITE32PL(ea + 2, privilege, (value >> 32) & 0xffffffff);
+ WRITE32PL(ea + 4, privilege, (value >> 32) & 0xffffffff);
break;
case 1:
diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp
index 701b4257265..1778084b8a6 100644
--- a/src/devices/cpu/i386/i386.cpp
+++ b/src/devices/cpu/i386/i386.cpp
@@ -481,7 +481,7 @@ uint64_t i386_device::READ64PL(uint32_t ea, uint8_t privilege)
case 0:
default:
value = READ32PL(ea, privilege);
- value |= uint64_t(READ32PL(ea + 2, privilege)) << 32;
+ value |= uint64_t(READ32PL(ea + 4, privilege)) << 32;
break;
case 1:
@@ -676,7 +676,7 @@ void i386_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
{
case 0:
WRITE32PL(ea, privilege, value & 0xffffffff);
- WRITE32PL(ea + 2, privilege, (value >> 32) & 0xffffffff);
+ WRITE32PL(ea + 4, privilege, (value >> 32) & 0xffffffff);
break;
case 1:
diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h
index f10cfee4a04..5f3053f7571 100644
--- a/src/devices/cpu/i386/i386.h
+++ b/src/devices/cpu/i386/i386.h
@@ -324,8 +324,10 @@ protected:
uint16_t m_x87_cw;
uint16_t m_x87_sw;
uint16_t m_x87_tw;
- uint64_t m_x87_data_ptr;
- uint64_t m_x87_inst_ptr;
+ uint16_t m_x87_ds;
+ uint32_t m_x87_data_ptr;
+ uint16_t m_x87_cs;
+ uint32_t m_x87_inst_ptr;
uint16_t m_x87_opcode;
i386_modrm_func m_opcode_table_x87_d8[256];
@@ -466,6 +468,7 @@ protected:
void modrm_to_EA(uint8_t mod_rm, uint32_t* out_ea, uint8_t* out_segment);
uint32_t GetNonTranslatedEA(uint8_t modrm,uint8_t *seg);
uint32_t GetEA(uint8_t modrm, int rwn);
+ uint32_t Getx87EA(uint8_t modrm, int rwn);
void i386_check_sreg_validity(int reg);
int i386_limit_check(int seg, uint32_t offset);
void i386_sreg_load(uint16_t selector, uint8_t reg, bool *fault);
@@ -638,6 +641,7 @@ protected:
void i386_aam();
void i386_clts();
void i386_wait();
+ void i486_wait();
void i386_lock();
void i386_mov_r32_tr();
void i386_mov_tr_r32();
@@ -1354,6 +1358,7 @@ protected:
int x87_inc_stack();
int x87_dec_stack();
int x87_check_exceptions();
+ int x87_mf_fault();
inline void x87_write_cw(uint16_t cw);
void x87_reset();
floatx80 x87_add(floatx80 a, floatx80 b);
@@ -1479,8 +1484,6 @@ protected:
void x87_fincstp(uint8_t modrm);
void x87_fclex(uint8_t modrm);
void x87_ffree(uint8_t modrm);
- void x87_fdisi(uint8_t modrm);
- void x87_feni(uint8_t modrm);
void x87_finit(uint8_t modrm);
void x87_fldcw(uint8_t modrm);
void x87_fstcw(uint8_t modrm);
diff --git a/src/devices/cpu/i386/i386ops.h b/src/devices/cpu/i386/i386ops.h
index cf5b3c588aa..a5bac22b126 100644
--- a/src/devices/cpu/i386/i386ops.h
+++ b/src/devices/cpu/i386/i386ops.h
@@ -160,6 +160,7 @@ const i386_device::X86_OPCODE i386_device::s_x86_opcode_table[] =
{ 0x99, OP_I386, &i386_device::i386_cwd, &i386_device::i386_cdq, false},
{ 0x9A, OP_I386, &i386_device::i386_call_abs16, &i386_device::i386_call_abs32, false},
{ 0x9B, OP_I386, &i386_device::i386_wait, &i386_device::i386_wait, false},
+ { 0x9B, OP_I486, &i386_device::i486_wait, &i386_device::i486_wait, false},
{ 0x9C, OP_I386, &i386_device::i386_pushf, &i386_device::i386_pushfd, false},
{ 0x9D, OP_I386, &i386_device::i386_popf, &i386_device::i386_popfd, false},
{ 0x9E, OP_I386, &i386_device::i386_sahf, &i386_device::i386_sahf, false},
diff --git a/src/devices/cpu/i386/i486ops.hxx b/src/devices/cpu/i386/i486ops.hxx
index 6946e463796..f06add430c3 100644
--- a/src/devices/cpu/i386/i486ops.hxx
+++ b/src/devices/cpu/i386/i486ops.hxx
@@ -533,3 +533,8 @@ void i386_device::i486_mov_cr_r32() // Opcode 0x0f 22
}
m_cr[cr] = data;
}
+
+void i386_device::i486_wait()
+{
+ x87_mf_fault();
+}
diff --git a/src/devices/cpu/i386/x87ops.hxx b/src/devices/cpu/i386/x87ops.hxx
index 5fd4bbc0614..b06db8e21c8 100644
--- a/src/devices/cpu/i386/x87ops.hxx
+++ b/src/devices/cpu/i386/x87ops.hxx
@@ -19,8 +19,6 @@
Corrections and Additions [8-December-2017 Andrey Merkulov)
FXAM, FPREM - fixed
FINCSTP, FDECSTP - tags and exceptions corrected
- Interrupt handling for 8087 added
- FENI, FDISI opcodes added
***************************************************************************/
@@ -126,8 +124,39 @@ int i386_device::x87_dec_stack()
*
*************************************/
+int i386_device::x87_mf_fault()
+{
+ if ((m_x87_sw & X87_SW_ES) && (m_cr[0] & 0x20)) // FIXME: 486 and up only
+ {
+ m_ext = 1;
+ i386_trap(FAULT_MF, 0, 0);
+ return 1;
+ }
+ return 0;
+}
+
+uint32_t i386_device::Getx87EA(uint8_t modrm, int rwn)
+{
+ uint8_t segment;
+ uint32_t ea;
+ modrm_to_EA(modrm, &ea, &segment);
+ uint32_t ret = i386_translate(segment, ea, rwn);
+ m_x87_ds = segment;
+ if (PROTECTED_MODE && !V8086_MODE)
+ m_x87_data_ptr = ea;
+ else
+ m_x87_data_ptr = ea + (segment << 4);
+ return ret;
+}
+
int i386_device::x87_check_exceptions()
{
+ m_x87_cs = m_sreg[CS].selector;
+ if (PROTECTED_MODE && !V8086_MODE)
+ m_x87_inst_ptr = m_prev_eip;
+ else
+ m_x87_inst_ptr = m_prev_eip + (m_x87_cs << 4);
+
/* Update the exceptions from SoftFloat */
if (float_exception_flags & float_flag_invalid)
{
@@ -155,14 +184,8 @@ int i386_device::x87_check_exceptions()
// m_device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE);
logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", m_x87_cw, m_x87_sw);
// interrupt handler
- if (!(m_x87_cw & X87_CW_IEM)) { m_x87_sw |= X87_SW_ES; m_ferr_handler(1); }
-
- if (m_cr[0] & 0x20) // FIXME: 486 and up only
- {
- m_ext = 1;
- i386_trap(FAULT_MF, 0, 0);
- }
- return 0;
+ m_x87_sw |= X87_SW_ES;
+ m_ferr_handler(1);
}
return 1;
@@ -334,7 +357,9 @@ void i386_device::x87_fadd_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -369,7 +394,9 @@ void i386_device::x87_fadd_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -405,6 +432,8 @@ void i386_device::x87_fadd_st_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -438,6 +467,8 @@ void i386_device::x87_fadd_sti_st(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -471,6 +502,8 @@ void i386_device::x87_faddp(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -506,7 +539,9 @@ void i386_device::x87_fiadd_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -541,7 +576,9 @@ void i386_device::x87_fiadd_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -583,7 +620,9 @@ void i386_device::x87_fsub_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -618,7 +657,9 @@ void i386_device::x87_fsub_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -654,6 +695,8 @@ void i386_device::x87_fsub_st_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -687,6 +730,8 @@ void i386_device::x87_fsub_sti_st(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -720,6 +765,8 @@ void i386_device::x87_fsubp(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -755,7 +802,9 @@ void i386_device::x87_fisub_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -790,7 +839,9 @@ void i386_device::x87_fisub_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -832,7 +883,9 @@ void i386_device::x87_fsubr_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -867,7 +920,9 @@ void i386_device::x87_fsubr_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -903,6 +958,8 @@ void i386_device::x87_fsubr_st_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -936,6 +993,8 @@ void i386_device::x87_fsubr_sti_st(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -969,6 +1028,8 @@ void i386_device::x87_fsubrp(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1004,7 +1065,9 @@ void i386_device::x87_fisubr_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1039,7 +1102,9 @@ void i386_device::x87_fisubr_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1081,7 +1146,9 @@ void i386_device::x87_fdiv_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1116,7 +1183,9 @@ void i386_device::x87_fdiv_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1152,6 +1221,8 @@ void i386_device::x87_fdiv_st_sti(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1187,6 +1258,8 @@ void i386_device::x87_fdiv_sti_st(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1222,6 +1295,8 @@ void i386_device::x87_fdivp(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1257,7 +1332,9 @@ void i386_device::x87_fidiv_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1292,7 +1369,9 @@ void i386_device::x87_fidiv_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1334,7 +1413,9 @@ void i386_device::x87_fdivr_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1369,7 +1450,9 @@ void i386_device::x87_fdivr_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1405,6 +1488,8 @@ void i386_device::x87_fdivr_st_sti(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1440,6 +1525,8 @@ void i386_device::x87_fdivr_sti_st(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1475,6 +1562,8 @@ void i386_device::x87_fdivrp(uint8_t modrm)
int i = modrm & 7;
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1511,7 +1600,9 @@ void i386_device::x87_fidivr_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1546,7 +1637,9 @@ void i386_device::x87_fidivr_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1588,7 +1681,9 @@ void i386_device::x87_fmul_m32real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1622,7 +1717,9 @@ void i386_device::x87_fmul_m64real(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1657,6 +1754,8 @@ void i386_device::x87_fmul_st_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1689,6 +1788,8 @@ void i386_device::x87_fmul_sti_st(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1721,6 +1822,8 @@ void i386_device::x87_fmulp(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -1755,7 +1858,9 @@ void i386_device::x87_fimul_m32int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1789,7 +1894,9 @@ void i386_device::x87_fimul_m16int(uint8_t modrm)
{
floatx80 result;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -1830,6 +1937,8 @@ void i386_device::x87_fcmovb_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_CF == 1)
{
if (X87_IS_ST_EMPTY(i))
@@ -1854,6 +1963,8 @@ void i386_device::x87_fcmove_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_ZF == 1)
{
if (X87_IS_ST_EMPTY(i))
@@ -1878,6 +1989,8 @@ void i386_device::x87_fcmovbe_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if ((m_CF | m_ZF) == 1)
{
if (X87_IS_ST_EMPTY(i))
@@ -1902,6 +2015,8 @@ void i386_device::x87_fcmovu_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_PF == 1)
{
if (X87_IS_ST_EMPTY(i))
@@ -1926,6 +2041,8 @@ void i386_device::x87_fcmovnb_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_CF == 0)
{
if (X87_IS_ST_EMPTY(i))
@@ -1950,6 +2067,8 @@ void i386_device::x87_fcmovne_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_ZF == 0)
{
if (X87_IS_ST_EMPTY(i))
@@ -1974,6 +2093,8 @@ void i386_device::x87_fcmovnbe_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if ((m_CF == 0) && (m_ZF == 0))
{
if (X87_IS_ST_EMPTY(i))
@@ -1998,6 +2119,8 @@ void i386_device::x87_fcmovnu_sti(uint8_t modrm)
floatx80 result;
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (m_PF == 0)
{
if (X87_IS_ST_EMPTY(i))
@@ -2027,6 +2150,8 @@ void i386_device::x87_fprem(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -2084,6 +2209,8 @@ void i386_device::x87_fprem1(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -2110,6 +2237,8 @@ void i386_device::x87_fsqrt(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2147,6 +2276,8 @@ void i386_device::x87_f2xm1(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2172,6 +2303,8 @@ void i386_device::x87_fyl2x(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -2209,6 +2342,8 @@ void i386_device::x87_fyl2xp1(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -2238,6 +2373,8 @@ void i386_device::x87_fptan(uint8_t modrm)
{
floatx80 result1, result2;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2283,6 +2420,8 @@ void i386_device::x87_fpatan(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2308,6 +2447,8 @@ void i386_device::x87_fsin(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2342,6 +2483,8 @@ void i386_device::x87_fcos(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2375,6 +2518,8 @@ void i386_device::x87_fsincos(uint8_t modrm)
{
floatx80 s_result, c_result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2430,7 +2575,9 @@ void i386_device::x87_fld_m32real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (x87_dec_stack())
{
uint32_t m32real = READ32(ea);
@@ -2460,7 +2607,9 @@ void i386_device::x87_fld_m64real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (x87_dec_stack())
{
uint64_t m64real = READ64(ea);
@@ -2490,7 +2639,9 @@ void i386_device::x87_fld_m80real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (x87_dec_stack())
{
m_x87_sw &= ~X87_SW_C1;
@@ -2511,6 +2662,8 @@ void i386_device::x87_fld_sti(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
m_x87_sw &= ~X87_SW_C1;
@@ -2531,7 +2684,9 @@ void i386_device::x87_fild_m16int(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (!x87_dec_stack())
{
value = fx80_inan;
@@ -2554,7 +2709,9 @@ void i386_device::x87_fild_m32int(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (!x87_dec_stack())
{
value = fx80_inan;
@@ -2577,7 +2734,9 @@ void i386_device::x87_fild_m64int(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (!x87_dec_stack())
{
value = fx80_inan;
@@ -2600,7 +2759,9 @@ void i386_device::x87_fbld(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (!x87_dec_stack())
{
value = fx80_inan;
@@ -2645,7 +2806,9 @@ void i386_device::x87_fst_m32real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 1);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 1);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2670,7 +2833,9 @@ void i386_device::x87_fst_m64real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 1);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 1);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2696,6 +2861,8 @@ void i386_device::x87_fst_sti(uint8_t modrm)
int i = modrm & 7;
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2717,7 +2884,9 @@ void i386_device::x87_fstp_m32real(uint8_t modrm)
{
floatx80 value;
- uint32_t ea = GetEA(modrm, 1);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 1);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2743,6 +2912,8 @@ void i386_device::x87_fstp_m64real(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2755,7 +2926,7 @@ void i386_device::x87_fstp_m64real(uint8_t modrm)
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
uint64_t m64real = floatx80_to_float64(value);
@@ -2770,6 +2941,8 @@ void i386_device::x87_fstp_m80real(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2781,7 +2954,7 @@ void i386_device::x87_fstp_m80real(uint8_t modrm)
value = ST(0);
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE80(ea, value);
@@ -2796,6 +2969,8 @@ void i386_device::x87_fstp_sti(uint8_t modrm)
int i = modrm & 7;
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2820,6 +2995,8 @@ void i386_device::x87_fist_m16int(uint8_t modrm)
{
int16_t m16int;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2840,7 +3017,7 @@ void i386_device::x87_fist_m16int(uint8_t modrm)
m16int = -32768;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE16(ea, m16int);
@@ -2853,6 +3030,8 @@ void i386_device::x87_fist_m32int(uint8_t modrm)
{
int32_t m32int;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2873,7 +3052,7 @@ void i386_device::x87_fist_m32int(uint8_t modrm)
m32int = 0x80000000;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE32(ea, m32int);
@@ -2886,7 +3065,9 @@ void i386_device::x87_fistp_m16int(uint8_t modrm)
{
int16_t m16int;
- if (X87_IS_ST_EMPTY(0))
+ if (x87_mf_fault())
+ return;
+if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
m16int = (uint16_t)0x8000;
@@ -2906,7 +3087,7 @@ void i386_device::x87_fistp_m16int(uint8_t modrm)
m16int = (uint16_t)0x8000;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE16(ea, m16int);
@@ -2920,6 +3101,8 @@ void i386_device::x87_fistp_m32int(uint8_t modrm)
{
int32_t m32int;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2940,7 +3123,7 @@ void i386_device::x87_fistp_m32int(uint8_t modrm)
m32int = 0x80000000;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE32(ea, m32int);
@@ -2954,6 +3137,8 @@ void i386_device::x87_fistp_m64int(uint8_t modrm)
{
int64_t m64int;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -2974,7 +3159,7 @@ void i386_device::x87_fistp_m64int(uint8_t modrm)
m64int = 0x8000000000000000U;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE64(ea, m64int);
@@ -2988,6 +3173,8 @@ void i386_device::x87_fbstp(uint8_t modrm)
{
floatx80 result;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3009,7 +3196,7 @@ void i386_device::x87_fbstp(uint8_t modrm)
result.high |= ST(0).high & 0x8000;
}
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
if (x87_check_exceptions())
{
WRITE80(ea, result);
@@ -3031,6 +3218,8 @@ void i386_device::x87_fld1(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
m_x87_sw &= ~X87_SW_C1;
@@ -3057,6 +3246,8 @@ void i386_device::x87_fldl2t(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
tag = X87_TW_VALID;
@@ -3089,6 +3280,8 @@ void i386_device::x87_fldl2e(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
int rc = X87_RC;
@@ -3122,6 +3315,8 @@ void i386_device::x87_fldpi(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
int rc = X87_RC;
@@ -3155,6 +3350,8 @@ void i386_device::x87_fldlg2(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
int rc = X87_RC;
@@ -3188,6 +3385,8 @@ void i386_device::x87_fldln2(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
int rc = X87_RC;
@@ -3221,6 +3420,8 @@ void i386_device::x87_fldz(uint8_t modrm)
floatx80 value;
int tag;
+ if (x87_mf_fault())
+ return;
if (x87_dec_stack())
{
value = fx80_zero;
@@ -3251,6 +3452,7 @@ void i386_device::x87_fldz(uint8_t modrm)
void i386_device::x87_fnop(uint8_t modrm)
{
+ x87_mf_fault();
CYCLES(3);
}
@@ -3258,6 +3460,8 @@ void i386_device::x87_fchs(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3281,6 +3485,8 @@ void i386_device::x87_fabs(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3304,6 +3510,8 @@ void i386_device::x87_fscale(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -3325,6 +3533,8 @@ void i386_device::x87_frndint(uint8_t modrm)
{
floatx80 value;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3347,6 +3557,8 @@ void i386_device::x87_fxtract(uint8_t modrm)
{
floatx80 sig80, exp80;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3398,6 +3610,8 @@ void i386_device::x87_fxtract(uint8_t modrm)
void i386_device::x87_ftst(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3431,6 +3645,8 @@ void i386_device::x87_fxam(uint8_t modrm)
{
floatx80 value = ST(0);
+ if (x87_mf_fault())
+ return;
m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
// TODO: Unsupported and denormal values
@@ -3463,7 +3679,9 @@ void i386_device::x87_fxam(uint8_t modrm)
void i386_device::x87_ficom_m16int(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3500,7 +3718,9 @@ void i386_device::x87_ficom_m16int(uint8_t modrm)
void i386_device::x87_ficom_m32int(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3537,7 +3757,9 @@ void i386_device::x87_ficom_m32int(uint8_t modrm)
void i386_device::x87_ficomp_m16int(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3575,7 +3797,9 @@ void i386_device::x87_ficomp_m16int(uint8_t modrm)
void i386_device::x87_ficomp_m32int(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3614,7 +3838,9 @@ void i386_device::x87_ficomp_m32int(uint8_t modrm)
void i386_device::x87_fcom_m32real(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3651,7 +3877,9 @@ void i386_device::x87_fcom_m32real(uint8_t modrm)
void i386_device::x87_fcom_m64real(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3690,6 +3918,8 @@ void i386_device::x87_fcom_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -3724,7 +3954,9 @@ void i386_device::x87_fcom_sti(uint8_t modrm)
void i386_device::x87_fcomp_m32real(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3762,7 +3994,9 @@ void i386_device::x87_fcomp_m32real(uint8_t modrm)
void i386_device::x87_fcomp_m64real(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
if (X87_IS_ST_EMPTY(0))
{
x87_set_stack_underflow();
@@ -3802,6 +4036,8 @@ void i386_device::x87_fcomp_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -3839,6 +4075,8 @@ void i386_device::x87_fcomi_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -3883,6 +4121,8 @@ void i386_device::x87_fcomip_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -3928,6 +4168,8 @@ void i386_device::x87_fucomi_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -3978,6 +4220,8 @@ void i386_device::x87_fucomip_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -4027,6 +4271,8 @@ void i386_device::x87_fucomip_sti(uint8_t modrm)
void i386_device::x87_fcompp(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -4074,6 +4320,8 @@ void i386_device::x87_fucom_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -4112,6 +4360,8 @@ void i386_device::x87_fucomp_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
{
x87_set_stack_underflow();
@@ -4149,6 +4399,8 @@ void i386_device::x87_fucomp_sti(uint8_t modrm)
void i386_device::x87_fucompp(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
{
x87_set_stack_underflow();
@@ -4196,6 +4448,8 @@ void i386_device::x87_fucompp(uint8_t modrm)
void i386_device::x87_fdecstp(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
m_x87_sw &= ~X87_SW_C1;
x87_set_stack_top(ST_TO_PHYS(7));
@@ -4205,6 +4459,8 @@ void i386_device::x87_fdecstp(uint8_t modrm)
void i386_device::x87_fincstp(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
m_x87_sw &= ~X87_SW_C1;
x87_set_stack_top(ST_TO_PHYS(1));
@@ -4221,26 +4477,13 @@ void i386_device::x87_fclex(uint8_t modrm)
void i386_device::x87_ffree(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
x87_set_tag(ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
CYCLES(3);
}
-void i386_device::x87_feni(uint8_t modrm)
-{
- m_x87_cw &= ~X87_CW_IEM;
- x87_check_exceptions();
-
- CYCLES(5);
-}
-
-void i386_device::x87_fdisi(uint8_t modrm)
-{
- m_x87_cw |= X87_CW_IEM;
-
- CYCLES(5);
-}
-
void i386_device::x87_finit(uint8_t modrm)
{
x87_reset();
@@ -4250,7 +4493,9 @@ void i386_device::x87_finit(uint8_t modrm)
void i386_device::x87_fldcw(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
uint16_t cw = READ16(ea);
x87_write_cw(cw);
@@ -4262,7 +4507,7 @@ void i386_device::x87_fldcw(uint8_t modrm)
void i386_device::x87_fstcw(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
WRITE16(ea, m_x87_cw);
CYCLES(3);
@@ -4270,8 +4515,10 @@ void i386_device::x87_fstcw(uint8_t modrm)
void i386_device::x87_fldenv(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
// TODO: Pointers and selectors
- uint32_t ea = GetEA(modrm, 0);
+ uint32_t ea = Getx87EA(modrm, 0);
if (m_operand_size)
{
@@ -4295,7 +4542,7 @@ void i386_device::x87_fldenv(uint8_t modrm)
void i386_device::x87_fstenv(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
// TODO: Pointers and selectors
switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
@@ -4304,38 +4551,37 @@ void i386_device::x87_fstenv(uint8_t modrm)
WRITE16(ea + 0, m_x87_cw);
WRITE16(ea + 2, m_x87_sw);
WRITE16(ea + 4, m_x87_tw);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ WRITE16(ea + 6, m_x87_inst_ptr & 0xffff);
+ WRITE16(ea + 8, (m_x87_opcode & 0x07ff) | ((m_x87_inst_ptr & 0x0f0000) >> 4));
+ WRITE16(ea + 10, m_x87_data_ptr & 0xffff);
+ WRITE16(ea + 12, (m_x87_data_ptr & 0x0f0000) >> 4);
break;
case 1: // 16-bit protected mode
WRITE16(ea + 0, m_x87_cw);
WRITE16(ea + 2, m_x87_sw);
WRITE16(ea + 4, m_x87_tw);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ WRITE16(ea + 6, m_x87_inst_ptr & 0xffff);
+ WRITE16(ea + 8, m_x87_cs);
+ WRITE16(ea + 10, m_x87_data_ptr & 0xffff);
+ WRITE16(ea + 12, m_x87_ds);
break;
case 2: // 32-bit real mode
- WRITE16(ea + 0, m_x87_cw);
- WRITE16(ea + 4, m_x87_sw);
- WRITE16(ea + 8, m_x87_tw);
-// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
+ WRITE32(ea + 0, 0xffff0000 | m_x87_cw);
+ WRITE32(ea + 4, 0xffff0000 | m_x87_sw);
+ WRITE32(ea + 8, 0xffff0000 | m_x87_tw);
+ WRITE32(ea + 12, 0xffff0000 | (m_x87_inst_ptr & 0xffff));
+ WRITE32(ea + 16, (m_x87_opcode & 0x07ff) | ((m_x87_inst_ptr & 0xffff0000) >> 4));
+ WRITE32(ea + 20, 0xffff0000 | (m_x87_data_ptr & 0xffff));
+ WRITE32(ea + 24, (m_x87_data_ptr & 0xffff0000) >> 4);
break;
case 3: // 32-bit protected mode
- WRITE16(ea + 0, m_x87_cw);
- WRITE16(ea + 4, m_x87_sw);
- WRITE16(ea + 8, m_x87_tw);
-// WRITE32(ea + 12, m_fpu_inst_ptr);
-// WRITE32(ea + 16, m_fpu_opcode);
-// WRITE32(ea + 20, m_fpu_data_ptr);
-// WRITE32(ea + 24, m_fpu_inst_ptr);
+ WRITE32(ea + 0, 0xffff0000 | m_x87_cw);
+ WRITE32(ea + 4, 0xffff0000 | m_x87_sw);
+ WRITE32(ea + 8, 0xffff0000 | m_x87_tw);
+ WRITE32(ea + 12, m_x87_inst_ptr);
+ WRITE32(ea + 16, (m_x87_opcode << 16) | m_x87_cs);
+ WRITE32(ea + 20, m_x87_data_ptr);
+ WRITE32(ea + 24, 0xffff0000 | m_x87_ds);
break;
}
m_x87_cw |= 0x3f; // set all masks
@@ -4345,7 +4591,7 @@ void i386_device::x87_fstenv(uint8_t modrm)
void i386_device::x87_fsave(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
// TODO: Pointers and selectors
switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
@@ -4354,41 +4600,40 @@ void i386_device::x87_fsave(uint8_t modrm)
WRITE16(ea + 0, m_x87_cw);
WRITE16(ea + 2, m_x87_sw);
WRITE16(ea + 4, m_x87_tw);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ WRITE16(ea + 6, m_x87_inst_ptr & 0xffff);
+ WRITE16(ea + 8, (m_x87_opcode & 0x07ff) | ((m_x87_inst_ptr & 0x0f0000) >> 4));
+ WRITE16(ea + 10, m_x87_data_ptr & 0xffff);
+ WRITE16(ea + 12, (m_x87_data_ptr & 0x0f0000) >> 4);
ea += 14;
break;
case 1: // 16-bit protected mode
WRITE16(ea + 0, m_x87_cw);
WRITE16(ea + 2, m_x87_sw);
WRITE16(ea + 4, m_x87_tw);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ WRITE16(ea + 6, m_x87_inst_ptr & 0xffff);
+ WRITE16(ea + 8, m_x87_cs);
+ WRITE16(ea + 10, m_x87_data_ptr & 0xffff);
+ WRITE16(ea + 12, m_x87_ds);
ea += 14;
break;
case 2: // 32-bit real mode
- WRITE16(ea + 0, m_x87_cw);
- WRITE16(ea + 4, m_x87_sw);
- WRITE16(ea + 8, m_x87_tw);
-// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
+ WRITE32(ea + 0, 0xffff0000 | m_x87_cw);
+ WRITE32(ea + 4, 0xffff0000 | m_x87_sw);
+ WRITE32(ea + 8, 0xffff0000 | m_x87_tw);
+ WRITE32(ea + 12, 0xffff0000 | (m_x87_inst_ptr & 0xffff));
+ WRITE32(ea + 16, (m_x87_opcode & 0x07ff) | ((m_x87_inst_ptr & 0xffff0000) >> 4));
+ WRITE32(ea + 20, 0xffff0000 | (m_x87_data_ptr & 0xffff));
+ WRITE32(ea + 24, (m_x87_data_ptr & 0xffff0000) >> 4);
ea += 28;
break;
case 3: // 32-bit protected mode
- WRITE16(ea + 0, m_x87_cw);
- WRITE16(ea + 4, m_x87_sw);
- WRITE16(ea + 8, m_x87_tw);
-// WRITE32(ea + 12, m_fpu_inst_ptr);
-// WRITE32(ea + 16, m_fpu_opcode);
-// WRITE32(ea + 20, m_fpu_data_ptr);
-// WRITE32(ea + 24, m_fpu_inst_ptr);
+ WRITE32(ea + 0, 0xffff0000 | m_x87_cw);
+ WRITE32(ea + 4, 0xffff0000 | m_x87_sw);
+ WRITE32(ea + 8, 0xffff0000 | m_x87_tw);
+ WRITE32(ea + 12, m_x87_inst_ptr);
+ WRITE32(ea + 16, (m_x87_opcode << 16) | m_x87_cs);
+ WRITE32(ea + 20, m_x87_data_ptr);
+ WRITE32(ea + 24, 0xffff0000 | m_x87_ds);
ea += 28;
break;
}
@@ -4401,7 +4646,10 @@ void i386_device::x87_fsave(uint8_t modrm)
void i386_device::x87_frstor(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 0);
+ if (x87_mf_fault())
+ return;
+ uint32_t ea = Getx87EA(modrm, 0);
+ uint32 temp;
// TODO: Pointers and selectors
switch((m_cr[0] & 1)|(m_operand_size & 1)<<1)
@@ -4410,41 +4658,49 @@ void i386_device::x87_frstor(uint8_t modrm)
x87_write_cw(READ16(ea));
m_x87_sw = READ16(ea + 2);
m_x87_tw = READ16(ea + 4);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ m_x87_inst_ptr = READ16(ea + 6);
+ temp = READ16(ea + 8);
+ m_x87_opcode = temp & 0x7ff;
+ m_x87_inst_ptr |= ((temp & 0xf000) << 4);
+ m_x87_data_ptr = READ16(ea + 10) | ((READ16(ea + 12) & 0xf000) << 4);
+ m_x87_cs = 0;
+ m_x87_ds = 0;
ea += 14;
break;
case 1: // 16-bit protected mode
x87_write_cw(READ16(ea));
m_x87_sw = READ16(ea + 2);
m_x87_tw = READ16(ea + 4);
-// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4);
+ m_x87_inst_ptr = READ16(ea + 6);
+ m_x87_opcode = 0;
+ m_x87_cs = READ16(ea + 8);
+ m_x87_data_ptr = READ16(ea + 10);
+ m_x87_ds = READ16(ea + 12);
ea += 14;
break;
case 2: // 32-bit real mode
x87_write_cw(READ16(ea));
m_x87_sw = READ16(ea + 4);
m_x87_tw = READ16(ea + 8);
-// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12);
+ m_x87_inst_ptr = READ16(ea + 12);
+ temp = READ32(ea + 16);
+ m_x87_opcode = temp & 0x7ff;
+ m_x87_inst_ptr |= ((temp & 0xffff000) << 4);
+ m_x87_data_ptr = READ16(ea + 20) | ((READ32(ea + 24) & 0xffff000) << 4);
+ m_x87_cs = 0;
+ m_x87_ds = 0;
ea += 28;
break;
case 3: // 32-bit protected mode
x87_write_cw(READ16(ea));
m_x87_sw = READ16(ea + 4);
m_x87_tw = READ16(ea + 8);
-// WRITE32(ea + 12, m_fpu_inst_ptr);
-// WRITE32(ea + 16, m_fpu_opcode);
-// WRITE32(ea + 20, m_fpu_data_ptr);
-// WRITE32(ea + 24, m_fpu_inst_ptr);
+ m_x87_inst_ptr = READ32(ea + 12);
+ temp = READ32(ea + 16);
+ m_x87_opcode = (temp >> 16) & 0x7ff;
+ m_x87_cs = temp & 0xffff;
+ m_x87_data_ptr = READ32(ea + 20);
+ m_x87_ds = READ16(ea + 24);
ea += 28;
break;
}
@@ -4457,6 +4713,8 @@ void i386_device::x87_frstor(uint8_t modrm)
void i386_device::x87_fxch(uint8_t modrm)
{
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
x87_set_stack_underflow();
@@ -4479,6 +4737,8 @@ void i386_device::x87_fxch_sti(uint8_t modrm)
{
int i = modrm & 7;
+ if (x87_mf_fault())
+ return;
if (X87_IS_ST_EMPTY(0))
{
ST(0) = fx80_inan;
@@ -4516,7 +4776,7 @@ void i386_device::x87_fstsw_ax(uint8_t modrm)
void i386_device::x87_fstsw_m2byte(uint8_t modrm)
{
- uint32_t ea = GetEA(modrm, 1);
+ uint32_t ea = Getx87EA(modrm, 1);
WRITE16(ea, m_x87_sw);
@@ -4779,8 +5039,6 @@ void i386_device::build_x87_opcode_table_db()
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fcmovne_sti; break;
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcmovnbe_sti; break;
case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcmovnu_sti; break;
- case 0xe0: ptr = &i386_device::x87_feni; break; /* FENI */
- case 0xe1: ptr = &i386_device::x87_fdisi; break; /* FDISI */
case 0xe2: ptr = &i386_device::x87_fclex; break;
case 0xe3: ptr = &i386_device::x87_finit; break;
case 0xe4: ptr = &i386_device::x87_fnop; break; /* FSETPM */
diff --git a/src/devices/cpu/i386/x87priv.h b/src/devices/cpu/i386/x87priv.h
index 67cf067a15f..78745cce804 100644
--- a/src/devices/cpu/i386/x87priv.h
+++ b/src/devices/cpu/i386/x87priv.h
@@ -36,7 +36,6 @@
#define X87_CW_OM 0x0008
#define X87_CW_UM 0x0010
#define X87_CW_PM 0x0020
-#define X87_CW_IEM 0x0080
#define X87_CW_PC_SHIFT 8
#define X87_CW_PC_MASK 3
#define X87_CW_PC_SINGLE 0