ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/fpp.cpp
(Generate patch)

Comparing BasiliskII/src/uae_cpu/fpp.cpp (file contents):
Revision 1.3 by cebix, 1999-10-27T17:50:08Z vs.
Revision 1.8 by cebix, 2000-07-14T21:29:16Z

# Line 43 | Line 43
43   * FDBcc:
44   *  The loop termination condition was wrong.
45   *  Possible leak from int16 to int32 fixed.
46 < * Now fpcr high 16 bits are always read as zeores, no matter what was
46 > * get_fp_value:
47 > *  Immediate addressing mode && Operation Length == Byte ->
48 > *  Use the low-order byte of the extension word.
49 > * Now fpcr high 16 bits are always read as zeroes, no matter what was
50   * written to them.
51   *
52   * Other:
# Line 71 | Line 74
74   #include "memory.h"
75   #include "readcpu.h"
76   #include "newcpu.h"
77 + #include "main.h"
78  
79   #define DEBUG 0
80   #include "debug.h"
# Line 79 | Line 83
83   // Only define if you have IEEE 64 bit doubles.
84   #define HAVE_IEEE_DOUBLE 1
85  
86 + #ifdef WORDS_BIGENDIAN
87 + #define FLO 1
88 + #define FHI 0
89 + #else
90 + #define FLO 0
91 + #define FHI 1
92 + #endif
93 +
94   // fpcr rounding modes
95   #define ROUND_TO_NEAREST                        0
96   #define ROUND_TO_ZERO                           0x10
# Line 173 | Line 185 | double_flags fl_dest, fl_source;
185  
186   static __inline__ uae_u32 IS_NAN(uae_u32 *p)
187   {
188 <        if( (p[1] & 0x7FF00000) == 0x7FF00000 ) {
188 >        if( (p[FHI] & 0x7FF00000) == 0x7FF00000 ) {
189                  // logical or is faster here.
190 <                if( (p[1] & 0x000FFFFF) || p[0] ) {
190 >                if( (p[FHI] & 0x000FFFFF) || p[FLO] ) {
191                          return(1);
192                  }
193          }
# Line 184 | Line 196 | static __inline__ uae_u32 IS_NAN(uae_u32
196  
197   static __inline__ uae_u32 IS_INFINITY(uae_u32 *p)
198   {
199 <        if( ((p[1] & 0x7FF00000) == 0x7FF00000) && p[0] == 0 ) {
199 >        if( ((p[FHI] & 0x7FF00000) == 0x7FF00000) && p[FLO] == 0 ) {
200                  return(1);
201          }
202          return(0);
# Line 192 | Line 204 | static __inline__ uae_u32 IS_INFINITY(ua
204  
205   static __inline__ uae_u32 IS_NEGATIVE(uae_u32 *p)
206   {
207 <        return( (p[1] & 0x80000000) != 0 );
207 >        return( (p[FHI] & 0x80000000) != 0 );
208   }
209  
210   static __inline__ uae_u32 IS_ZERO(uae_u32 *p)
211   {
212 <        return( ((p[1] & 0x7FF00000) == 0) && p[0] == 0 );
212 >        return( ((p[FHI] & 0x7FF00000) == 0) && p[FLO] == 0 );
213   }
214  
215   // This should not touch the quotient.
# Line 236 | Line 248 | static __inline__ void GET_SOURCE_FLAGS(
248  
249   static __inline__ void MAKE_NAN(uae_u32 *p)
250   {
251 <        p[0] = 0xFFFFFFFF;
252 <        p[1] = 0x7FFFFFFF;
251 >        p[FLO] = 0xFFFFFFFF;
252 >        p[FHI] = 0x7FFFFFFF;
253   }
254  
255   static __inline__ void MAKE_ZERO_POSITIVE(uae_u32 *p)
256   {
257 <        p[0] = p[1] = 0;
257 >        p[FLO] = p[FHI] = 0;
258   }
259  
260   static __inline__ void MAKE_ZERO_NEGATIVE(uae_u32 *p)
261   {
262 <        p[0] = 0;
263 <        p[1] = 0x80000000;
262 >        p[FLO] = 0;
263 >        p[FHI] = 0x80000000;
264   }
265  
266   static __inline__ void MAKE_INF_POSITIVE(uae_u32 *p)
267   {
268 <        p[0] = 0;
269 <        p[1] = 0x7FF00000;
268 >        p[FLO] = 0;
269 >        p[FHI] = 0x7FF00000;
270   }
271  
272   static __inline__ void MAKE_INF_NEGATIVE(uae_u32 *p)
273   {
274 <        p[0] = 0;
275 <        p[1] = 0xFFF00000;
274 >        p[FLO] = 0;
275 >        p[FHI] = 0xFFF00000;
276   }
277  
278   static __inline__ void FAST_SCALE(uae_u32 *p, int add)
279   {
280          int exp;
281  
282 <        exp = (p[1] & 0x7FF00000) >> 20;
282 >        exp = (p[FHI] & 0x7FF00000) >> 20;
283          // TODO: overflow flags
284          exp += add;
285          if(exp >= 2047) {
286                  MAKE_INF_POSITIVE(p);
287          } else if(exp < 0) {
288                  // keep sign (+/- 0)
289 <                p[1] &= 0x80000000;
289 >                p[FHI] &= 0x80000000;
290          } else {
291 <                p[1] = (p[1] & 0x800FFFFF) | ((uae_u32)exp << 20);
291 >                p[FHI] = (p[FHI] & 0x800FFFFF) | ((uae_u32)exp << 20);
292          }
293   }
294  
295   static __inline__ double FAST_FGETEXP(uae_u32 *p)
296   {
297 <        int exp = (p[1] & 0x7FF00000) >> 20;
297 >        int exp = (p[FHI] & 0x7FF00000) >> 20;
298          return( exp - 1023 );
299   }
300  
301   // Normalize to range 1..2
302   static __inline__ void FAST_REMOVE_EXPONENT(uae_u32 *p)
303   {
304 <        p[1] = (p[1] & 0x800FFFFF) | 0x3FF00000;
304 >        p[FHI] = (p[FHI] & 0x800FFFFF) | 0x3FF00000;
305   }
306  
307   // The sign of the quotient is the exclusive-OR of the sign bits
308   // of the source and destination operands.
309   static __inline__ uae_u32 GET_QUOTIENT_SIGN(uae_u32 *a, uae_u32 *b)
310   {
311 <        return( ((a[1] ^ b[1]) & 0x80000000) ? 0x800000 : 0);
311 >        return( ((a[FHI] ^ b[FHI]) & 0x80000000) ? 0x800000 : 0);
312   }
313  
314   // Quotient Byte is loaded with the sign and least significant
# Line 319 | Line 331 | static __inline__ double to_single (uae_
331          uae_u32 sign = (value & 0x80000000);
332          uae_u32 exp  = ((value & 0x7F800000) >> 23) + 1023 - 127;
333  
334 <        p[0] = value << 29;
335 <        p[1] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3);
334 >        p[FLO] = value << 29;
335 >        p[FHI] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3);
336  
337          D(bug("to_single (%X) = %.04f\r\n",value,(float)result));
338  
# Line 334 | Line 346 | static __inline__ uae_u32 from_single (d
346  
347    if (src == 0.0) return 0;
348  
349 <        uae_u32 sign = (p[1] & 0x80000000);
350 <        uae_u32 exp  = (p[1] & 0x7FF00000) >> 20;
349 >        uae_u32 sign = (p[FHI] & 0x80000000);
350 >        uae_u32 exp  = (p[FHI] & 0x7FF00000) >> 20;
351  
352          if(exp + 127 < 1023) {
353                  exp = 0;
# Line 345 | Line 357 | static __inline__ uae_u32 from_single (d
357                  exp = exp + 127 - 1023;
358          }
359  
360 <        result = sign | (exp << 23) | ((p[1] & 0x000FFFFF) << 3) | (p[0] >> 29);
360 >        result = sign | (exp << 23) | ((p[FHI] & 0x000FFFFF) << 3) | (p[FLO] >> 29);
361  
362          D(bug("from_single (%.04f) = %X\r\n",(float)src,result));
363  
# Line 368 | Line 380 | static __inline__ double to_exten(uae_u3
380                  if( wrd2 | wrd3 ) {
381                          // mantissa, not fraction.
382                          uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
383 <                        while( (man & UVAL64(0x8000000000000000)) == 0 ) {
383 >                        while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) {
384                                  man <<= 1;
385                                  exp--;
386                          }
# Line 395 | Line 407 | static __inline__ double to_exten(uae_u3
407          }
408  
409          // drop the explicit integer bit.
410 <        p[0] = (wrd2 << 21) | (wrd3 >> 11);
411 <        p[1] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
410 >        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
411 >        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
412  
413          D(bug("to_exten (%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)result));
414  
415          return(result);
416   }
417  
418 + /*
419 +        Would be so much easier with full size floats :(
420 +        ... this is so vague.
421 + */
422 + static __inline__ void to_exten_no_normalize(
423 +        uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, uae_u32 *p
424 + )
425 + {
426 +        // double result;
427 +        // uae_u32 *p = (uae_u32 *)&result;
428 +
429 +        // Is it zero?
430 +  if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
431 +                MAKE_ZERO_POSITIVE(p);
432 +                return;
433 +        }
434 +
435 +        // Is it NaN?
436 +        if( (wrd1 & 0x7FFF0000) == 0x7FFF0000 ) {
437 +                if( (wrd1 & 0x0000FFFF) || wrd2 || wrd3 ) {
438 +                        MAKE_NAN( p );
439 +                        return;
440 +                }
441 +        }
442 +
443 +        uae_u32 sign =  wrd1 & 0x80000000;
444 +        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
445 +
446 +        if(exp < 16383 - 1023) {
447 +                // should set underflow.
448 +                exp = 0;
449 +        } else if(exp > 16383 + 1023) {
450 +                // should set overflow.
451 +                exp = 2047;
452 +        } else {
453 +                exp = exp + 1023 - 16383;
454 +        }
455 +
456 +        // drop the explicit integer bit.
457 +        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
458 +        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
459 +
460 +        D(bug("to_exten (%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)(*(double *)p)));
461 +
462 +        // return(result);
463 + }
464 +
465   static __inline__ void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
466   {
467          uae_u32 *p = (uae_u32 *)&src;
# Line 412 | Line 471 | static __inline__ void from_exten(double
471                  return;
472    }
473  
474 <        D(bug("from_exten (%X,%X)\r\n",p[0],p[1]));
474 >        D(bug("from_exten (%X,%X)\r\n",p[FLO],p[FHI]));
475  
476 <        uae_u32 sign =  p[1] & 0x80000000;
476 >        uae_u32 sign =  p[FHI] & 0x80000000;
477  
478 <        uae_u32 exp  = ((p[1] >> 20) & 0x7ff);
478 >        uae_u32 exp  = ((p[FHI] >> 20) & 0x7ff);
479          // Check for maximum
480          if(exp == 0x7FF) {
481                  exp = 0x7FFF;
# Line 426 | Line 485 | static __inline__ void from_exten(double
485  
486          *wrd1 = sign | (exp << 16);
487          // always set the explicit integer bit.
488 <        *wrd2 = 0x80000000 | ((p[1] & 0x000FFFFF) << 11) | ((p[0] & 0xFFE00000) >> 21);
489 <        *wrd3 = p[0] << 11;
488 >        *wrd2 = 0x80000000 | ((p[FHI] & 0x000FFFFF) << 11) | ((p[FLO] & 0xFFE00000) >> 21);
489 >        *wrd3 = p[FLO] << 11;
490  
491          D(bug("from_exten (%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3));
492   }
# Line 440 | Line 499 | static __inline__ double to_double(uae_u
499    if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) return 0.0;
500  
501          p = (uae_u32 *)&result;
502 <        p[0] = wrd2;
503 <        p[1] = wrd1;
502 >        p[FLO] = wrd2;
503 >        p[FHI] = wrd1;
504  
505          D(bug("to_double (%X,%X) = %.04f\r\n",wrd1,wrd2,(float)result));
506  
# Line 450 | Line 509 | static __inline__ double to_double(uae_u
509  
510   static __inline__ void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
511   {
512 + /*
513    if (src == 0.0) {
514                  *wrd1 = *wrd2 = 0;
515                  return;
516    }
517 + */
518          uae_u32 *p = (uae_u32 *)&src;
519 <        *wrd2 = p[0];
520 <        *wrd1 = p[1];
519 >        *wrd2 = p[FLO];
520 >        *wrd1 = p[FHI];
521  
522          D(bug("from_double (%.04f) = %X,%X\r\n",(float)src,*wrd1,*wrd2));
523   }
# Line 792 | Line 853 | static __inline__ int get_fp_value (uae_
853                                  case 4:
854                              ad = m68k_getpc ();
855                                          m68k_setpc (ad + sz2[size]);
856 +                                        // Immediate addressing mode && Operation Length == Byte ->
857 +                                        // Use the low-order byte of the extension word.
858 +                                        if(size == 6) ad++;
859                                          break;
860                                  default:
861                                          return 0;
# Line 863 | Line 927 | static __inline__ int put_fp_value (doub
927    int mode;
928    int reg;
929    uae_u32 ad;
930 <  static int sz1[8] =
931 <  {4, 4, 12, 12, 2, 8, 1, 0};
868 <  static int sz2[8] =
869 <  {4, 4, 12, 12, 2, 8, 2, 0};
930 >  static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0};
931 >  static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0};
932  
933          // D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra));
934  
# Line 1046 | Line 1108 | static __inline__ int get_fp_ad(uae_u32
1108    return 1;
1109   }
1110  
1111 < static __inline__ int fpp_cond(uae_u32 opcode, int contition)
1111 > static __inline__ int fpp_cond(uae_u32 opcode, int condition)
1112   {
1113 <  int N = (regs.fpsr & 0x8000000) != 0;
1114 <  int Z = (regs.fpsr & 0x4000000) != 0;
1115 <  /* int I = (regs.fpsr & 0x2000000) != 0; */
1116 <  int NotANumber = (regs.fpsr & 0x1000000) != 0;
1113 > #define N ((regs.fpsr & 0x8000000) != 0)
1114 > #define Z ((regs.fpsr & 0x4000000) != 0)
1115 > #define I ((regs.fpsr & 0x2000000) != 0)
1116 > #define NotANumber ((regs.fpsr & 0x1000000) != 0)
1117  
1118 <  switch (contition) {
1118 >  switch (condition) {
1119      case 0x00:
1120                          CONDRET("False",0);
1121      case 0x01:
# Line 1119 | Line 1181 | static __inline__ int fpp_cond(uae_u32 o
1181                          CONDRET("Signaling Not Equal",!Z);
1182      case 0x1f:
1183                          CONDRET("Signaling True",1);
1184 +        default:
1185 +                        CONDRET("",-1);
1186    }
1187 <        CONDRET("",-1);
1187 > #undef N
1188 > #undef Z
1189 > #undef I
1190 > #undef NotANumber
1191   }
1192  
1193 < void fdbcc_opp(uae_u32 opcode, uae_u16 extra)
1193 > void REGPARAM2 fdbcc_opp(uae_u32 opcode, uae_u16 extra)
1194   {
1195    uaecptr pc = (uae_u32) m68k_getpc ();
1196    uae_s32 disp = (uae_s32) (uae_s16) next_iword();
# Line 1154 | Line 1221 | void fdbcc_opp(uae_u32 opcode, uae_u16 e
1221    }
1222   }
1223  
1224 < void fscc_opp(uae_u32 opcode, uae_u16 extra)
1224 > void REGPARAM2 fscc_opp(uae_u32 opcode, uae_u16 extra)
1225   {
1226    uae_u32 ad;
1227    int cc;
# Line 1177 | Line 1244 | void fscc_opp(uae_u32 opcode, uae_u16 ex
1244    }
1245   }
1246  
1247 < void ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
1247 > void REGPARAM2 ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
1248   {
1249    int cc;
1250  
# Line 1193 | Line 1260 | void ftrapcc_opp(uae_u32 opcode, uaecptr
1260   }
1261  
1262   // NOTE that we get here also when there is a FNOP (nontrapping false, displ 0)
1263 < void fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
1263 > void REGPARAM2 fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
1264   {
1265    int cc;
1266  
# Line 1212 | Line 1279 | void fbcc_opp(uae_u32 opcode, uaecptr pc
1279  
1280   // FSAVE has no post-increment
1281   // 0x1f180000 == IDLE state frame, coprocessor version number 1F
1282 < void fsave_opp(uae_u32 opcode)
1282 > void REGPARAM2 fsave_opp(uae_u32 opcode)
1283   {
1284    uae_u32 ad;
1285    int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
# Line 1226 | Line 1293 | void fsave_opp(uae_u32 opcode)
1293                  return;
1294    }
1295          
1296 <        // Put 28 byte IDLE frame.
1297 <        // NOTE!!! IDLE frame is only 4 bytes on a 68040!!
1298 <
1299 <  if (incr < 0) {
1300 <          D(bug("fsave_opp pre-decrement\r\n"));
1301 <                ad -= 4;
1302 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1303 <                put_long (ad, 0x70000000);
1237 <                for (i = 0; i < 5; i++) {
1238 <            ad -= 4;
1239 <            put_long (ad, 0x00000000);
1240 <                }
1241 <                ad -= 4;
1242 <                put_long (ad, 0x1f180000); // IDLE, vers 1f
1243 <  } else {
1244 <                put_long (ad, 0x1f180000); // IDLE, vers 1f
1245 <                ad += 4;
1246 <                for (i = 0; i < 5; i++) {
1247 <            put_long (ad, 0x00000000);
1248 <            ad += 4;
1296 >        if (CPUType == 4) {
1297 >                // Put 4 byte 68040 IDLE frame.
1298 >                if (incr < 0) {
1299 >                        ad -= 4;
1300 >                        put_long (ad, 0x41000000);
1301 >                } else {
1302 >                        put_long (ad, 0x41000000);
1303 >                        ad += 4;
1304                  }
1305 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1306 <                put_long (ad, 0x70000000);
1307 <                ad += 4;
1308 <  }
1305 >        } else {
1306 >                // Put 28 byte 68881 IDLE frame.
1307 >          if (incr < 0) {
1308 >                  D(bug("fsave_opp pre-decrement\r\n"));
1309 >                        ad -= 4;
1310 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1311 >                        put_long (ad, 0x70000000);
1312 >                        for (i = 0; i < 5; i++) {
1313 >                    ad -= 4;
1314 >                    put_long (ad, 0x00000000);
1315 >                        }
1316 >                        ad -= 4;
1317 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1318 >          } else {
1319 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1320 >                        ad += 4;
1321 >                        for (i = 0; i < 5; i++) {
1322 >                    put_long (ad, 0x00000000);
1323 >                    ad += 4;
1324 >                        }
1325 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1326 >                        put_long (ad, 0x70000000);
1327 >                        ad += 4;
1328 >          }
1329 >        }
1330    if ((opcode & 0x38) == 0x18) {
1331                  m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
1332            D(bug("PROBLEM: fsave_opp post-increment\r\n"));
# Line 1261 | Line 1337 | void fsave_opp(uae_u32 opcode)
1337          }
1338   }
1339  
1340 < // FSAVE has no pre-decrement
1341 < void frestore_opp(uae_u32 opcode)
1340 > // FRESTORE has no pre-decrement
1341 > void REGPARAM2 frestore_opp(uae_u32 opcode)
1342   {
1343    uae_u32 ad;
1344    uae_u32 d;
# Line 1276 | Line 1352 | void frestore_opp(uae_u32 opcode)
1352                  return;
1353    }
1354  
1355 <  if (incr < 0) {
1356 <
1357 <          D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1358 <
1359 <                // this may be wrong, but it's never called.
1360 <                ad -= 4;
1361 <                d = get_long (ad);
1362 <                if ((d & 0xff000000) != 0) {
1363 <            if ((d & 0x00ff0000) == 0x00180000)
1364 <                                ad -= 6 * 4;
1365 <            else if ((d & 0x00ff0000) == 0x00380000)
1366 <                                ad -= 14 * 4;
1367 <            else if ((d & 0x00ff0000) == 0x00b40000)
1368 <                                ad -= 45 * 4;
1355 >        if (CPUType == 4) {
1356 >                // 68040
1357 >                if (incr < 0) {
1358 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1359 >                        // this may be wrong, but it's never called.
1360 >                        ad -= 4;
1361 >                        d = get_long (ad);
1362 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1363 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1364 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1365 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1366 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1367 >                                        ad -= 44;
1368 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1369 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1370 >                                        ad -= 92;
1371 >                                }
1372 >                        }
1373 >                } else {
1374 >                        d = get_long (ad);
1375 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1376 >                        ad += 4;
1377 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1378 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1379 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1380 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1381 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1382 >                                        ad += 44;
1383 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1384 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1385 >                                        ad += 92;
1386 >                                }
1387 >                        }
1388                  }
1389 <  } else {
1390 <                d = get_long (ad);
1391 <
1392 <          D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1393 <
1394 <                ad += 4;
1395 <                if ((d & 0xff000000) != 0) { // Not a NULL frame?
1396 <            if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1397 <                          D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1398 <                                ad += 6 * 4;
1399 <            } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1400 <                                ad += 14 * 4;
1401 <                          D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1402 <            } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1403 <                          D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1404 <                                ad += 45 * 4;
1389 >        } else {
1390 >                // 68881
1391 >          if (incr < 0) {
1392 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1393 >                        // this may be wrong, but it's never called.
1394 >                        ad -= 4;
1395 >                        d = get_long (ad);
1396 >                        if ((d & 0xff000000) != 0) {
1397 >                    if ((d & 0x00ff0000) == 0x00180000)
1398 >                                        ad -= 6 * 4;
1399 >                    else if ((d & 0x00ff0000) == 0x00380000)
1400 >                                        ad -= 14 * 4;
1401 >                    else if ((d & 0x00ff0000) == 0x00b40000)
1402 >                                        ad -= 45 * 4;
1403 >                        }
1404 >          } else {
1405 >                        d = get_long (ad);
1406 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1407 >                        ad += 4;
1408 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1409 >                    if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1410 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1411 >                                        ad += 6 * 4;
1412 >                    } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1413 >                                        ad += 14 * 4;
1414 >                                  D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1415 >                    } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1416 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1417 >                                        ad += 45 * 4;
1418 >                                }
1419                          }
1420                  }
1421    }
# Line 1558 | Line 1667 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1667                                                  uae_u32 wrd1, wrd2, wrd3;
1668                                                  if( list & 0x80 ) {
1669                                                          from_exten(regs.fp[reg],&wrd1, &wrd2, &wrd3);
1670 <                                                        put_long (ad, wrd3);
1670 >                                                        put_long (ad, wrd1);
1671                                                          ad += 4;
1672                                                          put_long (ad, wrd2);
1673                                                          ad += 4;
1674 <                                                        put_long (ad, wrd1);
1674 >                                                        put_long (ad, wrd3);
1675                                                          ad += 4;
1676                                                  }
1677                                                  list <<= 1;
1678                                          }
1679                                  }
1680  
1572                                /*
1573                                while (list) {
1574                                        uae_u32 wrd1, wrd2, wrd3;
1575                                        if (incr < 0) {
1576                                                from_exten(regs.fp[fpp_movem_index2[list]],
1577                                                 &wrd1, &wrd2, &wrd3);
1578                                                ad -= 4;
1579                                                put_long (ad, wrd3);
1580                                                ad -= 4;
1581                                                put_long (ad, wrd2);
1582                                                ad -= 4;
1583                                                put_long (ad, wrd1);
1584                                        } else {
1585                                                from_exten(regs.fp[fpp_movem_index1[list]],
1586                                                 &wrd1, &wrd2, &wrd3);
1587                                                put_long (ad, wrd1);
1588                                                ad += 4;
1589                                                put_long (ad, wrd2);
1590                                                ad += 4;
1591                                                put_long (ad, wrd3);
1592                                                ad += 4;
1593                                        }
1594                                        list = fpp_movem_next[list];
1595                                }
1596                                */
1681                                  if ((opcode & 0x38) == 0x18) // post-increment?
1682                                          m68k_areg (regs, opcode & 7) = ad;
1683                                  if ((opcode & 0x38) == 0x20) // pre-decrement?
# Line 1636 | Line 1720 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1720                                          for(reg=7; reg>=0; reg--) {
1721                                                  uae_u32 wrd1, wrd2, wrd3;
1722                                                  if( list & 0x80 ) {
1639                                                        wrd1 = get_long (ad);
1640                                                        ad -= 4;
1641                                                        wrd2 = get_long (ad);
1723                                                          ad -= 4;
1724                                                          wrd3 = get_long (ad);
1725                                                          ad -= 4;
1726 <                                                        regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1726 >                                                        wrd2 = get_long (ad);
1727 >                                                        ad -= 4;
1728 >                                                        wrd1 = get_long (ad);
1729 >                                                        // regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1730 >                                                        to_exten_no_normalize (wrd1, wrd2, wrd3, (uae_u32 *)&regs.fp[reg]);
1731                                                  }
1732                                                  list <<= 1;
1733                                          }
# Line 1656 | Line 1741 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1741                                                          ad += 4;
1742                                                          wrd3 = get_long (ad);
1743                                                          ad += 4;
1744 <                                                        regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1744 >                                                        // regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1745 >                                                        to_exten_no_normalize (wrd1, wrd2, wrd3, (uae_u32 *)&regs.fp[reg]);
1746                                                  }
1747                                                  list <<= 1;
1748                                          }
1749                                  }
1664                                /**/
1665
1666                                /*
1667                                while (list) {
1668                                        uae_u32 wrd1, wrd2, wrd3;
1669                                        if (incr < 0) {
1670                                                ad -= 4;
1671                                                wrd3 = get_long (ad);
1672                                                ad -= 4;
1673                                                wrd2 = get_long (ad);
1674                                                ad -= 4;
1675                                                wrd1 = get_long (ad);
1676                                                regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
1677                            } else {
1678                                                wrd1 = get_long (ad);
1679                                                ad += 4;
1680                                                wrd2 = get_long (ad);
1681                                                ad += 4;
1682                                                wrd3 = get_long (ad);
1683                                                ad += 4;
1684                                                regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
1685                                        }
1686                                        list = fpp_movem_next[list];
1687                                }
1688                                */
1750                                  if ((opcode & 0x38) == 0x18) // post-increment?
1751                              m68k_areg (regs, opcode & 7) = ad;
1752                                  if ((opcode & 0x38) == 0x20) // pre-decrement?
# Line 1816 | Line 1877 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1877                                  dump_fp_regs( "END  ");
1878                                  return;
1879                          }
1880 +                        D(bug("returned from get_fp_value m68k_getpc()=%X\r\n",m68k_getpc()));
1881  
1882                          switch (extra & 0x7f) {
1883                                  case 0x00:              /* FMOVE */
# Line 1934 | Line 1996 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1996                                          MAKE_FPSR(regs.fpsr,regs.fp[reg]);
1997                                          break;
1998                                  case 0x18:              /* FABS */
1999 +                                case 0x58:              /* single precision rounding */
2000 +                                case 0x5C:              /* double precision rounding */
2001                                          D(bug("FABS %.04f\r\n",(float)src));
2002                                          regs.fp[reg] = src < 0 ? -src : src;
2003                                          MAKE_FPSR(regs.fpsr,regs.fp[reg]);
# Line 2016 | Line 2080 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2080                                  }
2081                                  break;
2082                          case 0x22:              /* FADD */
2083 +                        case 0x62:              /* single */
2084 +                        case 0x66:              /* double */
2085                                  D(bug("FADD %.04f\r\n",(float)src));
2086                                  regs.fp[reg] += src;
2087                                  MAKE_FPSR(regs.fpsr,regs.fp[reg]);
2088                                  break;
2089                          case 0x23:              /* FMUL */
2090                                  D(bug("FMUL %.04f\r\n",(float)src));
2091 + #if HAVE_IEEE_DOUBLE
2092                                  GET_DEST_FLAGS((uae_u32 *)&regs.fp[reg]);
2093                                  GET_SOURCE_FLAGS((uae_u32 *)&src);
2094                                  if(fl_dest.in_range && fl_source.in_range) {
# Line 2048 | Line 2115 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2115                                                  MAKE_INF_POSITIVE((uae_u32 *)&regs.fp[reg]);
2116                                          }
2117                                  }
2118 + #else
2119 +                                D(bug("FMUL %.04f\r\n",(float)src));
2120 +                                regs.fp[reg] *= src;
2121 + #endif
2122                                  MAKE_FPSR(regs.fpsr,regs.fp[reg]);
2123                                  break;
2124                          case 0x24:              /* FSGLDIV */
# Line 2152 | Line 2223 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2223                                          }
2224                                  } else {
2225                                          double tmp = regs.fp[reg] - src;
2226 <                                        regs.fpsr = (regs.fpsr & 0x00FFFFFF) | (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2226 >                                        // regs.fpsr = (regs.fpsr & 0x00FFFFFF) | (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2227 >                                        regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2228                                  }
2229   #else
2230                                  {
# Line 2172 | Line 2244 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2244                                  op_illg (opcode);
2245                                  break;
2246                  }
2247 +                D(bug("END m68k_getpc()=%X\r\n",m68k_getpc()));
2248                  dump_fp_regs( "END  ");
2249                  return;
2250    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines