1 // SPDX-License-Identifier: MIT
6 #include "softfloat/softfloat.h"
11 extern void exit(int);
13 static void fatalerror(char *format, ...) {
16 vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong
21 #define FPCC_N 0x08000000
22 #define FPCC_Z 0x04000000
23 #define FPCC_I 0x02000000
24 #define FPCC_NAN 0x01000000
26 #define FPES_OE 0x00002000
27 #define FPAE_IOP 0x00000080
29 #define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
30 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
31 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
33 /*----------------------------------------------------------------------------
34 | Returns 1 if the extended double-precision floating-point value `a' is a
35 | NaN; otherwise returns 0.
36 *----------------------------------------------------------------------------*/
38 flag floatx80_is_nan( floatx80 a )
41 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( a.low<<1 );
46 // masks for packed dwords, positive k-factor
47 static uint32 pkmask2[18] =
49 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
50 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
51 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
52 0xffffffff, 0xffffffff, 0xffffffff
55 static uint32 pkmask3[18] =
57 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
59 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
62 static inline double fx80_to_double(floatx80 fx)
69 d = floatx80_to_float64(fx, &status);
74 static inline floatx80 double_to_fx80(double in)
80 return float64_to_floatx80(*d, &status);
83 static inline floatx80 load_extended_float80(m68ki_cpu_core *state, uint32 ea)
89 d3 = m68ki_read_16(state, ea);
90 d1 = m68ki_read_32(state, ea + 4);
91 d2 = m68ki_read_32(state, ea + 8);
94 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
99 static inline void store_extended_float80(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
101 m68ki_write_16(state, ea + 0, fpr.high);
102 m68ki_write_16(state, ea + 2, 0);
103 m68ki_write_32(state, ea + 4, (fpr.low >> 32) & 0xffffffff);
104 m68ki_write_32(state, ea + 8, fpr.low & 0xffffffff);
107 static inline floatx80 load_pack_float80(m68ki_cpu_core *state, uint32 ea)
109 uint32 dw1, dw2, dw3;
114 dw1 = m68ki_read_32(state, ea);
115 dw2 = m68ki_read_32(state, ea + 4);
116 dw3 = m68ki_read_32(state, ea + 8);
119 if (dw1 & 0x80000000) // mantissa sign
123 *ch++ = (char)((dw1 & 0xf) + '0');
125 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
126 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
127 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
128 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
129 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
130 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
131 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
132 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
133 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
134 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
135 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
136 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
137 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
138 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
139 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
140 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
142 if (dw1 & 0x40000000) // exponent sign
146 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
147 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
148 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
151 sscanf(str, "%le", &tmp);
153 result = double_to_fx80(tmp);
158 static inline void store_pack_float80(m68ki_cpu_core *state, uint32 ea, int k, floatx80 fpr)
160 uint32 dw1, dw2, dw3;
167 sprintf(str, "%.16e", fx80_to_double(fpr));
180 dw1 |= (*ch++ - '0');
187 // handle negative k-factor here
188 if ((k <= 0) && (k >= -13))
191 for (i = 0; i < 3; i++)
193 if (ch[18+i] >= '0' && ch[18+i] <= '9')
195 exp = (exp << 4) | (ch[18+i] - '0');
205 // last digit is (k + exponent - 1)
208 // round up the last significant mantissa digit
214 // zero out the rest of the mantissa digits
215 for (j = (k+1); j < 16; j++)
220 // now zero out K to avoid tripping the positive K detection below
224 // crack 8 digits of the mantissa
225 for (i = 0; i < 8; i++)
228 if (*ch >= '0' && *ch <= '9')
234 // next 8 digits of the mantissa
235 for (i = 0; i < 8; i++)
238 if (*ch >= '0' && *ch <= '9')
242 // handle masking if k is positive
254 // state->fpcr |= (need to set OPERR bit)
258 // finally, crack the exponent
259 if (*ch == 'e' || *ch == 'E')
274 for (i = 0; i < 3; i++)
276 if (*ch >= '0' && *ch <= '9')
278 j = (j << 4) | (*ch++ - '0');
285 m68ki_write_32(state, ea, dw1);
286 m68ki_write_32(state, ea + 4, dw2);
287 m68ki_write_32(state, ea + 8, dw3);
290 static inline void SET_CONDITION_CODES(m68ki_cpu_core *state, floatx80 reg)
294 // regi = (u64 *)®
296 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
299 if (reg.high & 0x8000)
305 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
311 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
317 if (floatx80_is_nan(reg))
319 REG_FPSR |= FPCC_NAN;
323 static inline int TEST_CONDITION(m68ki_cpu_core *state, int condition)
325 int n = (REG_FPSR & FPCC_N) != 0;
326 int z = (REG_FPSR & FPCC_Z) != 0;
327 int nan = (REG_FPSR & FPCC_NAN) != 0;
332 case 0x00: return 0; // False
335 case 0x01: return (z); // Equal
338 case 0x02: return (!(nan || z || n)); // Greater Than
341 case 0x03: return (z || !(nan || n)); // Greater or Equal
344 case 0x04: return (n && !(nan || z)); // Less Than
347 case 0x05: return (z || (n && !nan)); // Less Than or Equal
350 case 0x06: return !nan && !z;
353 case 0x07: return !nan;
356 case 0x08: return nan;
359 case 0x09: return nan || z;
362 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
365 case 0x0b: return (nan || z || !n); // Not Less Than
368 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
371 case 0x0d: return (nan || z || n); // Not Greater Than
374 case 0x0e: return (!z); // Not Equal
377 case 0x0f: return 1; // True
379 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
385 static uint8 READ_EA_8(m68ki_cpu_core *state, int ea)
387 int mode = (ea >> 3) & 0x7;
388 int reg = (ea & 0x7);
398 uint32 ea = REG_A[reg];
399 return m68ki_read_8(state, ea);
403 uint32 ea = EA_AY_PI_8();
404 return m68ki_read_8(state, ea);
408 uint32 ea = EA_AY_PD_8();
409 return m68ki_read_8(state, ea);
413 uint32 ea = EA_AY_DI_8();
414 return m68ki_read_8(state, ea);
416 case 6: // (An) + (Xn) + d8
418 uint32 ea = EA_AY_IX_8();
419 return m68ki_read_8(state, ea);
427 uint32 ea = (uint32) OPER_I_16(state);
428 return m68ki_read_8(state, ea);
432 uint32 d1 = OPER_I_16(state);
433 uint32 d2 = OPER_I_16(state);
434 uint32 ea = (d1 << 16) | d2;
435 return m68ki_read_8(state, ea);
439 uint32 ea = EA_PCDI_8();
440 return m68ki_read_8(state, ea);
442 case 3: // (PC) + (Xn) + d8
444 uint32 ea = EA_PCIX_8();
445 return m68ki_read_8(state, ea);
449 return OPER_I_8(state);
451 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
455 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
461 static uint16 READ_EA_16(m68ki_cpu_core *state, int ea)
463 int mode = (ea >> 3) & 0x7;
464 int reg = (ea & 0x7);
470 return (uint16)(REG_D[reg]);
474 uint32 ea = REG_A[reg];
475 return m68ki_read_16(state, ea);
479 uint32 ea = EA_AY_PI_16();
480 return m68ki_read_16(state, ea);
484 uint32 ea = EA_AY_PD_16();
485 return m68ki_read_16(state, ea);
489 uint32 ea = EA_AY_DI_16();
490 return m68ki_read_16(state, ea);
492 case 6: // (An) + (Xn) + d8
494 uint32 ea = EA_AY_IX_16();
495 return m68ki_read_16(state, ea);
503 uint32 ea = (uint32) OPER_I_16(state);
504 return m68ki_read_16(state, ea);
508 uint32 d1 = OPER_I_16(state);
509 uint32 d2 = OPER_I_16(state);
510 uint32 ea = (d1 << 16) | d2;
511 return m68ki_read_16(state, ea);
515 uint32 ea = EA_PCDI_16();
516 return m68ki_read_16(state, ea);
518 case 3: // (PC) + (Xn) + d8
520 uint32 ea = EA_PCIX_16();
521 return m68ki_read_16(state, ea);
525 return OPER_I_16(state);
528 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
532 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
538 static uint32 READ_EA_32(m68ki_cpu_core *state, int ea)
540 int mode = (ea >> 3) & 0x7;
541 int reg = (ea & 0x7);
551 uint32 ea = REG_A[reg];
552 return m68ki_read_32(state, ea);
556 uint32 ea = EA_AY_PI_32();
557 return m68ki_read_32(state, ea);
561 uint32 ea = EA_AY_PD_32();
562 return m68ki_read_32(state, ea);
566 uint32 ea = EA_AY_DI_32();
567 return m68ki_read_32(state, ea);
569 case 6: // (An) + (Xn) + d8
571 uint32 ea = EA_AY_IX_32();
572 return m68ki_read_32(state, ea);
580 uint32 ea = (uint32) OPER_I_16(state);
581 return m68ki_read_32(state, ea);
585 uint32 d1 = OPER_I_16(state);
586 uint32 d2 = OPER_I_16(state);
587 uint32 ea = (d1 << 16) | d2;
588 return m68ki_read_32(state, ea);
592 uint32 ea = EA_PCDI_32();
593 return m68ki_read_32(state, ea);
595 case 3: // (PC) + (Xn) + d8
597 uint32 ea = EA_PCIX_32();
598 return m68ki_read_32(state, ea);
602 return OPER_I_32(state);
604 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
608 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
613 static uint64 READ_EA_64(m68ki_cpu_core *state, int ea)
615 int mode = (ea >> 3) & 0x7;
616 int reg = (ea & 0x7);
623 uint32 ea = REG_A[reg];
624 h1 = m68ki_read_32(state, ea + 0);
625 h2 = m68ki_read_32(state, ea + 4);
626 return (uint64)(h1) << 32 | (uint64)(h2);
630 uint32 ea = REG_A[reg];
632 h1 = m68ki_read_32(state, ea + 0);
633 h2 = m68ki_read_32(state, ea + 4);
634 return (uint64)(h1) << 32 | (uint64)(h2);
638 uint32 ea = REG_A[reg]-8;
640 h1 = m68ki_read_32(state, ea + 0);
641 h2 = m68ki_read_32(state, ea + 4);
642 return (uint64)(h1) << 32 | (uint64)(h2);
646 uint32 ea = EA_AY_DI_32();
647 h1 = m68ki_read_32(state, ea + 0);
648 h2 = m68ki_read_32(state, ea + 4);
649 return (uint64)(h1) << 32 | (uint64)(h2);
651 case 6: // (An) + (Xn) + d8
653 uint32 ea = EA_AY_IX_32();
654 h1 = m68ki_read_32(state, ea + 0);
655 h2 = m68ki_read_32(state, ea + 4);
656 return (uint64)(h1) << 32 | (uint64)(h2);
664 uint32 d1 = OPER_I_16(state);
665 uint32 d2 = OPER_I_16(state);
666 uint32 ea = (d1 << 16) | d2;
667 return (uint64)(m68ki_read_32(state, ea)) << 32 | (uint64)(m68ki_read_32(state, ea + 4));
669 case 3: // (PC) + (Xn) + d8
671 uint32 ea = EA_PCIX_32();
672 h1 = m68ki_read_32(state, ea + 0);
673 h2 = m68ki_read_32(state, ea + 4);
674 return (uint64)(h1) << 32 | (uint64)(h2);
678 h1 = OPER_I_32(state);
679 h2 = OPER_I_32(state);
680 return (uint64)(h1) << 32 | (uint64)(h2);
684 uint32 ea = EA_PCDI_32();
685 h1 = m68ki_read_32(state, ea + 0);
686 h2 = m68ki_read_32(state, ea + 4);
687 return (uint64)(h1) << 32 | (uint64)(h2);
689 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
693 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
700 static floatx80 READ_EA_FPE(m68ki_cpu_core *state, uint32 ea)
703 int mode = (ea >> 3) & 0x7;
704 int reg = (ea & 0x7);
710 uint32 ea = REG_A[reg];
711 fpr = load_extended_float80(state, ea);
717 uint32 ea = REG_A[reg];
719 fpr = load_extended_float80(state, ea);
724 uint32 ea = REG_A[reg]-12;
726 fpr = load_extended_float80(state, ea);
731 // FIXME: will fail for fmovem
732 uint32 ea = EA_AY_DI_32();
733 fpr = load_extended_float80(state, ea);
736 case 6: // (An) + (Xn) + d8
738 // FIXME: will fail for fmovem
739 uint32 ea = EA_AY_IX_32();
740 fpr = load_extended_float80(state, ea);
744 case 7: // extended modes
750 uint32 d1 = OPER_I_16(state);
751 uint32 d2 = OPER_I_16(state);
752 uint32 ea = (d1 << 16) | d2;
753 fpr = load_extended_float80(state, ea);
759 uint32 ea = EA_PCDI_32();
760 fpr = load_extended_float80(state, ea);
764 case 3: // (d16,PC,Dx.w)
766 uint32 ea = EA_PCIX_32();
767 fpr = load_extended_float80(state, ea);
771 case 4: // immediate (JFF)
774 fpr = load_extended_float80(state, ea);
780 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
786 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
792 static floatx80 READ_EA_PACK(m68ki_cpu_core *state, int ea)
795 int mode = (ea >> 3) & 0x7;
796 int reg = (ea & 0x7);
802 uint32 ea = REG_A[reg];
803 fpr = load_pack_float80(state, ea);
809 uint32 ea = REG_A[reg];
811 fpr = load_pack_float80(state, ea);
815 case 7: // extended modes
819 case 3: // (d16,PC,Dx.w)
821 uint32 ea = EA_PCIX_32();
822 fpr = load_pack_float80(state, ea);
827 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
833 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
839 static void WRITE_EA_8(m68ki_cpu_core *state, int ea, uint8 data)
841 int mode = (ea >> 3) & 0x7;
842 int reg = (ea & 0x7);
853 uint32 ea = REG_A[reg];
854 m68ki_write_8(state, ea, data);
859 uint32 ea = EA_AY_PI_8();
860 m68ki_write_8(state, ea, data);
865 uint32 ea = EA_AY_PD_8();
866 m68ki_write_8(state, ea, data);
871 uint32 ea = EA_AY_DI_8();
872 m68ki_write_8(state, ea, data);
875 case 6: // (An) + (Xn) + d8
877 uint32 ea = EA_AY_IX_8();
878 m68ki_write_8(state, ea, data);
887 uint32 d1 = OPER_I_16(state);
888 uint32 d2 = OPER_I_16(state);
889 uint32 ea = (d1 << 16) | d2;
890 m68ki_write_8(state, ea, data);
895 uint32 ea = EA_PCDI_16();
896 m68ki_write_8(state, ea, data);
899 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
903 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
907 static void WRITE_EA_16(m68ki_cpu_core *state, int ea, uint16 data)
909 int mode = (ea >> 3) & 0x7;
910 int reg = (ea & 0x7);
921 uint32 ea = REG_A[reg];
922 m68ki_write_16(state, ea, data);
927 uint32 ea = EA_AY_PI_16();
928 m68ki_write_16(state, ea, data);
933 uint32 ea = EA_AY_PD_16();
934 m68ki_write_16(state, ea, data);
939 uint32 ea = EA_AY_DI_16();
940 m68ki_write_16(state, ea, data);
943 case 6: // (An) + (Xn) + d8
945 uint32 ea = EA_AY_IX_16();
946 m68ki_write_16(state, ea, data);
955 uint32 d1 = OPER_I_16(state);
956 uint32 d2 = OPER_I_16(state);
957 uint32 ea = (d1 << 16) | d2;
958 m68ki_write_16(state, ea, data);
963 uint32 ea = EA_PCDI_16();
964 m68ki_write_16(state, ea, data);
967 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
971 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
975 static void WRITE_EA_32(m68ki_cpu_core *state, int ea, uint32 data)
977 int mode = (ea >> 3) & 0x7;
978 int reg = (ea & 0x7);
994 uint32 ea = REG_A[reg];
995 m68ki_write_32(state, ea, data);
1000 uint32 ea = EA_AY_PI_32();
1001 m68ki_write_32(state, ea, data);
1006 uint32 ea = EA_AY_PD_32();
1007 m68ki_write_32(state, ea, data);
1010 case 5: // (d16, An)
1012 uint32 ea = EA_AY_DI_32();
1013 m68ki_write_32(state, ea, data);
1016 case 6: // (An) + (Xn) + d8
1018 uint32 ea = EA_AY_IX_32();
1019 m68ki_write_32(state, ea, data);
1028 uint32 ea = OPER_I_16(state);
1029 m68ki_write_32(state, ea, data);
1034 uint32 d1 = OPER_I_16(state);
1035 uint32 d2 = OPER_I_16(state);
1036 uint32 ea = (d1 << 16) | d2;
1037 m68ki_write_32(state, ea, data);
1040 case 2: // (d16, PC)
1042 uint32 ea = EA_PCDI_32();
1043 m68ki_write_32(state, ea, data);
1046 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1050 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1054 static void WRITE_EA_64(m68ki_cpu_core *state, int ea, uint64 data)
1056 int mode = (ea >> 3) & 0x7;
1057 int reg = (ea & 0x7);
1063 uint32 ea = REG_A[reg];
1064 m68ki_write_32(state, ea, (uint32) (data >> 32));
1065 m68ki_write_32(state, ea + 4, (uint32) (data));
1070 uint32 ea = REG_A[reg];
1072 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1073 m68ki_write_32(state, ea + 4, (uint32) (data));
1081 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1082 m68ki_write_32(state, ea + 4, (uint32) (data));
1085 case 5: // (d16, An)
1087 uint32 ea = EA_AY_DI_32();
1088 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1089 m68ki_write_32(state, ea + 4, (uint32) (data));
1092 case 6: // (An) + (Xn) + d8
1094 uint32 ea = EA_AY_IX_32();
1095 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1096 m68ki_write_32(state, ea + 4, (uint32) (data));
1105 uint32 d1 = OPER_I_16(state);
1106 uint32 d2 = OPER_I_16(state);
1107 uint32 ea = (d1 << 16) | d2;
1108 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1109 m68ki_write_32(state, ea + 4, (uint32) (data));
1112 case 2: // (d16, PC)
1114 uint32 ea = EA_PCDI_32();
1115 m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1116 m68ki_write_32(state, ea + 4, (uint32) (data));
1119 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1123 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (uint32)(data >> 32), (uint32)(data), REG_PC);
1127 static void WRITE_EA_FPE(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
1129 int mode = (ea >> 3) & 0x7;
1130 int reg = (ea & 0x7);
1138 store_extended_float80(state, ea, fpr);
1146 store_extended_float80(state, ea, fpr);
1156 store_extended_float80(state, ea, fpr);
1159 case 5: // (d16, An)
1161 uint32 ea = EA_AY_DI_32();
1162 store_extended_float80(state, ea, fpr);
1170 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1174 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1178 static void WRITE_EA_PACK(m68ki_cpu_core *state, int ea, int k, floatx80 fpr)
1180 int mode = (ea >> 3) & 0x7;
1181 int reg = (ea & 0x7);
1189 store_pack_float80(state, ea, k, fpr);
1197 store_pack_float80(state, ea, k, fpr);
1207 store_pack_float80(state, ea, k, fpr);
1215 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1219 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1224 static void fpgen_rm_reg(m68ki_cpu_core *state, uint16 w2)
1226 int ea = REG_IR & 0x3f;
1227 int rm = (w2 >> 14) & 0x1;
1228 int src = (w2 >> 10) & 0x7;
1229 int dst = (w2 >> 7) & 0x7;
1230 int opmode = w2 & 0x7f;
1233 // fmovecr #$f, fp0 f200 5c0f
1239 case 0: // Long-Word Integer
1241 sint32 d = READ_EA_32(state, ea);
1242 source = int32_to_floatx80(d);
1245 case 1: // Single-precision Real
1247 uint32 d = READ_EA_32(state, ea);
1248 source = float32_to_floatx80(d, &status);
1251 case 2: // Extended-precision Real
1253 source = READ_EA_FPE(state, ea);
1256 case 3: // Packed-decimal Real
1258 source = READ_EA_PACK(state, ea);
1261 case 4: // Word Integer
1263 sint16 d = READ_EA_16(state, ea);
1264 source = int32_to_floatx80((sint32)d);
1267 case 5: // Double-precision Real
1269 uint64 d = READ_EA_64(state, ea);
1271 source = float64_to_floatx80(d, &status);
1274 case 6: // Byte Integer
1276 sint8 d = READ_EA_8(state, ea);
1277 source = int32_to_floatx80((sint32)d);
1280 case 7: // FMOVECR load from constant ROM
1285 source.high = 0x4000;
1286 source.low = U64(0xc90fdaa22168c235);
1289 case 0xb: // log10(2)
1290 source.high = 0x3ffd;
1291 source.low = U64(0x9a209a84fbcff798);
1295 source.high = 0x4000;
1296 source.low = U64(0xadf85458a2bb4a9b);
1299 case 0xd: // log2(e)
1300 source.high = 0x3fff;
1301 source.low = U64(0xb8aa3b295c17f0bc);
1304 case 0xe: // log10(e)
1305 source.high = 0x3ffd;
1306 source.low = U64(0xde5bd8a937287195);
1310 source = int32_to_floatx80((sint32)0);
1314 source.high = 0x3ffe;
1315 source.low = U64(0xb17217f7d1cf79ac);
1318 case 0x31: // ln(10)
1319 source.high = 0x4000;
1320 source.low = U64(0x935d8dddaaa8ac17);
1323 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1324 source = int32_to_floatx80((sint32)1);
1328 source = int32_to_floatx80((sint32)10);
1332 source = int32_to_floatx80((sint32)10*10);
1335 source = int32_to_floatx80((sint32)1000*10);
1339 source = int32_to_floatx80((sint32)10000000*10);
1342 case 0x37: // 1.0e16 - can't get the right precision from s32 so go "direct" with constants from h/w
1343 source.high = 0x4034;
1344 source.low = U64(0x8e1bc9bf04000000);
1347 case 0x38: // 1.0e32
1348 source.high = 0x4069;
1349 source.low = U64(0x9dc5ada82b70b59e);
1352 case 0x39: // 1.0e64
1353 source.high = 0x40d3;
1354 source.low = U64(0xc2781f49ffcfa6d5);
1357 case 0x3a: // 1.0e128
1358 source.high = 0x41a8;
1359 source.low = U64(0x93ba47c980e98ce0);
1362 case 0x3b: // 1.0e256
1363 source.high = 0x4351;
1364 source.low = U64(0xaa7eebfb9df9de8e);
1367 case 0x3c: // 1.0e512
1368 source.high = 0x46a3;
1369 source.low = U64(0xe319a0aea60e91c7);
1372 case 0x3d: // 1.0e1024
1373 source.high = 0x4d48;
1374 source.low = U64(0xc976758681750c17);
1377 case 0x3e: // 1.0e2048
1378 source.high = 0x5a92;
1379 source.low = U64(0x9e8b3b5dc53d5de5);
1382 case 0x3f: // 1.0e4096
1383 source.high = 0x7525;
1384 source.low = U64(0xc46052028a20979b);
1389 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1393 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1394 REG_FP[dst] = source;
1395 //FIXME mame doesn't use SET_CONDITION_CODES here
1396 SET_CONDITION_CODES(state, REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1400 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1405 source = REG_FP[src];
1408 // For FD* and FS* prefixes we already converted the source to floatx80
1409 // so we can treat these as their parent op.
1413 case 0x44: // FDMOVE
1414 case 0x40: // FSMOVE
1417 REG_FP[dst] = source;
1418 SET_CONDITION_CODES(state, REG_FP[dst]);
1425 temp = floatx80_to_int32(source, &status);
1426 REG_FP[dst] = int32_to_floatx80(temp);
1427 //FIXME mame doesn't use SET_CONDITION_CODES here
1428 SET_CONDITION_CODES(state, REG_FP[dst]); // JFF needs update condition codes
1434 REG_FP[dst] = floatx80_sinh(source, &status);
1435 SET_CONDITION_CODES(state, REG_FP[dst]);
1439 case 0x03: // FINTRZ
1442 temp = floatx80_to_int32_round_to_zero(source, &status);
1443 REG_FP[dst] = int32_to_floatx80(temp);
1444 //FIXME mame doesn't use SET_CONDITION_CODES here
1445 SET_CONDITION_CODES(state, REG_FP[dst]); // JFF needs update condition codes
1448 case 0x45: // FDSQRT
1449 case 0x41: // FSSQRT
1453 REG_FP[dst] = floatx80_sqrt(source, &status);
1454 SET_CONDITION_CODES(state, REG_FP[dst]);
1458 case 0x06: // FLOGNP1
1459 case 0x07: // FLOGNP1
1461 REG_FP[dst] = floatx80_lognp1 (source, &status);
1462 SET_CONDITION_CODES(state, REG_FP[dst]);
1463 USE_CYCLES(594); // for MC68881
1466 case 0x08: // FETOXM1
1468 REG_FP[dst] = floatx80_etoxm1(source, &status);
1469 SET_CONDITION_CODES(state, REG_FP[dst]);
1475 REG_FP[dst] = floatx80_tanh(source, &status);
1476 SET_CONDITION_CODES(state, REG_FP[dst]);
1483 REG_FP[dst] = floatx80_atan(source, &status);
1484 SET_CONDITION_CODES(state, REG_FP[dst]);
1490 REG_FP[dst] = floatx80_asin(source, &status);
1491 SET_CONDITION_CODES(state, REG_FP[dst]);
1495 case 0x0d: // FATANH
1497 REG_FP[dst] = floatx80_atanh(source, &status);
1498 SET_CONDITION_CODES(state, REG_FP[dst]);
1504 REG_FP[dst] = floatx80_sin(source, &status);
1505 SET_CONDITION_CODES(state, REG_FP[dst]);
1511 REG_FP[dst] = floatx80_tan(source, &status);
1512 SET_CONDITION_CODES(state, REG_FP[dst]);
1518 REG_FP[dst] = floatx80_etox(source, &status);
1519 SET_CONDITION_CODES(state, REG_FP[dst]);
1523 case 0x11: // FTWOTOX
1525 REG_FP[dst] = floatx80_twotox(source, &status);
1526 SET_CONDITION_CODES(state, REG_FP[dst]);
1530 case 0x12: // FTENTOX
1531 case 0x13: // FTENTOX
1533 REG_FP[dst] = floatx80_tentox(source, &status);
1534 SET_CONDITION_CODES(state, REG_FP[dst]);
1540 REG_FP[dst] = floatx80_logn(source, &status);
1541 SET_CONDITION_CODES(state, REG_FP[dst]);
1542 USE_CYCLES(548); // for MC68881
1545 case 0x15: // FLOG10
1547 REG_FP[dst] = floatx80_log10(source, &status);
1548 SET_CONDITION_CODES(state, REG_FP[dst]);
1549 USE_CYCLES(604); // for MC68881
1555 REG_FP[dst] = floatx80_log2(source, &status);
1556 SET_CONDITION_CODES(state, REG_FP[dst]);
1557 USE_CYCLES(604); // for MC68881
1564 REG_FP[dst] = source;
1565 REG_FP[dst].high &= 0x7fff;
1566 SET_CONDITION_CODES(state, REG_FP[dst]);
1572 REG_FP[dst] = floatx80_cosh(source, &status);
1573 SET_CONDITION_CODES(state, REG_FP[dst]);
1582 REG_FP[dst] = source;
1583 REG_FP[dst].high ^= 0x8000;
1584 SET_CONDITION_CODES(state, REG_FP[dst]);
1590 REG_FP[dst] = floatx80_acos(source, &status);
1591 SET_CONDITION_CODES(state, REG_FP[dst]);
1592 USE_CYCLES(604); // for MC68881
1598 REG_FP[dst] = floatx80_cos(source, &status);
1599 SET_CONDITION_CODES(state, REG_FP[dst]);
1603 case 0x1e: // FGETEXP
1605 REG_FP[dst] = floatx80_getexp(source, &status);
1606 SET_CONDITION_CODES(state, REG_FP[dst]);
1610 case 0x1f: // FGETMAN
1612 REG_FP[dst] = floatx80_getman(source, &status);
1613 SET_CONDITION_CODES(state, REG_FP[dst]);
1621 REG_FP[dst] = floatx80_div(REG_FP[dst], source, &status);
1622 //FIXME mame doesn't use SET_CONDITION_CODES here
1623 SET_CONDITION_CODES(state, REG_FP[dst]); // JFF
1629 sint8 const mode = status.float_rounding_mode;
1630 status.float_rounding_mode = float_round_to_zero;
1633 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1634 SET_CONDITION_CODES(state, REG_FP[dst]);
1635 status.float_rounding_mode = mode;
1636 USE_CYCLES(43); // guess
1643 REG_FP[dst] = floatx80_add(REG_FP[dst], source, &status);
1644 SET_CONDITION_CODES(state, REG_FP[dst]);
1652 REG_FP[dst] = floatx80_mul(REG_FP[dst], source, &status);
1653 SET_CONDITION_CODES(state, REG_FP[dst]);
1657 case 0x24: // FSGLDIV
1659 REG_FP[dst] = floatx80_sgldiv(REG_FP[dst], source, &status);
1660 USE_CYCLES(43); // // ? (value is from FDIV)
1665 sint8 const mode = status.float_rounding_mode;
1666 status.float_rounding_mode = float_round_nearest_even;
1669 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1670 SET_CONDITION_CODES(state, REG_FP[dst]);
1671 status.float_rounding_mode = mode;
1672 USE_CYCLES(43); // guess
1675 case 0x26: // FSCALE
1677 REG_FP[dst] = floatx80_scale(REG_FP[dst], source, &status);
1678 SET_CONDITION_CODES(state, REG_FP[dst]);
1679 USE_CYCLES(46); // (better?) guess
1682 case 0x27: // FSGLMUL
1684 REG_FP[dst] = floatx80_sglmul(REG_FP[dst], source, &status);
1685 SET_CONDITION_CODES(state, REG_FP[dst]);
1686 USE_CYCLES(11); // ? (value is from FMUL)
1700 REG_FP[dst] = floatx80_sub(REG_FP[dst], source, &status);
1701 SET_CONDITION_CODES(state, REG_FP[dst]);
1705 case 0x30: // FSINCOS
1706 case 0x31: // FSINCOS
1707 case 0x32: // FSINCOS
1708 case 0x33: // FSINCOS
1709 case 0x34: // FSINCOS
1710 case 0x35: // FSINCOS
1711 case 0x36: // FSINCOS
1712 case 0x37: // FSINCOS
1714 REG_FP[dst] = floatx80_cos(source, &status);
1715 REG_FP[w2&7] = floatx80_sin(source, &status);
1716 SET_CONDITION_CODES(state, REG_FP[dst]);
1727 res = floatx80_sub(REG_FP[dst], source, &status);
1728 SET_CONDITION_CODES(state, res);
1739 SET_CONDITION_CODES(state, res);
1744 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1748 static void fmove_reg_mem(m68ki_cpu_core *state, uint16 w2)
1750 int ea = REG_IR & 0x3f;
1751 int src = (w2 >> 7) & 0x7;
1752 int dst = (w2 >> 10) & 0x7;
1753 int k = (w2 & 0x7f);
1757 case 0: // Long-Word Integer
1759 sint32 d = (sint32)floatx80_to_int32(REG_FP[src], &status);
1760 WRITE_EA_32(state, ea, d);
1763 case 1: // Single-precision Real
1765 uint32 d = floatx80_to_float32(REG_FP[src], &status);
1766 WRITE_EA_32(state, ea, d);
1769 case 2: // Extended-precision Real
1771 WRITE_EA_FPE(state, ea, REG_FP[src]);
1774 case 3: // Packed-decimal Real with Static K-factor
1777 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1778 WRITE_EA_PACK(state, ea, k, REG_FP[src]);
1781 case 4: // Word Integer
1783 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1784 if (value > 0x7fff || value < -0x8000 )
1786 REG_FPSR |= FPES_OE | FPAE_IOP;
1788 WRITE_EA_16(state, ea, (sint16) value);
1791 case 5: // Double-precision Real
1795 d = floatx80_to_float64(REG_FP[src], &status);
1797 WRITE_EA_64(state, ea, d);
1800 case 6: // Byte Integer
1802 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1803 if (value > 127 || value < -128)
1805 REG_FPSR |= FPES_OE | FPAE_IOP;
1807 WRITE_EA_8(state, ea, (sint8) value);
1810 case 7: // Packed-decimal Real with Dynamic K-factor
1812 WRITE_EA_PACK(state, ea, REG_D[k >> 4], REG_FP[src]);
1820 static void fmove_fpcr(m68ki_cpu_core *state, uint16 w2)
1822 int ea = REG_IR & 0x3f;
1823 int dir = (w2 >> 13) & 0x1;
1824 int regsel = (w2 >> 10) & 0x7;
1825 int mode = (ea >> 3) & 0x7;
1827 if ((mode == 5) || (mode == 6))
1829 uint32 address = 0xffffffff; // force a bus error if this doesn't get assigned
1833 address = EA_AY_DI_32();
1837 address = EA_AY_IX_32();
1840 if (dir) // From system control reg to <ea>
1842 if (regsel & 4) { m68ki_write_32(state, address, REG_FPCR); address += 4; }
1843 if (regsel & 2) { m68ki_write_32(state, address, REG_FPSR); address += 4; }
1844 if (regsel & 1) { m68ki_write_32(state, address, REG_FPIAR); address += 4; }
1846 else // From <ea> to system control reg
1848 if (regsel & 4) { REG_FPCR = m68ki_read_32(state, address); address += 4; }
1849 if (regsel & 2) { REG_FPSR = m68ki_read_32(state, address); address += 4; }
1850 if (regsel & 1) { REG_FPIAR = m68ki_read_32(state, address); address += 4; }
1855 if (dir) // From system control reg to <ea>
1857 if (regsel & 4) WRITE_EA_32(state, ea, REG_FPCR);
1858 if (regsel & 2) WRITE_EA_32(state, ea, REG_FPSR);
1859 if (regsel & 1) WRITE_EA_32(state, ea, REG_FPIAR);
1861 else // From <ea> to system control reg
1863 if (regsel & 4) REG_FPCR = READ_EA_32(state, ea);
1864 if (regsel & 2) REG_FPSR = READ_EA_32(state, ea);
1865 if (regsel & 1) REG_FPIAR = READ_EA_32(state, ea);
1869 // FIXME: (2011-12-18 ost)
1870 // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1871 // but: with this code on Apollo the following programs in /systest/fptest will fail:
1872 // 1. Single Precision Whetstone will return wrong results never the less
1873 // 2. Vector Test will fault with 00040004: reference to illegal address
1875 if ((regsel & 4) && dir == 0)
1877 int rnd = (REG_FPCR >> 4) & 3;
1878 int prec = (REG_FPCR >> 6) & 3;
1880 // logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1885 case 0: // Extend (X)
1886 status.floatx80_rounding_precision = 80;
1888 case 1: // Single (S)
1889 status.floatx80_rounding_precision = 32;
1891 case 2: // Double (D)
1892 status.floatx80_rounding_precision = 64;
1894 case 3: // Undefined
1895 status.floatx80_rounding_precision = 80;
1902 case 0: // To Nearest (RN)
1903 status.float_rounding_mode = float_round_nearest_even;
1905 case 1: // To Zero (RZ)
1906 status.float_rounding_mode = float_round_to_zero;
1908 case 2: // To Minus Infinitiy (RM)
1909 status.float_rounding_mode = float_round_down;
1911 case 3: // To Plus Infinitiy (RP)
1912 status.float_rounding_mode = float_round_up;
1920 static void fmovem(m68ki_cpu_core *state, uint16 w2)
1923 int ea = REG_IR & 0x3f;
1924 int dir = (w2 >> 13) & 0x1;
1925 int mode = (w2 >> 11) & 0x3;
1926 int reglist = w2 & 0xff;
1928 uint32 mem_addr = 0;
1931 case 5: // (d16, An)
1932 mem_addr= EA_AY_DI_32();
1934 case 6: // (An) + (Xn) + d8
1935 mem_addr= EA_AY_IX_32();
1939 if (dir) // From FP regs to mem
1943 case 1: // Dynamic register list, postincrement or control addressing mode.
1944 // FIXME: not really tested, but seems to work
1945 reglist = REG_D[(reglist >> 4) & 7];
1948 case 0: // Static register list, predecrement or control addressing mode
1950 for (i=0; i < 8; i++)
1952 if (reglist & (1 << i))
1956 case 5: // (d16, An)
1957 case 6: // (An) + (Xn) + d8
1958 store_extended_float80(state, mem_addr, REG_FP[i]);
1962 WRITE_EA_FPE(state, ea, REG_FP[i]);
1972 case 2: // Static register list, postdecrement or control addressing mode.
1974 for (i=0; i < 8; i++)
1976 if (reglist & (1 << i))
1980 case 5: // (d16, An)
1981 case 6: // (An) + (Xn) + d8
1982 store_extended_float80(state, mem_addr, REG_FP[7 - i]);
1986 WRITE_EA_FPE(state, ea, REG_FP[7 - i]);
1996 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1999 else // From mem to FP regs
2003 case 3: // Dynamic register list, predecrement addressing mode.
2004 // FIXME: not really tested, but seems to work
2005 reglist = REG_D[(reglist >> 4) & 7];
2008 case 2: // Static register list, postincrement or control addressing mode
2010 for (i=0; i < 8; i++)
2012 if (reglist & (1 << i))
2016 case 5: // (d16, An)
2017 case 6: // (An) + (Xn) + d8
2018 REG_FP[7-i] = load_extended_float80(state, mem_addr);
2022 REG_FP[7-i] = READ_EA_FPE(state, ea);
2031 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
2036 static void fscc(m68ki_cpu_core *state)
2038 int ea = REG_IR & 0x3f;
2039 int condition = (sint16)(OPER_I_16(state));
2041 WRITE_EA_8(state, ea, TEST_CONDITION(state, condition) ? 0xff : 0);
2042 USE_CYCLES(7); // ???
2044 static void fbcc16(m68ki_cpu_core *state)
2047 int condition = REG_IR & 0x3f;
2049 offset = (sint16)(OPER_I_16(state));
2051 // TODO: condition and jump!!!
2052 if (TEST_CONDITION(state, condition))
2054 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2055 m68ki_branch_16(state, offset - 2);
2061 static void fbcc32(m68ki_cpu_core *state)
2064 int condition = REG_IR & 0x3f;
2066 offset = OPER_I_32(state);
2068 // TODO: condition and jump!!!
2069 if (TEST_CONDITION(state, condition))
2071 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2072 m68ki_branch_32(state, offset - 4);
2079 void m68040_fpu_op0(m68ki_cpu_core *state)
2081 state->fpu_just_reset = 0;
2083 switch ((REG_IR >> 6) & 0x3)
2087 uint16 w2 = OPER_I_16(state);
2088 switch ((w2 >> 13) & 0x7)
2090 case 0x0: // FPU ALU FP, FP
2091 case 0x2: // FPU ALU ea, FP
2093 fpgen_rm_reg(state, w2);
2097 case 0x3: // FMOVE FP, ea
2099 fmove_reg_mem(state, w2);
2103 case 0x4: // FMOVEM ea, FPCR
2104 case 0x5: // FMOVEM FPCR, ea
2106 fmove_fpcr(state, w2);
2110 case 0x6: // FMOVEM ea, list
2111 case 0x7: // FMOVEM list, ea
2117 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
2122 case 1: // FBcc disp16
2124 switch ((REG_IR >> 3) & 0x7) {
2127 printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2129 default: // FScc (?)
2133 fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2136 case 2: // FBcc disp16
2141 case 3: // FBcc disp32
2147 default: fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2151 static int perform_fsave(m68ki_cpu_core *state, uint32 addr, int inc)
2153 if(state->cpu_type & CPU_TYPE_040)
2157 m68ki_write_32(state, addr, 0x41000000);
2162 m68ki_write_32(state, addr, 0x41000000);
2169 // 68881 IDLE, version 0x1f
2170 m68ki_write_32(state, addr, 0x1f180000);
2171 m68ki_write_32(state, addr + 4, 0);
2172 m68ki_write_32(state, addr + 8, 0);
2173 m68ki_write_32(state, addr + 12, 0);
2174 m68ki_write_32(state, addr + 16, 0);
2175 m68ki_write_32(state, addr + 20, 0);
2176 m68ki_write_32(state, addr + 24, 0x70000000);
2181 m68ki_write_32(state, addr + 4 - 4, 0x70000000);
2182 m68ki_write_32(state, addr + 4 - 8, 0);
2183 m68ki_write_32(state, addr + 4 - 12, 0);
2184 m68ki_write_32(state, addr + 4 - 16, 0);
2185 m68ki_write_32(state, addr + 4 - 20, 0);
2186 m68ki_write_32(state, addr + 4 - 24, 0);
2187 m68ki_write_32(state, addr + 4 - 28, 0x1f180000);
2192 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
2193 static void do_frestore_null(m68ki_cpu_core *state)
2200 for (i = 0; i < 8; i++)
2202 REG_FP[i].high = 0x7fff;
2203 REG_FP[i].low = U64(0xffffffffffffffff);
2206 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
2207 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
2208 state->fpu_just_reset = 1;
2211 void m68040_do_fsave(m68ki_cpu_core *state, uint32 addr, int reg, int inc)
2213 if (state->fpu_just_reset)
2215 m68ki_write_32(state, addr, 0);
2219 // we normally generate an IDLE frame
2220 int delta = perform_fsave(state, addr, inc);
2222 REG_A[reg] += delta;
2226 void m68040_do_frestore(m68ki_cpu_core *state, uint32 addr, int reg)
2228 uint32 temp = m68ki_read_32(state, addr);
2229 // check for nullptr frame
2230 if (temp & 0xff000000)
2232 // we don't handle non-nullptr frames
2233 state->fpu_just_reset = 0;
2237 uint8 m40 = !!(state->cpu_type & CPU_TYPE_040);
2238 // how about an IDLE frame?
2239 if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2241 REG_A[reg] += 7*4-4;
2243 else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2247 else if ((temp & 0x00ff0000) == 0x00380000)
2251 else if ((temp & 0x00ff0000) == 0x00b40000)
2259 do_frestore_null(state);
2263 void m68040_fpu_op1(m68ki_cpu_core *state)
2265 int ea = REG_IR & 0x3f;
2266 int mode = (ea >> 3) & 0x7;
2267 int reg = (ea & 0x7);
2270 switch ((REG_IR >> 6) & 0x3)
2272 case 0: // FSAVE <ea>
2278 m68040_do_fsave(state, addr, -1, 1);
2282 addr = EA_AY_PI_32();
2283 printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
2284 m68040_do_fsave(state, addr, -1, 1); // FIXME: -1 was reg
2288 addr = EA_AY_PD_32();
2289 m68040_do_fsave(state, addr, reg, 0); // FIXME: -1 was reg
2291 case 5: // (D16, An)
2292 addr = EA_AY_DI_16();
2293 m68040_do_fsave(state, addr, -1, 1);
2296 case 6: // (An) + (Xn) + d8
2297 addr = EA_AY_IX_16();
2298 m68040_do_fsave(state, addr, -1, 1);
2308 m68040_do_fsave(state, addr, -1, 1);
2311 case 2: // (d16, PC)
2313 addr = EA_PCDI_16();
2314 m68040_do_fsave(state, addr, -1, 1);
2318 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2324 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2329 case 1: // FRESTORE <ea>
2335 m68040_do_frestore(state, addr, -1);
2339 addr = EA_AY_PI_32();
2340 m68040_do_frestore(state, addr, reg);
2343 case 5: // (D16, An)
2344 addr = EA_AY_DI_16();
2345 m68040_do_frestore(state, addr, -1);
2348 case 6: // (An) + (Xn) + d8
2349 addr = EA_AY_IX_16();
2350 m68040_do_frestore(state, addr, -1);
2360 m68040_do_frestore(state, addr, -1);
2363 case 2: // (d16, PC)
2365 addr = EA_PCDI_16();
2366 m68040_do_frestore(state, addr, -1);
2370 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2376 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2381 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2385 void m68881_ftrap(m68ki_cpu_core *state)
2387 uint16 w2 = OPER_I_16(state);
2389 // now check the condition
2390 if (TEST_CONDITION(state, w2 & 0x3f))
2393 m68ki_exception_trap(state, EXCEPTION_TRAPV);
2395 else // fall through, requires eating the operand
2397 switch (REG_IR & 0x7)
2399 case 2: // word operand
2403 case 3: // long word operand
2407 case 4: // no operand