1 // SPDX-License-Identifier: MIT
6 #include "softfloat/softfloat.h"
10 extern void exit(int);
12 static void fatalerror(char *format, ...) {
15 vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong
20 #define FPCC_N 0x08000000
21 #define FPCC_Z 0x04000000
22 #define FPCC_I 0x02000000
23 #define FPCC_NAN 0x01000000
25 #define FPES_OE 0x00002000
26 #define FPAE_IOP 0x00000080
28 #define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
29 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
30 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
32 /*----------------------------------------------------------------------------
33 | Returns 1 if the extended double-precision floating-point value `a' is a
34 | NaN; otherwise returns 0.
35 *----------------------------------------------------------------------------*/
37 flag floatx80_is_nan( floatx80 a )
40 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( a.low<<1 );
45 // masks for packed dwords, positive k-factor
46 static uint32 pkmask2[18] =
48 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
49 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
50 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
51 0xffffffff, 0xffffffff, 0xffffffff
54 static uint32 pkmask3[18] =
56 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
58 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
61 static inline double fx80_to_double(floatx80 fx)
68 d = floatx80_to_float64(fx, &status);
73 static inline floatx80 double_to_fx80(double in)
79 return float64_to_floatx80(*d, &status);
82 static inline floatx80 load_extended_float80(uint32 ea)
88 d3 = m68ki_read_16(ea);
89 d1 = m68ki_read_32(ea+4);
90 d2 = m68ki_read_32(ea+8);
93 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
98 static inline void store_extended_float80(uint32 ea, floatx80 fpr)
100 m68ki_write_16(ea+0, fpr.high);
101 m68ki_write_16(ea+2, 0);
102 m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff);
103 m68ki_write_32(ea+8, fpr.low&0xffffffff);
106 static inline floatx80 load_pack_float80(uint32 ea)
108 uint32 dw1, dw2, dw3;
113 dw1 = m68ki_read_32(ea);
114 dw2 = m68ki_read_32(ea+4);
115 dw3 = m68ki_read_32(ea+8);
118 if (dw1 & 0x80000000) // mantissa sign
122 *ch++ = (char)((dw1 & 0xf) + '0');
124 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
125 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
126 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
127 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
128 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
129 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
130 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
131 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
132 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
133 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
134 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
135 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
136 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
137 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
138 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
139 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
141 if (dw1 & 0x40000000) // exponent sign
145 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
146 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
147 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
150 sscanf(str, "%le", &tmp);
152 result = double_to_fx80(tmp);
157 static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr)
159 uint32 dw1, dw2, dw3;
166 sprintf(str, "%.16e", fx80_to_double(fpr));
179 dw1 |= (*ch++ - '0');
186 // handle negative k-factor here
187 if ((k <= 0) && (k >= -13))
190 for (i = 0; i < 3; i++)
192 if (ch[18+i] >= '0' && ch[18+i] <= '9')
194 exp = (exp << 4) | (ch[18+i] - '0');
204 // last digit is (k + exponent - 1)
207 // round up the last significant mantissa digit
213 // zero out the rest of the mantissa digits
214 for (j = (k+1); j < 16; j++)
219 // now zero out K to avoid tripping the positive K detection below
223 // crack 8 digits of the mantissa
224 for (i = 0; i < 8; i++)
227 if (*ch >= '0' && *ch <= '9')
233 // next 8 digits of the mantissa
234 for (i = 0; i < 8; i++)
237 if (*ch >= '0' && *ch <= '9')
241 // handle masking if k is positive
253 // m68ki_cpu.fpcr |= (need to set OPERR bit)
257 // finally, crack the exponent
258 if (*ch == 'e' || *ch == 'E')
273 for (i = 0; i < 3; i++)
275 if (*ch >= '0' && *ch <= '9')
277 j = (j << 4) | (*ch++ - '0');
284 m68ki_write_32(ea, dw1);
285 m68ki_write_32(ea+4, dw2);
286 m68ki_write_32(ea+8, dw3);
289 static inline void SET_CONDITION_CODES(floatx80 reg)
293 // regi = (u64 *)®
295 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
298 if (reg.high & 0x8000)
304 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
310 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
316 if (floatx80_is_nan(reg))
318 REG_FPSR |= FPCC_NAN;
322 static inline int TEST_CONDITION(int condition)
324 int n = (REG_FPSR & FPCC_N) != 0;
325 int z = (REG_FPSR & FPCC_Z) != 0;
326 int nan = (REG_FPSR & FPCC_NAN) != 0;
331 case 0x00: return 0; // False
334 case 0x01: return (z); // Equal
337 case 0x02: return (!(nan || z || n)); // Greater Than
340 case 0x03: return (z || !(nan || n)); // Greater or Equal
343 case 0x04: return (n && !(nan || z)); // Less Than
346 case 0x05: return (z || (n && !nan)); // Less Than or Equal
349 case 0x06: return !nan && !z;
352 case 0x07: return !nan;
355 case 0x08: return nan;
358 case 0x09: return nan || z;
361 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
364 case 0x0b: return (nan || z || !n); // Not Less Than
367 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
370 case 0x0d: return (nan || z || n); // Not Greater Than
373 case 0x0e: return (!z); // Not Equal
376 case 0x0f: return 1; // True
378 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
384 static uint8 READ_EA_8(m68ki_cpu_core *state, int ea)
386 int mode = (ea >> 3) & 0x7;
387 int reg = (ea & 0x7);
397 uint32 ea = REG_A[reg];
398 return m68ki_read_8(ea);
402 uint32 ea = EA_AY_PI_8();
403 return m68ki_read_8(ea);
407 uint32 ea = EA_AY_PD_8();
408 return m68ki_read_8(ea);
412 uint32 ea = EA_AY_DI_8();
413 return m68ki_read_8(ea);
415 case 6: // (An) + (Xn) + d8
417 uint32 ea = EA_AY_IX_8();
418 return m68ki_read_8(ea);
426 uint32 ea = (uint32) OPER_I_16(state);
427 return m68ki_read_8(ea);
431 uint32 d1 = OPER_I_16(state);
432 uint32 d2 = OPER_I_16(state);
433 uint32 ea = (d1 << 16) | d2;
434 return m68ki_read_8(ea);
438 uint32 ea = EA_PCDI_8();
439 return m68ki_read_8(ea);
441 case 3: // (PC) + (Xn) + d8
443 uint32 ea = EA_PCIX_8();
444 return m68ki_read_8(ea);
448 return OPER_I_8(state);
450 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
454 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
460 static uint16 READ_EA_16(m68ki_cpu_core *state, int ea)
462 int mode = (ea >> 3) & 0x7;
463 int reg = (ea & 0x7);
469 return (uint16)(REG_D[reg]);
473 uint32 ea = REG_A[reg];
474 return m68ki_read_16(ea);
478 uint32 ea = EA_AY_PI_16();
479 return m68ki_read_16(ea);
483 uint32 ea = EA_AY_PD_16();
484 return m68ki_read_16(ea);
488 uint32 ea = EA_AY_DI_16();
489 return m68ki_read_16(ea);
491 case 6: // (An) + (Xn) + d8
493 uint32 ea = EA_AY_IX_16();
494 return m68ki_read_16(ea);
502 uint32 ea = (uint32) OPER_I_16(state);
503 return m68ki_read_16(ea);
507 uint32 d1 = OPER_I_16(state);
508 uint32 d2 = OPER_I_16(state);
509 uint32 ea = (d1 << 16) | d2;
510 return m68ki_read_16(ea);
514 uint32 ea = EA_PCDI_16();
515 return m68ki_read_16(ea);
517 case 3: // (PC) + (Xn) + d8
519 uint32 ea = EA_PCIX_16();
520 return m68ki_read_16(ea);
524 return OPER_I_16(state);
527 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
531 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
537 static uint32 READ_EA_32(m68ki_cpu_core *state, int ea)
539 int mode = (ea >> 3) & 0x7;
540 int reg = (ea & 0x7);
550 uint32 ea = REG_A[reg];
551 return m68ki_read_32(ea);
555 uint32 ea = EA_AY_PI_32();
556 return m68ki_read_32(ea);
560 uint32 ea = EA_AY_PD_32();
561 return m68ki_read_32(ea);
565 uint32 ea = EA_AY_DI_32();
566 return m68ki_read_32(ea);
568 case 6: // (An) + (Xn) + d8
570 uint32 ea = EA_AY_IX_32();
571 return m68ki_read_32(ea);
579 uint32 ea = (uint32) OPER_I_16(state);
580 return m68ki_read_32(ea);
584 uint32 d1 = OPER_I_16(state);
585 uint32 d2 = OPER_I_16(state);
586 uint32 ea = (d1 << 16) | d2;
587 return m68ki_read_32(ea);
591 uint32 ea = EA_PCDI_32();
592 return m68ki_read_32(ea);
594 case 3: // (PC) + (Xn) + d8
596 uint32 ea = EA_PCIX_32();
597 return m68ki_read_32(ea);
601 return OPER_I_32(state);
603 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
607 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
612 static uint64 READ_EA_64(m68ki_cpu_core *state, int ea)
614 int mode = (ea >> 3) & 0x7;
615 int reg = (ea & 0x7);
622 uint32 ea = REG_A[reg];
623 h1 = m68ki_read_32(ea+0);
624 h2 = m68ki_read_32(ea+4);
625 return (uint64)(h1) << 32 | (uint64)(h2);
629 uint32 ea = REG_A[reg];
631 h1 = m68ki_read_32(ea+0);
632 h2 = m68ki_read_32(ea+4);
633 return (uint64)(h1) << 32 | (uint64)(h2);
637 uint32 ea = REG_A[reg]-8;
639 h1 = m68ki_read_32(ea+0);
640 h2 = m68ki_read_32(ea+4);
641 return (uint64)(h1) << 32 | (uint64)(h2);
645 uint32 ea = EA_AY_DI_32();
646 h1 = m68ki_read_32(ea+0);
647 h2 = m68ki_read_32(ea+4);
648 return (uint64)(h1) << 32 | (uint64)(h2);
650 case 6: // (An) + (Xn) + d8
652 uint32 ea = EA_AY_IX_32();
653 h1 = m68ki_read_32(ea+0);
654 h2 = m68ki_read_32(ea+4);
655 return (uint64)(h1) << 32 | (uint64)(h2);
663 uint32 d1 = OPER_I_16(state);
664 uint32 d2 = OPER_I_16(state);
665 uint32 ea = (d1 << 16) | d2;
666 return (uint64)(m68ki_read_32(ea)) << 32 | (uint64)(m68ki_read_32(ea+4));
668 case 3: // (PC) + (Xn) + d8
670 uint32 ea = EA_PCIX_32();
671 h1 = m68ki_read_32(ea+0);
672 h2 = m68ki_read_32(ea+4);
673 return (uint64)(h1) << 32 | (uint64)(h2);
677 h1 = OPER_I_32(state);
678 h2 = OPER_I_32(state);
679 return (uint64)(h1) << 32 | (uint64)(h2);
683 uint32 ea = EA_PCDI_32();
684 h1 = m68ki_read_32(ea+0);
685 h2 = m68ki_read_32(ea+4);
686 return (uint64)(h1) << 32 | (uint64)(h2);
688 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
692 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
699 static floatx80 READ_EA_FPE(m68ki_cpu_core *state, uint32 ea)
702 int mode = (ea >> 3) & 0x7;
703 int reg = (ea & 0x7);
709 uint32 ea = REG_A[reg];
710 fpr = load_extended_float80(ea);
716 uint32 ea = REG_A[reg];
718 fpr = load_extended_float80(ea);
723 uint32 ea = REG_A[reg]-12;
725 fpr = load_extended_float80(ea);
730 // FIXME: will fail for fmovem
731 uint32 ea = EA_AY_DI_32();
732 fpr = load_extended_float80(ea);
735 case 6: // (An) + (Xn) + d8
737 // FIXME: will fail for fmovem
738 uint32 ea = EA_AY_IX_32();
739 fpr = load_extended_float80(ea);
743 case 7: // extended modes
749 uint32 d1 = OPER_I_16(state);
750 uint32 d2 = OPER_I_16(state);
751 uint32 ea = (d1 << 16) | d2;
752 fpr = load_extended_float80(ea);
758 uint32 ea = EA_PCDI_32();
759 fpr = load_extended_float80(ea);
763 case 3: // (d16,PC,Dx.w)
765 uint32 ea = EA_PCIX_32();
766 fpr = load_extended_float80(ea);
770 case 4: // immediate (JFF)
773 fpr = load_extended_float80(ea);
779 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
785 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
791 static floatx80 READ_EA_PACK(m68ki_cpu_core *state, int ea)
794 int mode = (ea >> 3) & 0x7;
795 int reg = (ea & 0x7);
801 uint32 ea = REG_A[reg];
802 fpr = load_pack_float80(ea);
808 uint32 ea = REG_A[reg];
810 fpr = load_pack_float80(ea);
814 case 7: // extended modes
818 case 3: // (d16,PC,Dx.w)
820 uint32 ea = EA_PCIX_32();
821 fpr = load_pack_float80(ea);
826 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
832 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
838 static void WRITE_EA_8(m68ki_cpu_core *state, int ea, uint8 data)
840 int mode = (ea >> 3) & 0x7;
841 int reg = (ea & 0x7);
852 uint32 ea = REG_A[reg];
853 m68ki_write_8(ea, data);
858 uint32 ea = EA_AY_PI_8();
859 m68ki_write_8(ea, data);
864 uint32 ea = EA_AY_PD_8();
865 m68ki_write_8(ea, data);
870 uint32 ea = EA_AY_DI_8();
871 m68ki_write_8(ea, data);
874 case 6: // (An) + (Xn) + d8
876 uint32 ea = EA_AY_IX_8();
877 m68ki_write_8(ea, data);
886 uint32 d1 = OPER_I_16(state);
887 uint32 d2 = OPER_I_16(state);
888 uint32 ea = (d1 << 16) | d2;
889 m68ki_write_8(ea, data);
894 uint32 ea = EA_PCDI_16();
895 m68ki_write_8(ea, data);
898 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
902 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
906 static void WRITE_EA_16(m68ki_cpu_core *state, int ea, uint16 data)
908 int mode = (ea >> 3) & 0x7;
909 int reg = (ea & 0x7);
920 uint32 ea = REG_A[reg];
921 m68ki_write_16(ea, data);
926 uint32 ea = EA_AY_PI_16();
927 m68ki_write_16(ea, data);
932 uint32 ea = EA_AY_PD_16();
933 m68ki_write_16(ea, data);
938 uint32 ea = EA_AY_DI_16();
939 m68ki_write_16(ea, data);
942 case 6: // (An) + (Xn) + d8
944 uint32 ea = EA_AY_IX_16();
945 m68ki_write_16(ea, data);
954 uint32 d1 = OPER_I_16(state);
955 uint32 d2 = OPER_I_16(state);
956 uint32 ea = (d1 << 16) | d2;
957 m68ki_write_16(ea, data);
962 uint32 ea = EA_PCDI_16();
963 m68ki_write_16(ea, data);
966 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
970 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
974 static void WRITE_EA_32(m68ki_cpu_core *state, int ea, uint32 data)
976 int mode = (ea >> 3) & 0x7;
977 int reg = (ea & 0x7);
993 uint32 ea = REG_A[reg];
994 m68ki_write_32(ea, data);
999 uint32 ea = EA_AY_PI_32();
1000 m68ki_write_32(ea, data);
1005 uint32 ea = EA_AY_PD_32();
1006 m68ki_write_32(ea, data);
1009 case 5: // (d16, An)
1011 uint32 ea = EA_AY_DI_32();
1012 m68ki_write_32(ea, data);
1015 case 6: // (An) + (Xn) + d8
1017 uint32 ea = EA_AY_IX_32();
1018 m68ki_write_32(ea, data);
1027 uint32 ea = OPER_I_16(state);
1028 m68ki_write_32(ea, data);
1033 uint32 d1 = OPER_I_16(state);
1034 uint32 d2 = OPER_I_16(state);
1035 uint32 ea = (d1 << 16) | d2;
1036 m68ki_write_32(ea, data);
1039 case 2: // (d16, PC)
1041 uint32 ea = EA_PCDI_32();
1042 m68ki_write_32(ea, data);
1045 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1049 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1053 static void WRITE_EA_64(m68ki_cpu_core *state, int ea, uint64 data)
1055 int mode = (ea >> 3) & 0x7;
1056 int reg = (ea & 0x7);
1062 uint32 ea = REG_A[reg];
1063 m68ki_write_32(ea, (uint32)(data >> 32));
1064 m68ki_write_32(ea+4, (uint32)(data));
1069 uint32 ea = REG_A[reg];
1071 m68ki_write_32(ea+0, (uint32)(data >> 32));
1072 m68ki_write_32(ea+4, (uint32)(data));
1080 m68ki_write_32(ea+0, (uint32)(data >> 32));
1081 m68ki_write_32(ea+4, (uint32)(data));
1084 case 5: // (d16, An)
1086 uint32 ea = EA_AY_DI_32();
1087 m68ki_write_32(ea+0, (uint32)(data >> 32));
1088 m68ki_write_32(ea+4, (uint32)(data));
1091 case 6: // (An) + (Xn) + d8
1093 uint32 ea = EA_AY_IX_32();
1094 m68ki_write_32(ea+0, (uint32)(data >> 32));
1095 m68ki_write_32(ea+4, (uint32)(data));
1104 uint32 d1 = OPER_I_16(state);
1105 uint32 d2 = OPER_I_16(state);
1106 uint32 ea = (d1 << 16) | d2;
1107 m68ki_write_32(ea+0, (uint32)(data >> 32));
1108 m68ki_write_32(ea+4, (uint32)(data));
1111 case 2: // (d16, PC)
1113 uint32 ea = EA_PCDI_32();
1114 m68ki_write_32(ea+0, (uint32)(data >> 32));
1115 m68ki_write_32(ea+4, (uint32)(data));
1118 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1122 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);
1126 static void WRITE_EA_FPE(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
1128 int mode = (ea >> 3) & 0x7;
1129 int reg = (ea & 0x7);
1137 store_extended_float80(ea, fpr);
1145 store_extended_float80(ea, fpr);
1155 store_extended_float80(ea, fpr);
1158 case 5: // (d16, An)
1160 uint32 ea = EA_AY_DI_32();
1161 store_extended_float80(ea, fpr);
1169 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1173 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1177 static void WRITE_EA_PACK(m68ki_cpu_core *state, int ea, int k, floatx80 fpr)
1179 int mode = (ea >> 3) & 0x7;
1180 int reg = (ea & 0x7);
1188 store_pack_float80(ea, k, fpr);
1196 store_pack_float80(ea, k, fpr);
1206 store_pack_float80(ea, k, fpr);
1214 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1218 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1223 static void fpgen_rm_reg(m68ki_cpu_core *state, uint16 w2)
1225 int ea = REG_IR & 0x3f;
1226 int rm = (w2 >> 14) & 0x1;
1227 int src = (w2 >> 10) & 0x7;
1228 int dst = (w2 >> 7) & 0x7;
1229 int opmode = w2 & 0x7f;
1232 // fmovecr #$f, fp0 f200 5c0f
1238 case 0: // Long-Word Integer
1240 sint32 d = READ_EA_32(state, ea);
1241 source = int32_to_floatx80(d);
1244 case 1: // Single-precision Real
1246 uint32 d = READ_EA_32(state, ea);
1247 source = float32_to_floatx80(d, &status);
1250 case 2: // Extended-precision Real
1252 source = READ_EA_FPE(state, ea);
1255 case 3: // Packed-decimal Real
1257 source = READ_EA_PACK(state, ea);
1260 case 4: // Word Integer
1262 sint16 d = READ_EA_16(state, ea);
1263 source = int32_to_floatx80((sint32)d);
1266 case 5: // Double-precision Real
1268 uint64 d = READ_EA_64(state, ea);
1270 source = float64_to_floatx80(d, &status);
1273 case 6: // Byte Integer
1275 sint8 d = READ_EA_8(state, ea);
1276 source = int32_to_floatx80((sint32)d);
1279 case 7: // FMOVECR load from constant ROM
1284 source.high = 0x4000;
1285 source.low = U64(0xc90fdaa22168c235);
1288 case 0xb: // log10(2)
1289 source.high = 0x3ffd;
1290 source.low = U64(0x9a209a84fbcff798);
1294 source.high = 0x4000;
1295 source.low = U64(0xadf85458a2bb4a9b);
1298 case 0xd: // log2(e)
1299 source.high = 0x3fff;
1300 source.low = U64(0xb8aa3b295c17f0bc);
1303 case 0xe: // log10(e)
1304 source.high = 0x3ffd;
1305 source.low = U64(0xde5bd8a937287195);
1309 source = int32_to_floatx80((sint32)0);
1313 source.high = 0x3ffe;
1314 source.low = U64(0xb17217f7d1cf79ac);
1317 case 0x31: // ln(10)
1318 source.high = 0x4000;
1319 source.low = U64(0x935d8dddaaa8ac17);
1322 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1323 source = int32_to_floatx80((sint32)1);
1327 source = int32_to_floatx80((sint32)10);
1331 source = int32_to_floatx80((sint32)10*10);
1334 source = int32_to_floatx80((sint32)1000*10);
1338 source = int32_to_floatx80((sint32)10000000*10);
1341 case 0x37: // 1.0e16 - can't get the right precision from s32 so go "direct" with constants from h/w
1342 source.high = 0x4034;
1343 source.low = U64(0x8e1bc9bf04000000);
1346 case 0x38: // 1.0e32
1347 source.high = 0x4069;
1348 source.low = U64(0x9dc5ada82b70b59e);
1351 case 0x39: // 1.0e64
1352 source.high = 0x40d3;
1353 source.low = U64(0xc2781f49ffcfa6d5);
1356 case 0x3a: // 1.0e128
1357 source.high = 0x41a8;
1358 source.low = U64(0x93ba47c980e98ce0);
1361 case 0x3b: // 1.0e256
1362 source.high = 0x4351;
1363 source.low = U64(0xaa7eebfb9df9de8e);
1366 case 0x3c: // 1.0e512
1367 source.high = 0x46a3;
1368 source.low = U64(0xe319a0aea60e91c7);
1371 case 0x3d: // 1.0e1024
1372 source.high = 0x4d48;
1373 source.low = U64(0xc976758681750c17);
1376 case 0x3e: // 1.0e2048
1377 source.high = 0x5a92;
1378 source.low = U64(0x9e8b3b5dc53d5de5);
1381 case 0x3f: // 1.0e4096
1382 source.high = 0x7525;
1383 source.low = U64(0xc46052028a20979b);
1388 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1392 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1393 REG_FP[dst] = source;
1394 //FIXME mame doesn't use SET_CONDITION_CODES here
1395 SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1399 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1404 source = REG_FP[src];
1407 // For FD* and FS* prefixes we already converted the source to floatx80
1408 // so we can treat these as their parent op.
1412 case 0x44: // FDMOVE
1413 case 0x40: // FSMOVE
1416 REG_FP[dst] = source;
1417 SET_CONDITION_CODES(REG_FP[dst]);
1424 temp = floatx80_to_int32(source, &status);
1425 REG_FP[dst] = int32_to_floatx80(temp);
1426 //FIXME mame doesn't use SET_CONDITION_CODES here
1427 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1433 REG_FP[dst] = floatx80_sinh(source, &status);
1434 SET_CONDITION_CODES(REG_FP[dst]);
1438 case 0x03: // FINTRZ
1441 temp = floatx80_to_int32_round_to_zero(source, &status);
1442 REG_FP[dst] = int32_to_floatx80(temp);
1443 //FIXME mame doesn't use SET_CONDITION_CODES here
1444 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1447 case 0x45: // FDSQRT
1448 case 0x41: // FSSQRT
1452 REG_FP[dst] = floatx80_sqrt(source, &status);
1453 SET_CONDITION_CODES(REG_FP[dst]);
1457 case 0x06: // FLOGNP1
1458 case 0x07: // FLOGNP1
1460 REG_FP[dst] = floatx80_lognp1 (source, &status);
1461 SET_CONDITION_CODES(REG_FP[dst]);
1462 USE_CYCLES(594); // for MC68881
1465 case 0x08: // FETOXM1
1467 REG_FP[dst] = floatx80_etoxm1(source, &status);
1468 SET_CONDITION_CODES(REG_FP[dst]);
1474 REG_FP[dst] = floatx80_tanh(source, &status);
1475 SET_CONDITION_CODES(REG_FP[dst]);
1482 REG_FP[dst] = floatx80_atan(source, &status);
1483 SET_CONDITION_CODES(REG_FP[dst]);
1489 REG_FP[dst] = floatx80_asin(source, &status);
1490 SET_CONDITION_CODES(REG_FP[dst]);
1494 case 0x0d: // FATANH
1496 REG_FP[dst] = floatx80_atanh(source, &status);
1497 SET_CONDITION_CODES(REG_FP[dst]);
1503 REG_FP[dst] = floatx80_sin(source, &status);
1504 SET_CONDITION_CODES(REG_FP[dst]);
1510 REG_FP[dst] = floatx80_tan(source, &status);
1511 SET_CONDITION_CODES(REG_FP[dst]);
1517 REG_FP[dst] = floatx80_etox(source, &status);
1518 SET_CONDITION_CODES(REG_FP[dst]);
1522 case 0x11: // FTWOTOX
1524 REG_FP[dst] = floatx80_twotox(source, &status);
1525 SET_CONDITION_CODES(REG_FP[dst]);
1529 case 0x12: // FTENTOX
1530 case 0x13: // FTENTOX
1532 REG_FP[dst] = floatx80_tentox(source, &status);
1533 SET_CONDITION_CODES(REG_FP[dst]);
1539 REG_FP[dst] = floatx80_logn(source, &status);
1540 SET_CONDITION_CODES(REG_FP[dst]);
1541 USE_CYCLES(548); // for MC68881
1544 case 0x15: // FLOG10
1546 REG_FP[dst] = floatx80_log10(source, &status);
1547 SET_CONDITION_CODES(REG_FP[dst]);
1548 USE_CYCLES(604); // for MC68881
1554 REG_FP[dst] = floatx80_log2(source, &status);
1555 SET_CONDITION_CODES(REG_FP[dst]);
1556 USE_CYCLES(604); // for MC68881
1563 REG_FP[dst] = source;
1564 REG_FP[dst].high &= 0x7fff;
1565 SET_CONDITION_CODES(REG_FP[dst]);
1571 REG_FP[dst] = floatx80_cosh(source, &status);
1572 SET_CONDITION_CODES(REG_FP[dst]);
1581 REG_FP[dst] = source;
1582 REG_FP[dst].high ^= 0x8000;
1583 SET_CONDITION_CODES(REG_FP[dst]);
1589 REG_FP[dst] = floatx80_acos(source, &status);
1590 SET_CONDITION_CODES(REG_FP[dst]);
1591 USE_CYCLES(604); // for MC68881
1597 REG_FP[dst] = floatx80_cos(source, &status);
1598 SET_CONDITION_CODES(REG_FP[dst]);
1602 case 0x1e: // FGETEXP
1604 REG_FP[dst] = floatx80_getexp(source, &status);
1605 SET_CONDITION_CODES(REG_FP[dst]);
1609 case 0x1f: // FGETMAN
1611 REG_FP[dst] = floatx80_getman(source, &status);
1612 SET_CONDITION_CODES(REG_FP[dst]);
1620 REG_FP[dst] = floatx80_div(REG_FP[dst], source, &status);
1621 //FIXME mame doesn't use SET_CONDITION_CODES here
1622 SET_CONDITION_CODES(REG_FP[dst]); // JFF
1628 sint8 const mode = status.float_rounding_mode;
1629 status.float_rounding_mode = float_round_to_zero;
1632 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1633 SET_CONDITION_CODES(REG_FP[dst]);
1634 status.float_rounding_mode = mode;
1635 USE_CYCLES(43); // guess
1642 REG_FP[dst] = floatx80_add(REG_FP[dst], source, &status);
1643 SET_CONDITION_CODES(REG_FP[dst]);
1651 REG_FP[dst] = floatx80_mul(REG_FP[dst], source, &status);
1652 SET_CONDITION_CODES(REG_FP[dst]);
1656 case 0x24: // FSGLDIV
1658 REG_FP[dst] = floatx80_sgldiv(REG_FP[dst], source, &status);
1659 USE_CYCLES(43); // // ? (value is from FDIV)
1664 sint8 const mode = status.float_rounding_mode;
1665 status.float_rounding_mode = float_round_nearest_even;
1668 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1669 SET_CONDITION_CODES(REG_FP[dst]);
1670 status.float_rounding_mode = mode;
1671 USE_CYCLES(43); // guess
1674 case 0x26: // FSCALE
1676 REG_FP[dst] = floatx80_scale(REG_FP[dst], source, &status);
1677 SET_CONDITION_CODES(REG_FP[dst]);
1678 USE_CYCLES(46); // (better?) guess
1681 case 0x27: // FSGLMUL
1683 REG_FP[dst] = floatx80_sglmul(REG_FP[dst], source, &status);
1684 SET_CONDITION_CODES(REG_FP[dst]);
1685 USE_CYCLES(11); // ? (value is from FMUL)
1699 REG_FP[dst] = floatx80_sub(REG_FP[dst], source, &status);
1700 SET_CONDITION_CODES(REG_FP[dst]);
1704 case 0x30: // FSINCOS
1705 case 0x31: // FSINCOS
1706 case 0x32: // FSINCOS
1707 case 0x33: // FSINCOS
1708 case 0x34: // FSINCOS
1709 case 0x35: // FSINCOS
1710 case 0x36: // FSINCOS
1711 case 0x37: // FSINCOS
1713 REG_FP[dst] = floatx80_cos(source, &status);
1714 REG_FP[w2&7] = floatx80_sin(source, &status);
1715 SET_CONDITION_CODES(REG_FP[dst]);
1726 res = floatx80_sub(REG_FP[dst], source, &status);
1727 SET_CONDITION_CODES(res);
1738 SET_CONDITION_CODES(res);
1743 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1747 static void fmove_reg_mem(m68ki_cpu_core *state, uint16 w2)
1749 int ea = REG_IR & 0x3f;
1750 int src = (w2 >> 7) & 0x7;
1751 int dst = (w2 >> 10) & 0x7;
1752 int k = (w2 & 0x7f);
1756 case 0: // Long-Word Integer
1758 sint32 d = (sint32)floatx80_to_int32(REG_FP[src], &status);
1759 WRITE_EA_32(state, ea, d);
1762 case 1: // Single-precision Real
1764 uint32 d = floatx80_to_float32(REG_FP[src], &status);
1765 WRITE_EA_32(state, ea, d);
1768 case 2: // Extended-precision Real
1770 WRITE_EA_FPE(state, ea, REG_FP[src]);
1773 case 3: // Packed-decimal Real with Static K-factor
1776 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1777 WRITE_EA_PACK(state, ea, k, REG_FP[src]);
1780 case 4: // Word Integer
1782 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1783 if (value > 0x7fff || value < -0x8000 )
1785 REG_FPSR |= FPES_OE | FPAE_IOP;
1787 WRITE_EA_16(state, ea, (sint16) value);
1790 case 5: // Double-precision Real
1794 d = floatx80_to_float64(REG_FP[src], &status);
1796 WRITE_EA_64(state, ea, d);
1799 case 6: // Byte Integer
1801 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1802 if (value > 127 || value < -128)
1804 REG_FPSR |= FPES_OE | FPAE_IOP;
1806 WRITE_EA_8(state, ea, (sint8) value);
1809 case 7: // Packed-decimal Real with Dynamic K-factor
1811 WRITE_EA_PACK(state, ea, REG_D[k >> 4], REG_FP[src]);
1819 static void fmove_fpcr(m68ki_cpu_core *state, uint16 w2)
1821 int ea = REG_IR & 0x3f;
1822 int dir = (w2 >> 13) & 0x1;
1823 int regsel = (w2 >> 10) & 0x7;
1824 int mode = (ea >> 3) & 0x7;
1826 if ((mode == 5) || (mode == 6))
1828 uint32 address = 0xffffffff; // force a bus error if this doesn't get assigned
1832 address = EA_AY_DI_32();
1836 address = EA_AY_IX_32();
1839 if (dir) // From system control reg to <ea>
1841 if (regsel & 4) { m68ki_write_32(address, REG_FPCR); address += 4; }
1842 if (regsel & 2) { m68ki_write_32(address, REG_FPSR); address += 4; }
1843 if (regsel & 1) { m68ki_write_32(address, REG_FPIAR); address += 4; }
1845 else // From <ea> to system control reg
1847 if (regsel & 4) { REG_FPCR = m68ki_read_32(address); address += 4; }
1848 if (regsel & 2) { REG_FPSR = m68ki_read_32(address); address += 4; }
1849 if (regsel & 1) { REG_FPIAR = m68ki_read_32(address); address += 4; }
1854 if (dir) // From system control reg to <ea>
1856 if (regsel & 4) WRITE_EA_32(state, ea, REG_FPCR);
1857 if (regsel & 2) WRITE_EA_32(state, ea, REG_FPSR);
1858 if (regsel & 1) WRITE_EA_32(state, ea, REG_FPIAR);
1860 else // From <ea> to system control reg
1862 if (regsel & 4) REG_FPCR = READ_EA_32(state, ea);
1863 if (regsel & 2) REG_FPSR = READ_EA_32(state, ea);
1864 if (regsel & 1) REG_FPIAR = READ_EA_32(state, ea);
1868 // FIXME: (2011-12-18 ost)
1869 // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1870 // but: with this code on Apollo the following programs in /systest/fptest will fail:
1871 // 1. Single Precision Whetstone will return wrong results never the less
1872 // 2. Vector Test will fault with 00040004: reference to illegal address
1874 if ((regsel & 4) && dir == 0)
1876 int rnd = (REG_FPCR >> 4) & 3;
1877 int prec = (REG_FPCR >> 6) & 3;
1879 // logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1884 case 0: // Extend (X)
1885 status.floatx80_rounding_precision = 80;
1887 case 1: // Single (S)
1888 status.floatx80_rounding_precision = 32;
1890 case 2: // Double (D)
1891 status.floatx80_rounding_precision = 64;
1893 case 3: // Undefined
1894 status.floatx80_rounding_precision = 80;
1901 case 0: // To Nearest (RN)
1902 status.float_rounding_mode = float_round_nearest_even;
1904 case 1: // To Zero (RZ)
1905 status.float_rounding_mode = float_round_to_zero;
1907 case 2: // To Minus Infinitiy (RM)
1908 status.float_rounding_mode = float_round_down;
1910 case 3: // To Plus Infinitiy (RP)
1911 status.float_rounding_mode = float_round_up;
1919 static void fmovem(m68ki_cpu_core *state, uint16 w2)
1922 int ea = REG_IR & 0x3f;
1923 int dir = (w2 >> 13) & 0x1;
1924 int mode = (w2 >> 11) & 0x3;
1925 int reglist = w2 & 0xff;
1927 uint32 mem_addr = 0;
1930 case 5: // (d16, An)
1931 mem_addr= EA_AY_DI_32();
1933 case 6: // (An) + (Xn) + d8
1934 mem_addr= EA_AY_IX_32();
1938 if (dir) // From FP regs to mem
1942 case 1: // Dynamic register list, postincrement or control addressing mode.
1943 // FIXME: not really tested, but seems to work
1944 reglist = REG_D[(reglist >> 4) & 7];
1947 case 0: // Static register list, predecrement or control addressing mode
1949 for (i=0; i < 8; i++)
1951 if (reglist & (1 << i))
1955 case 5: // (d16, An)
1956 case 6: // (An) + (Xn) + d8
1957 store_extended_float80(mem_addr, REG_FP[i]);
1961 WRITE_EA_FPE(state, ea, REG_FP[i]);
1971 case 2: // Static register list, postdecrement or control addressing mode.
1973 for (i=0; i < 8; i++)
1975 if (reglist & (1 << i))
1979 case 5: // (d16, An)
1980 case 6: // (An) + (Xn) + d8
1981 store_extended_float80(mem_addr, REG_FP[7-i]);
1985 WRITE_EA_FPE(state, ea, REG_FP[7 - i]);
1995 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1998 else // From mem to FP regs
2002 case 3: // Dynamic register list, predecrement addressing mode.
2003 // FIXME: not really tested, but seems to work
2004 reglist = REG_D[(reglist >> 4) & 7];
2007 case 2: // Static register list, postincrement or control addressing mode
2009 for (i=0; i < 8; i++)
2011 if (reglist & (1 << i))
2015 case 5: // (d16, An)
2016 case 6: // (An) + (Xn) + d8
2017 REG_FP[7-i] = load_extended_float80(mem_addr);
2021 REG_FP[7-i] = READ_EA_FPE(state, ea);
2030 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
2035 static void fscc(m68ki_cpu_core *state)
2037 int ea = REG_IR & 0x3f;
2038 int condition = (sint16)(OPER_I_16(state));
2040 WRITE_EA_8(state, ea, TEST_CONDITION(condition) ? 0xff : 0);
2041 USE_CYCLES(7); // ???
2043 static void fbcc16(m68ki_cpu_core *state)
2046 int condition = REG_IR & 0x3f;
2048 offset = (sint16)(OPER_I_16(state));
2050 // TODO: condition and jump!!!
2051 if (TEST_CONDITION(condition))
2053 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2054 m68ki_branch_16(offset-2);
2060 static void fbcc32(m68ki_cpu_core *state)
2063 int condition = REG_IR & 0x3f;
2065 offset = OPER_I_32(state);
2067 // TODO: condition and jump!!!
2068 if (TEST_CONDITION(condition))
2070 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2071 m68ki_branch_32(offset-4);
2078 void m68040_fpu_op0(m68ki_cpu_core *state)
2080 m68ki_cpu.fpu_just_reset = 0;
2082 switch ((REG_IR >> 6) & 0x3)
2086 uint16 w2 = OPER_I_16(state);
2087 switch ((w2 >> 13) & 0x7)
2089 case 0x0: // FPU ALU FP, FP
2090 case 0x2: // FPU ALU ea, FP
2092 fpgen_rm_reg(state, w2);
2096 case 0x3: // FMOVE FP, ea
2098 fmove_reg_mem(state, w2);
2102 case 0x4: // FMOVEM ea, FPCR
2103 case 0x5: // FMOVEM FPCR, ea
2105 fmove_fpcr(state, w2);
2109 case 0x6: // FMOVEM ea, list
2110 case 0x7: // FMOVEM list, ea
2116 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
2121 case 1: // FBcc disp16
2123 switch ((REG_IR >> 3) & 0x7) {
2126 printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2128 default: // FScc (?)
2132 fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2135 case 2: // FBcc disp16
2140 case 3: // FBcc disp32
2146 default: fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2150 static int perform_fsave(m68ki_cpu_core *state, uint32 addr, int inc)
2152 if(m68ki_cpu.cpu_type & CPU_TYPE_040)
2156 m68ki_write_32(addr, 0x41000000);
2161 m68ki_write_32(addr, 0x41000000);
2168 // 68881 IDLE, version 0x1f
2169 m68ki_write_32(addr, 0x1f180000);
2170 m68ki_write_32(addr+4, 0);
2171 m68ki_write_32(addr+8, 0);
2172 m68ki_write_32(addr+12, 0);
2173 m68ki_write_32(addr+16, 0);
2174 m68ki_write_32(addr+20, 0);
2175 m68ki_write_32(addr+24, 0x70000000);
2180 m68ki_write_32(addr+4-4, 0x70000000);
2181 m68ki_write_32(addr+4-8, 0);
2182 m68ki_write_32(addr+4-12, 0);
2183 m68ki_write_32(addr+4-16, 0);
2184 m68ki_write_32(addr+4-20, 0);
2185 m68ki_write_32(addr+4-24, 0);
2186 m68ki_write_32(addr+4-28, 0x1f180000);
2191 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
2192 static void do_frestore_null(m68ki_cpu_core *state)
2199 for (i = 0; i < 8; i++)
2201 REG_FP[i].high = 0x7fff;
2202 REG_FP[i].low = U64(0xffffffffffffffff);
2205 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
2206 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
2207 m68ki_cpu.fpu_just_reset = 1;
2210 void m68040_do_fsave(m68ki_cpu_core *state, uint32 addr, int reg, int inc)
2212 if (m68ki_cpu.fpu_just_reset)
2214 m68ki_write_32(addr, 0);
2218 // we normally generate an IDLE frame
2219 int delta = perform_fsave(state, addr, inc);
2221 REG_A[reg] += delta;
2225 void m68040_do_frestore(m68ki_cpu_core *state, uint32 addr, int reg)
2227 uint32 temp = m68ki_read_32(addr);
2228 // check for nullptr frame
2229 if (temp & 0xff000000)
2231 // we don't handle non-nullptr frames
2232 m68ki_cpu.fpu_just_reset = 0;
2236 uint8 m40 = !!(m68ki_cpu.cpu_type & CPU_TYPE_040);
2237 // how about an IDLE frame?
2238 if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2240 REG_A[reg] += 7*4-4;
2242 else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2246 else if ((temp & 0x00ff0000) == 0x00380000)
2250 else if ((temp & 0x00ff0000) == 0x00b40000)
2258 do_frestore_null(state);
2262 void m68040_fpu_op1(m68ki_cpu_core *state)
2264 int ea = REG_IR & 0x3f;
2265 int mode = (ea >> 3) & 0x7;
2266 int reg = (ea & 0x7);
2269 switch ((REG_IR >> 6) & 0x3)
2271 case 0: // FSAVE <ea>
2277 m68040_do_fsave(state, addr, -1, 1);
2281 addr = EA_AY_PI_32();
2282 printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
2283 m68040_do_fsave(state, addr, -1, 1); // FIXME: -1 was reg
2287 addr = EA_AY_PD_32();
2288 m68040_do_fsave(state, addr, reg, 0); // FIXME: -1 was reg
2290 case 5: // (D16, An)
2291 addr = EA_AY_DI_16();
2292 m68040_do_fsave(state, addr, -1, 1);
2295 case 6: // (An) + (Xn) + d8
2296 addr = EA_AY_IX_16();
2297 m68040_do_fsave(state, addr, -1, 1);
2307 m68040_do_fsave(state, addr, -1, 1);
2310 case 2: // (d16, PC)
2312 addr = EA_PCDI_16();
2313 m68040_do_fsave(state, addr, -1, 1);
2317 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2323 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2328 case 1: // FRESTORE <ea>
2334 m68040_do_frestore(state, addr, -1);
2338 addr = EA_AY_PI_32();
2339 m68040_do_frestore(state, addr, reg);
2342 case 5: // (D16, An)
2343 addr = EA_AY_DI_16();
2344 m68040_do_frestore(state, addr, -1);
2347 case 6: // (An) + (Xn) + d8
2348 addr = EA_AY_IX_16();
2349 m68040_do_frestore(state, addr, -1);
2359 m68040_do_frestore(state, addr, -1);
2362 case 2: // (d16, PC)
2364 addr = EA_PCDI_16();
2365 m68040_do_frestore(state, addr, -1);
2369 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2375 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2380 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2384 void m68881_ftrap(m68ki_cpu_core *state)
2386 uint16 w2 = OPER_I_16(state);
2388 // now check the condition
2389 if (TEST_CONDITION(w2 & 0x3f))
2392 m68ki_exception_trap(EXCEPTION_TRAPV);
2394 else // fall through, requires eating the operand
2396 switch (REG_IR & 0x7)
2398 case 2: // word operand
2402 case 3: // long word operand
2406 case 4: // no operand