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