|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68881 emulation
5: *
6: * Copyright 1996 Herman ten Brugge
7: */
8:
9: #include <math.h>
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include "config.h"
15: #include "options.h"
16: #include "memory.h"
17: #include "custom.h"
1.1.1.2 root 18: #include "readcpu.h"
1.1 root 19: #include "newcpu.h"
20: #include "ersatz.h"
1.1.1.4 root 21: #include "md-fpp.h"
1.1 root 22:
1.1.1.3 root 23: #if 1
1.1 root 24:
25: #define DEBUG_FPP 0
26:
1.1.1.5 ! root 27: #define MAKE_FPSR(fpsr,r) (fpsr) = ((fpsr) & 0x00FFFFFF) | ((r) == 0 ? 0x4000000 : 0) | ((r) < 0 ? 0x8000000 : 0)
! 28:
1.1 root 29: /* single : S 8*E 23*F */
30: /* double : S 11*E 52*F */
31: /* extended : S 15*E 64*F */
32: /* E = 0 & F = 0 -> 0 */
33: /* E = MAX & F = 0 -> Infin */
34: /* E = MAX & F # 0 -> NotANumber */
35: /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */
36:
1.1.1.5 ! root 37: STATIC_INLINE double to_pack (uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1 root 38: {
1.1.1.3 root 39: double d;
40: char *cp;
41: char str[100];
42:
43: cp = str;
44: if (wrd1 & 0x80000000)
45: *cp++ = '-';
46: *cp++ = (wrd1 & 0xf) + '0';
47: *cp++ = '.';
48: *cp++ = ((wrd2 >> 28) & 0xf) + '0';
49: *cp++ = ((wrd2 >> 24) & 0xf) + '0';
50: *cp++ = ((wrd2 >> 20) & 0xf) + '0';
51: *cp++ = ((wrd2 >> 16) & 0xf) + '0';
52: *cp++ = ((wrd2 >> 12) & 0xf) + '0';
53: *cp++ = ((wrd2 >> 8) & 0xf) + '0';
54: *cp++ = ((wrd2 >> 4) & 0xf) + '0';
55: *cp++ = ((wrd2 >> 0) & 0xf) + '0';
56: *cp++ = ((wrd3 >> 28) & 0xf) + '0';
57: *cp++ = ((wrd3 >> 24) & 0xf) + '0';
58: *cp++ = ((wrd3 >> 20) & 0xf) + '0';
59: *cp++ = ((wrd3 >> 16) & 0xf) + '0';
60: *cp++ = ((wrd3 >> 12) & 0xf) + '0';
61: *cp++ = ((wrd3 >> 8) & 0xf) + '0';
62: *cp++ = ((wrd3 >> 4) & 0xf) + '0';
63: *cp++ = ((wrd3 >> 0) & 0xf) + '0';
64: *cp++ = 'E';
65: if (wrd1 & 0x40000000)
66: *cp++ = '-';
67: *cp++ = ((wrd1 >> 24) & 0xf) + '0';
68: *cp++ = ((wrd1 >> 20) & 0xf) + '0';
69: *cp++ = ((wrd1 >> 16) & 0xf) + '0';
70: *cp = 0;
1.1.1.5 ! root 71: sscanf (str, "%le", &d);
1.1.1.3 root 72: return d;
1.1 root 73: }
74:
1.1.1.5 ! root 75: STATIC_INLINE void from_pack (double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1 root 76: {
1.1.1.3 root 77: int i;
78: int t;
79: char *cp;
80: char str[100];
81:
1.1.1.5 ! root 82: sprintf (str, "%.16e", src);
1.1.1.3 root 83: cp = str;
84: *wrd1 = *wrd2 = *wrd3 = 0;
85: if (*cp == '-') {
86: cp++;
87: *wrd1 = 0x80000000;
88: }
89: if (*cp == '+')
90: cp++;
91: *wrd1 |= (*cp++ - '0');
92: if (*cp == '.')
93: cp++;
94: for (i = 0; i < 8; i++) {
95: *wrd2 <<= 4;
96: if (*cp >= '0' && *cp <= '9')
97: *wrd2 |= *cp++ - '0';
98: }
99: for (i = 0; i < 8; i++) {
100: *wrd3 <<= 4;
101: if (*cp >= '0' && *cp <= '9')
102: *wrd3 |= *cp++ - '0';
103: }
104: if (*cp == 'e' || *cp == 'E') {
105: cp++;
106: if (*cp == '-') {
107: cp++;
108: *wrd1 |= 0x40000000;
109: }
110: if (*cp == '+')
111: cp++;
112: t = 0;
113: for (i = 0; i < 3; i++) {
114: if (*cp >= '0' && *cp <= '9')
115: t = (t << 4) | (*cp++ - '0');
1.1 root 116: }
1.1.1.3 root 117: *wrd1 |= t << 16;
118: }
1.1 root 119: }
120:
1.1.1.4 root 121: STATIC_INLINE int get_fp_value (uae_u32 opcode, uae_u16 extra, double *src)
1.1 root 122: {
1.1.1.3 root 123: uaecptr tmppc;
124: uae_u16 tmp;
125: int size;
126: int mode;
127: int reg;
128: uae_u32 ad = 0;
1.1.1.5 ! root 129: static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
! 130: static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
1.1.1.3 root 131:
132: if ((extra & 0x4000) == 0) {
133: *src = regs.fp[(extra >> 10) & 7];
134: return 1;
135: }
136: mode = (opcode >> 3) & 7;
137: reg = opcode & 7;
138: size = (extra >> 10) & 7;
139: switch (mode) {
140: case 0:
141: switch (size) {
142: case 6:
143: *src = (double) (uae_s8) m68k_dreg (regs, reg);
144: break;
145: case 4:
146: *src = (double) (uae_s16) m68k_dreg (regs, reg);
147: break;
1.1 root 148: case 0:
1.1.1.3 root 149: *src = (double) (uae_s32) m68k_dreg (regs, reg);
150: break;
151: case 1:
1.1.1.5 ! root 152: *src = to_single (m68k_dreg (regs, reg));
1.1.1.3 root 153: break;
154: default:
155: return 0;
156: }
157: return 1;
158: case 1:
159: return 0;
160: case 2:
161: ad = m68k_areg (regs, reg);
162: break;
163: case 3:
164: ad = m68k_areg (regs, reg);
165: m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
166: break;
167: case 4:
168: m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
169: ad = m68k_areg (regs, reg);
170: break;
171: case 5:
1.1.1.5 ! root 172: ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 173: break;
174: case 6:
1.1.1.5 ! root 175: ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 176: break;
177: case 7:
178: switch (reg) {
179: case 0:
1.1.1.5 ! root 180: ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 181: break;
1.1 root 182: case 1:
1.1.1.5 ! root 183: ad = next_ilong ();
1.1.1.3 root 184: break;
1.1 root 185: case 2:
1.1.1.3 root 186: ad = m68k_getpc ();
1.1.1.5 ! root 187: ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 188: break;
1.1 root 189: case 3:
1.1.1.3 root 190: tmppc = m68k_getpc ();
1.1.1.5 ! root 191: tmp = next_iword ();
1.1.1.3 root 192: ad = get_disp_ea_020 (tmppc, tmp);
193: break;
1.1 root 194: case 4:
1.1.1.3 root 195: ad = m68k_getpc ();
196: m68k_setpc (ad + sz2[size]);
197: break;
1.1 root 198: default:
1.1.1.3 root 199: return 0;
1.1 root 200: }
1.1.1.3 root 201: }
202: switch (size) {
203: case 0:
204: *src = (double) (uae_s32) get_long (ad);
205: break;
206: case 1:
1.1.1.5 ! root 207: *src = to_single (get_long (ad));
1.1.1.3 root 208: break;
209: case 2:{
210: uae_u32 wrd1, wrd2, wrd3;
211: wrd1 = get_long (ad);
212: ad += 4;
213: wrd2 = get_long (ad);
214: ad += 4;
215: wrd3 = get_long (ad);
1.1.1.5 ! root 216: *src = to_exten (wrd1, wrd2, wrd3);
1.1.1.3 root 217: }
218: break;
219: case 3:{
220: uae_u32 wrd1, wrd2, wrd3;
221: wrd1 = get_long (ad);
222: ad += 4;
223: wrd2 = get_long (ad);
224: ad += 4;
225: wrd3 = get_long (ad);
1.1.1.5 ! root 226: *src = to_pack (wrd1, wrd2, wrd3);
1.1.1.3 root 227: }
228: break;
229: case 4:
1.1.1.5 ! root 230: *src = (double) (uae_s16) get_word (ad);
1.1.1.3 root 231: break;
232: case 5:{
233: uae_u32 wrd1, wrd2;
234: wrd1 = get_long (ad);
235: ad += 4;
236: wrd2 = get_long (ad);
1.1.1.5 ! root 237: *src = to_double (wrd1, wrd2);
1.1.1.3 root 238: }
239: break;
240: case 6:
1.1.1.5 ! root 241: *src = (double) (uae_s8) get_byte (ad);
1.1.1.3 root 242: break;
243: default:
244: return 0;
245: }
246: return 1;
1.1 root 247: }
248:
1.1.1.4 root 249: STATIC_INLINE int put_fp_value (double value, uae_u32 opcode, uae_u16 extra)
1.1 root 250: {
1.1.1.3 root 251: uae_u16 tmp;
252: uaecptr tmppc;
253: int size;
254: int mode;
255: int reg;
256: uae_u32 ad;
1.1.1.5 ! root 257: static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
! 258: static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
1.1.1.3 root 259:
260: if ((extra & 0x4000) == 0) {
261: regs.fp[(extra >> 10) & 7] = value;
262: return 1;
263: }
264: mode = (opcode >> 3) & 7;
265: reg = opcode & 7;
266: size = (extra >> 10) & 7;
267: ad = -1;
268: switch (mode) {
269: case 0:
270: switch (size) {
271: case 6:
272: m68k_dreg (regs, reg) = (((int) value & 0xff)
1.1.1.4 root 273: | (m68k_dreg (regs, reg) & ~0xff));
1.1.1.3 root 274: break;
275: case 4:
276: m68k_dreg (regs, reg) = (((int) value & 0xffff)
1.1.1.4 root 277: | (m68k_dreg (regs, reg) & ~0xffff));
1.1.1.3 root 278: break;
1.1 root 279: case 0:
1.1.1.3 root 280: m68k_dreg (regs, reg) = (int) value;
281: break;
1.1 root 282: case 1:
1.1.1.5 ! root 283: m68k_dreg (regs, reg) = from_single (value);
1.1.1.3 root 284: break;
285: default:
286: return 0;
287: }
288: return 1;
289: case 1:
290: return 0;
291: case 2:
292: ad = m68k_areg (regs, reg);
293: break;
294: case 3:
295: ad = m68k_areg (regs, reg);
296: m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
297: break;
298: case 4:
299: m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
300: ad = m68k_areg (regs, reg);
301: break;
302: case 5:
1.1.1.5 ! root 303: ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 304: break;
305: case 6:
1.1.1.5 ! root 306: ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 307: break;
308: case 7:
309: switch (reg) {
310: case 0:
1.1.1.5 ! root 311: ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 312: break;
313: case 1:
1.1.1.5 ! root 314: ad = next_ilong ();
1.1.1.3 root 315: break;
1.1 root 316: case 2:
1.1.1.3 root 317: ad = m68k_getpc ();
1.1.1.5 ! root 318: ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 319: break;
1.1 root 320: case 3:
1.1.1.3 root 321: tmppc = m68k_getpc ();
1.1.1.5 ! root 322: tmp = next_iword ();
1.1.1.3 root 323: ad = get_disp_ea_020 (tmppc, tmp);
324: break;
1.1 root 325: case 4:
1.1.1.3 root 326: ad = m68k_getpc ();
327: m68k_setpc (ad + sz2[size]);
328: break;
1.1 root 329: default:
1.1.1.3 root 330: return 0;
1.1 root 331: }
1.1.1.3 root 332: }
333: switch (size) {
334: case 0:
335: put_long (ad, (uae_s32) value);
336: break;
337: case 1:
1.1.1.5 ! root 338: put_long (ad, from_single (value));
1.1.1.3 root 339: break;
340: case 2:
341: {
342: uae_u32 wrd1, wrd2, wrd3;
1.1.1.5 ! root 343: from_exten (value, &wrd1, &wrd2, &wrd3);
1.1.1.3 root 344: put_long (ad, wrd1);
345: ad += 4;
346: put_long (ad, wrd2);
347: ad += 4;
348: put_long (ad, wrd3);
349: }
350: break;
351: case 3:
352: {
353: uae_u32 wrd1, wrd2, wrd3;
1.1.1.5 ! root 354: from_pack (value, &wrd1, &wrd2, &wrd3);
1.1.1.3 root 355: put_long (ad, wrd1);
356: ad += 4;
357: put_long (ad, wrd2);
358: ad += 4;
359: put_long (ad, wrd3);
360: }
361: break;
362: case 4:
1.1.1.5 ! root 363: put_word (ad, (uae_s16) value);
1.1.1.3 root 364: break;
365: case 5:{
366: uae_u32 wrd1, wrd2;
1.1.1.5 ! root 367: from_double (value, &wrd1, &wrd2);
1.1.1.3 root 368: put_long (ad, wrd1);
369: ad += 4;
370: put_long (ad, wrd2);
371: }
372: break;
373: case 6:
1.1.1.5 ! root 374: put_byte (ad, (uae_s8) value);
1.1.1.3 root 375: break;
376: default:
377: return 0;
378: }
379: return 1;
1.1 root 380: }
381:
1.1.1.5 ! root 382: STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad)
1.1 root 383: {
1.1.1.3 root 384: uae_u16 tmp;
385: uaecptr tmppc;
386: int mode;
387: int reg;
388:
389: mode = (opcode >> 3) & 7;
390: reg = opcode & 7;
391: switch (mode) {
392: case 0:
393: case 1:
394: return 0;
395: case 2:
396: *ad = m68k_areg (regs, reg);
397: break;
398: case 3:
399: *ad = m68k_areg (regs, reg);
400: break;
401: case 4:
402: *ad = m68k_areg (regs, reg);
403: break;
404: case 5:
1.1.1.5 ! root 405: *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 406: break;
407: case 6:
1.1.1.5 ! root 408: *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 409: break;
410: case 7:
411: switch (reg) {
1.1 root 412: case 0:
1.1.1.5 ! root 413: *ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 414: break;
1.1 root 415: case 1:
1.1.1.5 ! root 416: *ad = next_ilong ();
1.1.1.3 root 417: break;
1.1 root 418: case 2:
1.1.1.3 root 419: *ad = m68k_getpc ();
1.1.1.5 ! root 420: *ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 421: break;
1.1 root 422: case 3:
1.1.1.3 root 423: tmppc = m68k_getpc ();
1.1.1.5 ! root 424: tmp = next_iword ();
1.1.1.3 root 425: *ad = get_disp_ea_020 (tmppc, tmp);
426: break;
427: default:
428: return 0;
1.1 root 429: }
1.1.1.3 root 430: }
431: return 1;
1.1 root 432: }
433:
1.1.1.5 ! root 434: STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition)
1.1 root 435: {
1.1.1.3 root 436: int N = (regs.fpsr & 0x8000000) != 0;
437: int Z = (regs.fpsr & 0x4000000) != 0;
438: /* int I = (regs.fpsr & 0x2000000) != 0; */
439: int NotANumber = (regs.fpsr & 0x1000000) != 0;
440:
441: switch (contition) {
442: case 0x00:
443: return 0;
444: case 0x01:
445: return Z;
446: case 0x02:
447: return !(NotANumber || Z || N);
448: case 0x03:
449: return Z || !(NotANumber || N);
450: case 0x04:
451: return N && !(NotANumber || Z);
452: case 0x05:
453: return Z || (N && !NotANumber);
454: case 0x06:
455: return !(NotANumber || Z);
456: case 0x07:
457: return !NotANumber;
458: case 0x08:
459: return NotANumber;
460: case 0x09:
461: return NotANumber || Z;
462: case 0x0a:
463: return NotANumber || !(N || Z);
464: case 0x0b:
465: return NotANumber || Z || !N;
466: case 0x0c:
467: return NotANumber || (N && !Z);
468: case 0x0d:
469: return NotANumber || Z || N;
470: case 0x0e:
471: return !Z;
472: case 0x0f:
473: return 1;
474: case 0x10:
475: return 0;
476: case 0x11:
477: return Z;
478: case 0x12:
479: return !(NotANumber || Z || N);
480: case 0x13:
481: return Z || !(NotANumber || N);
482: case 0x14:
483: return N && !(NotANumber || Z);
484: case 0x15:
485: return Z || (N && !NotANumber);
486: case 0x16:
487: return !(NotANumber || Z);
488: case 0x17:
489: return !NotANumber;
490: case 0x18:
491: return NotANumber;
492: case 0x19:
493: return NotANumber || Z;
494: case 0x1a:
495: return NotANumber || !(N || Z);
496: case 0x1b:
497: return NotANumber || Z || !N;
498: case 0x1c:
499: return NotANumber || (Z && N);
500: case 0x1d:
501: return NotANumber || Z || N;
502: case 0x1e:
503: return !Z;
504: case 0x1f:
505: return 1;
506: }
507: return -1;
1.1 root 508: }
509:
1.1.1.5 ! root 510: void fdbcc_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 511: {
1.1.1.3 root 512: uaecptr pc = (uae_u32) m68k_getpc ();
1.1.1.5 ! root 513: uae_s32 disp = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 514: int cc;
1.1 root 515:
516: #if DEBUG_FPP
1.1.1.5 ! root 517: printf ("fdbcc_opp at %08lx\n", m68k_getpc ());
! 518: fflush (stdout);
1.1 root 519: #endif
1.1.1.5 ! root 520: cc = fpp_cond (opcode, extra & 0x3f);
1.1.1.3 root 521: if (cc == -1) {
522: m68k_setpc (pc - 4);
523: op_illg (opcode);
524: } else if (!cc) {
525: int reg = opcode & 0x7;
526:
527: m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff)
1.1.1.5 ! root 528: | ((m68k_dreg (regs, reg) - 1) & 0xffff));
1.1.1.3 root 529: if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff)
530: m68k_setpc (pc + disp);
531: }
1.1 root 532: }
533:
1.1.1.5 ! root 534: void fscc_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 535: {
1.1.1.3 root 536: uae_u32 ad;
537: int cc;
1.1 root 538:
539: #if DEBUG_FPP
1.1.1.5 ! root 540: printf ("fscc_opp at %08lx\n", m68k_getpc ());
! 541: fflush (stdout);
1.1 root 542: #endif
1.1.1.5 ! root 543: cc = fpp_cond (opcode, extra & 0x3f);
1.1.1.3 root 544: if (cc == -1) {
545: m68k_setpc (m68k_getpc () - 4);
546: op_illg (opcode);
547: } else if ((opcode & 0x38) == 0) {
1.1.1.5 ! root 548: m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | (cc ? 0xff : 0x00);
1.1.1.3 root 549: } else {
1.1.1.5 ! root 550: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 551: m68k_setpc (m68k_getpc () - 4);
552: op_illg (opcode);
553: } else
1.1.1.5 ! root 554: put_byte (ad, cc ? 0xff : 0x00);
1.1.1.3 root 555: }
1.1 root 556: }
557:
1.1.1.5 ! root 558: void ftrapcc_opp (uae_u32 opcode, uaecptr oldpc)
1.1 root 559: {
1.1.1.3 root 560: int cc;
1.1 root 561:
562: #if DEBUG_FPP
1.1.1.5 ! root 563: printf ("ftrapcc_opp at %08lx\n", m68k_getpc ());
! 564: fflush (stdout);
1.1 root 565: #endif
1.1.1.5 ! root 566: cc = fpp_cond (opcode, opcode & 0x3f);
1.1.1.3 root 567: if (cc == -1) {
568: m68k_setpc (oldpc);
569: op_illg (opcode);
570: }
571: if (cc)
1.1.1.5 ! root 572: Exception (7, oldpc - 2);
1.1 root 573: }
574:
1.1.1.5 ! root 575: void fbcc_opp (uae_u32 opcode, uaecptr pc, uae_u32 extra)
1.1 root 576: {
1.1.1.3 root 577: int cc;
1.1 root 578:
579: #if DEBUG_FPP
1.1.1.5 ! root 580: printf ("fbcc_opp at %08lx\n", m68k_getpc ());
! 581: fflush (stdout);
1.1 root 582: #endif
1.1.1.5 ! root 583: cc = fpp_cond (opcode, opcode & 0x3f);
1.1.1.3 root 584: if (cc == -1) {
585: m68k_setpc (pc);
586: op_illg (opcode);
587: } else if (cc) {
588: if ((opcode & 0x40) == 0)
589: extra = (uae_s32) (uae_s16) extra;
590: m68k_setpc (pc + extra);
591: }
1.1 root 592: }
593:
1.1.1.5 ! root 594: void fsave_opp (uae_u32 opcode)
1.1 root 595: {
1.1.1.3 root 596: uae_u32 ad;
597: int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
598: int i;
599:
1.1 root 600: #if DEBUG_FPP
1.1.1.5 ! root 601: printf ("fsave_opp at %08lx\n", m68k_getpc ());
! 602: fflush (stdout);
1.1 root 603: #endif
1.1.1.5 ! root 604: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 605: m68k_setpc (m68k_getpc () - 2);
606: op_illg (opcode);
607: return;
608: }
1.1.1.5 ! root 609:
! 610: if (currprefs.cpu_level == 4) {
1.1.1.3 root 611: } else {
1.1.1.5 ! root 612: if (incr < 0) {
! 613: ad -= 4;
! 614: put_long (ad, 0x70000000);
! 615: for (i = 0; i < 5; i++) {
! 616: ad -= 4;
! 617: put_long (ad, 0x00000000);
! 618: }
! 619: ad -= 4;
! 620: put_long (ad, 0x1f180000);
! 621: } else {
! 622: put_long (ad, 0x1f180000);
! 623: ad += 4;
! 624: for (i = 0; i < 5; i++) {
! 625: put_long (ad, 0x00000000);
! 626: ad += 4;
! 627: }
! 628: put_long (ad, 0x70000000);
1.1.1.3 root 629: ad += 4;
630: }
631: }
632: if ((opcode & 0x38) == 0x18)
633: m68k_areg (regs, opcode & 7) = ad;
634: if ((opcode & 0x38) == 0x20)
635: m68k_areg (regs, opcode & 7) = ad;
1.1 root 636: }
637:
1.1.1.5 ! root 638: void frestore_opp (uae_u32 opcode)
1.1 root 639: {
1.1.1.3 root 640: uae_u32 ad;
641: uae_u32 d;
642: int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
643:
1.1 root 644: #if DEBUG_FPP
1.1.1.5 ! root 645: printf ("frestore_opp at %08lx\n", m68k_getpc ());
! 646: fflush (stdout);
1.1 root 647: #endif
1.1.1.5 ! root 648: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 649: m68k_setpc (m68k_getpc () - 2);
650: op_illg (opcode);
651: return;
652: }
1.1.1.5 ! root 653: if (currprefs.cpu_level == 4) {
1.1.1.3 root 654: } else {
1.1.1.5 ! root 655: if (incr < 0) {
! 656: ad -= 4;
! 657: d = get_long (ad);
! 658: if ((d & 0xff000000) != 0) {
! 659: if ((d & 0x00ff0000) == 0x00180000)
! 660: ad -= 6 * 4;
! 661: else if ((d & 0x00ff0000) == 0x00380000)
! 662: ad -= 14 * 4;
! 663: else if ((d & 0x00ff0000) == 0x00b40000)
! 664: ad -= 45 * 4;
! 665: }
! 666: } else {
! 667: d = get_long (ad);
! 668: ad += 4;
! 669: if ((d & 0xff000000) != 0) {
! 670: if ((d & 0x00ff0000) == 0x00180000)
! 671: ad += 6 * 4;
! 672: else if ((d & 0x00ff0000) == 0x00380000)
! 673: ad += 14 * 4;
! 674: else if ((d & 0x00ff0000) == 0x00b40000)
! 675: ad += 45 * 4;
! 676: }
1.1.1.3 root 677: }
678: }
679: if ((opcode & 0x38) == 0x18)
680: m68k_areg (regs, opcode & 7) = ad;
681: if ((opcode & 0x38) == 0x20)
682: m68k_areg (regs, opcode & 7) = ad;
1.1 root 683: }
684:
1.1.1.5 ! root 685: void fpp_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 686: {
1.1.1.3 root 687: int reg;
688: double src;
1.1 root 689:
690: #if DEBUG_FPP
1.1.1.5 ! root 691: printf ("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, m68k_getpc () - 4);
! 692: fflush (stdout);
1.1 root 693: #endif
1.1.1.3 root 694: switch ((extra >> 13) & 0x7) {
695: case 3:
696: if (put_fp_value (regs.fp[(extra >> 7) & 7], opcode, extra) == 0) {
697: m68k_setpc (m68k_getpc () - 4);
698: op_illg (opcode);
699: }
700: return;
701: case 4:
702: case 5:
703: if ((opcode & 0x38) == 0) {
704: if (extra & 0x2000) {
705: if (extra & 0x1000)
706: m68k_dreg (regs, opcode & 7) = regs.fpcr;
707: if (extra & 0x0800)
708: m68k_dreg (regs, opcode & 7) = regs.fpsr;
709: if (extra & 0x0400)
710: m68k_dreg (regs, opcode & 7) = regs.fpiar;
711: } else {
712: if (extra & 0x1000)
713: regs.fpcr = m68k_dreg (regs, opcode & 7);
714: if (extra & 0x0800)
715: regs.fpsr = m68k_dreg (regs, opcode & 7);
716: if (extra & 0x0400)
717: regs.fpiar = m68k_dreg (regs, opcode & 7);
718: }
719: } else if ((opcode & 0x38) == 1) {
720: if (extra & 0x2000) {
721: if (extra & 0x1000)
722: m68k_areg (regs, opcode & 7) = regs.fpcr;
723: if (extra & 0x0800)
724: m68k_areg (regs, opcode & 7) = regs.fpsr;
725: if (extra & 0x0400)
726: m68k_areg (regs, opcode & 7) = regs.fpiar;
727: } else {
728: if (extra & 0x1000)
729: regs.fpcr = m68k_areg (regs, opcode & 7);
730: if (extra & 0x0800)
731: regs.fpsr = m68k_areg (regs, opcode & 7);
732: if (extra & 0x0400)
733: regs.fpiar = m68k_areg (regs, opcode & 7);
734: }
735: } else if ((opcode & 0x3f) == 0x3c) {
736: if ((extra & 0x2000) == 0) {
737: if (extra & 0x1000)
1.1.1.5 ! root 738: regs.fpcr = next_ilong ();
1.1.1.3 root 739: if (extra & 0x0800)
1.1.1.5 ! root 740: regs.fpsr = next_ilong ();
1.1.1.3 root 741: if (extra & 0x0400)
1.1.1.5 ! root 742: regs.fpiar = next_ilong ();
1.1.1.3 root 743: }
744: } else if (extra & 0x2000) {
745: /* FMOVEM FPP->memory */
746: uae_u32 ad;
747: int incr = 0;
748:
1.1.1.5 ! root 749: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 750: m68k_setpc (m68k_getpc () - 4);
751: op_illg (opcode);
1.1 root 752: return;
1.1.1.3 root 753: }
754: if ((opcode & 0x38) == 0x20) {
755: if (extra & 0x1000)
756: incr += 4;
757: if (extra & 0x0800)
758: incr += 4;
759: if (extra & 0x0400)
760: incr += 4;
761: }
762: ad -= incr;
763: if (extra & 0x1000) {
764: put_long (ad, regs.fpcr);
765: ad += 4;
766: }
767: if (extra & 0x0800) {
768: put_long (ad, regs.fpsr);
769: ad += 4;
770: }
771: if (extra & 0x0400) {
772: put_long (ad, regs.fpiar);
773: ad += 4;
774: }
775: ad -= incr;
776: if ((opcode & 0x38) == 0x18)
777: m68k_areg (regs, opcode & 7) = ad;
778: if ((opcode & 0x38) == 0x20)
779: m68k_areg (regs, opcode & 7) = ad;
780: } else {
781: /* FMOVEM memory->FPP */
782: uae_u32 ad;
783:
1.1.1.5 ! root 784: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 785: m68k_setpc (m68k_getpc () - 4);
786: op_illg (opcode);
1.1 root 787: return;
1.1.1.3 root 788: }
789: ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad;
790: if (extra & 0x1000) {
791: regs.fpcr = get_long (ad);
792: ad += 4;
793: }
794: if (extra & 0x0800) {
795: regs.fpsr = get_long (ad);
796: ad += 4;
797: }
798: if (extra & 0x0400) {
799: regs.fpiar = get_long (ad);
800: ad += 4;
801: }
802: if ((opcode & 0x38) == 0x18)
803: m68k_areg (regs, opcode & 7) = ad;
804: if ((opcode & 0x38) == 0x20)
805: m68k_areg (regs, opcode & 7) = ad - 12;
806: }
807: return;
808: case 6:
809: case 7:
810: {
811: uae_u32 ad, list = 0;
812: int incr = 0;
813: if (extra & 0x2000) {
814: /* FMOVEM FPP->memory */
1.1.1.5 ! root 815: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 816: m68k_setpc (m68k_getpc () - 4);
817: op_illg (opcode);
818: return;
819: }
820: switch ((extra >> 11) & 3) {
821: case 0: /* static pred */
822: list = extra & 0xff;
823: incr = -1;
824: break;
825: case 1: /* dynamic pred */
826: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
827: incr = -1;
828: break;
829: case 2: /* static postinc */
830: list = extra & 0xff;
831: incr = 1;
832: break;
833: case 3: /* dynamic postinc */
834: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
835: incr = 1;
836: break;
837: }
838: while (list) {
839: uae_u32 wrd1, wrd2, wrd3;
840: if (incr < 0) {
1.1.1.5 ! root 841: from_exten (regs.fp[fpp_movem_index2[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3 root 842: ad -= 4;
843: put_long (ad, wrd3);
844: ad -= 4;
845: put_long (ad, wrd2);
846: ad -= 4;
847: put_long (ad, wrd1);
848: } else {
1.1.1.5 ! root 849: from_exten (regs.fp[fpp_movem_index1[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3 root 850: put_long (ad, wrd1);
851: ad += 4;
852: put_long (ad, wrd2);
853: ad += 4;
854: put_long (ad, wrd3);
855: ad += 4;
1.1 root 856: }
1.1.1.3 root 857: list = fpp_movem_next[list];
858: }
859: if ((opcode & 0x38) == 0x18)
860: m68k_areg (regs, opcode & 7) = ad;
861: if ((opcode & 0x38) == 0x20)
862: m68k_areg (regs, opcode & 7) = ad;
863: } else {
864: /* FMOVEM memory->FPP */
1.1.1.5 ! root 865: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 866: m68k_setpc (m68k_getpc () - 4);
867: op_illg (opcode);
868: return;
869: }
870: switch ((extra >> 11) & 3) {
871: case 0: /* static pred */
872: list = extra & 0xff;
873: incr = -1;
874: break;
875: case 1: /* dynamic pred */
876: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
877: incr = -1;
878: break;
879: case 2: /* static postinc */
880: list = extra & 0xff;
881: incr = 1;
882: break;
883: case 3: /* dynamic postinc */
884: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
885: incr = 1;
886: break;
887: }
888: while (list) {
889: uae_u32 wrd1, wrd2, wrd3;
890: if (incr < 0) {
891: ad -= 4;
892: wrd3 = get_long (ad);
893: ad -= 4;
894: wrd2 = get_long (ad);
895: ad -= 4;
896: wrd1 = get_long (ad);
897: regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
898: } else {
899: wrd1 = get_long (ad);
900: ad += 4;
901: wrd2 = get_long (ad);
902: ad += 4;
903: wrd3 = get_long (ad);
904: ad += 4;
905: regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
1.1 root 906: }
1.1.1.3 root 907: list = fpp_movem_next[list];
1.1 root 908: }
1.1.1.3 root 909: if ((opcode & 0x38) == 0x18)
910: m68k_areg (regs, opcode & 7) = ad;
911: if ((opcode & 0x38) == 0x20)
912: m68k_areg (regs, opcode & 7) = ad;
913: }
914: }
915: return;
916: case 0:
917: case 2:
918: reg = (extra >> 7) & 7;
919: if ((extra & 0xfc00) == 0x5c00) {
920: switch (extra & 0x7f) {
921: case 0x00:
1.1.1.5 ! root 922: regs.fp[reg] = 4.0 * atan (1.0);
1.1.1.3 root 923: break;
924: case 0x0b:
925: regs.fp[reg] = log10 (2.0);
926: break;
927: case 0x0c:
928: regs.fp[reg] = exp (1.0);
929: break;
930: case 0x0d:
931: regs.fp[reg] = log (exp (1.0)) / log (2.0);
932: break;
933: case 0x0e:
934: regs.fp[reg] = log (exp (1.0)) / log (10.0);
935: break;
936: case 0x0f:
937: regs.fp[reg] = 0.0;
938: break;
939: case 0x30:
940: regs.fp[reg] = log (2.0);
941: break;
942: case 0x31:
943: regs.fp[reg] = log (10.0);
944: break;
945: case 0x32:
946: regs.fp[reg] = 1.0e0;
947: break;
948: case 0x33:
949: regs.fp[reg] = 1.0e1;
950: break;
951: case 0x34:
952: regs.fp[reg] = 1.0e2;
953: break;
954: case 0x35:
955: regs.fp[reg] = 1.0e4;
956: break;
957: case 0x36:
958: regs.fp[reg] = 1.0e8;
959: break;
960: case 0x37:
961: regs.fp[reg] = 1.0e16;
962: break;
963: case 0x38:
964: regs.fp[reg] = 1.0e32;
965: break;
966: case 0x39:
967: regs.fp[reg] = 1.0e64;
968: break;
969: case 0x3a:
970: regs.fp[reg] = 1.0e128;
971: break;
972: case 0x3b:
973: regs.fp[reg] = 1.0e256;
974: break;
1.1 root 975: #if 0
1.1.1.3 root 976: case 0x3c:
977: regs.fp[reg] = 1.0e512;
978: break;
979: case 0x3d:
980: regs.fp[reg] = 1.0e1024;
981: break;
982: case 0x3e:
983: regs.fp[reg] = 1.0e2048;
984: break;
985: case 0x3f:
986: regs.fp[reg] = 1.0e4096;
987: break;
1.1 root 988: #endif
1.1.1.3 root 989: default:
990: m68k_setpc (m68k_getpc () - 4);
991: op_illg (opcode);
992: break;
993: }
994: return;
995: }
996: if (get_fp_value (opcode, extra, &src) == 0) {
997: m68k_setpc (m68k_getpc () - 4);
998: op_illg (opcode);
999: return;
1000: }
1001: switch (extra & 0x7f) {
1002: case 0x00: /* FMOVE */
1003: regs.fp[reg] = src;
1.1.1.5 ! root 1004: /* Brian King was here. <ea> to register needs FPSR updated.
! 1005: * See page 3-73 in Motorola 68K programmers reference manual.
! 1006: * %%%FPU */
! 1007: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1008: break;
1.1.1.4 root 1009: case 0x01: /* FINT */
1.1.1.5 ! root 1010: /* need to take the current rounding mode into account */
! 1011: switch ((regs.fpcr >> 4) & 0x3) {
1.1.1.4 root 1012: case 0:
1.1.1.5 ! root 1013: regs.fp[reg] = (int) (src + 0.5);
! 1014: break;
1.1.1.4 root 1015: case 1:
1.1.1.5 ! root 1016: regs.fp[reg] = (int) src;
! 1017: break;
1.1.1.4 root 1018: case 2:
1.1.1.5 ! root 1019: regs.fp[reg] = floor (src);
! 1020: break;
1.1.1.4 root 1021: case 3:
1.1.1.5 ! root 1022: regs.fp[reg] = ceil (src);
! 1023: break;
! 1024: }
1.1.1.4 root 1025: break;
1.1.1.3 root 1026: case 0x02: /* FSINH */
1027: regs.fp[reg] = sinh (src);
1.1.1.5 ! root 1028: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1029: break;
1030: case 0x03: /* FINTRZ */
1031: regs.fp[reg] = (int) src;
1.1.1.5 ! root 1032: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1033: break;
1034: case 0x04: /* FSQRT */
1035: regs.fp[reg] = sqrt (src);
1.1.1.5 ! root 1036: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1037: break;
1038: case 0x06: /* FLOGNP1 */
1039: regs.fp[reg] = log (src + 1.0);
1.1.1.5 ! root 1040: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1041: break;
1042: case 0x08: /* FETOXM1 */
1043: regs.fp[reg] = exp (src) - 1.0;
1.1.1.5 ! root 1044: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1045: break;
1046: case 0x09: /* FTANH */
1047: regs.fp[reg] = tanh (src);
1.1.1.5 ! root 1048: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1049: break;
1050: case 0x0a: /* FATAN */
1051: regs.fp[reg] = atan (src);
1.1.1.5 ! root 1052: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1053: break;
1054: case 0x0c: /* FASIN */
1055: regs.fp[reg] = asin (src);
1.1.1.5 ! root 1056: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1057: break;
1058: case 0x0d: /* FATANH */
1059: #if 1 /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */
1060: regs.fp[reg] = log ((1 + src) / (1 - src)) / 2;
1.1 root 1061: #else
1.1.1.3 root 1062: regs.fp[reg] = atanh (src);
1.1 root 1063: #endif
1.1.1.5 ! root 1064: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1065: break;
1066: case 0x0e: /* FSIN */
1067: regs.fp[reg] = sin (src);
1.1.1.5 ! root 1068: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1069: break;
1070: case 0x0f: /* FTAN */
1071: regs.fp[reg] = tan (src);
1.1.1.5 ! root 1072: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1073: break;
1074: case 0x10: /* FETOX */
1075: regs.fp[reg] = exp (src);
1.1.1.5 ! root 1076: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1077: break;
1078: case 0x11: /* FTWOTOX */
1.1.1.5 ! root 1079: regs.fp[reg] = pow (2.0, src);
! 1080: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1081: break;
1082: case 0x12: /* FTENTOX */
1.1.1.5 ! root 1083: regs.fp[reg] = pow (10.0, src);
! 1084: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1085: break;
1086: case 0x14: /* FLOGN */
1087: regs.fp[reg] = log (src);
1.1.1.5 ! root 1088: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1089: break;
1090: case 0x15: /* FLOG10 */
1091: regs.fp[reg] = log10 (src);
1.1.1.5 ! root 1092: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1093: break;
1094: case 0x16: /* FLOG2 */
1095: regs.fp[reg] = log (src) / log (2.0);
1.1.1.5 ! root 1096: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1097: break;
1098: case 0x18: /* FABS */
1099: regs.fp[reg] = src < 0 ? -src : src;
1.1.1.5 ! root 1100: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1101: break;
1102: case 0x19: /* FCOSH */
1.1.1.5 ! root 1103: regs.fp[reg] = cosh (src);
! 1104: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1105: break;
1106: case 0x1a: /* FNEG */
1107: regs.fp[reg] = -src;
1.1.1.5 ! root 1108: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1109: break;
1110: case 0x1c: /* FACOS */
1.1.1.5 ! root 1111: regs.fp[reg] = acos (src);
! 1112: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1113: break;
1114: case 0x1d: /* FCOS */
1.1.1.5 ! root 1115: regs.fp[reg] = cos (src);
! 1116: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1117: break;
1118: case 0x1e: /* FGETEXP */
1119: {
1120: int expon;
1121: frexp (src, &expon);
1122: regs.fp[reg] = (double) (expon - 1);
1.1.1.5 ! root 1123: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1124: }
1125: break;
1126: case 0x1f: /* FGETMAN */
1127: {
1128: int expon;
1129: regs.fp[reg] = frexp (src, &expon) * 2.0;
1.1.1.5 ! root 1130: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1131: }
1132: break;
1133: case 0x20: /* FDIV */
1134: regs.fp[reg] /= src;
1.1.1.5 ! root 1135: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1136: break;
1137: case 0x21: /* FMOD */
1.1.1.5 ! root 1138: regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src)) * src;
! 1139: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1140: break;
1141: case 0x22: /* FADD */
1142: regs.fp[reg] += src;
1.1.1.5 ! root 1143: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1144: break;
1145: case 0x23: /* FMUL */
1146: regs.fp[reg] *= src;
1.1.1.5 ! root 1147: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1148: break;
1149: case 0x24: /* FSGLDIV */
1150: regs.fp[reg] /= src;
1.1.1.5 ! root 1151: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1152: break;
1153: case 0x25: /* FREM */
1.1.1.5 ! root 1154: regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src + 0.5)) * src;
! 1155: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1156: break;
1157: case 0x26: /* FSCALE */
1158: regs.fp[reg] *= exp (log (2.0) * src);
1.1.1.5 ! root 1159: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1160: break;
1161: case 0x27: /* FSGLMUL */
1162: regs.fp[reg] *= src;
1.1.1.5 ! root 1163: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1164: break;
1165: case 0x28: /* FSUB */
1166: regs.fp[reg] -= src;
1.1.1.5 ! root 1167: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1168: break;
1169: case 0x30: /* FSINCOS */
1170: case 0x31:
1171: case 0x32:
1172: case 0x33:
1173: case 0x34:
1174: case 0x35:
1175: case 0x36:
1176: case 0x37:
1177: regs.fp[reg] = sin (src);
1.1.1.5 ! root 1178: regs.fp[extra & 7] = cos (src);
! 1179: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1180: break;
1181: case 0x38: /* FCMP */
1182: {
1183: double tmp = regs.fp[reg] - src;
1.1.1.5 ! root 1184: regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
1.1.1.3 root 1185: }
1186: break;
1187: case 0x3a: /* FTST */
1.1.1.5 ! root 1188: regs.fpsr = (src == 0 ? 0x4000000 : 0) | (src < 0 ? 0x8000000 : 0);
1.1.1.3 root 1189: break;
1190: default:
1191: m68k_setpc (m68k_getpc () - 4);
1192: op_illg (opcode);
1193: break;
1194: }
1195: return;
1196: }
1197: m68k_setpc (m68k_getpc () - 4);
1198: op_illg (opcode);
1.1 root 1199: }
1200:
1201: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.