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