|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation
5: *
6: * (c) 1995 Bernd Schmidt
7: *
8: */
9: #include <stdio.h>
10: #include <assert.h>
11: #include <string.h>
12: #include <stdlib.h>
13:
14: #include "config.h"
15: #include "amiga.h"
16: #include "options.h"
17: #include "events.h"
18: #include "memory.h"
19: #include "custom.h"
20: #include "newcpu.h"
21: #include "ersatz.h"
22:
23: #undef COUNT_INSTRS
24:
25: #ifdef COUNT_INSTRS
26: static unsigned long int instrcount[65536];
27: static UWORD opcodenums[65536];
28:
29: int compfn(const void *el1, const void *el2)
30: {
31: return instrcount[*(const UWORD *)el1] < instrcount[*(const UWORD *)el2];
32: }
33:
34: void dump_counts(void)
35: {
36: FILE *f = fopen("insncount", "w");
37: unsigned long int total = 0;
38: int i;
39:
40: for(i=0; i < 65536; i++) {
41: opcodenums[i] = i;
42: total += instrcount[i];
43: }
44: qsort(opcodenums, 65536, sizeof(UWORD), compfn);
45:
46: fprintf(f, "Total: %ld\n", total);
47: for(i=0; i < 65536; i++) {
48: unsigned long int cnt = instrcount[opcodenums[i]];
49: if (!cnt)
50: break;
51: fprintf(f, "%04x: %ld\n", opcodenums[i], cnt);
52: }
53: fclose(f);
54: }
55: #endif
56:
57: bool broken_in;
58:
59: #ifdef DUALCPU
60: bool allowmem;
61: bool customacc;
62: #endif
63:
64: typedef enum {
65: Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r,
66: absw, absl, PC16, PC8r, imm, imm3, ill2, ill3
67: } amodes;
68:
69: typedef struct {
70: amodes mode;
71: UBYTE reg;
72: } addr_mode;
73:
74: static void set_addr_mode(addr_mode *a, int mode, int reg)
75: {
76: a->mode = mode == 7 ? (amodes)((int)absw + reg) : (amodes)mode;
77: a->reg = reg;
78: }
79:
80: typedef enum {
81: RegD, RegA, Addr, EAIM
82: } eatypes;
83:
84: typedef struct {
85: ULONG addr;
86: eatypes type;
87: ULONG szmask;
88: } effadr;
89:
90: typedef struct {
91: addr_mode src,dest;
92: ULONG mask;
93: UWORD clogs;
94: } instr_params;
95:
96: typedef void instr_result;
97: typedef instr_result (*instr_func)(const instr_params);
98:
99: typedef struct {
100: instr_func execfunc;
101: instr_params params;
102: } I_dec_tab_entry;
103:
104: static I_dec_tab_entry instr_dectab[65536];
105:
106: static void GenerateDecTab(void);
107:
108: void MC68000_init(void)
109: {
110: #ifdef COUNT_INSTRS
111: int i;
112: for(i=0;i<65536;i++) {
113: instrcount[i] = 0;
114: }
115: #endif
116: GenerateDecTab();
117: }
118:
119: struct regstruct regs;
120:
121: static ULONG sizemask(const int sz)
122: {
123: switch(sz){
124: case 0: return 0xff;
125: case 1: return 0xffff;
126: case 2: return 0xffffffff;
127: default: abort();
128: }
129: }
130:
131: static __inline__ int mask2shift(const ULONG mask)
132: {
133: if (mask == 0xff) return 7;
134: if (mask == 0xffff) return 15;
135: return 31;
136: }
137:
138: static __inline__ int mask2len(const ULONG mask)
139: {
140: if (mask == 0xff) return 1;
141: if (mask == 0xffff) return 2;
142: return 4;
143: }
144:
145: static __inline__ ULONG ExtendWord(const ULONG v)
146: {
147: return (LONG)(WORD)(v);
148: }
149:
150: static __inline__ ULONG ExtendByte(const ULONG v)
151: {
152: return (LONG)(BYTE)(v);
153: }
154:
155: static __inline__ ULONG Extend(const ULONG v,const ULONG mask)
156: {
157: switch(mask){
158: case 0xff:
159: return (LONG)(BYTE)v;
160: case 0xffff:
161: return (LONG)(WORD)v;
162: default:
163: return v;
164: }
165: }
166:
167: static effadr GetEA(const addr_mode a, const ULONG mask)
168: {
169: effadr ea;
170: UWORD dp;
171: BYTE disp8;
172: int r;
173: ULONG dispreg;
174:
175: ea.szmask = mask;
176: switch(a.mode){
177: case Dreg:
178: ea.addr = a.reg; ea.type = RegD; break;
179: case Areg:
180: ea.addr = a.reg; ea.type = RegA; break;
181: case Aind:
182: ea.addr = regs.a[a.reg]; ea.type = Addr; break;
183: case Aipi:
184: ea.addr = regs.a[a.reg];
185: if (a.reg == 7 && mask == 0xff) {
186: regs.a[a.reg] += 2;
187: } else {
188: regs.a[a.reg] += mask2len(mask);
189: }
190: ea.type = Addr; break;
191: case Apdi:
192: if (a.reg == 7 && mask == 0xff) {
193: ea.addr = regs.a[a.reg] -= 2;
194: } else {
195: ea.addr = regs.a[a.reg] -= mask2len(mask);
196: }
197: ea.type = Addr; break;
198: case Ad16:
199: ea.addr = regs.a[a.reg] + (WORD)nextiword();
200: ea.type = Addr; break;
201: case Ad8r:
202: dp = nextiword();
203: disp8 = dp & 0xFF;
204: r = (dp & 0x7000) >> 12;
205: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
206:
207: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
208: ea.addr = regs.a[a.reg] + disp8 + dispreg;
209: ea.type = Addr; break;
210: case PC16:
211: ea.addr = m68k_getpc();
212: ea.addr += (WORD)nextiword();
213: ea.type = Addr; break;
214: case PC8r:
215: ea.addr = m68k_getpc();
216: dp = nextiword();
217: disp8 = dp & 0xFF;
218: r = (dp & 0x7000) >> 12;
219: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
220:
221: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
222: ea.addr += disp8 + dispreg;
223: ea.type = Addr; break;
224: case absw:
225: ea.type = Addr;
226: ea.addr = (LONG)(WORD)nextiword();
227: break;
228: case absl:
229: ea.type = Addr;
230: ea.addr = nextilong();
231: break;
232: case imm:
233: switch(mask){
234: case 0xff:
235: ea.addr = ExtendByte(nextiword()); ea.type = EAIM; break;
236: case 0xffff:
237: ea.addr = ExtendWord(nextiword()); ea.type = EAIM; break;
238: case 0xffffffff:
239: ea.addr = nextilong(); ea.type = EAIM; break;
240: }
241: break;
242: case imm3:
243: ea.addr = a.reg; ea.type = EAIM; break;
244: default:
245: abort();
246: }
247: return ea;
248: }
249:
250: static effadr MGetEA(const addr_mode a, const ULONG mask)
251: {
252: effadr ea;
253: UWORD dp;
254: BYTE disp8;
255: int r;
256: ULONG dispreg;
257:
258: ea.szmask = mask;
259: switch(a.mode){
260: case Aind: case Aipi: case Apdi:
261: ea.addr = regs.a[a.reg]; ea.type = Addr; break;
262: case Ad16:
263: ea.addr = regs.a[a.reg] + (WORD)nextiword();
264: ea.type = Addr; break;
265: case Ad8r:
266: dp = nextiword();
267: disp8 = dp & 0xFF;
268: r = (dp & 0x7000) >> 12;
269: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
270:
271: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
272: ea.addr = regs.a[a.reg] + disp8 + dispreg;
273: ea.type = Addr; break;
274: case PC16:
275: ea.addr = m68k_getpc();
276: ea.addr += (WORD)nextiword();
277: ea.type = Addr; break;
278: case PC8r:
279: ea.addr = m68k_getpc();
280: dp = nextiword();
281: disp8 = dp & 0xFF;
282: r = (dp & 0x7000) >> 12;
283: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
284:
285: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
286: ea.addr += disp8 + dispreg;
287: ea.type = Addr; break;
288: case absw:
289: ea.type = Addr;
290: ea.addr = (LONG)(WORD)nextiword();
291: break;
292: case absl:
293: ea.type = Addr;
294: ea.addr = nextilong();
295: break;
296: default:
297: abort();
298: }
299: return ea;
300: }
301:
302: static void MCompleteEAFromRL(effadr *ea, const addr_mode a, ULONG mask, UWORD bitmask)
303: {
304: int bitcnt = 0;
305: int i;
306: for(i=0;i<16;i++) {
307: bitcnt += bitmask & 1;
308: bitmask >>= 1;
309: }
310: switch(a.mode){
311: case Aipi:
312: abort(); break;
313: case Apdi:
314: ea->addr = regs.a[a.reg] -= bitcnt * mask2len(mask); break;
315: default: break;
316: }
317: }
318:
319: static void MCompleteEAToRL(effadr ea, const addr_mode a)
320: {
321: switch(a.mode){
322: case Aipi:
323: regs.a[a.reg] = ea.addr; break;
324: case Apdi:
325: abort(); break;
326: default: break;
327: }
328: }
329:
330: static ULONG RetrieveEA(const effadr ea)
331: {
332: switch(ea.type){
333: case Addr:
334: return ea.addr;
335: default:
336: abort();
337: }
338: }
339:
340: static ULONG GetFromEA(const effadr ea)
341: {
342: switch(ea.type) {
343: case RegD:
344: return Extend(regs.d[ea.addr],ea.szmask);
345: case RegA:
346: return Extend(regs.a[ea.addr],ea.szmask);
347: case Addr:
348: switch(ea.szmask){
349: case 0xff:
350: return ExtendByte(get_byte(ea.addr));
351: case 0xffff:
352: return ExtendWord(get_word(ea.addr));
353: case 0xffffffff:
354: return get_long(ea.addr);
355: default:
356: abort();
357: }
358: case EAIM:
359: return ea.addr;
360: }
361: return 0; /* Nnnnnnngghhh! */
362: }
363:
364: static void StoreToEA(const effadr ea, const ULONG value)
365: {
366: switch(ea.type){
367: case RegD:
368: regs.d[ea.addr] &= ~ea.szmask; regs.d[ea.addr] |= (value & ea.szmask);
369: break;
370: case RegA:
371: regs.a[ea.addr] = value;
372: break;
373: case Addr:
374: switch(ea.szmask){
375: case 0xff:
376: put_byte(ea.addr,value);
377: break;
378: case 0xffff:
379: put_word(ea.addr,value);
380: break;
381: case 0xffffffff:
382: put_long(ea.addr,value);
383: break;
384: default:
385: abort();
386: }
387: break;
388: default:
389: abort();
390: }
391: }
392:
393: static effadr ShowEA(addr_mode a,ULONG mask)
394: {
395: effadr ea;
396: UWORD dp;
397: BYTE disp8;
398: WORD disp16;
399: int r;
400: ULONG dispreg;
401:
402: ea.szmask = mask;
403: switch(a.mode){
404: case Dreg:
405: ea.addr = a.reg; ea.type = RegD;
406: printf("D%d", (int)a.reg);
407: break;
408: case Areg:
409: ea.addr = a.reg; ea.type = RegA;
410: printf("A%d", (int)a.reg);
411: break;
412: case Aind:
413: ea.addr = regs.a[a.reg]; ea.type = Addr;
414: printf("(A%d)", (int)a.reg);
415: break;
416: case Aipi:
417: ea.addr = regs.a[a.reg];
418: ea.type = Addr;
419: printf("(A%d)+", (int)a.reg);
420: break;
421: case Apdi:
422: ea.addr = regs.a[a.reg] - mask2len(mask); ea.type = Addr;
423: printf("-(A%d)", (int)a.reg);
424: break;
425: case Ad16:
426: disp16 = nextiword();
427: ea.addr = regs.a[a.reg] + (WORD)disp16;
428: ea.type = Addr;
429: printf("(A%d,$%08lx) == $%08lx", (int)a.reg, disp16, ea.addr);
430: break;
431: case Ad8r:
432: dp = nextiword();
433: disp8 = dp & 0xFF;
434: r = (dp & 0x7000) >> 12;
435: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
436:
437: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
438: ea.addr = regs.a[a.reg] + disp8 + dispreg;
439: ea.type = Addr;
440: printf("(A%d, %c%d.%c, $%02x) == $%08lx", (int)a.reg,
441: dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', disp8,
442: ea.addr);
443: break;
444: case PC16:
445: ea.addr = m68k_getpc();
446: disp16 = nextiword();
447: ea.addr += (WORD)disp16;
448: ea.type = Addr;
449: printf("(PC,$%08lx) == $%08lx", disp16, ea.addr);
450: break;
451: case PC8r:
452: ea.addr = m68k_getpc();
453: dp = nextiword();
454: disp8 = dp & 0xFF;
455: r = (dp & 0x7000) >> 12;
456: dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
457:
458: if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
459: ea.addr += disp8 + dispreg;
460: ea.type = Addr;
461: printf("(PC, %c%d.%c, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D',
462: (int)r, dp & 0x800 ? 'L' : 'W', disp8, ea.addr);
463: break;
464: case absw:
465: ea.type = Addr;
466: ea.addr = (LONG)(WORD)nextiword();
467: printf("$%08lx", ea.addr);
468: break;
469: case absl:
470: ea.type = Addr;
471: ea.addr = nextilong();
472: printf("$%08lx", ea.addr);
473: break;
474: case imm:
475: switch(mask){
476: case 0xff:
477: ea.addr = nextiword() & 0xff; ea.type = EAIM; break;
478: case 0xffff:
479: ea.addr = nextiword(); ea.type = EAIM; break;
480: case 0xffffffff:
481: ea.addr = nextilong(); ea.type = EAIM; break;
482: }
483: printf("#$%08lx", ea.addr);
484: break;
485: case imm3:
486: ea.addr = a.reg; ea.type = EAIM;
487: printf("#$%08lx", ea.addr);
488: break;
489: default:
490: abort();
491: }
492: return ea;
493: }
494:
495: static void SuperState(void)
496: {
497: if (!regs.s){
498: CPTR temp = regs.usp;
499: regs.s = 1;
500: regs.t = 0;
501: regs.usp = regs.a[7];
502: regs.a[7] = temp;
503: }
504: }
505:
506: static void UserState(void)
507: {
508: if (regs.s){
509: CPTR temp = regs.usp;
510: regs.s = 0;
511: /* regs.t = 0; */
512: regs.usp = regs.a[7];
513: regs.a[7] = temp;
514: }
515: }
516:
517: void MakeSR(void)
518: {
519: assert((regs.n & 1) == regs.n);
520: assert((regs.s & 1) == regs.s);
521: assert((regs.x & 1) == regs.x);
522: assert((regs.c & 1) == regs.c);
523: assert((regs.v & 1) == regs.v);
524: assert((regs.z & 1) == regs.z);
525: regs.sr = ((regs.t << 15) | (regs.s << 13) | (regs.intmask << 8)
526: | (regs.x << 4) | (regs.n << 3) | (regs.z << 2) | (regs.v << 1)
527: | regs.c);
528: }
529:
530: void MakeFromSR(void)
531: {
532: int olds = regs.s;
533:
534: regs.t = (regs.sr >> 15) & 1;
535: regs.s = (regs.sr >> 13) & 1;
536: regs.intmask = (regs.sr >> 8) & 7;
537: regs.x = (regs.sr >> 4) & 1;
538: regs.n = (regs.sr >> 3) & 1;
539: regs.z = (regs.sr >> 2) & 1;
540: regs.v = (regs.sr >> 1) & 1;
541: regs.c = regs.sr & 1;
542: if (olds != regs.s) {
543: regs.s = olds;
544: if (regs.s) UserState(); else SuperState();
545: }
546: specialflags |= SPCFLAG_INT;
547: if (regs.t)
548: specialflags |= SPCFLAG_TRACE;
549: else
550: specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
551: }
552:
553: void Exception(int nr)
554: {
555: addr_mode pda7 = { Apdi, 7 };
556: effadr lea;
557: effadr wea;
558:
559: MakeSR();
560: SuperState();
561: lea = GetEA(pda7,0xffffffff);
562: wea = GetEA(pda7,0xffff);
563: StoreToEA(wea,regs.sr);
564: StoreToEA(lea,m68k_getpc());
565: m68k_setpc(get_long(4*nr));
566: regs.t = 0;
567: specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
568: }
569:
570: static void Interrupt(int nr)
571: {
572: assert(nr < 8 && nr >= 0);
573: Exception(nr+24);
574:
575: regs.intmask = nr;
576: specialflags |= SPCFLAG_INT;
577: }
578:
579: /*
580: * instruction emulations
581: */
582:
583: static instr_result INST_ILLG(const instr_params p)
584: {
585: m68k_setpc(m68k_getpc()-2);
586:
587: Exception(4);
588: }
589:
590: static instr_result INST_NIMP(const instr_params p)
591: {
592: INST_ILLG(p);
593: }
594:
595: static instr_result INST_OR(const instr_params p)
596: {
597: effadr src = GetEA(p.src, p.mask);
598: ULONG srcv = GetFromEA(src);
599: effadr dst = GetEA(p.dest, p.mask);
600: ULONG dstv = GetFromEA(dst);
601: dstv |= srcv;
602: setflags_logical(dstv, p.mask);
603: StoreToEA(dst,dstv);
604: }
605:
606: static instr_result INST_AND(const instr_params p)
607: {
608: effadr src = GetEA(p.src, p.mask);
609: ULONG srcv = GetFromEA(src);
610: effadr dst = GetEA(p.dest, p.mask);
611: ULONG dstv = GetFromEA(dst);
612: dstv &= srcv;
613: setflags_logical(dstv, p.mask);
614: StoreToEA(dst,dstv);
615: }
616:
617: static instr_result INST_EOR(const instr_params p)
618: {
619: effadr src = GetEA(p.src, p.mask);
620: ULONG srcv = GetFromEA(src);
621: effadr dst = GetEA(p.dest, p.mask);
622: ULONG dstv = GetFromEA(dst);
623: dstv ^= srcv;
624: setflags_logical(dstv, p.mask);
625: StoreToEA(dst,dstv);
626: }
627:
628: static instr_result INST_CMP(const instr_params p)
629: {
630: effadr src = GetEA(p.src, p.mask);
631: ULONG srcv = GetFromEA(src);
632: effadr dst = GetEA(p.dest, p.mask);
633: ULONG dstv = GetFromEA(dst);
634: ULONG newv = dstv - srcv;
635: setflags_cmp(srcv, dstv, newv, p.mask);
636: }
637:
638: static instr_result INST_ADD(const instr_params p)
639: {
640: effadr src = GetEA(p.src, p.mask);
641: ULONG srcv = GetFromEA(src);
642: effadr dst = GetEA(p.dest, p.mask);
643: ULONG dstv = GetFromEA(dst);
644: ULONG newv = dstv + srcv;
645: setflags_add(srcv, dstv, newv, p.mask);
646: StoreToEA(dst,newv);
647: }
648:
649: static instr_result INST_SUB(const instr_params p)
650: {
651: effadr src = GetEA(p.src, p.mask);
652: ULONG srcv = GetFromEA(src);
653: effadr dst = GetEA(p.dest, p.mask);
654: ULONG dstv = GetFromEA(dst);
655: ULONG newv = dstv - srcv;
656: setflags_sub(srcv, dstv, newv, p.mask);
657: StoreToEA(dst,newv);
658: }
659:
660: static instr_result INST_ADDX(const instr_params p)
661: {
662: effadr src = GetEA(p.src, p.mask);
663: ULONG srcv = GetFromEA(src);
664: effadr dst = GetEA(p.dest, p.mask);
665: ULONG dstv = GetFromEA(dst);
666: ULONG newv = dstv + srcv + regs.x;
667: setflags_addx(srcv, dstv, newv, p.mask);
668: StoreToEA(dst,newv);
669: }
670:
671: static instr_result INST_SUBX(const instr_params p)
672: {
673: effadr src = GetEA(p.src, p.mask);
674: ULONG srcv = GetFromEA(src);
675: effadr dst = GetEA(p.dest, p.mask);
676: ULONG dstv = GetFromEA(dst);
677: ULONG newv = dstv - srcv - regs.x;
678: setflags_subx(srcv, dstv, newv, p.mask);
679: StoreToEA(dst,newv);
680: }
681:
682: static instr_result INST_ADDA(const instr_params p)
683: {
684: effadr src = GetEA(p.src, p.mask);
685: ULONG srcv = GetFromEA(src);
686: effadr dst = GetEA(p.dest, 0xffffffff);
687: ULONG dstv = GetFromEA(dst);
688: StoreToEA(dst,dstv + srcv);
689: }
690:
691: static instr_result INST_SUBA(const instr_params p)
692: {
693: effadr src = GetEA(p.src, p.mask);
694: ULONG srcv = GetFromEA(src);
695: effadr dst = GetEA(p.dest, 0xffffffff);
696: ULONG dstv = GetFromEA(dst);
697: StoreToEA(dst,dstv - srcv);
698: }
699:
700: static instr_result INST_CMPA(const instr_params p)
701: {
702: effadr src = GetEA(p.src, p.mask);
703: ULONG srcv = GetFromEA(src);
704: effadr dst = GetEA(p.dest, 0xffffffff);
705: ULONG dstv = GetFromEA(dst);
706: ULONG newv = dstv - srcv;
707: setflags_cmp(srcv, dstv, newv, 0xffffffff);
708: }
709:
710: static instr_result INST_CHK(const instr_params p)
711: {
712: fprintf(stderr, "CHK occurred\n");
713: INST_ILLG(p);
714: }
715:
716: static instr_result INST_EXGL(const instr_params p)
717: {
718: effadr src = GetEA(p.src, p.mask);
719: ULONG srcv = GetFromEA(src);
720: effadr dst = GetEA(p.dest, p.mask);
721: ULONG dstv = GetFromEA(dst);
722: StoreToEA(dst,srcv);
723: StoreToEA(src,dstv);
724: }
725:
726: static instr_result INST_LEA(const instr_params p)
727: {
728: effadr src = GetEA(p.src, p.mask);
729: effadr dst = GetEA(p.dest, p.mask);
730: StoreToEA(dst,RetrieveEA(src));
731: }
732:
733: static instr_result INST_MOVE(const instr_params p)
734: {
735: effadr src = GetEA(p.src, p.mask);
736: ULONG srcv = GetFromEA(src);
737: effadr dst = GetEA(p.dest, p.mask);
738: setflags_logical(srcv,p.mask);
739: StoreToEA(dst,srcv);
740: }
741:
742: static instr_result INST_MOVEQ(const instr_params p)
743: {
744: effadr src = GetEA(p.src, p.mask);
745: effadr dst = GetEA(p.dest, p.mask);
746: ULONG srcv = ExtendByte(GetFromEA(src));
747: setflags_logical(srcv,p.mask);
748: StoreToEA(dst,srcv);
749: }
750:
751: static instr_result INST_MOVEA(const instr_params p)
752: {
753: effadr src = GetEA(p.src, p.mask);
754: ULONG srcv = GetFromEA(src);
755: effadr dst = GetEA(p.dest, p.mask);
756: StoreToEA(dst,srcv);
757: }
758:
759: static instr_result INST_BTST(const instr_params p)
760: {
761: effadr src = GetEA(p.src, p.mask);
762: ULONG srcv = GetFromEA(src);
763: effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
764: ULONG dstv = GetFromEA(dst);
765: if (p.dest.mode == Dreg) {
766: srcv &= 31;
767: } else {
768: srcv &= 7;
769: }
770: regs.z = !(dstv & (1 << srcv));
771: }
772:
773: static instr_result INST_BCLR(const instr_params p)
774: {
775: effadr src = GetEA(p.src, p.mask);
776: ULONG srcv = GetFromEA(src);
777: effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
778: ULONG dstv = GetFromEA(dst);
779: if (p.dest.mode == Dreg) {
780: srcv &= 31;
781: } else {
782: srcv &= 7;
783: }
784: regs.z = !(dstv & (1 << srcv));
785: StoreToEA(dst,dstv & ~(1 << srcv));
786: }
787:
788: static instr_result INST_BSET(const instr_params p)
789: {
790: effadr src = GetEA(p.src, p.mask);
791: ULONG srcv = GetFromEA(src);
792: effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
793: ULONG dstv = GetFromEA(dst);
794: if (p.dest.mode == Dreg) {
795: srcv &= 31;
796: } else {
797: srcv &= 7;
798: }
799: regs.z = !(dstv & (1 << srcv));
800: StoreToEA(dst,dstv | (1 << srcv));
801: }
802:
803: static instr_result INST_BCHG(const instr_params p)
804: {
805: effadr src = GetEA(p.src, p.mask);
806: ULONG srcv = GetFromEA(src);
807: effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
808: ULONG dstv = GetFromEA(dst);
809: if (p.dest.mode == Dreg) {
810: srcv &= 31;
811: } else {
812: srcv &= 7;
813: }
814: regs.z = !(dstv & (1 << srcv));
815: StoreToEA(dst,dstv ^ (1 << srcv));
816: }
817:
818: static instr_result INST_NEG(const instr_params p)
819: {
820: effadr ea = GetEA(p.src, p.mask);
821: ULONG val = GetFromEA(ea);
822: ULONG newv = -val;
823: setflags_sub(val, 0, newv, p.mask);
824: StoreToEA(ea,newv);
825: }
826:
827: static instr_result INST_NEGX(const instr_params p)
828: {
829: effadr ea = GetEA(p.src, p.mask);
830: ULONG val = GetFromEA(ea);
831: ULONG newv = -val-regs.x;
832: setflags_sub(val, 0, newv, p.mask);
833: StoreToEA(ea,newv);
834: }
835:
836: static instr_result INST_NOT(const instr_params p)
837: {
838: effadr ea = GetEA(p.src, p.mask);
839: ULONG val = GetFromEA(ea);
840: ULONG newv = ~val;
841: setflags_logical(newv,p.mask);
842: StoreToEA(ea,newv);
843: }
844:
845: static instr_result INST_CLR(const instr_params p)
846: {
847: effadr ea = GetEA(p.src, p.mask);
848: ULONG newv = 0;
849: setflags_logical(newv,p.mask);
850: StoreToEA(ea,newv);
851: }
852:
853: static instr_result INST_TST(const instr_params p)
854: {
855: effadr ea = GetEA(p.src, p.mask);
856: ULONG val = GetFromEA(ea);
857: setflags_logical(val,p.mask);
858: }
859:
860: static instr_result INST_SWAP(const instr_params p)
861: {
862: effadr ea = GetEA(p.src, p.mask);
863: ULONG val = GetFromEA(ea);
864: val = (val >> 16) | (val << 16);
865: StoreToEA(ea, val);
866: setflags_logical(val,p.mask);
867: }
868:
869: static instr_result INST_EXTW(const instr_params p)
870: {
871: effadr ea = GetEA(p.src, p.mask);
872: ULONG val = ExtendByte(GetFromEA(ea));
873: setflags_logical(val,p.mask);
874: StoreToEA(ea, val);
875: }
876:
877: static instr_result INST_EXTL(const instr_params p)
878: {
879: effadr ea = GetEA(p.src, p.mask);
880: ULONG val = ExtendWord(GetFromEA(ea));
881: setflags_logical(val,p.mask);
882: StoreToEA(ea, val);
883: }
884:
885: static instr_result INST_Scc(const instr_params p)
886: {
887: effadr ea = GetEA(p.src, p.mask);
888: StoreToEA(ea,cctrue(p.dest.reg) ? 0xff : 0);
889: }
890:
891: static instr_result INST_ABCD(const instr_params p)
892: {
893: abort();
894: }
895:
896: static instr_result INST_SBCD(const instr_params p)
897: {
898: abort();
899: }
900:
901: static instr_result INST_NBCD(const instr_params p)
902: {
903: abort();
904: }
905:
906: static instr_result INST_NOP(const instr_params p)
907: {
908:
909: }
910:
911: static instr_result INST_RESET(const instr_params p)
912: {
913: customreset();
914: }
915:
916: static instr_result INST_STOP(const instr_params p)
917: {
918: if ((p.mask != 0xff) && !regs.s) {
919: m68k_setpc(m68k_getpc()-2);
920: Exception(8);
921: } else {
922: effadr ea = GetEA(p.src, p.mask);
923: regs.sr = GetFromEA(ea);
924: MakeFromSR();
925: regs.stopped = 1;
926: }
927: }
928:
929: static instr_result INST_TRAPV(const instr_params p)
930: {
931: if (regs.v) Exception(7);
932: }
933:
934: static instr_result INST_TRAP(const instr_params p)
935: {
936: UWORD val = GetFromEA(GetEA(p.src,p.mask));
937: Exception(val+32);
938: }
939:
940: static instr_result INST_BSRB(const instr_params p)
941: {
942: addr_mode pda7 = { Apdi, 7 };
943: effadr ea = GetEA(p.src, p.mask);
944: BYTE offset = GetFromEA(ea);
945: effadr stackp;
946: stackp = GetEA(pda7,0xffffffff);
947: StoreToEA(stackp,m68k_getpc());
948: m68k_setpc(m68k_getpc() + offset);
949:
950: }
951:
952: static instr_result INST_BccB(const instr_params p)
953: {
954: if (cctrue(p.dest.reg)){
955: effadr ea = GetEA(p.src, p.mask);
956: BYTE offset = GetFromEA(ea);
957: m68k_setpc(m68k_getpc() + offset);
958: }
959: }
960:
961: static instr_result INST_BSRW(const instr_params p)
962: {
963: addr_mode pda7 = { Apdi, 7 };
964: effadr ea = GetEA(p.src, p.mask);
965: WORD offset = GetFromEA(ea);
966: effadr stackp;
967: stackp = GetEA(pda7,0xffffffff);
968: StoreToEA(stackp,m68k_getpc());
969: m68k_setpc(m68k_getpc() + offset - 2);
970: }
971:
972: static instr_result INST_BccW(const instr_params p)
973: {
974: effadr ea = GetEA(p.src, p.mask);
975: WORD offset = GetFromEA(ea);
976: if (cctrue(p.dest.reg)){
977: m68k_setpc(m68k_getpc() + offset - 2);
978: }
979: }
980:
981: static instr_result INST_DBcc(const instr_params p)
982: {
983: WORD offset = nextiword();
984:
985: if (!cctrue(p.dest.reg)){
986: effadr ea = GetEA(p.src, p.mask); /* safe inside if, can only be Dreg */
987: ULONG dr = GetFromEA(ea);
988: if (dr--){
989: m68k_setpc(m68k_getpc() + offset - 2);
990: }
991: StoreToEA(ea,dr);
992: }
993: }
994:
995: static instr_result INST_JMP(const instr_params p)
996: {
997: effadr ea = GetEA(p.src, p.mask);
998: m68k_setpc(RetrieveEA(ea));
999: }
1000:
1001: static instr_result INST_JSR(const instr_params p)
1002: {
1003: effadr ea = GetEA(p.src, p.mask);
1004: addr_mode pda7 = { Apdi, 7 };
1005: effadr stackp;
1006: stackp = GetEA(pda7,0xffffffff);
1007: StoreToEA(stackp, m68k_getpc());
1008:
1009: m68k_setpc(RetrieveEA(ea));
1010: }
1011:
1012: static instr_result INST_RTE(const instr_params p)
1013: {
1014: addr_mode a7pi = { Aipi, 7 };
1015: effadr stackp;
1016: stackp = GetEA(a7pi,0xffff);
1017: regs.sr = GetFromEA(stackp);
1018: stackp = GetEA(a7pi,0xffffffff);
1019: m68k_setpc(GetFromEA(stackp));
1020: MakeFromSR();
1021: }
1022:
1023: static instr_result INST_RTD(const instr_params p)
1024: {
1025: INST_NIMP(p);
1026: }
1027:
1028: static instr_result INST_RTS(const instr_params p)
1029: {
1030: addr_mode a7pi = { Aipi, 7 };
1031: effadr stackp;
1032: stackp = GetEA(a7pi,0xffffffff);
1033: m68k_setpc(GetFromEA(stackp));
1034: }
1035:
1036: static instr_result INST_RTR(const instr_params p)
1037: {
1038: addr_mode a7pi = { Aipi, 7 };
1039: effadr stackp;
1040: stackp = GetEA(a7pi,0xffff);
1041: MakeSR();
1042: regs.sr &= 0xff00;
1043: regs.sr |= GetFromEA(stackp) & 0xff;
1044: stackp = GetEA(a7pi,0xffffffff);
1045: m68k_setpc(GetFromEA(stackp));
1046: MakeFromSR();
1047: }
1048:
1049: static instr_result INST_LINK(const instr_params p)
1050: {
1051: addr_mode pda7 = { Apdi, 7 };
1052: effadr stackp, ar, ea;
1053: ULONG offset;
1054: stackp = GetEA(pda7,0xffffffff);
1055: ar = GetEA(p.src, 0xffffffff);
1056: ea = GetEA(p.dest, p.mask);
1057: StoreToEA(stackp, GetFromEA(ar));
1058: StoreToEA(ar, regs.a[7]);
1059: offset = GetFromEA(ea);
1060: regs.a[7] += offset;
1061: }
1062:
1063: static instr_result INST_UNLK(const instr_params p)
1064: {
1065: addr_mode a7pi = { Aipi, 7 };
1066: effadr stackp, ar;
1067: stackp = GetEA(a7pi,0xffffffff);
1068: ar = GetEA(p.src, 0xffffffff);
1069: regs.a[7] = GetFromEA(ar);
1070:
1071: StoreToEA(ar, GetFromEA(stackp));
1072: }
1073:
1074: static instr_result INST_MULU(const instr_params p)
1075: {
1076: effadr src = GetEA(p.src, p.mask);
1077: UWORD srcv = GetFromEA(src);
1078: effadr dst = GetEA(p.dest, p.mask);
1079: UWORD dstv = GetFromEA(dst);
1080: ULONG newv = (ULONG)dstv * (ULONG)srcv;
1081: setflags_logical(newv, 0xffffffff);
1082: dst.szmask = 0xffffffff;
1083: StoreToEA(dst,newv);
1084: }
1085:
1086: static instr_result INST_MULS(const instr_params p)
1087: {
1088: effadr src = GetEA(p.src, p.mask);
1089: WORD srcv = GetFromEA(src);
1090: effadr dst = GetEA(p.dest, p.mask);
1091: WORD dstv = GetFromEA(dst);
1092: ULONG newv = (LONG)dstv * (LONG)srcv;
1093: setflags_logical(newv, 0xffffffff);
1094: dst.szmask = 0xffffffff;
1095: StoreToEA(dst,newv);
1096: }
1097:
1098: static instr_result INST_DIVU(const instr_params p)
1099: {
1100: effadr src = GetEA(p.src, 0xffff);
1101: UWORD srcv = GetFromEA(src);
1102: effadr dst = GetEA(p.dest, 0xffffffff);
1103: ULONG dstv = GetFromEA(dst);
1104: if (srcv == 0){
1105: /* FOO ! */
1106: } else {
1107: ULONG newv = dstv / srcv;
1108: UWORD rem = dstv % srcv;
1109: setflags_logical(newv, 0xffff);
1110: regs.v = newv > 0xffff;
1111: newv = (newv & 0xffff) | (rem << 16);
1112: StoreToEA(dst,newv);
1113: }
1114: }
1115:
1116: static instr_result INST_DIVS(const instr_params p)
1117: {
1118: effadr src = GetEA(p.src, 0xffff);
1119: WORD srcv = GetFromEA(src);
1120: effadr dst = GetEA(p.dest, 0xffffffff);
1121: LONG dstv = GetFromEA(dst);
1122: if (srcv == 0){
1123: /* FOO ! */
1124: } else {
1125: LONG newv = dstv / srcv;
1126: UWORD rem = dstv % srcv;
1127: if ((rem & 0x8000) != (newv & 0x8000)) rem = -rem;
1128: setflags_logical(newv, 0xffff);
1129: regs.v = (newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000;
1130: newv = (newv & 0xffff) | (rem << 16);
1131: StoreToEA(dst,newv);
1132: }
1133: }
1134:
1135: static instr_result INST_ASL(const instr_params p)
1136: {
1137: effadr src = GetEA(p.src, p.mask);
1138: effadr dst = GetEA(p.dest, p.mask);
1139: ULONG cnt = GetFromEA(src) & 63;
1140: ULONG data = GetFromEA(dst) & p.mask;
1141:
1142: ULONG cmask = 1 << mask2shift(p.mask);
1143: ULONG sign = data & cmask;
1144: regs.v = 0;
1145: for (;cnt;--cnt){
1146: regs.c = regs.x = (data & cmask) != 0;
1147: data <<= 1;
1148: if ((data & cmask) != sign) regs.v = 1;
1149: }
1150: regs.n = (data & cmask) != 0;
1151: regs.z = (data & p.mask) == 0;
1152: StoreToEA(dst,data);
1153: }
1154:
1155: static instr_result INST_ASR(const instr_params p)
1156: {
1157: effadr src = GetEA(p.src, p.mask);
1158: effadr dst = GetEA(p.dest, p.mask);
1159: ULONG cnt = GetFromEA(src) & 63;
1160: ULONG data = GetFromEA(dst) & p.mask;
1161:
1162: ULONG cmask = 1 << mask2shift(p.mask);
1163: ULONG sign = data & cmask;
1164: regs.v = 0;
1165: for (;cnt;--cnt){
1166: regs.c = regs.x = data & 1;
1167: data = (data >> 1) | sign;
1168: }
1169: regs.n = sign != 0;
1170: regs.z = (data & p.mask) == 0;
1171: StoreToEA(dst,data);
1172: }
1173:
1174: static instr_result INST_LSR(const instr_params p)
1175: {
1176: effadr src = GetEA(p.src, p.mask);
1177: effadr dst = GetEA(p.dest, p.mask);
1178: ULONG cnt = GetFromEA(src) & 63;
1179: ULONG data = GetFromEA(dst) & p.mask;
1180:
1181: int carry = 0;
1182: for (;cnt;--cnt){
1183: carry = data & 1;
1184: data >>= 1;
1185: }
1186: setflags_logical(data,p.mask);
1187: regs.c = regs.x = carry;
1188: StoreToEA(dst,data);
1189: }
1190:
1191: static instr_result INST_LSL(const instr_params p)
1192: {
1193: effadr src = GetEA(p.src, p.mask);
1194: effadr dst = GetEA(p.dest, p.mask);
1195: ULONG cnt = GetFromEA(src) & 63;
1196: ULONG data = GetFromEA(dst) & p.mask;
1197:
1198: ULONG cmask = 1 << mask2shift(p.mask);
1199: ULONG carry = 0;
1200:
1201: for (;cnt;--cnt){
1202: carry = data & cmask;
1203: data <<= 1;
1204: }
1205: setflags_logical(data,p.mask);
1206: regs.c = regs.x = carry != 0;
1207: StoreToEA(dst,data);
1208: }
1209:
1210: static instr_result INST_ROR(const instr_params p)
1211: {
1212: effadr src = GetEA(p.src, p.mask);
1213: effadr dst = GetEA(p.dest, p.mask);
1214: ULONG cnt = GetFromEA(src) & 63;
1215: ULONG data = GetFromEA(dst) & p.mask;
1216:
1217: ULONG cmask = 1 << mask2shift(p.mask);
1218: int carry = 0;
1219: for (;cnt;--cnt){
1220: carry = data & 1;
1221: data >>= 1;
1222: if (carry) data |= cmask;
1223: }
1224: setflags_logical(data,p.mask);
1225: regs.c = carry;
1226: StoreToEA(dst,data);
1227: }
1228:
1229: static instr_result INST_ROL(const instr_params p)
1230: {
1231: effadr src = GetEA(p.src, p.mask);
1232: effadr dst = GetEA(p.dest, p.mask);
1233: ULONG cnt = GetFromEA(src) & 63;
1234: ULONG data = GetFromEA(dst) & p.mask;
1235:
1236: ULONG cmask = 1 << mask2shift(p.mask);
1237: ULONG carry = 0;
1238:
1239: for (;cnt;--cnt){
1240: carry = data & cmask;
1241: data <<= 1;
1242: if (carry) data |= 1;
1243: }
1244: setflags_logical(data,p.mask);
1245: regs.c = carry != 0;
1246: StoreToEA(dst,data);
1247: }
1248:
1249: static instr_result INST_ROXR(const instr_params p)
1250: {
1251: effadr src = GetEA(p.src, p.mask);
1252: effadr dst = GetEA(p.dest, p.mask);
1253: ULONG cnt = GetFromEA(src) & 63;
1254: ULONG data = GetFromEA(dst) & p.mask;
1255:
1256: ULONG cmask = 1 << mask2shift(p.mask);
1257: int carry = 0;
1258: for (;cnt;--cnt){
1259: carry = data & 1;
1260: data >>= 1;
1261: if (regs.x) data |= cmask;
1262: regs.x = carry;
1263: }
1264: setflags_logical(data,p.mask);
1265: regs.c = regs.x = carry;
1266: StoreToEA(dst,data);
1267: }
1268:
1269: static instr_result INST_ROXL(const instr_params p)
1270: {
1271: effadr src = GetEA(p.src, p.mask);
1272: effadr dst = GetEA(p.dest, p.mask);
1273: ULONG cnt = GetFromEA(src) & 63;
1274: ULONG data = GetFromEA(dst) & p.mask;
1275:
1276: ULONG cmask = 1 << mask2shift(p.mask);
1277: int carry = 0;
1278:
1279: for (;cnt;--cnt){
1280: carry = data & cmask;
1281: data <<= 1;
1282: if (regs.x) data |= 1;
1283: regs.x = carry != 0;
1284: }
1285: setflags_logical(data,p.mask);
1286: regs.c = regs.x = carry != 0;
1287: StoreToEA(dst,data);
1288: }
1289:
1290: static instr_result INST_ASL1(const instr_params p)
1291: {
1292: effadr dst = GetEA(p.dest, p.mask);
1293: ULONG data = GetFromEA(dst) & p.mask;
1294:
1295: ULONG cmask = 1 << mask2shift(p.mask);
1296: ULONG sign = data & cmask;
1297: regs.v = 0;
1298: regs.c = regs.x = sign != 0;
1299: data <<= 1;
1300: if ((data & cmask) != sign) regs.v = 1;
1301: regs.n = (data & cmask) != 0;
1302: regs.z = (data & p.mask) == 0;
1303: StoreToEA(dst,data);
1304: }
1305:
1306: static instr_result INST_ASR1(const instr_params p)
1307: {
1308: effadr dst = GetEA(p.dest, p.mask);
1309: ULONG data = GetFromEA(dst) & p.mask;
1310:
1311: ULONG cmask = 1 << mask2shift(p.mask);
1312: ULONG sign = data & cmask;
1313: regs.v = 0;
1314: regs.c = regs.x = data & 1;
1315: data = (data >> 1) | sign;
1316: regs.n = sign != 0;
1317: regs.z = (data & p.mask) == 0;
1318: StoreToEA(dst,data);
1319: }
1320:
1321: static instr_result INST_LSR1(const instr_params p)
1322: {
1323: effadr dst = GetEA(p.dest, p.mask);
1324: ULONG data = GetFromEA(dst) & p.mask;
1325: int carry = data & 1;
1326: data >>= 1;
1327: setflags_logical(data, p.mask);
1328: regs.c = regs.x = carry;
1329: StoreToEA(dst,data);
1330: }
1331:
1332: static instr_result INST_LSL1(const instr_params p)
1333: {
1334: effadr dst = GetEA(p.dest, p.mask);
1335: ULONG data = GetFromEA(dst) & p.mask;
1336:
1337: ULONG cmask = 1 << mask2shift(p.mask);
1338: ULONG carry = data & cmask;
1339: data <<= 1;
1340: setflags_logical(data,p.mask);
1341: regs.c = regs.x = carry != 0;
1342: StoreToEA(dst,data);
1343: }
1344:
1345: static instr_result INST_ROR1(const instr_params p)
1346: {
1347: effadr dst = GetEA(p.dest, p.mask);
1348: ULONG data = GetFromEA(dst) & p.mask;
1349:
1350: ULONG cmask = 1 << mask2shift(p.mask);
1351: int carry = data & 1;
1352: data >>= 1;
1353: if (carry) data |= cmask;
1354: setflags_logical(data,p.mask);
1355: regs.c = carry;
1356: StoreToEA(dst,data);
1357: }
1358:
1359: static instr_result INST_ROL1(const instr_params p)
1360: {
1361: effadr dst = GetEA(p.dest, p.mask);
1362: ULONG data = GetFromEA(dst) & p.mask;
1363:
1364: ULONG cmask = 1 << mask2shift(p.mask);
1365: ULONG carry = data & cmask;
1366:
1367: data <<= 1;
1368: if (carry) data |= 1;
1369: setflags_logical(data,p.mask);
1370: regs.c = carry != 0;
1371: StoreToEA(dst,data);
1372: }
1373:
1374: static instr_result INST_ROXR1(const instr_params p)
1375: {
1376: effadr dst = GetEA(p.dest, p.mask);
1377: ULONG data = GetFromEA(dst) & p.mask;
1378:
1379: ULONG cmask = 1 << mask2shift(p.mask);
1380: int carry = data & 1;
1381: data >>= 1;
1382: if (regs.x) data |= cmask;
1383: setflags_logical(data,p.mask);
1384: regs.c = regs.x = carry;
1385: StoreToEA(dst,data);
1386: }
1387:
1388: static instr_result INST_ROXL1(const instr_params p)
1389: {
1390: effadr dst = GetEA(p.dest, p.mask);
1391: ULONG data = GetFromEA(dst) & p.mask;
1392:
1393: ULONG cmask = 1 << mask2shift(p.mask);
1394: ULONG carry = data & cmask;
1395:
1396: data <<= 1;
1397: if (regs.x) data |= 1;
1398:
1399: setflags_logical(data,p.mask);
1400: regs.c = regs.x = carry != 0;
1401: StoreToEA(dst,data);
1402: }
1403:
1404: static instr_result INST_MOVECCREA(const instr_params p)
1405: {
1406: INST_NIMP(p);
1407: }
1408:
1409: static instr_result INST_MOVESREA(const instr_params p)
1410: {
1411: effadr ea = GetEA(p.src, p.mask);
1412: MakeSR();
1413: StoreToEA(ea,regs.sr);
1414: }
1415:
1416: static instr_result INST_MOVEEACCR(const instr_params p)
1417: {
1418: effadr ea = GetEA(p.src, p.mask);
1419: MakeSR();
1420: regs.sr &= 0xFF00;
1421: regs.sr |= GetFromEA(ea) & 0xFF;
1422: MakeFromSR();
1423: }
1424:
1425: static instr_result INST_MOVEEASR(const instr_params p)
1426: {
1427: if ((p.mask != 0xff) && !regs.s) {
1428: m68k_setpc(m68k_getpc()-2);
1429: Exception(8);
1430: } else {
1431: effadr ea = GetEA(p.src, p.mask);
1432: regs.sr = GetFromEA(ea);
1433: MakeFromSR();
1434: }
1435: }
1436:
1437: static instr_result INST_ORSR(const instr_params p)
1438: {
1439: if ((p.mask != 0xff) && !regs.s) {
1440: m68k_setpc(m68k_getpc()-2);
1441: Exception(8);
1442: } else {
1443: effadr ea = GetEA(p.src, p.mask);
1444: MakeSR();
1445: regs.sr |= GetFromEA(ea);
1446: MakeFromSR();
1447: }
1448: }
1449:
1450: static instr_result INST_EORSR(const instr_params p)
1451: {
1452: if ((p.mask != 0xff) && !regs.s) {
1453: m68k_setpc(m68k_getpc()-2);
1454: Exception(8);
1455: } else {
1456: effadr ea = GetEA(p.src, p.mask);
1457: MakeSR();
1458: regs.sr ^= GetFromEA(ea);
1459: MakeFromSR();
1460: }
1461: }
1462:
1463: static instr_result INST_ANDSR(const instr_params p)
1464: {
1465: if ((p.mask != 0xff) && !regs.s) {
1466: m68k_setpc(m68k_getpc()-2);
1467: Exception(8);
1468: } else {
1469: effadr ea = GetEA(p.src, p.mask);
1470: MakeSR();
1471: regs.sr &= GetFromEA(ea);
1472: MakeFromSR();
1473: }
1474: }
1475:
1476: static instr_result INST_MOVEMEARL(const instr_params p)
1477: {
1478: int i;
1479: UWORD bitmask = nextiword();
1480: effadr ea = MGetEA(p.src, p.mask);
1481:
1482: for(i=0; i<8; i++) {
1483: if (bitmask & (1 << i)) {
1484: regs.d[i] = Extend(GetFromEA(ea), p.mask);
1485: ea.addr += mask2len(p.mask);
1486: }
1487: }
1488: for(i=0; i<8; i++) {
1489: if (bitmask & (1 << (i + 8))) {
1490: regs.a[i] = Extend(GetFromEA(ea),p.mask);
1491: ea.addr += mask2len(p.mask);
1492: }
1493: }
1494: MCompleteEAToRL(ea, p.src);
1495: }
1496:
1497: static instr_result INST_MOVEMRLEA(const instr_params p)
1498: {
1499: UWORD bitmask = nextiword();
1500: effadr ea;
1501: int rd[8], ra[8], i, kludge;
1502: for(i=0;i<8;i++){
1503: rd[i] = regs.d[i]; ra[i] = regs.a[i];
1504: }
1505: ea = MGetEA(p.src, p.mask);
1506: kludge = (p.src.mode == Apdi) ? 15 : 0;
1507: MCompleteEAFromRL(&ea, p.src, p.mask, bitmask);
1508: for(i=0; i<8; i++) {
1509: if (bitmask & (1 << (i ^ kludge))) {
1510: StoreToEA(ea,rd[i]);
1511: ea.addr += mask2len(p.mask);
1512: }
1513: }
1514: for(i=0; i<8; i++) {
1515: if (bitmask & (1 << ((i + 8) ^ kludge))) {
1516: StoreToEA(ea,ra[i]);
1517: ea.addr += mask2len(p.mask);
1518: }
1519: }
1520: }
1521:
1522: static instr_result INST_MOVEAUSP(const instr_params p)
1523: {
1524: effadr ea = GetEA(p.src,0xffffffff);
1525: if (regs.s) {
1526: regs.usp = GetFromEA(ea);
1527: } else {
1528: m68k_setpc(m68k_getpc()-2); Exception(8);
1529: }
1530: }
1531:
1532: static instr_result INST_MOVEUSPA(const instr_params p)
1533: {
1534: effadr ea = GetEA(p.src,0xffffffff);
1535: if (regs.s) {
1536: StoreToEA(ea,regs.usp);
1537: } else {
1538: m68k_setpc(m68k_getpc()-2); Exception(8);
1539: }
1540: }
1541:
1542: static instr_result INST_LINEA(const instr_params p)
1543: {
1544: m68k_setpc(m68k_getpc()-2);
1545:
1546: Exception(10);
1547: }
1548:
1549: static instr_result INST_LINEF(const instr_params p)
1550: {
1551: m68k_setpc(m68k_getpc()-2);
1552:
1553: Exception(11);
1554: }
1555:
1556: /*
1557: * debugging functions
1558: */
1559:
1560: typedef struct {
1561: instr_func f;
1562: char *name;
1563: bool src,dest,spc;
1564: } debug_entry;
1565:
1566: static debug_entry debugtbl[] = {
1567: { &INST_OR,"OR",1,1,0 },
1568: { &INST_AND,"AND",1,1,0 },
1569: { &INST_EOR,"EOR",1,1,0 },
1570: { &INST_CMP,"CMP",1,1,0 },
1571: { &INST_ADD,"ADD",1,1,0 },
1572: { &INST_SUB,"SUB",1,1,0 },
1573: { &INST_ADDX,"ADDX",1,1,0 },
1574: { &INST_SUBX,"SUBX",1,1,0 },
1575:
1576: { &INST_ADDA,"ADDA",1,1,0 },
1577: { &INST_SUBA,"SUBA",1,1,0 },
1578: { &INST_CMPA,"CMPA",1,1,0 },
1579:
1580: { &INST_CHK,"CHK",1,1,0 },
1581:
1582: { &INST_EXGL,"EXG",1,1,0 },
1583:
1584: { &INST_LEA,"LEA",1,1,0 },
1585: { &INST_MOVE,"MOVE",1,1,0 },
1586: { &INST_MOVEA,"MOVEA",1,1,0 },
1587: { &INST_MOVEQ,"MOVEQ",1,1,0 },
1588: { &INST_BTST,"BTST",1,1,0 },
1589: { &INST_BCLR,"BCLR",1,1,0 },
1590: { &INST_BSET,"BSET",1,1,0 },
1591: { &INST_BCHG,"BCHG",1,1,0 },
1592: { &INST_NEG,"NEG",1,0,0 },
1593: { &INST_NEGX,"NEGX",1,0,0 },
1594: { &INST_NOT,"NOT",1,0,0 },
1595: { &INST_CLR,"CLR",1,0,0 },
1596: { &INST_TST,"TST",1,0,0 },
1597: { &INST_SWAP,"SWAP",1,0,0 },
1598: { &INST_EXTW,"EXT",1,0,0 },
1599: { &INST_EXTL,"EXT",1,0,0 },
1600: { &INST_Scc,"Scc",1,0,0 },
1601: { &INST_ABCD,"ABCD",1,1,0 },
1602: { &INST_SBCD,"SBCD",1,1,0 },
1603: { &INST_NBCD,"NBCD",1,1,0 },
1604: { &INST_NOP,"NOP",0,0,0 },
1605: { &INST_RESET,"RESET",0,0,0 },
1606: { &INST_STOP,"STOP",1,0,0 },
1607: { &INST_TRAPV,"TRAPV",1,0,0 },
1608: { &INST_TRAP,"TRAP",1,0,0 },
1609: { &INST_BSRB,"BSR",1,0,0 },
1610: { &INST_BccB,"Bcc",1,0,0 },
1611: { &INST_BSRW,"BSR",1,0,0 },
1612: { &INST_BccW,"Bcc",1,0,0 },
1613: { &INST_DBcc,"DBcc",1,0,10 },
1614: { &INST_JMP,"JMP",1,0,0 },
1615: { &INST_JSR,"JSR",1,0,0 },
1616: { &INST_RTE,"RTE",0,0,0 },
1617: { &INST_RTD,"RTD",0,0,0 },
1618: { &INST_RTS,"RTS",0,0,0 },
1619: { &INST_RTR,"RTR",0,0,0 },
1620: { &INST_LINK,"LINK",1,1,0 },
1621: { &INST_UNLK,"UNLK",1,0,0 },
1622: { &INST_MULU,"MULU",1,1,0 },
1623: { &INST_MULS,"MULS",1,1,0 },
1624: { &INST_DIVU, "DIVU",1,1,0 },
1625: { &INST_DIVS,"DIVS",1,1,0 },
1626: { &INST_ASR,"ASR",1,1,0 },
1627: { &INST_ASL,"ASL",1,1,0 },
1628: { &INST_LSR,"LSR",1,1,0 },
1629: { &INST_LSL,"LSL",1,1,0 },
1630: { &INST_ROR,"ROR",1,1,0 },
1631: { &INST_ROL,"ROL",1,1,0 },
1632: { &INST_ROXR,"ROXR",1,1,0 },
1633: { &INST_ROXL,"ROXL",1,1,0 },
1634: { &INST_ASR1,"ASR",1,0,0 },
1635: { &INST_ASL1,"ASL",1,0,0 },
1636: { &INST_LSR1,"LSR",1,0,0 },
1637: { &INST_LSL1,"LSL",1,0,0 },
1638: { &INST_ROR1,"ROR",1,0,0 },
1639: { &INST_ROL1,"ROL",1,0,0 },
1640: { &INST_ROXR1,"ROXR",1,0,0 },
1641: { &INST_ROXL1,"ROXL",1,0,0 },
1642: { &INST_MOVECCREA,"MOVE CCR,",1,0,0 },
1643: { &INST_MOVESREA,"MOVE SR,",1,0,0 },
1644: { &INST_MOVEEACCR,"MOVE2CCR",1,0,0 },
1645: { &INST_MOVEEASR,"MOVE2SR",1,0,0 },
1646: { &INST_MOVEMEARL,"MOVEM",1,0,9 },
1647: { &INST_MOVEMRLEA,"MOVEM",1,0,5 },
1648: { &INST_MOVEAUSP,"MOVE2USP",1,1,0 },
1649: { &INST_MOVEUSPA,"MOVE USP,",1,1,0 },
1650:
1651: { &INST_ORSR,"ORSR",1,0,0 },
1652: { &INST_ANDSR,"ANDSR",1,0,0 },
1653: { &INST_EORSR,"EORSR",1,0,0 },
1654:
1655: { &INST_LINEA,"LINEA",0,0,0 },
1656: { &INST_LINEF,"LINEF",0,0,0 },
1657: { &INST_ILLG,"ILLEGAL",0,0,0 },
1658: { &INST_NIMP,"NOT IMPLEMENTED",0,0,0 },
1659: { NULL,NULL,0,0,0 }
1660: };
1661:
1662: static char* ccnames[] =
1663: { "T ","F ","HI","LS","CC","CS","NE","EQ",
1664: "VC","VS","PL","MI","GE","LT","GT","LE" };
1665:
1666: void MC68000_reset(void)
1667: {
1668: instr_params p;
1669:
1670: regs.a[7] = get_long(0x00f80000);
1671: m68k_setpc(get_long(0x00f80004));
1672: regs.s = 1;
1673: regs.stopped = 0;
1674: regs.t = 0;
1675: specialflags = 0;
1676: regs.intmask = 7;
1677: INST_RESET(p);
1678: }
1679:
1680: void op_illg(UWORD opcode)
1681: {
1682: if (opcode == 0xF00D && ((m68k_getpc() & 0xF80000) == 0xF80000)) {
1683: /* This is from the dummy Kickstart replacement */
1684: ersatz_perform (nextiword ());
1685: return;
1686: }
1687: regs.pc_p--;
1688: if ((opcode & 0xF000) == 0xF000) {
1689: Exception(0xB);
1690: return;
1691: }
1692: if ((opcode & 0xF000) == 0xA000) {
1693: Exception(0xA);
1694: return;
1695: }
1696: fprintf(stderr, "Illegal instruction: %04x\n", opcode);
1697: Exception(4);
1698: }
1699:
1700: static int n_insns=0, n_spcinsns=0;
1701:
1702: static __inline__ void do_hardware(void)
1703: {
1704: if (specialflags & SPCFLAG_BLIT) {
1705: do_blitter();
1706: #ifdef NO_FAST_BLITTER
1707: do_blitter();
1708: do_blitter();
1709: do_blitter();
1710: #endif
1711: }
1712: if (specialflags & SPCFLAG_DISK) {
1713: do_disk(); /* This is not critical. Four calls make disk */
1714: do_disk(); /* loading quite fast. */
1715: do_disk();
1716: do_disk();
1717: }
1718: }
1719:
1720: void MC68000_run(void)
1721: {
1722: for(;;) {
1723: UWORD opcode;
1724: /* assert (!regs.stopped && !(specialflags & SPCFLAG_STOP)); */
1725: opcode = nextiword();
1726: #ifdef COUNT_INSTRS
1727: instrcount[opcode]++;
1728: #endif
1729: (*cpufunctbl[opcode])(opcode);
1730: #ifndef NO_EXCEPTION_3
1731: if (buserr) {
1732: Exception(3);
1733: buserr = false;
1734: }
1735: #endif
1736: /*n_insns++;*/
1737: do_cycles();
1738: if (specialflags) {
1739: /*n_spcinsns++;*/
1740: while (specialflags & SPCFLAG_STOP) {
1741: do_cycles();
1742: do_hardware();
1743: if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
1744: int intr = intlev();
1745: specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
1746: specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
1747: if (intr != -1 && intr > regs.intmask) {
1748: Interrupt(intr);
1749: regs.stopped = 0;
1750: specialflags &= ~SPCFLAG_STOP;
1751: }
1752: }
1753: }
1754: if (specialflags & SPCFLAG_DOTRACE) {
1755: Exception(9);
1756: }
1757: if (specialflags & SPCFLAG_TRACE) {
1758: specialflags &= ~SPCFLAG_TRACE;
1759: specialflags |= SPCFLAG_DOTRACE;
1760: }
1761: #ifdef WANT_SLOW_MULTIPLY
1762: /* Kludge for Hardwired demo. The guys who wrote it should be
1763: * mutilated. */
1764: if (specialflags & SPCFLAG_EXTRA_CYCLES) {
1765: do_cycles ();
1766: do_cycles ();
1767: do_cycles ();
1768: do_cycles ();
1769: specialflags &= ~SPCFLAG_EXTRA_CYCLES;
1770: }
1771: #endif
1772: do_hardware();
1773:
1774: if (specialflags & SPCFLAG_DOINT) {
1775: int intr = intlev();
1776: specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
1777: if (intr != -1 && intr > regs.intmask) {
1778: Interrupt(intr);
1779: regs.stopped = 0;
1780: }
1781: }
1782: if (specialflags & SPCFLAG_INT) {
1783: specialflags &= ~SPCFLAG_INT;
1784: specialflags |= SPCFLAG_DOINT;
1785: }
1786: if (specialflags & SPCFLAG_BRK) {
1787: specialflags &= ~SPCFLAG_BRK;
1788: return;
1789: }
1790: }
1791: }
1792: }
1793:
1794: void MC68000_step(void)
1795: {
1796: specialflags |= SPCFLAG_BRK;
1797: MC68000_run();
1798: }
1799:
1800: void MC68000_skip(CPTR nextpc)
1801: {
1802: broken_in = false;
1803: specialflags |= SPCFLAG_BRK;
1804: do {
1805: MC68000_step();
1806: } while (nextpc != m68k_getpc() && !broken_in);
1807: }
1808:
1809: void MC68000_disasm(CPTR addr, CPTR *nextpc, int cnt)
1810: {
1811: CPTR pc = m68k_getpc();
1812: m68k_setpc(addr);
1813: for (;cnt--;){
1814: char instrname[20],*ccpt;
1815: int opwords;
1816: UWORD opcode;
1817: I_dec_tab_entry dtentry;
1818: debug_entry *dp;
1819: UWORD special = 0;
1820:
1821: printf("%08lx: ", m68k_getpc());
1822: for(opwords = 0; opwords < 5; opwords++){
1823: printf("%04x ", get_word(m68k_getpc() + opwords*2));
1824: }
1825:
1826: opcode = nextiword();
1827: if (cpufunctbl[opcode] == op_illg) {
1828: opcode = 0x4AFC;
1829: }
1830:
1831: dtentry = instr_dectab[opcode];
1832:
1833: for (dp = debugtbl;dp->f && dp->f != dtentry.execfunc;dp++)
1834: ;
1835:
1836: strcpy(instrname,dp->name);
1837: ccpt = strstr(instrname,"cc");
1838: if (ccpt != 0) {
1839: strncpy(ccpt,ccnames[dtentry.params.dest.reg],2);
1840: }
1841: printf("%s", instrname);
1842: switch(dtentry.params.mask){
1843: case 0xff: printf(".B "); break;
1844: case 0xffff: printf(".W "); break;
1845: case 0xffffffff: printf(".L "); break;
1846: }
1847:
1848: if (dp->spc & 1) {
1849: special = nextiword();
1850: }
1851: if (dp->spc & 4) {
1852: printf("#$%04x,", special);
1853: }
1854: if (dp->src) {
1855: ShowEA(dtentry.params.src,dtentry.params.mask);
1856: }
1857: if (dp->src && dp->dest) printf(",");
1858: if (dp->dest) {
1859: ShowEA(dtentry.params.dest,dtentry.params.mask);
1860: }
1861: if (dp->spc & 2) {
1862: special = nextiword();
1863: }
1864: if (dp->spc & 8) {
1865: printf(",#$%04x", special);
1866: }
1867: if (ccpt != 0) {
1868: if (cctrue(dtentry.params.dest.reg))
1869: printf(" (TRUE)");
1870: else
1871: printf(" (FALSE)");
1872: }
1873: printf("\n");
1874: }
1875: *nextpc = m68k_getpc();
1876: m68k_setpc(pc);
1877: }
1878:
1879: void MC68000_dumpstate(CPTR *nextpc)
1880: {
1881: int i;
1882: for(i = 0; i < 8; i++){
1883: printf("D%d: %08lx ", i, regs.d[i]);
1884: if ((i & 3) == 3) printf("\n");
1885: }
1886: for(i=0;i<8;i++){
1887: printf("A%d: %08lx ", i, regs.a[i]);
1888: if ((i & 3) == 3) printf("\n");
1889: }
1890: printf ("T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t, regs.s,
1891: regs.x, regs.n, regs.z, regs.v, regs.c, regs.intmask);
1892: MC68000_disasm(m68k_getpc(), nextpc, 1);
1893: printf("next PC: %08lx\n", *nextpc);
1894: }
1895:
1896: /*
1897: * GenerateDecTab() creates the instruction decode table.
1898: * FIXME: This should generate all legal instructions, but some illegal ones
1899: * will not be directed to INST_ILLG. On an accidental execution, a function
1900: * like GetEA() may call abort().
1901: * This is no longer a big problem, as the other CPU emulator is used now
1902: * and the disassembler has more error checks.
1903: */
1904:
1905: static void GenerateDecTab(void)
1906: {
1907: int offset;
1908: long int opcode;
1909: for(opcode = 0; opcode < 65536; opcode++){
1910: int r1 = (opcode & 0x0E00) >> 9;
1911: int m1 = (opcode & 0x01C0) >> 6;
1912: int m2 = (opcode & 0x0038) >> 3;
1913: int r2 = (opcode & 0x0007);
1914: int x = (m1 & 4) >> 2;
1915: int sz = (m1 & 3);
1916: addr_mode am1, am2;
1917: I_dec_tab_entry entry;
1918: set_addr_mode(&am1, m1, r1);
1919: set_addr_mode(&am2, m2, r2);
1920:
1921: switch(opcode & 0xF000) {
1922: case 0x0000:
1923: if (x) {
1924: if (am2.mode == Dreg || am2.mode == Aind ||
1925: am2.mode == Aipi || am2.mode == Apdi ||
1926: am2.mode == Ad16 || am2.mode == Ad8r ||
1927: am2.mode == absw || am2.mode == absl) {
1928: switch(sz){
1929: case 0:
1930: entry.execfunc = &INST_BTST;
1931: break;
1932: case 1:
1933: entry.execfunc = &INST_BCHG;
1934: break;
1935: case 2:
1936: entry.execfunc = &INST_BCLR;
1937: break;
1938: case 3:
1939: entry.execfunc = &INST_BSET;
1940: break;
1941: }
1942: entry.params.mask = 0xffffffff;
1943: am1 = am2;
1944: am2.mode = Dreg; am2.reg = r1;
1945: } else {
1946: entry.execfunc = &INST_NIMP; /* MOVEP */
1947: }
1948: } else {
1949: am1.mode = imm;
1950: if (sz == 3) {
1951: switch(r1){
1952: case 0:
1953: case 1:
1954: case 2:
1955: case 6:
1956: case 7:
1957: entry.execfunc = &INST_ILLG;
1958: break;
1959: case 3:
1960: entry.execfunc = &INST_NIMP; /* RTM */
1961: break;
1962: case 4:
1963: entry.execfunc = &INST_BSET;
1964: am1 = am2;
1965: am2.mode = imm;
1966: entry.params.mask = 0xffff;
1967: break;
1968: case 5:
1969: entry.execfunc = &INST_NIMP; /* CAS */
1970: break;
1971: }
1972: } else {
1973: entry.params.mask = sizemask(sz);
1974: switch(r1){
1975: case 0:
1976: if (am2.mode == imm)
1977: entry.execfunc = &INST_ORSR;
1978: else
1979: entry.execfunc = &INST_OR;
1980: break;
1981: case 1:
1982: if (am2.mode == imm)
1983: entry.execfunc = &INST_ANDSR;
1984: else
1985: entry.execfunc = &INST_AND;
1986: break;
1987: case 2:
1988: entry.execfunc = &INST_SUB;
1989: break;
1990: case 3:
1991: entry.execfunc = &INST_ADD;
1992: break;
1993: case 4:
1994: switch(sz){
1995: case 0: entry.execfunc = &INST_BTST; break;
1996: case 1: entry.execfunc = &INST_BCHG; break;
1997: case 2: entry.execfunc = &INST_BCLR; break;
1998: }
1999: entry.params.mask = 0xffff;
2000: break;
2001: case 5:
2002: if (am2.mode == imm)
2003: entry.execfunc = &INST_EORSR;
2004: else
2005: entry.execfunc = &INST_EOR;
2006: break;
2007: case 6:
2008: entry.execfunc = &INST_CMP;
2009: break;
2010: case 7:
2011: entry.execfunc = &INST_NIMP; /* MOVES */
2012: break;
2013: }
2014: am1 = am2; am2.mode = imm;
2015: }
2016: }
2017: break;
2018: case 0x1000:
2019: switch(am1.mode) {
2020: case Areg: case imm: case imm3: case ill2: case ill3:
2021: entry.execfunc = &INST_ILLG; /* MOVEA.B ??? */
2022: break;
2023: default:
2024: entry.execfunc = &INST_MOVE; /* MOVE.B */
2025: break;
2026: }
2027: entry.params.mask = 0xff;
2028: break;
2029: case 0x2000:
2030: switch(am1.mode) {
2031: case Areg:
2032: entry.execfunc = &INST_MOVEA; /* MOVEA.L */
2033: break;
2034: case imm: case imm3: case ill2: case ill3:
2035: entry.execfunc = &INST_ILLG;
2036: break;
2037: default:
2038: entry.execfunc = &INST_MOVE; /* MOVE.L */
2039: break;
2040: }
2041: entry.params.mask = 0xffffffff;
2042: break;
2043: case 0x3000:
2044: switch(am1.mode) {
2045: case Areg:
2046: entry.execfunc = &INST_MOVEA; /* MOVEA.W */
2047: break;
2048: case imm: case imm3: case ill2: case ill3:
2049: entry.execfunc = &INST_ILLG;
2050: break;
2051: default:
2052: entry.execfunc = &INST_MOVE; /* MOVE.W */
2053: break;
2054: }
2055: entry.params.mask = 0xffff;
2056: break;
2057: case 0x4000:
2058: if (x){
2059: switch(sz){
2060: case 0:
2061: entry.execfunc = &INST_CHK;
2062: entry.params.mask = 0xffffffff;
2063: am1.mode = Dreg; am1.reg = r1;
2064: break;
2065: case 1:
2066: entry.execfunc = &INST_ILLG;
2067: break;
2068: case 2:
2069: entry.execfunc = &INST_CHK;
2070: entry.params.mask = 0xffff;
2071: am1.mode = Dreg; am1.reg = r1;
2072: break;
2073: case 3:
2074: if (am2.mode == Dreg) {
2075: entry.execfunc = &INST_NIMP; /* EXTB.L */
2076: } else {
2077: entry.execfunc = &INST_LEA;
2078: entry.params.mask = 0xffffffff;
2079: am1.mode = Areg; am1.reg = r1;
2080: }
2081: break;
2082: }
2083: } else {
2084: switch(sz){
2085: case 0:
2086: switch(r1){
2087: case 0:
2088: entry.execfunc = &INST_NEG;
2089: entry.params.mask = 0xff;
2090: break;
2091: case 1:
2092: entry.execfunc = &INST_CLR;
2093: entry.params.mask = 0xff;
2094: break;
2095: case 2:
2096: entry.execfunc = &INST_NEG;
2097: entry.params.mask = 0xff;
2098: break;
2099: case 3:
2100: entry.execfunc = &INST_NOT;
2101: entry.params.mask = 0xff;
2102: break;
2103: case 4:
2104: if (am2.mode == Areg) {
2105: entry.execfunc = &INST_LINK; /* this is from 020 upwards */
2106: entry.params.mask = 0xffffffff;
2107: am1.mode = imm;
2108: } else {
2109: entry.execfunc = &INST_NBCD;
2110: entry.params.mask = 0xff;
2111: }
2112: break;
2113: case 5:
2114: entry.execfunc = &INST_TST;
2115: entry.params.mask = 0xff;
2116: break;
2117: case 6:
2118: entry.execfunc = &INST_NIMP; /* MUL[US].L */
2119: break;
2120: case 7:
2121: entry.execfunc = &INST_ILLG;
2122: break;
2123: }
2124: break;
2125: case 1:
2126: switch(r1){
2127: case 0:
2128: entry.execfunc = &INST_NEG;
2129: entry.params.mask = 0xffff;
2130: break;
2131: case 1:
2132: entry.execfunc = &INST_CLR;
2133: entry.params.mask = 0xffff;
2134: break;
2135: case 2:
2136: entry.execfunc = &INST_NEG;
2137: entry.params.mask = 0xffff;
2138: break;
2139: case 3:
2140: entry.execfunc = &INST_NOT;
2141: entry.params.mask = 0xffff;
2142: break;
2143: case 4:
2144: if (am2.mode == Dreg) {
2145: entry.execfunc = &INST_SWAP;
2146: entry.params.mask = 0xffffffff;
2147: } else {
2148: entry.execfunc = &INST_LEA; /* PEA == LEA ea,-(A7) */
2149: entry.params.mask = 0xffffffff;
2150: am1.mode = Apdi;
2151: am1.reg = 7;
2152: }
2153: break;
2154: case 5:
2155: entry.execfunc = &INST_TST;
2156: entry.params.mask = 0xffff;
2157: break;
2158: case 6:
2159: entry.execfunc = &INST_NIMP; /* DIV[US]{L}.L */
2160: break;
2161: case 7:
2162: switch(am2.mode){
2163: case Areg: case Dreg:
2164: entry.execfunc = &INST_TRAP;
2165: am2.mode = imm3;
2166: am2.reg = opcode & 0xf;
2167: break;
2168: case Aind:
2169: entry.execfunc = &INST_LINK;
2170: am1.mode = imm;
2171: am2.mode = Areg;
2172: entry.params.mask = 0xffff;
2173: break;
2174: case Aipi:
2175: entry.execfunc = &INST_UNLK;
2176: am2.mode = Areg;
2177: break;
2178: case Apdi:
2179: entry.execfunc = &INST_MOVEAUSP;
2180: am2.mode = Areg;
2181: break;
2182: case Ad16:
2183: entry.execfunc = &INST_MOVEUSPA;
2184: am2.mode = Areg;
2185: break;
2186: case Ad8r:
2187: am2.mode = imm;
2188: switch(am2.reg){
2189: case 0: entry.execfunc = &INST_RESET; break;
2190: case 1: entry.execfunc = &INST_NOP; break;
2191: case 2: entry.execfunc = &INST_STOP; break;
2192: case 3: entry.execfunc = &INST_RTE; break;
2193: case 4: entry.execfunc = &INST_RTD; break;
2194: case 5: entry.execfunc = &INST_RTS; break;
2195: case 6: entry.execfunc = &INST_TRAPV; break;
2196: case 7: entry.execfunc = &INST_RTR; break;
2197: }
2198: break;
2199: case absw: case absl: case PC16: case PC8r: case imm:
2200: case imm3: case ill2: case ill3:
2201: entry.execfunc = &INST_ILLG;
2202: break;
2203: }
2204: }
2205: break;
2206: case 2:
2207: switch(r1){
2208: case 0:
2209: entry.execfunc = &INST_NEG;
2210: entry.params.mask = 0xffffffff;
2211: break;
2212: case 1:
2213: entry.execfunc = &INST_CLR;
2214: entry.params.mask = 0xffffffff;
2215: break;
2216: case 2:
2217: entry.execfunc = &INST_NEG;
2218: entry.params.mask = 0xffffffff;
2219: break;
2220: case 3:
2221: entry.execfunc = &INST_NOT;
2222: entry.params.mask = 0xffffffff;
2223: break;
2224: case 4:
2225: entry.params.mask = 0xffff;
2226: if (am2.mode == Dreg) {
2227: entry.execfunc = &INST_EXTW;
2228: } else {
2229: entry.execfunc = &INST_MOVEMRLEA;
2230: }
2231: break;
2232: case 5:
2233: entry.execfunc = &INST_TST;
2234: entry.params.mask = 0xffffffff;
2235: break;
2236: case 6:
2237: entry.params.mask =0xffff;
2238: entry.execfunc = &INST_MOVEMEARL;
2239: break;
2240: case 7:
2241: entry.params.mask =0xffffffff;
2242: if (am2.mode == imm) {
2243: entry.execfunc = &INST_ILLG;
2244: } else {
2245: entry.execfunc = &INST_JSR;
2246: }
2247: break;
2248: }
2249: break;
2250: case 3:
2251: entry.params.mask = 0xffff;
2252: switch(r1){
2253: case 0:
2254: entry.execfunc = &INST_MOVESREA;
2255: break;
2256: case 1:
2257: entry.execfunc = &INST_MOVECCREA;
2258: break;
2259: case 2:
2260: entry.execfunc = &INST_MOVEEACCR;
2261: break;
2262: case 3:
2263: entry.execfunc = &INST_MOVEEASR;
2264: break;
2265: case 4:
2266: entry.params.mask = 0xffffffff;
2267: if (am2.mode == Dreg) {
2268: entry.execfunc = &INST_EXTL;
2269: } else {
2270: entry.execfunc = &INST_MOVEMRLEA;
2271: }
2272: break;
2273: case 5:
2274: entry.execfunc = &INST_NIMP; /* TAS.B */
2275: break;
2276: case 6:
2277: entry.params.mask =0xffffffff;
2278: entry.execfunc = &INST_MOVEMEARL;
2279: break;
2280: case 7:
2281: entry.params.mask =0xffffffff;
2282: if (am2.mode == imm) {
2283: entry.execfunc = &INST_ILLG;
2284: } else {
2285: entry.execfunc = &INST_JMP;
2286: }
2287: break;
2288: }
2289: break;
2290: }
2291: }
2292: break;
2293: case 0x5000:
2294: switch(sz){
2295: case 0: case 1: case 2:
2296: entry.params.mask = sizemask(sz);
2297: if (x) {
2298: if (am2.mode == Areg)
2299: entry.execfunc = &INST_SUBA/*Q*/;
2300: else
2301: entry.execfunc = &INST_SUB/*Q*/;
2302:
2303: } else {
2304: if (am2.mode == Areg)
2305: entry.execfunc = &INST_ADDA/*Q*/;
2306: else
2307: entry.execfunc = &INST_ADD/*Q*/;
2308: }
2309: am1 = am2; am2.mode = imm3; am2.reg = r1 ? r1 : 8;
2310: break;
2311: case 3:
2312: if (am2.mode == Areg) {
2313: entry.params.mask = 0xffff;
2314: entry.execfunc = &INST_DBcc;
2315: am2.mode = Dreg;
2316: } else {
2317: entry.params.mask = 0xff;
2318: entry.execfunc = &INST_Scc;
2319: }
2320: am1.mode = imm3;
2321: am1.reg = (opcode & 0xf00) >> 8;
2322: }
2323: break;
2324: case 0x6000:
2325: offset = opcode & 0xff;
2326: if (x == 1 && r1 == 0) {
2327: if (offset == 0) {
2328: entry.execfunc = &INST_BSRW;
2329: entry.params.mask = 0xffff;
2330: am2.mode = imm;
2331: } else {
2332: entry.execfunc = &INST_BSRB;
2333: entry.params.mask = 0xff;
2334: am2.mode = imm3; am2.reg = opcode & 0xff;
2335: }
2336: } else {
2337: if (offset == 0) {
2338: entry.execfunc = &INST_BccW;
2339: entry.params.mask = 0xffff;
2340: am2.mode = imm;
2341: } else {
2342: entry.execfunc = &INST_BccB;
2343: entry.params.mask = 0xff;
2344: am2.mode = imm3; am2.reg = opcode & 0xff;
2345: }
2346: }
2347: am1.reg = (opcode & 0xf00) >> 8;
2348: break;
2349: case 0x7000:
2350: if (x) {
2351: entry.execfunc = &INST_ILLG;
2352: } else {
2353: entry.execfunc = &INST_MOVEQ;
2354: am1.mode = Dreg; am1.reg = r1; entry.params.mask = 0xffffffff;
2355: am2.mode = imm3; am2.reg = opcode & 0xff;
2356: }
2357: break;
2358: case 0x8000:
2359: if (x) {
2360: switch(sz) {
2361: case 0: case 1: case 2:
2362: entry.params.mask = sizemask(sz);
2363: switch (am2.mode) {
2364: case Dreg:
2365: if (sz != 0) {
2366: entry.execfunc = &INST_NIMP; /* PACK, UNPK */
2367: } else {
2368: entry.execfunc = &INST_SBCD;
2369: entry.params.mask = 0xff;
2370: am1.mode = Dreg;
2371: am1.reg = r1;
2372: }
2373: break;
2374: case Areg:
2375: if (sz != 0) {
2376: entry.execfunc = &INST_NIMP; /* PACK, UNPK */
2377: } else {
2378: entry.execfunc = &INST_SBCD;
2379: entry.params.mask = 0xff;
2380: am1.mode = am2.mode = Apdi;
2381: am1.reg = r1;
2382: }
2383: break;
2384: default:
2385: entry.execfunc = &INST_OR;
2386: am1 = am2; am2.mode = Dreg; am2.reg = r1;
2387: break;
2388: }
2389: break;
2390: case 3:
2391: entry.execfunc = &INST_DIVS;
2392: entry.params.mask = 0xffff;
2393: am1.mode = Dreg; am1.reg = r1;
2394: break;
2395: }
2396: } else {
2397: am1.mode = Dreg; am1.reg = r1;
2398: switch(sz) {
2399: case 0: case 1: case 2:
2400: entry.execfunc = &INST_OR;
2401: entry.params.mask = sizemask(sz);
2402: break;
2403: case 3:
2404: entry.execfunc = &INST_DIVU;
2405: entry.params.mask = 0xffff;
2406: break;
2407: }
2408: }
2409: break;
2410: case 0x9000:
2411: if (sz == 3) {
2412: entry.execfunc = &INST_SUBA;
2413: entry.params.mask = x ? 0xffffffff : 0xffff;
2414: am1.mode = Areg; am1.reg = r1;
2415: } else {
2416: entry.execfunc = &INST_SUB;
2417: entry.params.mask = sizemask(sz);
2418: if (x) {
2419: switch(am2.mode) {
2420: case Dreg:
2421: entry.execfunc = &INST_SUBX;
2422: am1.mode = Dreg;
2423: am1.reg = r1;
2424: break;
2425: case Areg:
2426: entry.execfunc = &INST_SUBX;
2427: am1.mode = am2.mode = Apdi;
2428: am1.reg = r1;
2429: break;
2430: default:
2431: am1 = am2;
2432: am2.mode = Dreg;
2433: am2.reg = r1;
2434: break;
2435: }
2436: } else {
2437: am1.mode = Dreg;
2438: am1.reg = r1;
2439: }
2440: }
2441: break;
2442: case 0xA000:
2443: entry.execfunc = &INST_LINEA;
2444: break;
2445: case 0xB000:
2446: if (sz == 3) {
2447: entry.execfunc = &INST_CMPA;
2448: entry.params.mask = x ? 0xffffffff : 0xffff;
2449: am1.mode = Areg; am1.reg = r1;
2450: } else {
2451: entry.params.mask = sizemask(sz);
2452: am1.mode = Dreg; am1.reg = r1;
2453: if (x) {
2454: if (am2.mode == Areg){
2455: am1.mode = am2.mode = Aipi;
2456: am1.reg = r1;
2457: entry.execfunc = &INST_CMP/*M*/;
2458: } else {
2459: entry.execfunc = &INST_EOR;
2460: am1 = am2; am2.mode = Dreg; am2.reg = r1;
2461: }
2462: } else {
2463: entry.execfunc = &INST_CMP;
2464: }
2465: }
2466: break;
2467: case 0xC000:
2468: if (x) {
2469: switch(sz) {
2470: case 0: case 1: case 2:
2471: entry.params.mask = sizemask(sz);
2472: switch (am2.mode) {
2473: case Dreg:
2474: switch(sz) {
2475: case 2:
2476: entry.execfunc = &INST_ILLG;
2477: break;
2478: case 1:
2479: entry.execfunc = &INST_EXGL;
2480: entry.params.mask = 0xffffffff;
2481: am1 = am2;
2482: am2.mode = Dreg; am2.reg = r1;
2483: break;
2484: case 0:
2485: entry.execfunc = &INST_ABCD;
2486: entry.params.mask = 0xff;
2487: am1.mode = Dreg; am1.reg = r1;
2488: break;
2489: }
2490: break;
2491: case Areg:
2492: switch(sz) {
2493: case 2:
2494: entry.execfunc = &INST_EXGL;
2495: entry.params.mask = 0xffffffff;
2496: am1 = am2;
2497: am2.mode = Dreg; am2.reg = r1;
2498: break;
2499: case 1:
2500: entry.execfunc = &INST_EXGL;
2501: entry.params.mask = 0xffffffff;
2502: am1 = am2;
2503: am2.mode = Areg; am2.reg = r1;
2504: break;
2505: case 0:
2506: entry.execfunc = &INST_ABCD;
2507: entry.params.mask = 0xff;
2508: am1.mode = am2.mode = Apdi;
2509: am1.reg = r1;
2510: break;
2511: }
2512: break;
2513: default:
2514: entry.execfunc = &INST_AND;
2515: am1 = am2;
2516: am2.mode = Dreg; am2.reg = r1;
2517: break;
2518: }
2519: break;
2520: case 3:
2521: entry.execfunc = &INST_MULS;
2522: entry.params.mask = 0xffff;
2523: am1.mode = Dreg; am1.reg = r1;
2524: break;
2525: }
2526: } else {
2527: am1.mode = Dreg; am1.reg = r1;
2528: switch(sz) {
2529: case 0: case 1: case 2:
2530: entry.execfunc = &INST_AND;
2531: entry.params.mask = sizemask(sz);
2532: break;
2533: case 3:
2534: entry.execfunc = &INST_MULU;
2535: entry.params.mask = 0xffff;
2536: break;
2537: }
2538: }
2539: break;
2540: case 0xD000:
2541: if (sz == 3) {
2542: entry.execfunc = &INST_ADDA;
2543: entry.params.mask = x ? 0xffffffff : 0xffff;
2544: am1.mode = Areg; am1.reg = r1;
2545: } else {
2546: entry.execfunc = &INST_ADD;
2547: entry.params.mask = sizemask(sz);
2548: if (x) {
2549: switch(am2.mode) {
2550: case Dreg:
2551: entry.execfunc = &INST_ADDX;
2552: am1.mode = Dreg;
2553: am1.reg = r1;
2554: break;
2555: case Areg:
2556: entry.execfunc = &INST_ADDX;
2557: am1.mode = am2.mode = Apdi;
2558: am1.reg = r1;
2559: break;
2560: default:
2561: am1 = am2;
2562: am2.mode = Dreg;
2563: am2.reg = r1;
2564: break;
2565: }
2566: } else {
2567: am1.mode = Dreg;
2568: am1.reg = r1;
2569: }
2570: }
2571: break;
2572: case 0xE000:
2573: {
2574: int type;
2575:
2576: if (sz == 3) {
2577: entry.params.mask = 0xffff;
2578: type = r1*2 + x;
2579: switch(type) {
2580: case 0: entry.execfunc = &INST_ASR1; break;
2581: case 1: entry.execfunc = &INST_ASL1; break;
2582: case 2: entry.execfunc = &INST_LSR1; break;
2583: case 3: entry.execfunc = &INST_LSL1; break;
2584: case 4: entry.execfunc = &INST_ROXR1; break;
2585: case 5: entry.execfunc = &INST_ROXL1; break;
2586: case 6: entry.execfunc = &INST_ROR1; break;
2587: case 7: entry.execfunc = &INST_ROL1; break;
2588: default:
2589: entry.execfunc = &INST_NIMP; /* 020 bit fiends */
2590: break;
2591: }
2592: if (type < 8) {
2593: if (am2.mode == Dreg || am2.mode == Areg || am2.mode == PC16 ||
2594: am2.mode == PC8r || am2.mode == imm) {
2595: entry.execfunc = &INST_ILLG;
2596: }
2597: }
2598: am1 = am2;
2599: } else {
2600: type = x + (m2 & 3)*2;
2601: entry.params.mask = sizemask(sz);
2602: switch(type) {
2603: case 0: entry.execfunc = &INST_ASR; break;
2604: case 1: entry.execfunc = &INST_ASL; break;
2605: case 2: entry.execfunc = &INST_LSR; break;
2606: case 3: entry.execfunc = &INST_LSL; break;
2607: case 4: entry.execfunc = &INST_ROXR; break;
2608: case 5: entry.execfunc = &INST_ROXL; break;
2609: case 6: entry.execfunc = &INST_ROR; break;
2610: case 7: entry.execfunc = &INST_ROL; break;
2611: }
2612: am1.mode = Dreg; am1.reg = r2;
2613: if (m2 > 3) {
2614: am2.mode = Dreg; am2.reg = r1;
2615: } else {
2616: am2.mode = imm3;
2617: am2.reg = r1 ? r1 : 8;
2618: }
2619: }
2620: }
2621: break;
2622: case 0xF000:
2623: entry.execfunc = &INST_LINEF;
2624: break;
2625: }
2626: entry.params.dest = am1; entry.params.src = am2;
2627: instr_dectab[opcode] = entry;
2628: }
2629: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.