summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kfpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68kfpu.cpp')
-rw-r--r--src/devices/cpu/m68000/m68kfpu.cpp123
1 files changed, 73 insertions, 50 deletions
diff --git a/src/devices/cpu/m68000/m68kfpu.cpp b/src/devices/cpu/m68000/m68kfpu.cpp
index c265bf2b2f7..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 == '-')
{
@@ -288,7 +288,7 @@ inline floatx80 getman(floatx80 src)
return packFloatx80(sign, 0x3fff, signific);
}
-inline void m68000_base_device::SET_CONDITION_CODES(floatx80 reg)
+inline void m68000_musashi_device::SET_CONDITION_CODES(floatx80 reg)
{
// u64 *regi;
@@ -321,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;
@@ -383,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);
@@ -463,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);
@@ -544,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);
@@ -623,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);
@@ -709,7 +709,7 @@ u64 m68000_base_device::READ_EA_64(int ea)
return 0;
}
-floatx80 m68000_base_device::READ_EA_FPE(int mode, int reg, uint32 di_mode_ea)
+floatx80 m68000_musashi_device::READ_EA_FPE(int mode, int reg, uint32 di_mode_ea)
{
floatx80 fpr;
@@ -792,7 +792,7 @@ floatx80 m68000_base_device::READ_EA_FPE(int mode, int reg, uint32 di_mode_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;
@@ -815,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)
@@ -839,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);
@@ -907,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);
@@ -975,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);
@@ -1054,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);
@@ -1127,7 +1134,7 @@ void m68000_base_device::WRITE_EA_64(int ea, u64 data)
}
}
-void m68000_base_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea)
+void m68000_musashi_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea)
{
switch (mode)
{
@@ -1183,7 +1190,7 @@ void m68000_base_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di
}
}
-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);
@@ -1227,7 +1234,7 @@ 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)
{
const int ea = m_ir & 0x3f;
const int rm = (w2 >> 14) & 0x1;
@@ -1653,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;
@@ -1729,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;
@@ -1833,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;
@@ -1860,19 +1867,27 @@ void m68000_base_device::fmovem(u16 w2)
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)
{
- if (reglist & (1 << i))
+ for (i=0; i < 8; i++)
{
- WRITE_EA_FPE(imode, reg, m_fpr[i], di_mode_ea);
- if (di_mode)
+ if (reglist & (1 << i))
{
- di_mode_ea += 12;
- }
+ 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;
}
@@ -1887,19 +1902,27 @@ void m68000_base_device::fmovem(u16 w2)
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)
{
- if (reglist & (1 << i))
+ for (i=0; i < 8; i++)
{
- WRITE_EA_FPE(imode, reg, m_fpr[7 - i], di_mode_ea);
- if (di_mode)
+ if (reglist & (1 << i))
{
- di_mode_ea += 12;
- }
+ 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;
}
@@ -1941,7 +1964,7 @@ void m68000_base_device::fmovem(u16 w2)
}
}
-void m68000_base_device::fscc()
+void m68000_musashi_device::fscc()
{
const int mode = (m_ir & 0x38) >> 3;
const int condition = OPER_I_16() & 0x3f;
@@ -1964,7 +1987,7 @@ void m68000_base_device::fscc()
m_icount -= 7; // ???
}
-void m68000_base_device::fbcc16()
+void m68000_musashi_device::fbcc16()
{
s32 offset;
int condition = m_ir & 0x3f;
@@ -1981,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;
@@ -1999,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;
@@ -2070,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)
{
@@ -2112,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;
@@ -2130,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)
{
@@ -2145,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);
@@ -2183,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;
@@ -2305,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();