static void fmovem(m68ki_cpu_core *m68k, UINT16 w2) { int i; int ea = m68k->ir & 0x3f; int dir = (w2 >> 13) & 0x1; int mode = (w2 >> 11) & 0x3; int reglist = w2 & 0xff; if (dir) // From FP regs to mem { switch (mode) { case 0: // Static register list, predecrement addressing mode { for (i=0; i < 8; i++) { if (reglist & (1 << i)) { WRITE_EA_FPE(m68k, ea, REG_FP[i]); m68k->remaining_cycles -= 2; } } break; } default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); } } else // From mem to FP regs { switch (mode) { case 2: // Static register list, postincrement addressing mode { for (i=0; i < 8; i++) { if (reglist & (1 << i)) { REG_FP[7-i] = READ_EA_FPE(m68k, ea); m68k->remaining_cycles -= 2; } } break; } default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4); } } }
static void fmove_reg_mem(m68000_base_device *m68k, UINT16 w2) { int ea = m68k->ir & 0x3f; int src = (w2 >> 7) & 0x7; int dst = (w2 >> 10) & 0x7; int k = (w2 & 0x7f); switch (dst) { case 0: // Long-Word Integer { INT32 d = (INT32)floatx80_to_int32(REG_FP(m68k)[src]); WRITE_EA_32(m68k, ea, d); break; } case 1: // Single-precision Real { UINT32 d = floatx80_to_float32(REG_FP(m68k)[src]); WRITE_EA_32(m68k, ea, d); break; } case 2: // Extended-precision Real { WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[src]); break; } case 3: // Packed-decimal Real with Static K-factor { // sign-extend k k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f); WRITE_EA_PACK(m68k, ea, k, REG_FP(m68k)[src]); break; } case 4: // Word Integer { int32 value = floatx80_to_int32(REG_FP(m68k)[src]); if (value > 0x7fff || value < -0x8000 ) { REG_FPSR(m68k) |= FPES_OE | FPAE_IOP; } WRITE_EA_16(m68k, ea, (INT16)value); break; } case 5: // Double-precision Real { UINT64 d; d = floatx80_to_float64(REG_FP(m68k)[src]); WRITE_EA_64(m68k, ea, d); break; } case 6: // Byte Integer { int32 value = floatx80_to_int32(REG_FP(m68k)[src]); if (value > 127 || value < -128) { REG_FPSR(m68k) |= FPES_OE | FPAE_IOP; } WRITE_EA_8(m68k, ea, (INT8) value); break; } case 7: // Packed-decimal Real with Dynamic K-factor { WRITE_EA_PACK(m68k, ea, REG_D(m68k)[k>>4], REG_FP(m68k)[src]); break; } } m68k->remaining_cycles -= 12; }
static void fmovem(m68ki_cpu_core *m68k, UINT16 w2) { int i; int ea = m68k->ir & 0x3f; int dir = (w2 >> 13) & 0x1; int mode = (w2 >> 11) & 0x3; int reglist = w2 & 0xff; UINT32 mem_addr = 0; switch (ea >> 3) { case 5: // (d16, An) mem_addr= EA_AY_DI_32(m68k); break; case 6: // (An) + (Xn) + d8 mem_addr= EA_AY_IX_32(m68k); break; } if (dir) // From FP regs to mem { switch (mode) { case 1: // Dynamic register list, postincrement or control addressing mode. // FIXME: not really tested, but seems to work reglist = REG_D(m68k)[(reglist >> 4) & 7]; case 0: // Static register list, predecrement or control addressing mode { for (i=0; i < 8; i++) { if (reglist & (1 << i)) { switch (ea >> 3) { case 5: // (d16, An) case 6: // (An) + (Xn) + d8 store_extended_float80(m68k, mem_addr, REG_FP(m68k)[i]); mem_addr += 12; break; default: WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[i]); break; } m68k->remaining_cycles -= 2; } } break; } case 2: // Static register list, postdecrement or control addressing mode { for (i=0; i < 8; i++) { if (reglist & (1 << i)) { switch (ea >> 3) { case 5: // (d16, An) case 6: // (An) + (Xn) + d8 store_extended_float80(m68k, mem_addr, REG_FP(m68k)[7-i]); mem_addr += 12; break; default: WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[7-i]); break; } m68k->remaining_cycles -= 2; } } break; } default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4); } } else // From mem to FP regs { switch (mode)