diff options
Diffstat (limited to 'src/devices/cpu/m68000/m68kfpu.cpp')
-rw-r--r-- | src/devices/cpu/m68000/m68kfpu.cpp | 370 |
1 files changed, 261 insertions, 109 deletions
diff --git a/src/devices/cpu/m68000/m68kfpu.cpp b/src/devices/cpu/m68000/m68kfpu.cpp index 3a2ec85e0ee..e8acf965db6 100644 --- a/src/devices/cpu/m68000/m68kfpu.cpp +++ b/src/devices/cpu/m68000/m68kfpu.cpp @@ -2,7 +2,7 @@ // copyright-holders:Karl Stenerud #include "emu.h" -#include "m68000.h" +#include "m68kmusashi.h" static constexpr int FPCC_N = 0x08000000; static constexpr int FPCC_Z = 0x04000000; @@ -19,7 +19,7 @@ static constexpr u64 DOUBLE_MANTISSA = 0x000fffffffffffffU; #endif // masks for packed dwords, positive k-factor -const u32 m68000_base_device::pkmask2[18] = +const u32 m68000_musashi_device::pkmask2[18] = { 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, @@ -27,14 +27,14 @@ const u32 m68000_base_device::pkmask2[18] = 0xffffffff, 0xffffffff, 0xffffffff }; -const u32 m68000_base_device::pkmask3[18] = +const u32 m68000_musashi_device::pkmask3[18] = { 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000, 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff, }; -inline floatx80 m68000_base_device::load_extended_float80(u32 ea) +inline floatx80 m68000_musashi_device::load_extended_float80(u32 ea) { u32 d1,d2; u16 d3; @@ -50,7 +50,7 @@ inline floatx80 m68000_base_device::load_extended_float80(u32 ea) return fp; } -inline void m68000_base_device::store_extended_float80(u32 ea, floatx80 fpr) +inline void m68000_musashi_device::store_extended_float80(u32 ea, floatx80 fpr) { m68ki_write_16(ea+0, fpr.high); m68ki_write_16(ea+2, 0); @@ -58,7 +58,7 @@ inline void m68000_base_device::store_extended_float80(u32 ea, floatx80 fpr) m68ki_write_32(ea+8, fpr.low&0xffffffff); } -inline floatx80 m68000_base_device::load_pack_float80(u32 ea) +inline floatx80 m68000_musashi_device::load_pack_float80(u32 ea) { u32 dw1, dw2, dw3; floatx80 result; @@ -109,7 +109,7 @@ inline floatx80 m68000_base_device::load_pack_float80(u32 ea) return result; } -inline void m68000_base_device::store_pack_float80(u32 ea, int k, floatx80 fpr) +inline void m68000_musashi_device::store_pack_float80(u32 ea, int k, floatx80 fpr) { u32 dw1, dw2, dw3; char str[128], *ch; @@ -118,7 +118,7 @@ inline void m68000_base_device::store_pack_float80(u32 ea, int k, floatx80 fpr) dw1 = dw2 = dw3 = 0; ch = &str[0]; - sprintf(str, "%.16e", fx80_to_double(fpr)); + snprintf(str, 128, "%.16e", fx80_to_double(fpr)); if (*ch == '-') { @@ -241,7 +241,54 @@ inline void m68000_base_device::store_pack_float80(u32 ea, int k, floatx80 fpr) m68ki_write_32(ea+8, dw3); } -inline void m68000_base_device::SET_CONDITION_CODES(floatx80 reg) +inline floatx80 propagateFloatx80NaNOneArg(floatx80 a) +{ + if (floatx80_is_signaling_nan(a)) + float_raise(float_flag_invalid); + + a.low |= 0xC000000000000000U; + + return a; +} + +static void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr) +{ + int shiftCount = countLeadingZeros64(aSig); + *zSigPtr = aSig << shiftCount; + *zExpPtr = 1 - shiftCount; +} + +inline floatx80 getman(floatx80 src) +{ + const flag sign = (src.high >> 15); + int32_t exp = (src.high & 0x7fff); + uint64_t signific = src.low; + + if (exp == 0x7fff) + { + if ((uint64_t)(signific << 1)) + { + return propagateFloatx80NaNOneArg(src); + } + else + { + return packFloatx80(0, 0xffff, 0xffffffffffffffffU); + } + } + + if (exp == 0) + { + if (signific == 0) + { + return packFloatx80(sign, 0, 0); + } + normalizeFloatx80Subnormal(signific, &exp, &signific); + } + + return packFloatx80(sign, 0x3fff, signific); +} + +inline void m68000_musashi_device::SET_CONDITION_CODES(floatx80 reg) { // u64 *regi; @@ -274,7 +321,7 @@ inline void m68000_base_device::SET_CONDITION_CODES(floatx80 reg) } } -inline int m68000_base_device::TEST_CONDITION(int condition) +inline int m68000_musashi_device::TEST_CONDITION(int condition) { int n = (m_fpsr & FPCC_N) != 0; int z = (m_fpsr & FPCC_Z) != 0; @@ -336,7 +383,7 @@ inline int m68000_base_device::TEST_CONDITION(int condition) return r; } -u8 m68000_base_device::READ_EA_8(int ea) +u8 m68000_musashi_device::READ_EA_8(int ea) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -347,6 +394,10 @@ u8 m68000_base_device::READ_EA_8(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -412,7 +463,7 @@ u8 m68000_base_device::READ_EA_8(int ea) return 0; } -u16 m68000_base_device::READ_EA_16(int ea) +u16 m68000_musashi_device::READ_EA_16(int ea) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -423,6 +474,10 @@ u16 m68000_base_device::READ_EA_16(int ea) { return (u16)(REG_D()[reg]); } + case 1: // An + { + return (u16)REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -489,7 +544,7 @@ u16 m68000_base_device::READ_EA_16(int ea) return 0; } -u32 m68000_base_device::READ_EA_32(int ea) +u32 m68000_musashi_device::READ_EA_32(int ea) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -500,6 +555,10 @@ u32 m68000_base_device::READ_EA_32(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -564,7 +623,7 @@ u32 m68000_base_device::READ_EA_32(int ea) return 0; } -u64 m68000_base_device::READ_EA_64(int ea) +u64 m68000_musashi_device::READ_EA_64(int ea) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -650,12 +709,9 @@ u64 m68000_base_device::READ_EA_64(int ea) return 0; } - -floatx80 m68000_base_device::READ_EA_FPE(int ea) +floatx80 m68000_musashi_device::READ_EA_FPE(int mode, int reg, uint32 di_mode_ea) { floatx80 fpr; - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); switch (mode) { @@ -682,16 +738,12 @@ floatx80 m68000_base_device::READ_EA_FPE(int ea) } case 5: // (d16, An) { - // FIXME: will fail for fmovem - u32 ea = EA_AY_DI_32(); - fpr = load_extended_float80(ea); + fpr = load_extended_float80(di_mode_ea); break; } case 6: // (An) + (Xn) + d8 { - // FIXME: will fail for fmovem - u32 ea = EA_AY_IX_32(); - fpr = load_extended_float80(ea); + fpr = load_extended_float80(di_mode_ea); break; } @@ -722,6 +774,11 @@ floatx80 m68000_base_device::READ_EA_FPE(int ea) } break; + case 4: // #<data> + fpr = load_extended_float80(m_pc); + m_pc += 12; + break; + default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, m_pc); break; @@ -735,7 +792,7 @@ floatx80 m68000_base_device::READ_EA_FPE(int ea) return fpr; } -floatx80 m68000_base_device::READ_EA_PACK(int ea) +floatx80 m68000_musashi_device::READ_EA_PACK(int ea) { floatx80 fpr; int mode = (ea >> 3) & 0x7; @@ -758,6 +815,13 @@ floatx80 m68000_base_device::READ_EA_PACK(int ea) break; } + case 5: // (d16,An) + { + u32 ea = REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16()); + fpr = load_pack_float80(ea); + break; + } + case 7: // extended modes { switch (reg) @@ -782,7 +846,7 @@ floatx80 m68000_base_device::READ_EA_PACK(int ea) return fpr; } -void m68000_base_device::WRITE_EA_8(int ea, u8 data) +void m68000_musashi_device::WRITE_EA_8(int ea, u8 data) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -850,7 +914,7 @@ void m68000_base_device::WRITE_EA_8(int ea, u8 data) } } -void m68000_base_device::WRITE_EA_16(int ea, u16 data) +void m68000_musashi_device::WRITE_EA_16(int ea, u16 data) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -918,7 +982,7 @@ void m68000_base_device::WRITE_EA_16(int ea, u16 data) } } -void m68000_base_device::WRITE_EA_32(int ea, u32 data) +void m68000_musashi_device::WRITE_EA_32(int ea, u32 data) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -997,7 +1061,7 @@ void m68000_base_device::WRITE_EA_32(int ea, u32 data) } } -void m68000_base_device::WRITE_EA_64(int ea, u64 data) +void m68000_musashi_device::WRITE_EA_64(int ea, u64 data) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -1070,11 +1134,8 @@ void m68000_base_device::WRITE_EA_64(int ea, u64 data) } } -void m68000_base_device::WRITE_EA_FPE(int ea, floatx80 fpr) +void m68000_musashi_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea) { - int mode = (ea >> 3) & 0x7; - int reg = (ea & 0x7); - switch (mode) { case 2: // (An) @@ -1105,7 +1166,15 @@ void m68000_base_device::WRITE_EA_FPE(int ea, floatx80 fpr) case 5: // (d16,An) { - u32 ea = EA_AY_DI_32(); + // EA_AY_DI_32() should not be done here because fmovem would increase + // PC each time, reading incorrect displacement & advancing PC too much. + store_extended_float80(di_mode_ea, fpr); + break; + } + + case 6: // (An) + (Xn) + d8 + { + u32 ea = EA_AY_IX_32(); store_extended_float80(ea, fpr); break; } @@ -1121,7 +1190,7 @@ void m68000_base_device::WRITE_EA_FPE(int ea, floatx80 fpr) } } -void m68000_base_device::WRITE_EA_PACK(int ea, int k, floatx80 fpr) +void m68000_musashi_device::WRITE_EA_PACK(int ea, int k, floatx80 fpr) { int mode = (ea >> 3) & 0x7; int reg = (ea & 0x7); @@ -1165,13 +1234,13 @@ void m68000_base_device::WRITE_EA_PACK(int ea, int k, floatx80 fpr) } } -void m68000_base_device::fpgen_rm_reg(u16 w2) +void m68000_musashi_device::fpgen_rm_reg(u16 w2) { - int ea = m_ir & 0x3f; - int rm = (w2 >> 14) & 0x1; - int src = (w2 >> 10) & 0x7; - int dst = (w2 >> 7) & 0x7; - int opmode = w2 & 0x7f; + const int ea = m_ir & 0x3f; + const int rm = (w2 >> 14) & 0x1; + const int src = (w2 >> 10) & 0x7; + const int dst = (w2 >> 7) & 0x7; + const int opmode = w2 & 0x7f; floatx80 source; // fmovecr #$f, fp0 f200 5c0f @@ -1194,7 +1263,10 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) } case 2: // Extended-precision Real { - source = READ_EA_FPE(ea); + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 di_mode_ea = imode == 5 ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; + source = READ_EA_FPE(imode, reg, di_mode_ea); break; } case 3: // Packed-decimal Real @@ -1336,6 +1408,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) // handle it right here, the usual opmode bits aren't valid in the FMOVECR case m_fpr[dst] = source; + SET_CONDITION_CODES(m_fpr[dst]); m_icount -= 4; return; } @@ -1363,6 +1436,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) s32 temp; temp = floatx80_to_int32(source); m_fpr[dst] = int32_to_floatx80(temp); + SET_CONDITION_CODES(m_fpr[dst]); break; } case 0x03: // FINTRZ @@ -1370,6 +1444,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) s32 temp; temp = floatx80_to_int32_round_to_zero(source); m_fpr[dst] = int32_to_floatx80(temp); + SET_CONDITION_CODES(m_fpr[dst]); break; } case 0x04: // FSQRT @@ -1381,11 +1456,18 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) } case 0x06: // FLOGNP1 { - m_fpr[dst] = floatx80_flognp1 (source); + m_fpr[dst] = floatx80_flognp1(source); SET_CONDITION_CODES(m_fpr[dst]); m_icount -= 594; // for MC68881 break; } + case 0x0a: // FATAN + { + m_fpr[dst] = floatx80_fatan (source); + SET_CONDITION_CODES(m_fpr[dst]); + m_icount -= 426; // for MC68881 + break; + } case 0x0e: // FSIN { m_fpr[dst] = source; @@ -1458,9 +1540,18 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 6; break; } + case 0x1f: // FGETMAN + { + m_fpr[dst] = getman(source); + SET_CONDITION_CODES(m_fpr[dst]); + m_icount -= 31; + break; + } + case 0x60: // FSDIVS case 0x20: // FDIV { m_fpr[dst] = floatx80_div(m_fpr[dst], source); + SET_CONDITION_CODES(m_fpr[dst]); m_icount -= 43; break; } @@ -1481,6 +1572,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 9; break; } + case 0x63: // FSMULS (JFF) case 0x23: // FMUL { m_fpr[dst] = floatx80_mul(m_fpr[dst], source); @@ -1529,6 +1621,24 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 9; break; } + case 0x30: // FSINCOS + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + { + m_fpr[dst] = source; + floatx80_fsin(m_fpr[dst]); + SET_CONDITION_CODES(m_fpr[dst]); // condition codes are set for the sine result + + m_fpr[(w2 & 0x7)] = source; + floatx80_fcos(m_fpr[(w2 & 0x7)]); + m_icount -= 451; + break; + } case 0x38: // FCMP { floatx80 res; @@ -1550,7 +1660,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) } } -void m68000_base_device::fmove_reg_mem(u16 w2) +void m68000_musashi_device::fmove_reg_mem(u16 w2) { int ea = m_ir & 0x3f; int src = (w2 >> 7) & 0x7; @@ -1573,7 +1683,11 @@ void m68000_base_device::fmove_reg_mem(u16 w2) } case 2: // Extended-precision Real { - WRITE_EA_FPE(ea, m_fpr[src]); + int mode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + uint32 di_mode_ea = mode == 5 ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; + + WRITE_EA_FPE(mode, reg, m_fpr[src], di_mode_ea); break; } case 3: // Packed-decimal Real with Static K-factor @@ -1622,7 +1736,7 @@ void m68000_base_device::fmove_reg_mem(u16 w2) m_icount -= 12; } -void m68000_base_device::fmove_fpcr(u16 w2) +void m68000_musashi_device::fmove_fpcr(u16 w2) { int ea = m_ir & 0x3f; int dir = (w2 >> 13) & 0x1; @@ -1665,7 +1779,11 @@ void m68000_base_device::fmove_fpcr(u16 w2) } else // From <ea> to system control reg { - if (regsel & 4) m_fpcr = READ_EA_32(ea); + if (regsel & 4) + { + m_fpcr = READ_EA_32(ea); + // should update softfloat rounding mode here + } if (regsel & 2) m_fpsr = READ_EA_32(ea); if (regsel & 1) m_fpiar = READ_EA_32(ea); } @@ -1722,7 +1840,7 @@ void m68000_base_device::fmove_fpcr(u16 w2) m_icount -= 10; } -void m68000_base_device::fmovem(u16 w2) +void m68000_musashi_device::fmovem(u16 w2) { int i; int ea = m_ir & 0x3f; @@ -1730,17 +1848,6 @@ void m68000_base_device::fmovem(u16 w2) int mode = (w2 >> 11) & 0x3; int reglist = w2 & 0xff; - u32 mem_addr = 0; - switch (ea >> 3) - { - case 5: // (d16, An) - mem_addr= EA_AY_DI_32(); - break; - case 6: // (An) + (Xn) + d8 - mem_addr= EA_AY_IX_32(); - break; - } - if (dir) // From FP regs to mem { switch (mode) @@ -1748,52 +1855,74 @@ void m68000_base_device::fmovem(u16 w2) case 1: // Dynamic register list, postincrement or control addressing mode. // FIXME: not really tested, but seems to work reglist = REG_D()[(reglist >> 4) & 7]; - + [[fallthrough]]; case 0: // Static register list, predecrement or control addressing mode { - for (i=0; i < 8; i++) + // the "di_mode_ea" parameter kludge is required here else WRITE_EA_FPE would have + // to call EA_AY_DI_32() (that advances PC & reads displacement) each time + // when the proper behaviour is 1) read once, 2) increment ea for each matching register + // this forces to pre-read the mode (named "imode") so we can decide to read displacement, only once + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + int di_mode = imode == 5; + uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; + + if (reglist) { - if (reglist & (1 << i)) + for (i=0; i < 8; i++) { - switch (ea >> 3) + if (reglist & (1 << i)) { - case 5: // (d16, An) - case 6: // (An) + (Xn) + d8 - store_extended_float80(mem_addr, m_fpr[i]); - mem_addr += 12; - break; - default: - WRITE_EA_FPE(ea, m_fpr[i]); - break; - } + WRITE_EA_FPE(imode, reg, m_fpr[i], di_mode_ea); + if (di_mode) + { + di_mode_ea += 12; + } - m_icount -= 2; + m_icount -= 2; + } } } + else if (imode == 6) + // advance PC if the register list is empty + EA_AY_IX_32(); + else if (imode == 7) + fatalerror("m68881: fmovem addressing mode %d unimplemented at 0x%08x\n", imode, m_pc - 4); break; } + case 3: // Dynamic register list, postincrement or control addressing mode. + // FIXME: not really tested, but seems to work + reglist = REG_D()[(reglist >> 4) & 7]; + [[fallthrough]]; case 2: // Static register list, postdecrement or control addressing mode { - for (i=0; i < 8; i++) + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + int di_mode = (imode == 5); + uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; + + if (reglist) { - if (reglist & (1 << i)) + for (i=0; i < 8; i++) { - switch (ea >> 3) + if (reglist & (1 << i)) { - case 5: // (d16, An) - case 6: // (An) + (Xn) + d8 - store_extended_float80(mem_addr, m_fpr[7-i]); - mem_addr += 12; - break; - default: - WRITE_EA_FPE(ea, m_fpr[7-i]); - break; - } + WRITE_EA_FPE(imode, reg, m_fpr[7 - i], di_mode_ea); + if (di_mode) + { + di_mode_ea += 12; + } - m_icount -= 2; + m_icount -= 2; + } } } + else if (imode == 6) + // advance PC if the register list is empty + EA_AY_IX_32(); + else if (imode == 7) + fatalerror("m68881: fmovem addressing mode %d unimplemented at 0x%08x\n", imode, m_pc - 4); break; } @@ -1807,23 +1936,22 @@ void m68000_base_device::fmovem(u16 w2) case 3: // Dynamic register list, predecrement addressing mode. // FIXME: not really tested, but seems to work reglist = REG_D()[(reglist >> 4) & 7]; - + [[fallthrough]]; case 2: // Static register list, postincrement or control addressing mode { + int imode = (ea >> 3) & 0x7; + int reg = (ea & 0x7); + int di_mode = (imode == 5); + uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; + for (i=0; i < 8; i++) { if (reglist & (1 << i)) { - switch (ea >> 3) + m_fpr[7 - i] = READ_EA_FPE(imode, reg, di_mode_ea); + if (di_mode) { - case 5: // (d16, An) - case 6: // (An) + (Xn) + d8 - m_fpr[7-i] = load_extended_float80(mem_addr); - mem_addr += 12; - break; - default: - m_fpr[7-i] = READ_EA_FPE(ea); - break; + di_mode_ea += 12; } m_icount -= 2; } @@ -1836,16 +1964,30 @@ void m68000_base_device::fmovem(u16 w2) } } -void m68000_base_device::fscc() +void m68000_musashi_device::fscc() { - int ea = m_ir & 0x3f; - int condition = (s16)(OPER_I_16()); + const int mode = (m_ir & 0x38) >> 3; + const int condition = OPER_I_16() & 0x3f; + const int v = (TEST_CONDITION(condition) ? 0xff : 0x00); + + switch (mode) + { + case 0: // Dx (handled specially because it only changes the low byte of Dx) + { + const int reg = m_ir & 7; + REG_D()[reg] = (REG_D()[reg] & 0xffffff00) | v; + } + break; + + default: + WRITE_EA_8(m_ir & 0x3f, v); + break; + } - WRITE_EA_8(ea, TEST_CONDITION(condition) ? 0xff : 0); m_icount -= 7; // ??? } -void m68000_base_device::fbcc16() +void m68000_musashi_device::fbcc16() { s32 offset; int condition = m_ir & 0x3f; @@ -1862,7 +2004,7 @@ void m68000_base_device::fbcc16() m_icount -= 7; } -void m68000_base_device::fbcc32() +void m68000_musashi_device::fbcc32() { s32 offset; int condition = m_ir & 0x3f; @@ -1880,7 +2022,7 @@ void m68000_base_device::fbcc32() } -void m68000_base_device::m68040_fpu_op0() +void m68000_musashi_device::m68040_fpu_op0() { m_fpu_just_reset = 0; @@ -1951,7 +2093,7 @@ void m68000_base_device::m68040_fpu_op0() } } -int m68000_base_device::perform_fsave(u32 addr, int inc) +int m68000_musashi_device::perform_fsave(u32 addr, int inc) { if(m_cpu_type & CPU_TYPE_040) { @@ -1993,7 +2135,7 @@ int m68000_base_device::perform_fsave(u32 addr, int inc) } // FRESTORE on a nullptr frame reboots the FPU - all registers to NaN, the 3 status regs to 0 -void m68000_base_device::do_frestore_null() +void m68000_musashi_device::do_frestore_null() { int i; @@ -2011,7 +2153,7 @@ void m68000_base_device::do_frestore_null() m_fpu_just_reset = 1; } -void m68000_base_device::m68040_do_fsave(u32 addr, int reg, int inc) +void m68000_musashi_device::m68040_do_fsave(u32 addr, int reg, int inc) { if (m_fpu_just_reset) { @@ -2026,7 +2168,7 @@ void m68000_base_device::m68040_do_fsave(u32 addr, int reg, int inc) } } -void m68000_base_device::m68040_do_frestore(u32 addr, int reg) +void m68000_musashi_device::m68040_do_frestore(u32 addr, int reg) { bool m40 = m_cpu_type & CPU_TYPE_040; u32 temp = m68ki_read_32(addr); @@ -2064,7 +2206,7 @@ void m68000_base_device::m68040_do_frestore(u32 addr, int reg) } } -void m68000_base_device::m68040_fpu_op1() +void m68000_musashi_device::m68040_fpu_op1() { int ea = m_ir & 0x3f; int mode = (ea >> 3) & 0x7; @@ -2097,6 +2239,11 @@ void m68000_base_device::m68040_fpu_op1() m68040_do_fsave(addr, -1, 1); break; + case 6: // (An) + (Xn) + d8 + addr = EA_AY_IX_16(); + m68040_do_fsave(addr, -1, 1); + break; + case 7: // switch (reg) { @@ -2144,6 +2291,11 @@ void m68000_base_device::m68040_fpu_op1() m68040_do_frestore(addr, -1); break; + case 6: // (An) + (Xn) + d8 + addr = EA_AY_IX_16(); + m68040_do_frestore(addr, -1); + break; + case 7: // switch (reg) { @@ -2176,7 +2328,7 @@ void m68000_base_device::m68040_fpu_op1() } } -void m68000_base_device::m68881_ftrap() +void m68000_musashi_device::m68881_ftrap() { u16 w2 = OPER_I_16(); |