#include <stdarg.h>
#include "softfloat/softfloat.h"
+
float_status status;
extern void exit(int);
return r;
}
-static uint8 READ_EA_8(int ea)
+static uint8 READ_EA_8(m68ki_cpu_core *state, int ea)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 0: // (xxx).W
{
- uint32 ea = (uint32)OPER_I_16();
+ uint32 ea = (uint32) OPER_I_16(state);
return m68ki_read_8(ea);
}
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
return m68ki_read_8(ea);
}
}
case 3: // (PC) + (Xn) + d8
{
- uint32 ea = EA_PCIX_8();
+ uint32 ea = EA_PCIX_8();
return m68ki_read_8(ea);
}
case 4: // #<data>
{
- return OPER_I_8();
+ return OPER_I_8(state);
}
default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
}
return 0;
}
-static uint16 READ_EA_16(int ea)
+static uint16 READ_EA_16(m68ki_cpu_core *state, int ea)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 0: // (xxx).W
{
- uint32 ea = (uint32)OPER_I_16();
+ uint32 ea = (uint32) OPER_I_16(state);
return m68ki_read_16(ea);
}
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
return m68ki_read_16(ea);
}
}
case 4: // #<data>
{
- return OPER_I_16();
+ return OPER_I_16(state);
}
default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
return 0;
}
-static uint32 READ_EA_32(int ea)
+static uint32 READ_EA_32(m68ki_cpu_core *state, int ea)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 0: // (xxx).W
{
- uint32 ea = (uint32)OPER_I_16();
+ uint32 ea = (uint32) OPER_I_16(state);
return m68ki_read_32(ea);
}
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
return m68ki_read_32(ea);
}
}
case 4: // #<data>
{
- return OPER_I_32();
+ return OPER_I_32(state);
}
default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
}
return 0;
}
-static uint64 READ_EA_64(int ea)
+static uint64 READ_EA_64(m68ki_cpu_core *state, int ea)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
return (uint64)(m68ki_read_32(ea)) << 32 | (uint64)(m68ki_read_32(ea+4));
}
}
case 4: // #<data>
{
- h1 = OPER_I_32();
- h2 = OPER_I_32();
+ h1 = OPER_I_32(state);
+ h2 = OPER_I_32(state);
return (uint64)(h1) << 32 | (uint64)(h2);
}
case 2: // (d16, PC)
}
-static floatx80 READ_EA_FPE(uint32 ea)
+static floatx80 READ_EA_FPE(m68ki_cpu_core *state, uint32 ea)
{
floatx80 fpr;
int mode = (ea >> 3) & 0x7;
{
case 1: // (xxx)
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
fpr = load_extended_float80(ea);
}
return fpr;
}
-static floatx80 READ_EA_PACK(int ea)
+static floatx80 READ_EA_PACK(m68ki_cpu_core *state, int ea)
{
floatx80 fpr;
int mode = (ea >> 3) & 0x7;
return fpr;
}
-static void WRITE_EA_8(int ea, uint8 data)
+static void WRITE_EA_8(m68ki_cpu_core *state, int ea, uint8 data)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 1: // (xxx).B
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
m68ki_write_8(ea, data);
break;
}
}
-static void WRITE_EA_16(int ea, uint16 data)
+static void WRITE_EA_16(m68ki_cpu_core *state, int ea, uint16 data)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 1: // (xxx).W
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
m68ki_write_16(ea, data);
break;
}
}
-static void WRITE_EA_32(int ea, uint32 data)
+static void WRITE_EA_32(m68ki_cpu_core *state, int ea, uint32 data)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 0: // (xxx).W
{
- uint32 ea = OPER_I_16();
+ uint32 ea = OPER_I_16(state);
m68ki_write_32(ea, data);
break;
}
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
m68ki_write_32(ea, data);
break;
}
}
-static void WRITE_EA_64(int ea, uint64 data)
+static void WRITE_EA_64(m68ki_cpu_core *state, int ea, uint64 data)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
{
case 1: // (xxx).L
{
- uint32 d1 = OPER_I_16();
- uint32 d2 = OPER_I_16();
+ uint32 d1 = OPER_I_16(state);
+ uint32 d2 = OPER_I_16(state);
uint32 ea = (d1 << 16) | d2;
m68ki_write_32(ea+0, (uint32)(data >> 32));
m68ki_write_32(ea+4, (uint32)(data));
}
}
-static void WRITE_EA_FPE(uint32 ea, floatx80 fpr)
+static void WRITE_EA_FPE(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
}
}
-static void WRITE_EA_PACK(int ea, int k, floatx80 fpr)
+static void WRITE_EA_PACK(m68ki_cpu_core *state, int ea, int k, floatx80 fpr)
{
int mode = (ea >> 3) & 0x7;
int reg = (ea & 0x7);
}
-static void fpgen_rm_reg(uint16 w2)
+static void fpgen_rm_reg(m68ki_cpu_core *state, uint16 w2)
{
int ea = REG_IR & 0x3f;
int rm = (w2 >> 14) & 0x1;
{
case 0: // Long-Word Integer
{
- sint32 d = READ_EA_32(ea);
+ sint32 d = READ_EA_32(state, ea);
source = int32_to_floatx80(d);
break;
}
case 1: // Single-precision Real
{
- uint32 d = READ_EA_32(ea);
+ uint32 d = READ_EA_32(state, ea);
source = float32_to_floatx80(d, &status);
break;
}
case 2: // Extended-precision Real
{
- source = READ_EA_FPE(ea);
+ source = READ_EA_FPE(state, ea);
break;
}
case 3: // Packed-decimal Real
{
- source = READ_EA_PACK(ea);
+ source = READ_EA_PACK(state, ea);
break;
}
case 4: // Word Integer
{
- sint16 d = READ_EA_16(ea);
+ sint16 d = READ_EA_16(state, ea);
source = int32_to_floatx80((sint32)d);
break;
}
case 5: // Double-precision Real
{
- uint64 d = READ_EA_64(ea);
+ uint64 d = READ_EA_64(state, ea);
source = float64_to_floatx80(d, &status);
break;
}
case 6: // Byte Integer
{
- sint8 d = READ_EA_8(ea);
+ sint8 d = READ_EA_8(state, ea);
source = int32_to_floatx80((sint32)d);
break;
}
source = REG_FP[src];
}
-
+ // For FD* and FS* prefixes we already converted the source to floatx80
+ // so we can treat these as their parent op.
switch (opmode)
{
+ case 0x44: // FDMOVE
+ case 0x40: // FSMOVE
case 0x00: // FMOVE
{
REG_FP[dst] = source;
SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
break;
}
+ case 0x45: // FDSQRT
+ case 0x41: // FSSQRT
case 0x04: // FSQRT
+ case 0x05: // FSQRT
{
REG_FP[dst] = floatx80_sqrt(source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
break;
}
case 0x06: // FLOGNP1
+ case 0x07: // FLOGNP1
{
REG_FP[dst] = floatx80_lognp1 (source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
break;
}
case 0x0a: // FATAN
+ case 0x0b: // FATAN
{
REG_FP[dst] = floatx80_atan(source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
break;
}
case 0x12: // FTENTOX
+ case 0x13: // FTENTOX
{
REG_FP[dst] = floatx80_tentox(source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
break;
}
case 0x16: // FLOG2
+ case 0x17: // FLOG2
{
REG_FP[dst] = floatx80_log2(source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
USE_CYCLES(604); // for MC68881
break;
}
+ case 0x5C: // FDABS
+ case 0x58: // FSABS
case 0x18: // FABS
{
REG_FP[dst] = source;
USE_CYCLES(64);
break;
}
+ case 0x5e: // FDNEG
+ case 0x5a: // FSNEG
case 0x1a: // FNEG
+ case 0x1b: // FNEG
{
REG_FP[dst] = source;
REG_FP[dst].high ^= 0x8000;
USE_CYCLES(6);
break;
}
- case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80)
+ case 0x64: // FDDIV
+ case 0x60: // FSDIV
case 0x20: // FDIV
{
REG_FP[dst] = floatx80_div(REG_FP[dst], source, &status);
USE_CYCLES(43); // guess
break;
}
+ case 0x66: // FDADD
+ case 0x62: // FSADD
case 0x22: // FADD
{
REG_FP[dst] = floatx80_add(REG_FP[dst], source, &status);
USE_CYCLES(9);
break;
}
- case 0x63: // FSMULS (JFF) (source has already been converted to floatx80)
+ case 0x67: // FDMUL
+ case 0x63: // FSMUL
case 0x23: // FMUL
{
REG_FP[dst] = floatx80_mul(REG_FP[dst], source, &status);
USE_CYCLES(11); // ? (value is from FMUL)
break;
}
+ case 0x6c: // FDSUB
+ case 0x68: // FSSUB
case 0x28: // FSUB
+ case 0x29: // FSUB
+ case 0x2a: // FSUB
+ case 0x2b: // FSUB
+ case 0x2c: // FSUB
+ case 0x2d: // FSUB
+ case 0x2e: // FSUB
+ case 0x2f: // FSUB
{
REG_FP[dst] = floatx80_sub(REG_FP[dst], source, &status);
SET_CONDITION_CODES(REG_FP[dst]);
break;
}
case 0x38: // FCMP
+ case 0x39: // FCMP
+ case 0x3c: // FCMP
+ case 0x3d: // FCMP
{
floatx80 res;
res = floatx80_sub(REG_FP[dst], source, &status);
break;
}
case 0x3a: // FTST
+ case 0x3b: // FTST
+ case 0x3e: // FTST
+ case 0x3f: // FTST
{
floatx80 res;
res = source;
}
}
-static void fmove_reg_mem(uint16 w2)
+static void fmove_reg_mem(m68ki_cpu_core *state, uint16 w2)
{
int ea = REG_IR & 0x3f;
int src = (w2 >> 7) & 0x7;
case 0: // Long-Word Integer
{
sint32 d = (sint32)floatx80_to_int32(REG_FP[src], &status);
- WRITE_EA_32(ea, d);
+ WRITE_EA_32(state, ea, d);
break;
}
case 1: // Single-precision Real
{
uint32 d = floatx80_to_float32(REG_FP[src], &status);
- WRITE_EA_32(ea, d);
+ WRITE_EA_32(state, ea, d);
break;
}
case 2: // Extended-precision Real
{
- WRITE_EA_FPE(ea, REG_FP[src]);
+ WRITE_EA_FPE(state, ea, REG_FP[src]);
break;
}
case 3: // Packed-decimal Real with Static K-factor
{
// sign-extend k
k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
- WRITE_EA_PACK(ea, k, REG_FP[src]);
+ WRITE_EA_PACK(state, ea, k, REG_FP[src]);
break;
}
case 4: // Word Integer
{
REG_FPSR |= FPES_OE | FPAE_IOP;
}
- WRITE_EA_16(ea, (sint16)value);
+ WRITE_EA_16(state, ea, (sint16) value);
break;
}
case 5: // Double-precision Real
d = floatx80_to_float64(REG_FP[src], &status);
- WRITE_EA_64(ea, d);
+ WRITE_EA_64(state, ea, d);
break;
}
case 6: // Byte Integer
{
REG_FPSR |= FPES_OE | FPAE_IOP;
}
- WRITE_EA_8(ea, (sint8)value);
+ WRITE_EA_8(state, ea, (sint8) value);
break;
}
case 7: // Packed-decimal Real with Dynamic K-factor
{
- WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]);
+ WRITE_EA_PACK(state, ea, REG_D[k >> 4], REG_FP[src]);
break;
}
}
USE_CYCLES(12);
}
-static void fmove_fpcr(uint16 w2)
+static void fmove_fpcr(m68ki_cpu_core *state, uint16 w2)
{
int ea = REG_IR & 0x3f;
int dir = (w2 >> 13) & 0x1;
{
if (dir) // From system control reg to <ea>
{
- if (regsel & 4) WRITE_EA_32(ea, REG_FPCR);
- if (regsel & 2) WRITE_EA_32(ea, REG_FPSR);
- if (regsel & 1) WRITE_EA_32(ea, REG_FPIAR);
+ if (regsel & 4) WRITE_EA_32(state, ea, REG_FPCR);
+ if (regsel & 2) WRITE_EA_32(state, ea, REG_FPSR);
+ if (regsel & 1) WRITE_EA_32(state, ea, REG_FPIAR);
}
else // From <ea> to system control reg
{
- if (regsel & 4) REG_FPCR = READ_EA_32(ea);
- if (regsel & 2) REG_FPSR = READ_EA_32(ea);
- if (regsel & 1) REG_FPIAR = READ_EA_32(ea);
+ if (regsel & 4) REG_FPCR = READ_EA_32(state, ea);
+ if (regsel & 2) REG_FPSR = READ_EA_32(state, ea);
+ if (regsel & 1) REG_FPIAR = READ_EA_32(state, ea);
}
}
USE_CYCLES(10);
}
-static void fmovem(uint16 w2)
+static void fmovem(m68ki_cpu_core *state, uint16 w2)
{
int i;
int ea = REG_IR & 0x3f;
mem_addr += 12;
break;
default:
- WRITE_EA_FPE(ea, REG_FP[i]);
+ WRITE_EA_FPE(state, ea, REG_FP[i]);
break;
}
mem_addr += 12;
break;
default:
- WRITE_EA_FPE(ea, REG_FP[7-i]);
+ WRITE_EA_FPE(state, ea, REG_FP[7 - i]);
break;
}
mem_addr += 12;
break;
default:
- REG_FP[7-i] = READ_EA_FPE(ea);
+ REG_FP[7-i] = READ_EA_FPE(state, ea);
break;
}
USE_CYCLES(2);
}
}
-static void fscc()
+static void fscc(m68ki_cpu_core *state)
{
int ea = REG_IR & 0x3f;
- int condition = (sint16)(OPER_I_16());
+ int condition = (sint16)(OPER_I_16(state));
- WRITE_EA_8(ea, TEST_CONDITION(condition) ? 0xff : 0);
+ WRITE_EA_8(state, ea, TEST_CONDITION(condition) ? 0xff : 0);
USE_CYCLES(7); // ???
}
-static void fbcc16(void)
+static void fbcc16(m68ki_cpu_core *state)
{
sint32 offset;
int condition = REG_IR & 0x3f;
- offset = (sint16)(OPER_I_16());
+ offset = (sint16)(OPER_I_16(state));
// TODO: condition and jump!!!
if (TEST_CONDITION(condition))
USE_CYCLES(7);
}
-static void fbcc32(void)
+static void fbcc32(m68ki_cpu_core *state)
{
sint32 offset;
int condition = REG_IR & 0x3f;
- offset = OPER_I_32();
+ offset = OPER_I_32(state);
// TODO: condition and jump!!!
if (TEST_CONDITION(condition))
}
-void m68040_fpu_op0()
+void m68040_fpu_op0(m68ki_cpu_core *state)
{
m68ki_cpu.fpu_just_reset = 0;
{
case 0:
{
- uint16 w2 = OPER_I_16();
+ uint16 w2 = OPER_I_16(state);
switch ((w2 >> 13) & 0x7)
{
case 0x0: // FPU ALU FP, FP
case 0x2: // FPU ALU ea, FP
{
- fpgen_rm_reg(w2);
+ fpgen_rm_reg(state, w2);
break;
}
case 0x3: // FMOVE FP, ea
{
- fmove_reg_mem(w2);
+ fmove_reg_mem(state, w2);
break;
}
case 0x4: // FMOVEM ea, FPCR
case 0x5: // FMOVEM FPCR, ea
{
- fmove_fpcr(w2);
+ fmove_fpcr(state, w2);
break;
}
case 0x6: // FMOVEM ea, list
case 0x7: // FMOVEM list, ea
{
- fmovem(w2);
+ fmovem(state, w2);
break;
}
printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
break;
default: // FScc (?)
- fscc();
+ fscc(state);
return;
}
fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
}
case 2: // FBcc disp16
{
- fbcc16();
+ fbcc16(state);
break;
}
case 3: // FBcc disp32
{
- fbcc32();
+ fbcc32(state);
break;
}
}
}
-static int perform_fsave(uint32 addr, int inc)
+static int perform_fsave(m68ki_cpu_core *state, uint32 addr, int inc)
{
if(m68ki_cpu.cpu_type & CPU_TYPE_040)
{
}
// FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
-static void do_frestore_null(void)
+static void do_frestore_null(m68ki_cpu_core *state)
{
int i;
m68ki_cpu.fpu_just_reset = 1;
}
-void m68040_do_fsave(uint32 addr, int reg, int inc)
+void m68040_do_fsave(m68ki_cpu_core *state, uint32 addr, int reg, int inc)
{
if (m68ki_cpu.fpu_just_reset)
{
else
{
// we normally generate an IDLE frame
- int delta = perform_fsave(addr, inc);
+ int delta = perform_fsave(state, addr, inc);
if(reg != -1)
REG_A[reg] += delta;
}
}
-void m68040_do_frestore(uint32 addr, int reg)
+void m68040_do_frestore(m68ki_cpu_core *state, uint32 addr, int reg)
{
uint32 temp = m68ki_read_32(addr);
// check for nullptr frame
}
else
{
- do_frestore_null();
+ do_frestore_null(state);
}
}
-void m68040_fpu_op1()
+void m68040_fpu_op1(m68ki_cpu_core *state)
{
int ea = REG_IR & 0x3f;
int mode = (ea >> 3) & 0x7;
{
case 2: // (An)
addr = REG_A[reg];
- m68040_do_fsave(addr, -1, 1);
+ m68040_do_fsave(state, addr, -1, 1);
break;
case 3: // (An)+
addr = EA_AY_PI_32();
printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
- m68040_do_fsave(addr, -1, 1); // FIXME: -1 was reg
+ m68040_do_fsave(state, addr, -1, 1); // FIXME: -1 was reg
break;
case 4: // -(An)
addr = EA_AY_PD_32();
- m68040_do_fsave(addr, reg, 0); // FIXME: -1 was reg
+ m68040_do_fsave(state, addr, reg, 0); // FIXME: -1 was reg
break;
case 5: // (D16, An)
addr = EA_AY_DI_16();
- m68040_do_fsave(addr, -1, 1);
+ m68040_do_fsave(state, addr, -1, 1);
break;
case 6: // (An) + (Xn) + d8
addr = EA_AY_IX_16();
- m68040_do_fsave(addr, -1, 1);
+ m68040_do_fsave(state, addr, -1, 1);
break;
case 7: //
case 1: // (abs32)
{
addr = EA_AL_32();
- m68040_do_fsave(addr, -1, 1);
+ m68040_do_fsave(state, addr, -1, 1);
break;
}
case 2: // (d16, PC)
{
addr = EA_PCDI_16();
- m68040_do_fsave(addr, -1, 1);
+ m68040_do_fsave(state, addr, -1, 1);
break;
}
default:
{
case 2: // (An)
addr = REG_A[reg];
- m68040_do_frestore(addr, -1);
+ m68040_do_frestore(state, addr, -1);
break;
case 3: // (An)+
addr = EA_AY_PI_32();
- m68040_do_frestore(addr, reg);
+ m68040_do_frestore(state, addr, reg);
break;
case 5: // (D16, An)
addr = EA_AY_DI_16();
- m68040_do_frestore(addr, -1);
+ m68040_do_frestore(state, addr, -1);
break;
case 6: // (An) + (Xn) + d8
addr = EA_AY_IX_16();
- m68040_do_frestore(addr, -1);
+ m68040_do_frestore(state, addr, -1);
break;
case 7: //
case 1: // (abs32)
{
addr = EA_AL_32();
- m68040_do_frestore(addr, -1);
+ m68040_do_frestore(state, addr, -1);
break;
}
case 2: // (d16, PC)
{
addr = EA_PCDI_16();
- m68040_do_frestore(addr, -1);
+ m68040_do_frestore(state, addr, -1);
break;
}
default:
}
}
-void m68881_ftrap()
+void m68881_ftrap(m68ki_cpu_core *state)
{
- uint16 w2 = OPER_I_16();
+ uint16 w2 = OPER_I_16(state);
// now check the condition
if (TEST_CONDITION(w2 & 0x3f))
switch (REG_IR & 0x7)
{
case 2: // word operand
- OPER_I_16();
+ OPER_I_16(state);
break;
case 3: // long word operand
- OPER_I_32();
+ OPER_I_32(state);
break;
case 4: // no operand