]> git.sesse.net Git - pistorm/blob - m68kfpu.c
Add Meson build files.
[pistorm] / m68kfpu.c
1 // SPDX-License-Identifier: MIT
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdarg.h>
5
6 #include "softfloat/softfloat.h"
7 #include "m68kcpu.h"
8
9 float_status status;
10
11 extern void exit(int);
12
13 static void fatalerror(char *format, ...) {
14       va_list ap;
15       va_start(ap,format);
16       vfprintf(stderr,format,ap);  // JFF: fixed. Was using fprintf and arguments were wrong
17       va_end(ap);
18       exit(1);
19 }
20
21 #define FPCC_N                  0x08000000
22 #define FPCC_Z                  0x04000000
23 #define FPCC_I                  0x02000000
24 #define FPCC_NAN                0x01000000
25
26 #define FPES_OE      0x00002000
27 #define FPAE_IOP     0x00000080
28
29 #define DOUBLE_INFINITY                                 (unsigned long long)(0x7ff0000000000000)
30 #define DOUBLE_EXPONENT                                 (unsigned long long)(0x7ff0000000000000)
31 #define DOUBLE_MANTISSA                                 (unsigned long long)(0x000fffffffffffff)
32
33 /*----------------------------------------------------------------------------
34 | Returns 1 if the extended double-precision floating-point value `a' is a
35 | NaN; otherwise returns 0.
36 *----------------------------------------------------------------------------*/
37
38 flag floatx80_is_nan( floatx80 a )
39 {
40
41     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( a.low<<1 );
42
43 }
44
45
46 // masks for packed dwords, positive k-factor
47 static uint32 pkmask2[18] =
48 {
49         0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
50         0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
51         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
52         0xffffffff, 0xffffffff, 0xffffffff
53 };
54
55 static uint32 pkmask3[18] =
56 {
57         0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58         0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
59         0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
60 };
61
62 static inline double fx80_to_double(floatx80 fx)
63 {
64         uint64 d;
65         double *foo;
66
67         foo = (double *)&d;
68
69         d = floatx80_to_float64(fx, &status);
70
71         return *foo;
72 }
73
74 static inline floatx80 double_to_fx80(double in)
75 {
76         uint64 *d;
77
78         d = (uint64 *)&in;
79
80         return float64_to_floatx80(*d, &status);
81 }
82
83 static inline floatx80 load_extended_float80(m68ki_cpu_core *state, uint32 ea)
84 {
85         uint32 d1,d2;
86         uint16 d3;
87         floatx80 fp;
88
89         d3 = m68ki_read_16(state, ea);
90         d1 = m68ki_read_32(state, ea + 4);
91         d2 = m68ki_read_32(state, ea + 8);
92
93         fp.high = d3;
94         fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
95
96         return fp;
97 }
98
99 static inline void store_extended_float80(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
100 {
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);
105 }
106
107 static inline floatx80 load_pack_float80(m68ki_cpu_core *state, uint32 ea)
108 {
109         uint32 dw1, dw2, dw3;
110         floatx80 result;
111         double tmp;
112         char str[128], *ch;
113
114         dw1 = m68ki_read_32(state, ea);
115         dw2 = m68ki_read_32(state, ea + 4);
116         dw3 = m68ki_read_32(state, ea + 8);
117
118         ch = &str[0];
119         if (dw1 & 0x80000000)   // mantissa sign
120         {
121                 *ch++ = '-';
122         }
123         *ch++ = (char)((dw1 & 0xf) + '0');
124         *ch++ = '.';
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');
141         *ch++ = 'E';
142         if (dw1 & 0x40000000)   // exponent sign
143         {
144                 *ch++ = '-';
145         }
146         *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
147         *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
148         *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
149         *ch = '\0';
150
151         sscanf(str, "%le", &tmp);
152
153         result = double_to_fx80(tmp);
154
155         return result;
156 }
157
158 static inline void store_pack_float80(m68ki_cpu_core *state, uint32 ea, int k, floatx80 fpr)
159 {
160         uint32 dw1, dw2, dw3;
161         char str[128], *ch;
162         int i, j, exp;
163
164         dw1 = dw2 = dw3 = 0;
165         ch = &str[0];
166
167         sprintf(str, "%.16e", fx80_to_double(fpr));
168
169         if (*ch == '-')
170         {
171                 ch++;
172                 dw1 = 0x80000000;
173         }
174
175         if (*ch == '+')
176         {
177                 ch++;
178         }
179
180         dw1 |= (*ch++ - '0');
181
182         if (*ch == '.')
183         {
184                 ch++;
185         }
186
187         // handle negative k-factor here
188         if ((k <= 0) && (k >= -13))
189         {
190                 exp = 0;
191                 for (i = 0; i < 3; i++)
192                 {
193                         if (ch[18+i] >= '0' && ch[18+i] <= '9')
194                         {
195                                 exp = (exp << 4) | (ch[18+i] - '0');
196                         }
197                 }
198
199                 if (ch[17] == '-')
200                 {
201                         exp = -exp;
202                 }
203
204                 k = -k;
205                 // last digit is (k + exponent - 1)
206                 k += (exp - 1);
207
208                 // round up the last significant mantissa digit
209                 if (ch[k+1] >= '5')
210                 {
211                         ch[k]++;
212                 }
213
214                 // zero out the rest of the mantissa digits
215                 for (j = (k+1); j < 16; j++)
216                 {
217                         ch[j] = '0';
218                 }
219
220                 // now zero out K to avoid tripping the positive K detection below
221                 k = 0;
222         }
223
224         // crack 8 digits of the mantissa
225         for (i = 0; i < 8; i++)
226         {
227                 dw2 <<= 4;
228                 if (*ch >= '0' && *ch <= '9')
229                 {
230                         dw2 |= *ch++ - '0';
231                 }
232         }
233
234         // next 8 digits of the mantissa
235         for (i = 0; i < 8; i++)
236         {
237                 dw3 <<= 4;
238                 if (*ch >= '0' && *ch <= '9')
239                 dw3 |= *ch++ - '0';
240         }
241
242         // handle masking if k is positive
243         if (k >= 1)
244         {
245                 if (k <= 17)
246                 {
247                         dw2 &= pkmask2[k];
248                         dw3 &= pkmask3[k];
249                 }
250                 else
251                 {
252                         dw2 &= pkmask2[17];
253                         dw3 &= pkmask3[17];
254 //                      state->fpcr |=  (need to set OPERR bit)
255                 }
256         }
257
258         // finally, crack the exponent
259         if (*ch == 'e' || *ch == 'E')
260         {
261                 ch++;
262                 if (*ch == '-')
263                 {
264                         ch++;
265                         dw1 |= 0x40000000;
266                 }
267
268                 if (*ch == '+')
269                 {
270                         ch++;
271                 }
272
273                 j = 0;
274                 for (i = 0; i < 3; i++)
275                 {
276                         if (*ch >= '0' && *ch <= '9')
277                         {
278                                 j = (j << 4) | (*ch++ - '0');
279                         }
280                 }
281
282                 dw1 |= (j << 16);
283         }
284
285         m68ki_write_32(state, ea, dw1);
286         m68ki_write_32(state, ea + 4, dw2);
287         m68ki_write_32(state, ea + 8, dw3);
288 }
289
290 static inline void SET_CONDITION_CODES(m68ki_cpu_core *state, floatx80 reg)
291 {
292 //  u64 *regi;
293
294 //  regi = (u64 *)&reg;
295
296         REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
297
298         // sign flag
299         if (reg.high & 0x8000)
300         {
301                 REG_FPSR |= FPCC_N;
302         }
303
304         // zero flag
305         if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
306         {
307                 REG_FPSR |= FPCC_Z;
308         }
309
310         // infinity flag
311         if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
312         {
313                 REG_FPSR |= FPCC_I;
314         }
315
316         // NaN flag
317         if (floatx80_is_nan(reg))
318         {
319                 REG_FPSR |= FPCC_NAN;
320         }
321 }
322
323 static inline int TEST_CONDITION(m68ki_cpu_core *state, int condition)
324 {
325         int n = (REG_FPSR & FPCC_N) != 0;
326         int z = (REG_FPSR & FPCC_Z) != 0;
327         int nan = (REG_FPSR & FPCC_NAN) != 0;
328         int r = 0;
329         switch (condition)
330         {
331                 case 0x10:
332                 case 0x00:              return 0;                                       // False
333
334                 case 0x11:
335                 case 0x01:              return (z);                                     // Equal
336
337                 case 0x12:
338                 case 0x02:              return (!(nan || z || n));                      // Greater Than
339
340                 case 0x13:
341                 case 0x03:              return (z || !(nan || n));                      // Greater or Equal
342
343                 case 0x14:
344                 case 0x04:              return (n && !(nan || z));                      // Less Than
345
346                 case 0x15:
347                 case 0x05:              return (z || (n && !nan));                      // Less Than or Equal
348
349                 case 0x16:
350                 case 0x06:              return !nan && !z;
351
352                 case 0x17:
353                 case 0x07:              return !nan;
354
355                 case 0x18:
356                 case 0x08:              return nan;
357
358                 case 0x19:
359                 case 0x09:              return nan || z;
360
361                 case 0x1a:
362                 case 0x0a:              return (nan || !(n || z));                      // Not Less Than or Equal
363
364                 case 0x1b:
365                 case 0x0b:              return (nan || z || !n);                        // Not Less Than
366
367                 case 0x1c:
368                 case 0x0c:              return (nan || (n && !z));                      // Not Greater or Equal Than
369
370                 case 0x1d:
371                 case 0x0d:              return (nan || z || n);                         // Not Greater Than
372
373                 case 0x1e:
374                 case 0x0e:              return (!z);                                    // Not Equal
375
376                 case 0x1f:
377                 case 0x0f:              return 1;                                       // True
378
379                 default:                fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
380         }
381
382         return r;
383 }
384
385 static uint8 READ_EA_8(m68ki_cpu_core *state, int ea)
386 {
387         int mode = (ea >> 3) & 0x7;
388         int reg = (ea & 0x7);
389
390         switch (mode)
391         {
392                 case 0:         // Dn
393                 {
394                         return REG_D[reg];
395                 }
396                 case 2:         // (An)
397                 {
398                         uint32 ea = REG_A[reg];
399                         return m68ki_read_8(state, ea);
400                 }
401                 case 3:     // (An)+
402                 {
403                         uint32 ea = EA_AY_PI_8();
404                         return m68ki_read_8(state, ea);
405                 }
406                 case 4:     // -(An)
407                 {
408                         uint32 ea = EA_AY_PD_8();
409                         return m68ki_read_8(state, ea);
410                 }
411                 case 5:         // (d16, An)
412                 {
413                         uint32 ea = EA_AY_DI_8();
414                         return m68ki_read_8(state, ea);
415                 }
416                 case 6:         // (An) + (Xn) + d8
417                 {
418                         uint32 ea = EA_AY_IX_8();
419                         return m68ki_read_8(state, ea);
420                 }
421                 case 7:
422                 {
423                         switch (reg)
424                         {
425                                 case 0:         // (xxx).W
426                                 {
427                                         uint32 ea = (uint32) OPER_I_16(state);
428                                         return m68ki_read_8(state, ea);
429                                 }
430                                 case 1:         // (xxx).L
431                                 {
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);
436                                 }
437                                 case 2:     // (d16, PC)
438                                 {
439                                         uint32 ea = EA_PCDI_8();
440                                         return m68ki_read_8(state, ea);
441                                 }
442                                 case 3:     // (PC) + (Xn) + d8
443                                 {
444                                         uint32 ea = EA_PCIX_8();
445                                         return m68ki_read_8(state, ea);
446                                 }
447                                 case 4:         // #<data>
448                                 {
449                                         return OPER_I_8(state);
450                                 }
451                                 default:        fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
452                         }
453                         break;
454                 }
455                 default:        fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
456         }
457
458         return 0;
459 }
460
461 static uint16 READ_EA_16(m68ki_cpu_core *state, int ea)
462 {
463         int mode = (ea >> 3) & 0x7;
464         int reg = (ea & 0x7);
465
466         switch (mode)
467         {
468                 case 0:         // Dn
469                 {
470                         return (uint16)(REG_D[reg]);
471                 }
472                 case 2:         // (An)
473                 {
474                         uint32 ea = REG_A[reg];
475                         return m68ki_read_16(state, ea);
476                 }
477                 case 3:     // (An)+
478                 {
479                         uint32 ea = EA_AY_PI_16();
480                         return m68ki_read_16(state, ea);
481                 }
482                 case 4:     // -(An)
483                 {
484                         uint32 ea = EA_AY_PD_16();
485                         return m68ki_read_16(state, ea);
486                 }
487                 case 5:         // (d16, An)
488                 {
489                         uint32 ea = EA_AY_DI_16();
490                         return m68ki_read_16(state, ea);
491                 }
492                 case 6:         // (An) + (Xn) + d8
493                 {
494                         uint32 ea = EA_AY_IX_16();
495                         return m68ki_read_16(state, ea);
496                 }
497                 case 7:
498                 {
499                         switch (reg)
500                         {
501                                 case 0:         // (xxx).W
502                                 {
503                                         uint32 ea = (uint32) OPER_I_16(state);
504                                         return m68ki_read_16(state, ea);
505                                 }
506                                 case 1:         // (xxx).L
507                                 {
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);
512                                 }
513                                 case 2:     // (d16, PC)
514                                 {
515                                         uint32 ea = EA_PCDI_16();
516                                         return m68ki_read_16(state, ea);
517                                 }
518                                 case 3:     // (PC) + (Xn) + d8
519                                 {
520                                         uint32 ea =  EA_PCIX_16();
521                                         return m68ki_read_16(state, ea);
522                                 }
523                                 case 4:         // #<data>
524                                 {
525                                         return OPER_I_16(state);
526                                 }
527
528                                 default:        fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
529                         }
530                         break;
531                 }
532                 default:        fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
533         }
534
535         return 0;
536 }
537
538 static uint32 READ_EA_32(m68ki_cpu_core *state, int ea)
539 {
540         int mode = (ea >> 3) & 0x7;
541         int reg = (ea & 0x7);
542
543         switch (mode)
544         {
545                 case 0:         // Dn
546                 {
547                         return REG_D[reg];
548                 }
549                 case 2:         // (An)
550                 {
551                         uint32 ea = REG_A[reg];
552                         return m68ki_read_32(state, ea);
553                 }
554                 case 3:         // (An)+
555                 {
556                         uint32 ea = EA_AY_PI_32();
557                         return m68ki_read_32(state, ea);
558                 }
559                 case 4:         // -(An)
560                 {
561                         uint32 ea = EA_AY_PD_32();
562                         return m68ki_read_32(state, ea);
563                 }
564                 case 5:         // (d16, An)
565                 {
566                         uint32 ea = EA_AY_DI_32();
567                         return m68ki_read_32(state, ea);
568                 }
569                 case 6:         // (An) + (Xn) + d8
570                 {
571                         uint32 ea = EA_AY_IX_32();
572                         return m68ki_read_32(state, ea);
573                 }
574                 case 7:
575                 {
576                         switch (reg)
577                         {
578                                 case 0:         // (xxx).W
579                                 {
580                                         uint32 ea = (uint32) OPER_I_16(state);
581                                         return m68ki_read_32(state, ea);
582                                 }
583                                 case 1:         // (xxx).L
584                                 {
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);
589                                 }
590                                 case 2:         // (d16, PC)
591                                 {
592                                         uint32 ea = EA_PCDI_32();
593                                         return m68ki_read_32(state, ea);
594                                 }
595                                 case 3:     // (PC) + (Xn) + d8
596                                 {
597                                         uint32 ea =  EA_PCIX_32();
598                                         return m68ki_read_32(state, ea);
599                                 }
600                                 case 4:         // #<data>
601                                 {
602                                         return OPER_I_32(state);
603                                 }
604                                 default:        fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
605                         }
606                         break;
607                 }
608                 default:        fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
609         }
610         return 0;
611 }
612
613 static uint64 READ_EA_64(m68ki_cpu_core *state, int ea)
614 {
615         int mode = (ea >> 3) & 0x7;
616         int reg = (ea & 0x7);
617         uint32 h1, h2;
618
619         switch (mode)
620         {
621                 case 2:         // (An)
622                 {
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);
627                 }
628                 case 3:         // (An)+
629                 {
630                         uint32 ea = REG_A[reg];
631                         REG_A[reg] += 8;
632                         h1 = m68ki_read_32(state, ea + 0);
633                         h2 = m68ki_read_32(state, ea + 4);
634                         return  (uint64)(h1) << 32 | (uint64)(h2);
635                 }
636                 case 4:     // -(An)
637                 {
638                         uint32 ea = REG_A[reg]-8;
639                         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);
643                 }
644                 case 5:         // (d16, An)
645                 {
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);
650                 }
651                 case 6:     // (An) + (Xn) + d8
652                 {
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);
657                 }
658                 case 7:
659                 {
660                         switch (reg)
661                         {
662                                 case 1:     // (xxx).L
663                                 {
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));
668                                 }
669                                 case 3:     // (PC) + (Xn) + d8
670                                 {
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);
675                                 }
676                                 case 4:         // #<data>
677                                 {
678                                         h1 = OPER_I_32(state);
679                                         h2 = OPER_I_32(state);
680                                         return  (uint64)(h1) << 32 | (uint64)(h2);
681                                 }
682                                 case 2:         // (d16, PC)
683                                 {
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);
688                                 }
689                                 default:        fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
690                         }
691                         break;
692                 }
693                 default:        fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
694         }
695
696         return 0;
697 }
698
699
700 static floatx80 READ_EA_FPE(m68ki_cpu_core *state, uint32 ea)
701 {
702         floatx80 fpr;
703         int mode = (ea >> 3) & 0x7;
704         int reg = (ea & 0x7);
705
706         switch (mode)
707         {
708                 case 2:         // (An)
709                 {
710                         uint32 ea = REG_A[reg];
711                         fpr = load_extended_float80(state, ea);
712                         break;
713                 }
714
715                 case 3:         // (An)+
716                 {
717                         uint32 ea = REG_A[reg];
718                         REG_A[reg] += 12;
719                         fpr = load_extended_float80(state, ea);
720                         break;
721                 }
722                 case 4:     // -(An)
723                 {
724                         uint32 ea = REG_A[reg]-12;
725                         REG_A[reg] -= 12;
726                         fpr = load_extended_float80(state, ea);
727                         break;
728                 }
729       case 5:           // (d16, An)
730                 {
731                         // FIXME: will fail for fmovem
732                         uint32 ea = EA_AY_DI_32();
733                         fpr = load_extended_float80(state, ea);
734                 break;
735                 }
736                 case 6:     // (An) + (Xn) + d8
737                 {
738                         // FIXME: will fail for fmovem
739                         uint32 ea = EA_AY_IX_32();
740                         fpr = load_extended_float80(state, ea);
741                         break;
742                 }
743
744                 case 7: // extended modes
745                 {
746                         switch (reg)
747                         {
748                                 case 1:     // (xxx)
749                                         {
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);
754                                         }
755                                         break;
756
757                                 case 2: // (d16, PC)
758                                         {
759                                                 uint32 ea = EA_PCDI_32();
760                                                 fpr = load_extended_float80(state, ea);
761                                         }
762                                         break;
763
764                                 case 3: // (d16,PC,Dx.w)
765                                         {
766                                                 uint32 ea = EA_PCIX_32();
767                                                 fpr = load_extended_float80(state, ea);
768                                         }
769                                         break;
770
771                                 case 4: // immediate (JFF)
772                                         {
773                                                 uint32 ea = REG_PC;
774                                                 fpr = load_extended_float80(state, ea);
775                                                 REG_PC += 12;
776                                         }
777                                         break;
778
779                                 default:
780                                         fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
781                                         break;
782                         }
783                 }
784                 break;
785
786                 default:        fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
787         }
788
789         return fpr;
790 }
791
792 static floatx80 READ_EA_PACK(m68ki_cpu_core *state, int ea)
793 {
794         floatx80 fpr;
795         int mode = (ea >> 3) & 0x7;
796         int reg = (ea & 0x7);
797
798         switch (mode)
799         {
800                 case 2:         // (An)
801                 {
802                         uint32 ea = REG_A[reg];
803                         fpr = load_pack_float80(state, ea);
804                         break;
805                 }
806
807                 case 3:         // (An)+
808                 {
809                         uint32 ea = REG_A[reg];
810                         REG_A[reg] += 12;
811                         fpr = load_pack_float80(state, ea);
812                         break;
813                 }
814
815                 case 7: // extended modes
816                 {
817                         switch (reg)
818                         {
819                                 case 3: // (d16,PC,Dx.w)
820                                         {
821                                                 uint32 ea = EA_PCIX_32();
822                                                 fpr = load_pack_float80(state, ea);
823                                         }
824                                         break;
825
826                                 default:
827                                         fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
828                                         break;
829                         }
830                 }
831                 break;
832
833                 default:        fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
834         }
835
836         return fpr;
837 }
838
839 static void WRITE_EA_8(m68ki_cpu_core *state, int ea, uint8 data)
840 {
841         int mode = (ea >> 3) & 0x7;
842         int reg = (ea & 0x7);
843
844         switch (mode)
845         {
846                 case 0:         // Dn
847                 {
848                         REG_D[reg] = data;
849                         break;
850                 }
851                 case 2:         // (An)
852                 {
853                         uint32 ea = REG_A[reg];
854                         m68ki_write_8(state, ea, data);
855                         break;
856                 }
857                 case 3:         // (An)+
858                 {
859                         uint32 ea = EA_AY_PI_8();
860                         m68ki_write_8(state, ea, data);
861                         break;
862                 }
863                 case 4:         // -(An)
864                 {
865                         uint32 ea = EA_AY_PD_8();
866                         m68ki_write_8(state, ea, data);
867                         break;
868                 }
869                 case 5:         // (d16, An)
870                 {
871                         uint32 ea = EA_AY_DI_8();
872                         m68ki_write_8(state, ea, data);
873                         break;
874                 }
875                 case 6:         // (An) + (Xn) + d8
876                 {
877                         uint32 ea = EA_AY_IX_8();
878                         m68ki_write_8(state, ea, data);
879                         break;
880                 }
881                 case 7:
882                 {
883                         switch (reg)
884                         {
885                                 case 1:         // (xxx).B
886                                 {
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);
891                                         break;
892                                 }
893                                 case 2:         // (d16, PC)
894                                 {
895                                         uint32 ea = EA_PCDI_16();
896                                         m68ki_write_8(state, ea, data);
897                                         break;
898                                 }
899                                 default:        fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
900                         }
901                         break;
902                 }
903                 default:        fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
904         }
905 }
906
907 static void WRITE_EA_16(m68ki_cpu_core *state, int ea, uint16 data)
908 {
909         int mode = (ea >> 3) & 0x7;
910         int reg = (ea & 0x7);
911
912         switch (mode)
913         {
914                 case 0:         // Dn
915                 {
916                         REG_D[reg] = data;
917                         break;
918                 }
919                 case 2:         // (An)
920                 {
921                         uint32 ea = REG_A[reg];
922                         m68ki_write_16(state, ea, data);
923                         break;
924                 }
925                 case 3:         // (An)+
926                 {
927                         uint32 ea = EA_AY_PI_16();
928                         m68ki_write_16(state, ea, data);
929                         break;
930                 }
931                 case 4:         // -(An)
932                 {
933                         uint32 ea = EA_AY_PD_16();
934                         m68ki_write_16(state, ea, data);
935                         break;
936                 }
937                 case 5:         // (d16, An)
938                 {
939                         uint32 ea = EA_AY_DI_16();
940                         m68ki_write_16(state, ea, data);
941                         break;
942                 }
943                 case 6:         // (An) + (Xn) + d8
944                 {
945                         uint32 ea = EA_AY_IX_16();
946                         m68ki_write_16(state, ea, data);
947                         break;
948                 }
949                 case 7:
950                 {
951                         switch (reg)
952                         {
953                                 case 1:         // (xxx).W
954                                 {
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);
959                                         break;
960                                 }
961                                 case 2:         // (d16, PC)
962                                 {
963                                         uint32 ea = EA_PCDI_16();
964                                         m68ki_write_16(state, ea, data);
965                                         break;
966                                 }
967                                 default:        fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
968                         }
969                         break;
970                 }
971                 default:        fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
972         }
973 }
974
975 static void WRITE_EA_32(m68ki_cpu_core *state, int ea, uint32 data)
976 {
977         int mode = (ea >> 3) & 0x7;
978         int reg = (ea & 0x7);
979
980         switch (mode)
981         {
982                 case 0:         // Dn
983                 {
984                         REG_D[reg] = data;
985                         break;
986                 }
987                 case 1:         // An
988                 {
989                         REG_A[reg] = data;
990                         break;
991                 }
992                 case 2:         // (An)
993                 {
994                         uint32 ea = REG_A[reg];
995                         m68ki_write_32(state, ea, data);
996                         break;
997                 }
998                 case 3:         // (An)+
999                 {
1000                         uint32 ea = EA_AY_PI_32();
1001                         m68ki_write_32(state, ea, data);
1002                         break;
1003                 }
1004                 case 4:         // -(An)
1005                 {
1006                         uint32 ea = EA_AY_PD_32();
1007                         m68ki_write_32(state, ea, data);
1008                         break;
1009                 }
1010                 case 5:         // (d16, An)
1011                 {
1012                         uint32 ea = EA_AY_DI_32();
1013                         m68ki_write_32(state, ea, data);
1014                         break;
1015                 }
1016                 case 6:         // (An) + (Xn) + d8
1017                 {
1018                         uint32 ea = EA_AY_IX_32();
1019                         m68ki_write_32(state, ea, data);
1020                         break;
1021                 }
1022                 case 7:
1023                 {
1024                         switch (reg)
1025                         {
1026                                 case 0:     // (xxx).W
1027                                 {
1028                                         uint32 ea = OPER_I_16(state);
1029                                         m68ki_write_32(state, ea, data);
1030                                         break;
1031                                 }
1032                                 case 1:         // (xxx).L
1033                                 {
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);
1038                                         break;
1039                                 }
1040                                 case 2:         // (d16, PC)
1041                                 {
1042                                         uint32 ea = EA_PCDI_32();
1043                                         m68ki_write_32(state, ea, data);
1044                                         break;
1045                                 }
1046                                 default:        fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1047                         }
1048                         break;
1049                 }
1050                 default:        fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1051         }
1052 }
1053
1054 static void WRITE_EA_64(m68ki_cpu_core *state, int ea, uint64 data)
1055 {
1056         int mode = (ea >> 3) & 0x7;
1057         int reg = (ea & 0x7);
1058
1059         switch (mode)
1060         {
1061                 case 2:         // (An)
1062                 {
1063                         uint32 ea = REG_A[reg];
1064                         m68ki_write_32(state, ea, (uint32) (data >> 32));
1065                         m68ki_write_32(state, ea + 4, (uint32) (data));
1066                         break;
1067                 }
1068                 case 3:     // (An)+
1069                 {
1070                         uint32 ea = REG_A[reg];
1071                         REG_A[reg] += 8;
1072                         m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1073                         m68ki_write_32(state, ea + 4, (uint32) (data));
1074                         break;
1075                 }
1076                 case 4:         // -(An)
1077                 {
1078                         uint32 ea;
1079                         REG_A[reg] -= 8;
1080                         ea = REG_A[reg];
1081                         m68ki_write_32(state, ea + 0, (uint32) (data >> 32));
1082                         m68ki_write_32(state, ea + 4, (uint32) (data));
1083                         break;
1084                 }
1085                 case 5:         // (d16, An)
1086                 {
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));
1090                         break;
1091                 }
1092                 case 6:     // (An) + (Xn) + d8
1093                 {
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));
1097                         break;
1098                 }
1099                 case 7:
1100                 {
1101                         switch (reg)
1102                         {
1103                                 case 1:     // (xxx).L
1104                                 {
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));
1110                                         break;
1111                                 }
1112                                 case 2:     // (d16, PC)
1113                                 {
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));
1117                                         break;
1118                                 }
1119                                 default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1120                         }
1121                         break;
1122                 }
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);
1124         }
1125 }
1126
1127 static void WRITE_EA_FPE(m68ki_cpu_core *state, uint32 ea, floatx80 fpr)
1128 {
1129         int mode = (ea >> 3) & 0x7;
1130         int reg = (ea & 0x7);
1131
1132         switch (mode)
1133         {
1134                 case 2:         // (An)
1135                 {
1136                         uint32 ea;
1137                         ea = REG_A[reg];
1138                         store_extended_float80(state, ea, fpr);
1139                         break;
1140                 }
1141
1142                 case 3:         // (An)+
1143                 {
1144                         uint32 ea;
1145                         ea = REG_A[reg];
1146                         store_extended_float80(state, ea, fpr);
1147                         REG_A[reg] += 12;
1148                         break;
1149                 }
1150
1151                 case 4:         // -(An)
1152                 {
1153                         uint32 ea;
1154                         REG_A[reg] -= 12;
1155                         ea = REG_A[reg];
1156                         store_extended_float80(state, ea, fpr);
1157                         break;
1158                 }
1159           case 5:               // (d16, An)
1160                 {
1161                   uint32 ea = EA_AY_DI_32();
1162                         store_extended_float80(state, ea, fpr);
1163                  break;
1164
1165                 }
1166                 case 7:
1167                 {
1168                         switch (reg)
1169                         {
1170                                 default:        fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1171                         }
1172                         break;
1173                 }
1174                 default:        fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1175         }
1176 }
1177
1178 static void WRITE_EA_PACK(m68ki_cpu_core *state, int ea, int k, floatx80 fpr)
1179 {
1180         int mode = (ea >> 3) & 0x7;
1181         int reg = (ea & 0x7);
1182
1183         switch (mode)
1184         {
1185                 case 2:         // (An)
1186                 {
1187                         uint32 ea;
1188                         ea = REG_A[reg];
1189                         store_pack_float80(state, ea, k, fpr);
1190                         break;
1191                 }
1192
1193                 case 3:         // (An)+
1194                 {
1195                         uint32 ea;
1196                         ea = REG_A[reg];
1197                         store_pack_float80(state, ea, k, fpr);
1198                         REG_A[reg] += 12;
1199                         break;
1200                 }
1201
1202                 case 4:         // -(An)
1203                 {
1204                         uint32 ea;
1205                         REG_A[reg] -= 12;
1206                         ea = REG_A[reg];
1207                         store_pack_float80(state, ea, k, fpr);
1208                         break;
1209                 }
1210
1211                 case 7:
1212                 {
1213                         switch (reg)
1214                         {
1215                                 default:        fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1216                         }
1217                 }
1218                 break;
1219                 default:        fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1220         }
1221 }
1222
1223
1224 static void fpgen_rm_reg(m68ki_cpu_core *state, uint16 w2)
1225 {
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;
1231         floatx80 source;
1232
1233         // fmovecr #$f, fp0     f200 5c0f
1234
1235         if (rm)
1236         {
1237                 switch (src)
1238                 {
1239                         case 0:         // Long-Word Integer
1240                         {
1241                                 sint32 d = READ_EA_32(state, ea);
1242                                 source = int32_to_floatx80(d);
1243                                 break;
1244                         }
1245                         case 1:         // Single-precision Real
1246                         {
1247                                 uint32 d = READ_EA_32(state, ea);
1248                                 source = float32_to_floatx80(d, &status);
1249                                 break;
1250                         }
1251                         case 2:         // Extended-precision Real
1252                         {
1253                                 source = READ_EA_FPE(state, ea);
1254                                 break;
1255                         }
1256                         case 3:         // Packed-decimal Real
1257                         {
1258                                 source = READ_EA_PACK(state, ea);
1259                                 break;
1260                         }
1261                         case 4:         // Word Integer
1262                         {
1263                                 sint16 d = READ_EA_16(state, ea);
1264                                 source = int32_to_floatx80((sint32)d);
1265                                 break;
1266                         }
1267                         case 5:         // Double-precision Real
1268                         {
1269                                 uint64 d = READ_EA_64(state, ea);
1270
1271                                 source = float64_to_floatx80(d, &status);
1272                                 break;
1273                         }
1274                         case 6:         // Byte Integer
1275                         {
1276                                 sint8 d = READ_EA_8(state, ea);
1277                                 source = int32_to_floatx80((sint32)d);
1278                                 break;
1279                         }
1280                         case 7:         // FMOVECR load from constant ROM
1281                         {
1282                                 switch (w2 & 0x7f)
1283                                 {
1284                                         case 0x0:       // Pi
1285                                                 source.high = 0x4000;
1286                                                 source.low = U64(0xc90fdaa22168c235);
1287                                                 break;
1288
1289                                         case 0xb:       // log10(2)
1290                                                 source.high = 0x3ffd;
1291                                                 source.low = U64(0x9a209a84fbcff798);
1292                                                 break;
1293
1294                                         case 0xc:       // e
1295                                                 source.high = 0x4000;
1296                                                 source.low = U64(0xadf85458a2bb4a9b);
1297                                                 break;
1298
1299                                         case 0xd:       // log2(e)
1300                                                 source.high = 0x3fff;
1301                                                 source.low = U64(0xb8aa3b295c17f0bc);
1302                                                 break;
1303
1304                                         case 0xe:       // log10(e)
1305                                                 source.high = 0x3ffd;
1306                                                 source.low = U64(0xde5bd8a937287195);
1307                                                 break;
1308
1309                                         case 0xf:       // 0.0
1310                                                 source = int32_to_floatx80((sint32)0);
1311                                                 break;
1312
1313                                         case 0x30:      // ln(2)
1314                                                 source.high = 0x3ffe;
1315                                                 source.low = U64(0xb17217f7d1cf79ac);
1316                                                 break;
1317
1318                                         case 0x31:      // ln(10)
1319                                                 source.high = 0x4000;
1320                                                 source.low = U64(0x935d8dddaaa8ac17);
1321                                                 break;
1322
1323                                         case 0x32:      // 1 (or 100?  manuals are unclear, but 1 would make more sense)
1324                                                 source = int32_to_floatx80((sint32)1);
1325                                                 break;
1326
1327                                         case 0x33:      // 10^1
1328                                                 source = int32_to_floatx80((sint32)10);
1329                                                 break;
1330
1331                                         case 0x34:      // 10^2
1332                                                 source = int32_to_floatx80((sint32)10*10);
1333                                                 break;
1334                                         case 0x35:  // 10^4
1335                                                 source = int32_to_floatx80((sint32)1000*10);
1336                                                 break;
1337
1338                                         case 0x36:  // 1.0e8
1339                                                 source = int32_to_floatx80((sint32)10000000*10);
1340                                                 break;
1341
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);
1345                                                 break;
1346
1347                                         case 0x38:  // 1.0e32
1348                                                 source.high = 0x4069;
1349                                                 source.low = U64(0x9dc5ada82b70b59e);
1350                                                 break;
1351
1352                                         case 0x39:  // 1.0e64
1353                                                 source.high = 0x40d3;
1354                                                 source.low = U64(0xc2781f49ffcfa6d5);
1355                                                 break;
1356
1357                                         case 0x3a:  // 1.0e128
1358                                                 source.high = 0x41a8;
1359                                                 source.low = U64(0x93ba47c980e98ce0);
1360                                                 break;
1361
1362                                         case 0x3b:  // 1.0e256
1363                                                 source.high = 0x4351;
1364                                                 source.low = U64(0xaa7eebfb9df9de8e);
1365                                                 break;
1366
1367                                         case 0x3c:  // 1.0e512
1368                                                 source.high = 0x46a3;
1369                                                 source.low = U64(0xe319a0aea60e91c7);
1370                                                 break;
1371
1372                                         case 0x3d:  // 1.0e1024
1373                                                 source.high = 0x4d48;
1374                                                 source.low = U64(0xc976758681750c17);
1375                                                 break;
1376
1377                                         case 0x3e:  // 1.0e2048
1378                                                 source.high = 0x5a92;
1379                                                 source.low = U64(0x9e8b3b5dc53d5de5);
1380                                                 break;
1381
1382                                         case 0x3f:  // 1.0e4096
1383                                                 source.high = 0x7525;
1384                                                 source.low = U64(0xc46052028a20979b);
1385                                                 break;
1386
1387
1388                                         default:
1389                                                 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1390                                                 break;
1391                                 }
1392
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
1397                                 USE_CYCLES(4);
1398                                 return;
1399                         }
1400                         default:        fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1401                 }
1402         }
1403         else
1404         {
1405                 source = REG_FP[src];
1406         }
1407
1408         // For FD* and FS* prefixes we already converted the source to floatx80
1409         // so we can treat these as their parent op.
1410
1411         switch (opmode)
1412         {
1413                 case 0x44:              // FDMOVE
1414                 case 0x40:              // FSMOVE
1415                 case 0x00:              // FMOVE
1416                 {
1417                         REG_FP[dst] = source;
1418                         SET_CONDITION_CODES(state, REG_FP[dst]);
1419                         USE_CYCLES(4);
1420                         break;
1421                 }
1422                 case 0x01:              // FINT
1423                 {
1424                         sint32 temp;
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
1429                         USE_CYCLES(4);
1430                         break;
1431                 }
1432                 case 0x02:              // FSINH
1433                 {
1434                         REG_FP[dst] = floatx80_sinh(source, &status);
1435                         SET_CONDITION_CODES(state, REG_FP[dst]);
1436                         USE_CYCLES(75);
1437                         break;
1438                 }
1439                 case 0x03:              // FINTRZ
1440                 {
1441                         sint32 temp;
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
1446                         break;
1447                 }
1448                 case 0x45:              // FDSQRT
1449                 case 0x41:              // FSSQRT
1450                 case 0x04:              // FSQRT
1451                 case 0x05:              // FSQRT
1452                 {
1453                         REG_FP[dst] = floatx80_sqrt(source, &status);
1454                         SET_CONDITION_CODES(state, REG_FP[dst]);
1455                         USE_CYCLES(109);
1456                         break;
1457                 }
1458                 case 0x06:      // FLOGNP1
1459                 case 0x07:      // FLOGNP1
1460                 {
1461                         REG_FP[dst] = floatx80_lognp1 (source, &status);
1462                         SET_CONDITION_CODES(state, REG_FP[dst]);
1463                         USE_CYCLES(594); // for MC68881
1464                         break;
1465                 }
1466                 case 0x08:      // FETOXM1
1467                 {
1468                         REG_FP[dst] = floatx80_etoxm1(source, &status);
1469                         SET_CONDITION_CODES(state, REG_FP[dst]);
1470                         USE_CYCLES(6);
1471                         break;
1472                 }
1473                 case 0x09:      // FTANH
1474                 {
1475                         REG_FP[dst] = floatx80_tanh(source, &status);
1476                         SET_CONDITION_CODES(state, REG_FP[dst]);
1477                         USE_CYCLES(75);
1478                         break;
1479                 }
1480                 case 0x0a:      // FATAN
1481                 case 0x0b:      // FATAN
1482                 {
1483                         REG_FP[dst] = floatx80_atan(source, &status);
1484                         SET_CONDITION_CODES(state, REG_FP[dst]);
1485                         USE_CYCLES(75);
1486                         break;
1487                 }
1488                 case 0x0c:      // FASIN
1489                 {
1490                         REG_FP[dst] = floatx80_asin(source, &status);
1491                         SET_CONDITION_CODES(state, REG_FP[dst]);
1492                         USE_CYCLES(75);
1493                         break;
1494                 }
1495                 case 0x0d:      // FATANH
1496                 {
1497                         REG_FP[dst] = floatx80_atanh(source, &status);
1498                         SET_CONDITION_CODES(state, REG_FP[dst]);
1499                         USE_CYCLES(75);
1500                         break;
1501                 }
1502                 case 0x0e:      // FSIN
1503                 {
1504                         REG_FP[dst] = floatx80_sin(source, &status);
1505                         SET_CONDITION_CODES(state, REG_FP[dst]);
1506                         USE_CYCLES(75);
1507                         break;
1508                 }
1509                 case 0x0f:      // FTAN
1510                 {
1511                         REG_FP[dst] = floatx80_tan(source, &status);
1512                         SET_CONDITION_CODES(state, REG_FP[dst]);
1513                         USE_CYCLES(75);
1514                         break;
1515                 }
1516                 case 0x10:      // FETOX
1517                 {
1518                         REG_FP[dst] = floatx80_etox(source, &status);
1519                         SET_CONDITION_CODES(state, REG_FP[dst]);
1520                         USE_CYCLES(75);
1521                         break;
1522                 }
1523                 case 0x11:      // FTWOTOX
1524                 {
1525                         REG_FP[dst] = floatx80_twotox(source, &status);
1526                         SET_CONDITION_CODES(state, REG_FP[dst]);
1527                         USE_CYCLES(75);
1528                         break;
1529                 }
1530                 case 0x12:      // FTENTOX
1531                 case 0x13:      // FTENTOX
1532                 {
1533                         REG_FP[dst] = floatx80_tentox(source, &status);
1534                         SET_CONDITION_CODES(state, REG_FP[dst]);
1535                         USE_CYCLES(75);
1536                         break;
1537                 }
1538                 case 0x14:      // FLOGN
1539                 {
1540                         REG_FP[dst] = floatx80_logn(source, &status);
1541                         SET_CONDITION_CODES(state, REG_FP[dst]);
1542                         USE_CYCLES(548); // for MC68881
1543                         break;
1544                 }
1545                 case 0x15:      // FLOG10
1546                 {
1547                         REG_FP[dst] = floatx80_log10(source, &status);
1548                         SET_CONDITION_CODES(state, REG_FP[dst]);
1549                         USE_CYCLES(604); // for MC68881
1550                         break;
1551                 }
1552                 case 0x16:      // FLOG2
1553                 case 0x17:      // FLOG2
1554                 {
1555                         REG_FP[dst] = floatx80_log2(source, &status);
1556                         SET_CONDITION_CODES(state, REG_FP[dst]);
1557                         USE_CYCLES(604); // for MC68881
1558                         break;
1559                 }
1560                 case 0x5C:              // FDABS
1561                 case 0x58:              // FSABS
1562                 case 0x18:              // FABS
1563                 {
1564                         REG_FP[dst] = source;
1565                         REG_FP[dst].high &= 0x7fff;
1566                         SET_CONDITION_CODES(state, REG_FP[dst]);
1567                         USE_CYCLES(3);
1568                         break;
1569                 }
1570                 case 0x19:      // FCOSH
1571                 {
1572                         REG_FP[dst] = floatx80_cosh(source, &status);
1573                         SET_CONDITION_CODES(state, REG_FP[dst]);
1574                         USE_CYCLES(64);
1575                         break;
1576                 }
1577                 case 0x5e:              // FDNEG
1578                 case 0x5a:              // FSNEG
1579                 case 0x1a:              // FNEG
1580                 case 0x1b:              // FNEG
1581                 {
1582                         REG_FP[dst] = source;
1583                         REG_FP[dst].high ^= 0x8000;
1584                         SET_CONDITION_CODES(state, REG_FP[dst]);
1585                         USE_CYCLES(3);
1586                         break;
1587                 }
1588                 case 0x1c:      // FACOS
1589                 {
1590                         REG_FP[dst] = floatx80_acos(source, &status);
1591                         SET_CONDITION_CODES(state, REG_FP[dst]);
1592                         USE_CYCLES(604); // for MC68881
1593                         break;
1594                         break;
1595                 }
1596                 case 0x1d:      // FCOS
1597                 {
1598                         REG_FP[dst] = floatx80_cos(source, &status);
1599                         SET_CONDITION_CODES(state, REG_FP[dst]);
1600                         USE_CYCLES(75);
1601                         break;
1602                 }
1603                 case 0x1e:              // FGETEXP
1604                 {
1605                         REG_FP[dst] = floatx80_getexp(source, &status);
1606                         SET_CONDITION_CODES(state, REG_FP[dst]);
1607                         USE_CYCLES(6);
1608                         break;
1609                 }
1610                 case 0x1f:      // FGETMAN
1611                 {
1612                         REG_FP[dst] = floatx80_getman(source, &status);
1613                         SET_CONDITION_CODES(state, REG_FP[dst]);
1614                         USE_CYCLES(6);
1615                         break;
1616                 }
1617                 case 0x64:              // FDDIV
1618                 case 0x60:              // FSDIV
1619                 case 0x20:              // FDIV
1620                 {
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
1624                         USE_CYCLES(43);
1625                         break;
1626                 }
1627                 case 0x21:      // FMOD
1628                 {
1629                         sint8 const mode = status.float_rounding_mode;
1630                         status.float_rounding_mode = float_round_to_zero;
1631                         uint64_t q;
1632                         flag s;
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
1637                         break;
1638                 }
1639                 case 0x66:              // FDADD
1640                 case 0x62:              // FSADD
1641                 case 0x22:              // FADD
1642                 {
1643                         REG_FP[dst] = floatx80_add(REG_FP[dst], source, &status);
1644                         SET_CONDITION_CODES(state, REG_FP[dst]);
1645                         USE_CYCLES(9);
1646                         break;
1647                 }
1648                 case 0x67:              // FDMUL
1649                 case 0x63:              // FSMUL
1650                 case 0x23:              // FMUL
1651                 {
1652                         REG_FP[dst] = floatx80_mul(REG_FP[dst], source, &status);
1653                         SET_CONDITION_CODES(state, REG_FP[dst]);
1654                         USE_CYCLES(11);
1655                         break;
1656                 }
1657                 case 0x24:      // FSGLDIV
1658                 {
1659                         REG_FP[dst] = floatx80_sgldiv(REG_FP[dst], source, &status);
1660                         USE_CYCLES(43); //  // ? (value is from FDIV)
1661                         break;
1662                 }
1663                 case 0x25:              // FREM
1664                 {
1665                         sint8 const mode = status.float_rounding_mode;
1666                         status.float_rounding_mode = float_round_nearest_even;
1667                         uint64_t q;
1668                         flag s;
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
1673                         break;
1674                 }
1675                 case 0x26:      // FSCALE
1676                 {
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
1680                         break;
1681                 }
1682                 case 0x27:      // FSGLMUL
1683                 {
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)
1687                         break;
1688                 }
1689                 case 0x6c:              // FDSUB
1690                 case 0x68:              // FSSUB
1691                 case 0x28:              // FSUB
1692                 case 0x29:              // FSUB
1693                 case 0x2a:              // FSUB
1694                 case 0x2b:              // FSUB
1695                 case 0x2c:              // FSUB
1696                 case 0x2d:              // FSUB
1697                 case 0x2e:              // FSUB
1698                 case 0x2f:              // FSUB
1699                 {
1700                         REG_FP[dst] = floatx80_sub(REG_FP[dst], source, &status);
1701                         SET_CONDITION_CODES(state, REG_FP[dst]);
1702                         USE_CYCLES(9);
1703                         break;
1704                 }
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
1713                 {
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]);
1717                         USE_CYCLES(75);
1718
1719                         break;
1720                 }
1721                 case 0x38:              // FCMP
1722                 case 0x39:              // FCMP
1723                 case 0x3c:              // FCMP
1724                 case 0x3d:              // FCMP
1725                 {
1726                         floatx80 res;
1727                         res = floatx80_sub(REG_FP[dst], source, &status);
1728                         SET_CONDITION_CODES(state, res);
1729                         USE_CYCLES(7);
1730                         break;
1731                 }
1732                 case 0x3a:              // FTST
1733                 case 0x3b:              // FTST
1734                 case 0x3e:              // FTST
1735                 case 0x3f:              // FTST
1736                 {
1737                         floatx80 res;
1738                         res = source;
1739                         SET_CONDITION_CODES(state, res);
1740                         USE_CYCLES(7);
1741                         break;
1742                 }
1743
1744                 default:        fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1745         }
1746 }
1747
1748 static void fmove_reg_mem(m68ki_cpu_core *state, uint16 w2)
1749 {
1750         int ea = REG_IR & 0x3f;
1751         int src = (w2 >>  7) & 0x7;
1752         int dst = (w2 >> 10) & 0x7;
1753         int k = (w2 & 0x7f);
1754
1755         switch (dst)
1756         {
1757                 case 0:         // Long-Word Integer
1758                 {
1759                         sint32 d = (sint32)floatx80_to_int32(REG_FP[src], &status);
1760                         WRITE_EA_32(state, ea, d);
1761                         break;
1762                 }
1763                 case 1:         // Single-precision Real
1764                 {
1765                         uint32 d = floatx80_to_float32(REG_FP[src], &status);
1766                         WRITE_EA_32(state, ea, d);
1767                         break;
1768                 }
1769                 case 2:         // Extended-precision Real
1770                 {
1771                         WRITE_EA_FPE(state, ea, REG_FP[src]);
1772                         break;
1773                 }
1774                 case 3:         // Packed-decimal Real with Static K-factor
1775                 {
1776                         // sign-extend k
1777                         k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1778                         WRITE_EA_PACK(state, ea, k, REG_FP[src]);
1779                         break;
1780                 }
1781                 case 4:         // Word Integer
1782                 {
1783                         sint32 value = floatx80_to_int32(REG_FP[src], &status);
1784                         if (value > 0x7fff || value < -0x8000 )
1785                         {
1786                                 REG_FPSR |= FPES_OE | FPAE_IOP;
1787                         }
1788                         WRITE_EA_16(state, ea, (sint16) value);
1789                         break;
1790                 }
1791                 case 5:         // Double-precision Real
1792                 {
1793                         uint64 d;
1794
1795                         d = floatx80_to_float64(REG_FP[src], &status);
1796
1797                         WRITE_EA_64(state, ea, d);
1798                         break;
1799                 }
1800                 case 6:         // Byte Integer
1801                 {
1802                         sint32 value = floatx80_to_int32(REG_FP[src], &status);
1803                         if (value > 127 || value < -128)
1804                         {
1805                                 REG_FPSR |= FPES_OE | FPAE_IOP;
1806                         }
1807                         WRITE_EA_8(state, ea, (sint8) value);
1808                         break;
1809                 }
1810                 case 7:         // Packed-decimal Real with Dynamic K-factor
1811                 {
1812                         WRITE_EA_PACK(state, ea, REG_D[k >> 4], REG_FP[src]);
1813                         break;
1814                 }
1815         }
1816
1817         USE_CYCLES(12);
1818 }
1819
1820 static void fmove_fpcr(m68ki_cpu_core *state, uint16 w2)
1821 {
1822         int ea = REG_IR & 0x3f;
1823         int dir = (w2 >> 13) & 0x1;
1824         int regsel = (w2 >> 10) & 0x7;
1825         int mode = (ea >> 3) & 0x7;
1826
1827         if ((mode == 5) || (mode == 6))
1828         {
1829                 uint32 address = 0xffffffff;    // force a bus error if this doesn't get assigned
1830
1831                 if (mode == 5)
1832                 {
1833                         address = EA_AY_DI_32();
1834                 }
1835                 else if (mode == 6)
1836                 {
1837                         address = EA_AY_IX_32();
1838                 }
1839
1840                 if (dir)        // From system control reg to <ea>
1841                 {
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; }
1845                 }
1846                 else            // From <ea> to system control reg
1847                 {
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; }
1851                 }
1852         }
1853         else
1854         {
1855                 if (dir)    // From system control reg to <ea>
1856                 {
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);
1860                 }
1861                 else        // From <ea> to system control reg
1862                 {
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);
1866                 }
1867         }
1868
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
1874
1875         if ((regsel & 4) && dir == 0)
1876         {
1877                 int rnd = (REG_FPCR >> 4) & 3;
1878                 int prec = (REG_FPCR >> 6) & 3;
1879
1880 //      logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1881
1882 #ifdef FLOATX80
1883                 switch (prec)
1884                 {
1885                 case 0: // Extend (X)
1886                         status.floatx80_rounding_precision = 80;
1887                         break;
1888                 case 1: // Single (S)
1889                         status.floatx80_rounding_precision = 32;
1890                         break;
1891                 case 2: // Double (D)
1892                         status.floatx80_rounding_precision = 64;
1893                         break;
1894                 case 3: // Undefined
1895                         status.floatx80_rounding_precision = 80;
1896                         break;
1897                 }
1898 #endif
1899
1900                 switch (rnd)
1901                 {
1902                 case 0: // To Nearest (RN)
1903                         status.float_rounding_mode = float_round_nearest_even;
1904                         break;
1905                 case 1: // To Zero (RZ)
1906                         status.float_rounding_mode = float_round_to_zero;
1907                         break;
1908                 case 2: // To Minus Infinitiy (RM)
1909                         status.float_rounding_mode = float_round_down;
1910                         break;
1911                 case 3: // To Plus Infinitiy (RP)
1912                         status.float_rounding_mode = float_round_up;
1913                         break;
1914                 }
1915         }
1916
1917         USE_CYCLES(10);
1918 }
1919
1920 static void fmovem(m68ki_cpu_core *state, uint16 w2)
1921 {
1922         int i;
1923         int ea = REG_IR & 0x3f;
1924         int dir = (w2 >> 13) & 0x1;
1925         int mode = (w2 >> 11) & 0x3;
1926         int reglist = w2 & 0xff;
1927
1928         uint32 mem_addr = 0;
1929         switch (ea >> 3)
1930         {
1931                 case 5:     // (d16, An)
1932                         mem_addr= EA_AY_DI_32();
1933                         break;
1934                 case 6:     // (An) + (Xn) + d8
1935                         mem_addr= EA_AY_IX_32();
1936                         break;
1937         }
1938
1939         if (dir)        // From FP regs to mem
1940         {
1941                 switch (mode)
1942                 {
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];
1946                                 /* fall through */
1947                                 /* no break */
1948                         case 0:     // Static register list, predecrement or control addressing mode
1949                         {
1950                                 for (i=0; i < 8; i++)
1951                                 {
1952                                         if (reglist & (1 << i))
1953                                         {
1954                                                 switch (ea >> 3)
1955                                                 {
1956                                                         case 5:     // (d16, An)
1957                                                         case 6:     // (An) + (Xn) + d8
1958                                                                 store_extended_float80(state, mem_addr, REG_FP[i]);
1959                                                                 mem_addr += 12;
1960                                                                 break;
1961                                                         default:
1962                                                                 WRITE_EA_FPE(state, ea, REG_FP[i]);
1963                                                                 break;
1964                                                 }
1965
1966                                                 USE_CYCLES(2);
1967                                         }
1968                                 }
1969                                 break;
1970                         }
1971
1972                         case 2:         // Static register list, postdecrement or control addressing mode.     
1973                         {
1974                                 for (i=0; i < 8; i++)
1975                                 {
1976                                         if (reglist & (1 << i))
1977                                         {
1978                                                 switch (ea >> 3)
1979                                                 {
1980                                                         case 5:     // (d16, An)
1981                                                         case 6:     // (An) + (Xn) + d8
1982                                                                 store_extended_float80(state, mem_addr, REG_FP[7 - i]);
1983                                                                 mem_addr += 12;
1984                                                                 break;
1985                                                         default:
1986                                                                 WRITE_EA_FPE(state, ea, REG_FP[7 - i]);
1987                                                                 break;
1988                                                 }
1989
1990                                                 USE_CYCLES(2);
1991                                         }
1992                                 }
1993                                 break;
1994                         }
1995
1996                         default:        fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1997                 }
1998         }
1999         else            // From mem to FP regs
2000         {
2001                 switch (mode)
2002                 {
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];
2006                                 /* fall through */
2007                                 /* no break */
2008                         case 2:         // Static register list, postincrement or control addressing mode
2009                         {
2010                                 for (i=0; i < 8; i++)
2011                                 {
2012                                         if (reglist & (1 << i))
2013                                         {
2014                                                 switch (ea >> 3)
2015                                                 {
2016                                                         case 5:     // (d16, An)
2017                                                         case 6:     // (An) + (Xn) + d8
2018                                                                 REG_FP[7-i] = load_extended_float80(state, mem_addr);
2019                                                                 mem_addr += 12;
2020                                                                 break;
2021                                                         default:
2022                                                                 REG_FP[7-i] = READ_EA_FPE(state, ea);
2023                                                                 break;
2024                                                 }
2025                                                 USE_CYCLES(2);
2026                                         }
2027                                 }
2028                                 break;
2029                         }
2030
2031                         default:        fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
2032                 }
2033         }
2034 }
2035
2036 static void fscc(m68ki_cpu_core *state)
2037 {
2038         int ea = REG_IR & 0x3f;
2039         int condition = (sint16)(OPER_I_16(state));
2040
2041         WRITE_EA_8(state, ea, TEST_CONDITION(state, condition) ? 0xff : 0);
2042         USE_CYCLES(7);  // ???
2043 }
2044 static void fbcc16(m68ki_cpu_core *state)
2045 {
2046         sint32 offset;
2047         int condition = REG_IR & 0x3f;
2048
2049         offset = (sint16)(OPER_I_16(state));
2050
2051         // TODO: condition and jump!!!
2052         if (TEST_CONDITION(state, condition))
2053         {
2054                 m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
2055                 m68ki_branch_16(state, offset - 2);
2056         }
2057
2058         USE_CYCLES(7);
2059 }
2060
2061 static void fbcc32(m68ki_cpu_core *state)
2062 {
2063         sint32 offset;
2064         int condition = REG_IR & 0x3f;
2065
2066         offset = OPER_I_32(state);
2067
2068         // TODO: condition and jump!!!
2069         if (TEST_CONDITION(state, condition))
2070         {
2071                 m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
2072                 m68ki_branch_32(state, offset - 4);
2073         }
2074
2075         USE_CYCLES(7);
2076 }
2077
2078
2079 void m68040_fpu_op0(m68ki_cpu_core *state)
2080 {
2081         state->fpu_just_reset = 0;
2082
2083         switch ((REG_IR >> 6) & 0x3)
2084         {
2085                 case 0:
2086                 {
2087                         uint16 w2 = OPER_I_16(state);
2088                         switch ((w2 >> 13) & 0x7)
2089                         {
2090                                 case 0x0:       // FPU ALU FP, FP
2091                                 case 0x2:       // FPU ALU ea, FP
2092                                 {
2093                                         fpgen_rm_reg(state, w2);
2094                                         break;
2095                                 }
2096
2097                                 case 0x3:       // FMOVE FP, ea
2098                                 {
2099                                         fmove_reg_mem(state, w2);
2100                                         break;
2101                                 }
2102
2103                                 case 0x4:       // FMOVEM ea, FPCR
2104                                 case 0x5:       // FMOVEM FPCR, ea
2105                                 {
2106                                         fmove_fpcr(state, w2);
2107                                         break;
2108                                 }
2109
2110                                 case 0x6:       // FMOVEM ea, list
2111                                 case 0x7:       // FMOVEM list, ea
2112                                 {
2113                                         fmovem(state, w2);
2114                                         break;
2115                                 }
2116
2117                                 default:        fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
2118                         }
2119                         break;
2120                 }
2121
2122                 case 1:           // FBcc disp16
2123                 {
2124                         switch ((REG_IR >> 3) & 0x7) {
2125                         case 1: // FDBcc
2126                                 // TODO:
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);
2128                                 break;
2129                         default: // FScc (?)
2130                                 fscc(state);
2131                                 return;
2132                         }
2133                         fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2134                         break;
2135                 }
2136                 case 2:     // FBcc disp16
2137                 {
2138                         fbcc16(state);
2139                         break;
2140                 }
2141                 case 3:     // FBcc disp32
2142                 {
2143                         fbcc32(state);
2144                         break;
2145                 }
2146
2147                 default:    fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2148         }
2149 }
2150
2151 static int perform_fsave(m68ki_cpu_core *state, uint32 addr, int inc)
2152 {
2153         if(state->cpu_type & CPU_TYPE_040)
2154         {
2155                 if(inc)
2156                 {
2157                         m68ki_write_32(state, addr, 0x41000000);
2158                         return 4 -4;
2159                 }
2160                 else
2161                 {
2162                         m68ki_write_32(state, addr, 0x41000000);
2163                         return -4 +4;
2164                 }
2165         }
2166
2167         if (inc)
2168         {
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);
2177                 return 7*4 -4;
2178         }
2179         else
2180         {
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);
2188                 return -7*4 +4;
2189         }
2190 }
2191
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)
2194 {
2195         int i;
2196
2197         REG_FPCR = 0;
2198         REG_FPSR = 0;
2199         REG_FPIAR = 0;
2200         for (i = 0; i < 8; i++)
2201         {
2202                 REG_FP[i].high = 0x7fff;
2203                 REG_FP[i].low = U64(0xffffffffffffffff);
2204         }
2205
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;
2209 }
2210
2211 void m68040_do_fsave(m68ki_cpu_core *state, uint32 addr, int reg, int inc)
2212 {
2213         if (state->fpu_just_reset)
2214         {
2215                 m68ki_write_32(state, addr, 0);
2216         }
2217         else
2218         {
2219                 // we normally generate an IDLE frame
2220                 int delta = perform_fsave(state, addr, inc);
2221                 if(reg != -1)
2222                         REG_A[reg] += delta;
2223         }
2224 }
2225
2226 void m68040_do_frestore(m68ki_cpu_core *state, uint32 addr, int reg)
2227 {
2228         uint32 temp = m68ki_read_32(state, addr);
2229         // check for nullptr frame
2230         if (temp & 0xff000000)
2231         {
2232                 // we don't handle non-nullptr frames
2233                 state->fpu_just_reset = 0;
2234
2235                 if (reg != -1)
2236                 {
2237                         uint8 m40 = !!(state->cpu_type & CPU_TYPE_040);
2238                         // how about an IDLE frame?
2239                         if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2240                         {
2241                                 REG_A[reg] += 7*4-4;
2242                         }
2243                         else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2244                         {
2245 //                              REG_A[reg] += 4;
2246                         } // check UNIMP
2247                         else if ((temp & 0x00ff0000) == 0x00380000)
2248                         {
2249                                 REG_A[reg] += 14*4;
2250                         } // check BUSY
2251                         else if ((temp & 0x00ff0000) == 0x00b40000)
2252                         {
2253                                 REG_A[reg] += 45*4;
2254                         }
2255                 }
2256         }
2257         else
2258         {
2259                 do_frestore_null(state);
2260         }
2261 }
2262
2263 void m68040_fpu_op1(m68ki_cpu_core *state)
2264 {
2265         int ea = REG_IR & 0x3f;
2266         int mode = (ea >> 3) & 0x7;
2267         int reg = (ea & 0x7);
2268         uint32 addr;
2269
2270         switch ((REG_IR >> 6) & 0x3)
2271         {
2272                 case 0:         // FSAVE <ea>
2273                 {
2274                         switch (mode)
2275                         {
2276                                 case 2: // (An)
2277                                         addr = REG_A[reg];
2278                                         m68040_do_fsave(state, addr, -1, 1);
2279                                         break;
2280
2281                                 case 3: // (An)+
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
2285                                         break;
2286
2287                                 case 4: // -(An)
2288                                         addr = EA_AY_PD_32();
2289                                         m68040_do_fsave(state, addr, reg, 0); // FIXME: -1 was reg
2290                                         break;
2291                                 case 5: // (D16, An)
2292                                         addr = EA_AY_DI_16();
2293                                         m68040_do_fsave(state, addr, -1, 1);
2294                                         break;
2295
2296                                 case 6: // (An) + (Xn) + d8
2297                                         addr = EA_AY_IX_16();
2298                                         m68040_do_fsave(state, addr, -1, 1);
2299                                         break;
2300
2301                                 case 7: //
2302                                 {
2303                                         switch (reg)
2304                                         {
2305                                                 case 1:     // (abs32)
2306                                                 {
2307                                                         addr = EA_AL_32();
2308                                                         m68040_do_fsave(state, addr, -1, 1);
2309                                                         break;
2310                                                 }
2311                                                 case 2:     // (d16, PC)
2312                                                 {
2313                                                         addr = EA_PCDI_16();
2314                                                         m68040_do_fsave(state, addr, -1, 1);
2315                                                         break;
2316                                                 }
2317                                                 default:
2318                                                         fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2319                                         }
2320                                 }
2321                                 break;
2322
2323                                 default:
2324                                         fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2325                         }
2326                 }
2327                 break;
2328
2329                 case 1:         // FRESTORE <ea>
2330                 {
2331                         switch (mode)
2332                         {
2333                                 case 2: // (An)
2334                                         addr = REG_A[reg];
2335                                         m68040_do_frestore(state, addr, -1);
2336                                         break;
2337
2338                                 case 3: // (An)+
2339                                         addr = EA_AY_PI_32();
2340                                         m68040_do_frestore(state, addr, reg);
2341                                         break;
2342
2343                                 case 5: // (D16, An)
2344                                         addr = EA_AY_DI_16();
2345                                         m68040_do_frestore(state, addr, -1);
2346                                         break;
2347
2348                                 case 6: // (An) + (Xn) + d8
2349                                         addr = EA_AY_IX_16();
2350                                         m68040_do_frestore(state, addr, -1);
2351                                         break;
2352
2353                                 case 7: //
2354                                 {
2355                                         switch (reg)
2356                                         {
2357                                                 case 1:     // (abs32)
2358                                                 {
2359                                                         addr = EA_AL_32();
2360                                                         m68040_do_frestore(state, addr, -1);
2361                                                         break;
2362                                                 }
2363                                                 case 2:     // (d16, PC)
2364                                                 {
2365                                                         addr = EA_PCDI_16();
2366                                                         m68040_do_frestore(state, addr, -1);
2367                                                         break;
2368                                                 }
2369                                                 default:
2370                                                         fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2371                                         }
2372                                 }
2373                                 break;
2374
2375                                 default:
2376                                         fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2377                         }
2378                 }
2379                 break;
2380
2381                 default:    fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2382         }
2383 }
2384
2385 void m68881_ftrap(m68ki_cpu_core *state)
2386 {
2387         uint16 w2  = OPER_I_16(state);
2388
2389         // now check the condition
2390         if (TEST_CONDITION(state, w2 & 0x3f))
2391         {
2392                 // trap here
2393                 m68ki_exception_trap(state, EXCEPTION_TRAPV);
2394         }
2395         else    // fall through, requires eating the operand
2396         {
2397                 switch (REG_IR & 0x7)
2398                 {
2399                         case 2: // word operand
2400                                 OPER_I_16(state);
2401                                 break;
2402
2403                         case 3: // long word operand
2404                                 OPER_I_32(state);
2405                                 break;
2406
2407                         case 4: // no operand
2408                                 break;
2409                 }
2410         }
2411 }