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: |
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" |
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 |
|
} |
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; |
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[FLO]; |
520 |
|
*wrd1 = p[FHI]; |
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; |
927 |
|
int mode; |
928 |
|
int reg; |
929 |
|
uae_u32 ad; |
930 |
< |
static int sz1[8] = |
931 |
< |
{4, 4, 12, 12, 2, 8, 1, 0}; |
876 |
< |
static int sz2[8] = |
877 |
< |
{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 |
|
|
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: |
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(); |
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; |
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 |
|
|
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 |
|
|
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; |
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); |
1245 |
< |
for (i = 0; i < 5; i++) { |
1246 |
< |
ad -= 4; |
1247 |
< |
put_long (ad, 0x00000000); |
1248 |
< |
} |
1249 |
< |
ad -= 4; |
1250 |
< |
put_long (ad, 0x1f180000); // IDLE, vers 1f |
1251 |
< |
} else { |
1252 |
< |
put_long (ad, 0x1f180000); // IDLE, vers 1f |
1253 |
< |
ad += 4; |
1254 |
< |
for (i = 0; i < 5; i++) { |
1255 |
< |
put_long (ad, 0x00000000); |
1256 |
< |
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")); |
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; |
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 |
|
} |
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 |
|
|
1580 |
– |
/* |
1581 |
– |
while (list) { |
1582 |
– |
uae_u32 wrd1, wrd2, wrd3; |
1583 |
– |
if (incr < 0) { |
1584 |
– |
from_exten(regs.fp[fpp_movem_index2[list]], |
1585 |
– |
&wrd1, &wrd2, &wrd3); |
1586 |
– |
ad -= 4; |
1587 |
– |
put_long (ad, wrd3); |
1588 |
– |
ad -= 4; |
1589 |
– |
put_long (ad, wrd2); |
1590 |
– |
ad -= 4; |
1591 |
– |
put_long (ad, wrd1); |
1592 |
– |
} else { |
1593 |
– |
from_exten(regs.fp[fpp_movem_index1[list]], |
1594 |
– |
&wrd1, &wrd2, &wrd3); |
1595 |
– |
put_long (ad, wrd1); |
1596 |
– |
ad += 4; |
1597 |
– |
put_long (ad, wrd2); |
1598 |
– |
ad += 4; |
1599 |
– |
put_long (ad, wrd3); |
1600 |
– |
ad += 4; |
1601 |
– |
} |
1602 |
– |
list = fpp_movem_next[list]; |
1603 |
– |
} |
1604 |
– |
*/ |
1681 |
|
if ((opcode & 0x38) == 0x18) // post-increment? |
1682 |
|
m68k_areg (regs, opcode & 7) = ad; |
1683 |
|
if ((opcode & 0x38) == 0x20) // pre-decrement? |
1720 |
|
for(reg=7; reg>=0; reg--) { |
1721 |
|
uae_u32 wrd1, wrd2, wrd3; |
1722 |
|
if( list & 0x80 ) { |
1647 |
– |
wrd1 = get_long (ad); |
1648 |
– |
ad -= 4; |
1649 |
– |
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 *)®s.fp[reg]); |
1731 |
|
} |
1732 |
|
list <<= 1; |
1733 |
|
} |
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 *)®s.fp[reg]); |
1746 |
|
} |
1747 |
|
list <<= 1; |
1748 |
|
} |
1749 |
|
} |
1672 |
– |
/**/ |
1673 |
– |
|
1674 |
– |
/* |
1675 |
– |
while (list) { |
1676 |
– |
uae_u32 wrd1, wrd2, wrd3; |
1677 |
– |
if (incr < 0) { |
1678 |
– |
ad -= 4; |
1679 |
– |
wrd3 = get_long (ad); |
1680 |
– |
ad -= 4; |
1681 |
– |
wrd2 = get_long (ad); |
1682 |
– |
ad -= 4; |
1683 |
– |
wrd1 = get_long (ad); |
1684 |
– |
regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3); |
1685 |
– |
} else { |
1686 |
– |
wrd1 = get_long (ad); |
1687 |
– |
ad += 4; |
1688 |
– |
wrd2 = get_long (ad); |
1689 |
– |
ad += 4; |
1690 |
– |
wrd3 = get_long (ad); |
1691 |
– |
ad += 4; |
1692 |
– |
regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3); |
1693 |
– |
} |
1694 |
– |
list = fpp_movem_next[list]; |
1695 |
– |
} |
1696 |
– |
*/ |
1750 |
|
if ((opcode & 0x38) == 0x18) // post-increment? |
1751 |
|
m68k_areg (regs, opcode & 7) = ad; |
1752 |
|
if ((opcode & 0x38) == 0x20) // pre-decrement? |
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 */ |
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]); |
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 *)®s.fp[reg]); |
2093 |
|
GET_SOURCE_FLAGS((uae_u32 *)&src); |
2094 |
|
if(fl_dest.in_range && fl_source.in_range) { |
2115 |
|
MAKE_INF_POSITIVE((uae_u32 *)®s.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 */ |
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 |
|
{ |
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 |
|
} |