diff options
| author | 2019-12-20 16:31:55 -0600 | |
|---|---|---|
| committer | 2019-12-20 16:31:55 -0600 | |
| commit | e2451e5c6f21308664874613c833d414c424afef (patch) | |
| tree | b9b4bf3a7b999faafda0772ebb192ec3ab38eff7 | |
| parent | 8d28138ed527116e4a860ce76e1a39cb678cf83c (diff) | |
i386: unbreak the x87 and flesh out 486 float exceptions a bit (nw)
| -rw-r--r-- | src/devices/cpu/i386/athlon.cpp | 4 | ||||
| -rw-r--r-- | src/devices/cpu/i386/i386.cpp | 4 | ||||
| -rw-r--r-- | src/devices/cpu/i386/i386.h | 11 | ||||
| -rw-r--r-- | src/devices/cpu/i386/i386ops.h | 1 | ||||
| -rw-r--r-- | src/devices/cpu/i386/i486ops.hxx | 5 | ||||
| -rw-r--r-- | src/devices/cpu/i386/x87ops.hxx | 554 | ||||
| -rw-r--r-- | src/devices/cpu/i386/x87priv.h | 1 |
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 |
