17 u32int r[16], pc, curpc;
18 u32int asp, irq, stop;
19 extern u32int irql[8];
29 sysfatal("undefined opcode %#o at pc=%#.6x", op, curpc);
55 memwrite(ra[7], u, -1);
72 memwrite(ra[7], u >> 16, -1);
73 memwrite(ra[7] + 2, u, -1);
80 v = memread(ra[7]) << 16;
81 v |= memread(ra[7] + 2);
87 amode(int m, int n, int s)
103 tim += s == 2 ? 8 : 4;
108 tim += s == 2 ? 8 : 4;
111 tim += s == 2 ? 10 : 6;
112 return ra[n] -= 1<<s;
114 tim += s == 2 ? 12 : 8;
115 return (u32int)(ra[n] + (s16int)fetch16());
117 tim += s == 2 ? 14 : 10;
122 return (u32int)(ra[n] + v + (s8int)w);
126 tim += s == 2 ? 12 : 8;
127 return (u32int)(s16int)fetch16();
129 tim += s == 2 ? 16 : 12;
132 tim += s == 2 ? 12 : 8;
134 return (u32int)(pc + (s16int)v - 2);
136 tim += s == 2 ? 14 : 4;
141 return (u32int)(pc + v + (s8int)w - 2);
143 tim += s == 2 ? 8 : 4;
159 rmode(vlong a, int s)
171 return (s16int) memread(a);
173 v = memread(a) << 16;
174 return v | memread(a + 2);
179 case 0: return (s8int) v;
180 case 1: return (s16int) v;
186 wmode(vlong a, int s, u32int v)
193 memwrite(a, (u8int)v | (u8int)v << 8, (a & 1) != 0 ? 0xff : 0xff00);
199 memwrite(a, v >> 16, -1);
200 memwrite(a + 2, v, -1);
207 case 0: r[n] = r[n] & 0xffffff00 | v & 0xff; break;
208 case 1: r[n] = r[n] & 0xffff0000 | v & 0xffff; break;
222 case 0: v = (s8int) v; break;
223 case 1: v = (s16int) v; break;
225 rS &= ~(FLAGC|FLAGN|FLAGV|FLAGZ);
233 add(u32int u, u32int w, int c, int s)
237 rS &= ~(FLAGN|FLAGV|FLAGC);
240 v = (u8int)w + (u8int)u + c;
245 if((~(w ^ u) & (v ^ u) & 0x80) != 0)
251 v = (u16int)w + (u16int)u + c;
254 if((v & 0x8000) != 0)
256 if((~(w ^ u) & (v ^ u) & 0x8000) != 0)
262 v = (u64int)w + u + c;
265 if((v & 0x80000000) != 0)
267 if((~(w ^ u) & (v ^ u) & 0x80000000) != 0)
277 sub(u32int u, u32int w, int c, int s)
281 rS &= ~(FLAGN|FLAGV|FLAGC);
284 v = (u8int)u - (u8int)w - c;
289 if(((w ^ u) & (v ^ u) & 0x80) != 0)
295 v = (u16int)u - (u16int)w - c;
298 if((v & 0x8000) != 0)
300 if(((w ^ u) & (v ^ u) & 0x8000) != 0)
306 v = (u64int)u - w - c;
309 if((v & 0x80000000) != 0)
311 if(((w ^ u) & (v ^ u) & (1<<31)) != 0)
324 case 0: return 1; break;
325 default: return 0; break;
326 case 2: return (rS & (FLAGC|FLAGZ)) == 0; break;
327 case 3: return (rS & (FLAGC|FLAGZ)) != 0; break;
328 case 4: return (rS & FLAGC) == 0; break;
329 case 5: return (rS & FLAGC) != 0; break;
330 case 6: return (rS & FLAGZ) == 0; break;
331 case 7: return (rS & FLAGZ) != 0; break;
332 case 8: return (rS & FLAGV) == 0; break;
333 case 9: return (rS & FLAGV) != 0; break;
334 case 10: return (rS & FLAGN) == 0; break;
335 case 11: return (rS & FLAGN) != 0; break;
336 case 12: return ((rS ^ (rS << 2)) & FLAGN) == 0; break;
337 case 13: return ((rS ^ (rS << 2)) & FLAGN) != 0; break;
338 case 14: return ((rS ^ (rS << 2)) & FLAGN) == 0 && (rS & FLAGZ) == 0; break;
339 case 15: return ((rS ^ (rS << 2)) & FLAGN) != 0 || (rS & FLAGZ) != 0; break;
344 rot(u32int v, int m, int n, int s)
349 msb = 1 << ((8 << s) - 1);
356 ll = l = (rS & FLAGX) != 0;
368 rS = rS & ~FLAGX | l << 4;
380 vf |= x ^ (v & msb) != 0;
387 tim += s == 2 ? 8 : 6;
392 addbcd(u8int a, u8int b)
396 r = (a & 0xf) + (b & 0xf) + ((rS & FLAGX) != 0);
397 if(r > 0x09) r += 0x06;
398 if(r > 0x1f) r -= 0x10;
399 r += (a & 0xf0) + (b & 0xf0);
400 if(r > 0x9f) r += 0x60;
406 rS &= ~(FLAGC|FLAGX);
411 subbcd(u8int a, u8int b)
415 x = (a & 0xf) + (~b & 0xf) + ((rS & FLAGX) == 0);
416 if(x < 0x10) x -= 0x06;
418 x += (a & 0xf0) + (~b & 0xf0);
420 rS &= ~(FLAGC|FLAGX);
431 dtime(u16int op, u8int s)
433 if((op & 0x100) != 0){
435 if((op & 0x30) == 0 || (op & 0x3f) == 0x3c)
442 tim += s == 2 ? 12 : 8;
446 stime(int a, u8int s)
449 tim += s == 2 ? 6 : 4;
451 tim += s == 2 ? 12 : 8;
455 trap(int n, u32int pcv)
462 for(l = 7; l > ((rS >> 8) & 7); l--)
463 if((irql[l] & irq) != 0)
466 rS = rS & ~0x700 | l << 8;
470 case 2: case 3: tim += 50; break;
471 case 5: tim += 38; break;
472 case 6: tim += 40; break;
473 default: tim += 34; break;
477 if((rS & FLAGS) == 0){
485 pc = memread(v * 4) << 16;
486 pc |= memread(v * 4 + 2);
496 ra[7] = memread(0) << 16 | memread(2);
497 pc = memread(4) << 16 | memread(6);
499 for(i = 7, v = 0; i >= 0; i--){
514 if(0 && pc == 0x4118c){
516 print("%x\n", curpc);
520 if(irq && (irqla[(rS >> 8) & 7] & irq) != 0){
528 print("%.6ux %.6uo %.4ux %.8ux | %.8ux %.8ux %.8ux %.8ux | %.8ux %.8ux %.8ux\n", curpc, op, rS, memread(ra[7])<<16|memread(ra[7]+2), r[0], r[1], r[2], r[3], ra[0], ra[6], ra[7]);
533 if((op & 0x3f) == 0x3c){ /* (ORI|ANDI|EORI) to (CCR|SR) */
534 if(s == 1 && (rS & FLAGS) == 0){
541 case 0: v |= w; break;
542 case 1: v &= w; break;
543 case 5: v ^= w; break;
547 v = v & 0xff | rS & 0xff00;
549 if(s == 1 && (rS & FLAGS) == 0){
557 if((op & 0x138) == 0x108){ /* MOVEP */
558 a = ra[op & 7] + (s16int)fetch16();
561 v = (u8int)rmode(a, 0) << 8;
562 v |= (u8int)rmode(a + 2, 0);
563 r[n] = r[n] & 0xff00 | v;
567 v = (u8int)rmode(a, 0) << 24;
568 v |= (u8int)rmode(a + 2, 0) << 16;
569 v |= (u8int)rmode(a + 4, 0) << 8;
570 v |= (u8int)rmode(a + 6, 0);
575 wmode(a, 0, r[n] >> 8);
576 wmode(a + 2, 0, r[n]);
580 wmode(a, 0, r[n] >> 24);
581 wmode(a + 2, 0, r[n] >> 16);
582 wmode(a + 4, 0, r[n] >> 8);
583 wmode(a + 6, 0, r[n]);
589 if((op & 0x100) != 0 || n == 4){ /* BTST, BCHG, BCLR, BSET */
590 if((op & 0x100) != 0)
594 if((op & 0x38) != 0){
601 a = amode(op >> 3, op, n);
607 case 1: v ^= w; break;
608 case 2: v &= ~w; if(n == 2) tim += 2; break;
609 case 3: v |= w; break;
613 tim += (op & 0x100) != 0 ? 8 : 12;
615 tim += (op & 0x100) != 0 ? 4 : 8;
622 case 0: w = (s8int)fetch16(); break;
623 default: w = fetch16(); break;
624 case 2: w = fetch32(); break;
626 a = amode(op >> 3, op, s);
629 case 0: nz(v |= w, s); break;
630 case 1: nz(v &= w, s); break;
631 case 2: rS |= FLAGZ; v = sub(v, w, 0, s); break;
632 case 3: rS |= FLAGZ; v = add(v, w, 0, s); break;
633 case 5: nz(v ^= w, s); break;
634 case 6: rS |= FLAGZ; sub(v, w, 0, s); break;
638 tim += s == 2 ? (n == 1 || n == 6 ? 14 : 16) : 8;
640 tim += s == 2 ? 20 : 12;
653 v = rmode(amode(op >> 3, op, s), s);
654 wmode(amode(op >> 6, op >> 9, s), s, v);
655 if((op & 0x1c0) != 0x40)
660 if((op & 0x1c0) == 0x1c0){ /* LEA */
661 ra[n] = amode(op >> 3, op, 2);
664 if((op & 0x1c0) == 0x180){ /* CHK */
665 a = amode(op >> 3, op, s);
667 if((s32int)r[n] < 0 || (s32int)r[n] > (s32int)v)
672 if((op & 0xb80) == 0x880 && (op & 0x38) >= 0x10){ /* MOVEM */
673 s = (op >> 6 & 1) + 1;
675 if((op & 0x38) == 0x18){
678 for(m = 0; m < 16; m++){
690 if((op & 0x38) == 0x20){
693 for(m = 0; m < 16; m++){
696 wmode(a, s, r[15 - m]);
705 a = amode(op >> 3, op, s);
706 for(m = 0; m < 16; m++){
708 if((op & 0x400) != 0)
717 tim += (op & 0x400) != 0 ? 8 : 12;
720 switch(op >> 8 & 0xf){
722 if(s == 3){ /* MOVE from SR */
723 if((rS & FLAGS) != 0){
724 a = amode(op >> 3, op, 1);
726 tim += a < 0 ? 6 : 8;
731 a = amode(op >> 3, op, s);
732 m = (rS & FLAGX) != 0;
735 w = -(v+m) & (d << 1) - 1;
736 rS &= ~(FLAGC|FLAGX|FLAGN|FLAGV);
749 a = amode(op >> 3, op, s);
755 if(s == 3){ /* MOVE to CCR */
756 rS = rS & 0xff00 | rmode(amode(op >> 3, op, 1), 1);
760 a = amode(op >> 3, op, s);
763 rS = rS & ~FLAGX | ~rS << 2 & FLAGX | ~rS >> 2 & FLAGC;
768 if(s == 3){ /* MOVE to SR */
769 if((rS & FLAGS) != 0){
770 rS = rmode(amode(op >> 3, op, 1), 1);
771 if((rS & FLAGS) == 0){
781 a = amode(op >> 3, op, s);
791 a = amode(op >> 3, op, 0);
793 wmode(a, 0, subbcd(0, v));
800 if((op >> 3 & 7) != 0){
801 push32(amode(op >> 3, op, 0)); /* PEA */
804 nz(r[n] = r[n] >> 16 | r[n] << 16, 2); /* SWAP */
809 nz(r[n] = r[n] & 0xffff0000 | (u16int)(s8int)r[n], 1);
813 nz(r[n] = (s16int)r[n], 2);
819 if(s == 3){ /* TAS */
820 a = amode(op >> 3, op, 0);
823 wmode(a, s, v | 0x80);
824 tim += a < 0 ? 4 : 14;
827 a = amode(op >> 3, op, s);
834 if(v == 4){ /* TRAP */
835 trap(0x20 | op & 0xf, pc);
838 if((op & 8) == 0){ /* LINK */
841 ra[7] += (s16int)fetch16();
849 }else if(v == 6){ /* MOVE USP */
850 if((rS & FLAGS) != 0){
860 if((op & 0xc0) == 0xc0){ /* JMP */
861 pc = amode(op >> 3, op, 2);
865 if((op & 0xc0) == 0x80){ /* JSR */
866 a = amode(op >> 3, op, 2);
873 case 0x4e70: tim += 132; break; /* RESET */
874 case 0x4e71: tim += 4; break; /* NOP */
875 case 0x4e72: /* STOP */
876 if((rS & FLAGS) != 0){
883 case 0x4e73: /* RTE */
884 if((rS & FLAGS) != 0){
888 if(((v ^ rS) & FLAGS) != 0){
897 case 0x4e75: pc = pop32(); tim += 16; break; /* RTS */
898 case 0x4e76: if((rS & FLAGV) != 0) trap(7, curpc); tim += 4; break; /* TRAPV */
899 case 0x4e77: /* RTR */
900 rS = rS & 0xff00 | pop16() & 0xff;
912 if((op & 0xf8) == 0xc8){ /* DBcc */
914 v = (s16int)fetch16();
915 if(!cond((op >> 8) & 0xf)){
916 if((u16int)r[n] != 0){
928 if(s == 3){ /* Scc */
929 a = amode(op >> 3, op, 0);
930 v = cond(op >> 8 & 0xf);
939 if((op & 0x38) == 0x08)
941 a = amode(op >> 3, op, s);
945 if((op & 0x100) == 0)
949 rS = rS & ~FLAGX | rS << 4 & FLAGX;
951 tim += s == 2 || (op & 0x130) == 0x110 ? 8 : 4;
953 tim += s == 2 ? 12 : 8;
959 v = (s16int)fetch16();
960 else if(v == (u32int)-1)
962 if((op & 0xf00) == 0x100){ /* BSR */
968 if(cond((op >> 8) & 0xf)){
972 tim += (u8int)(op + 1) <= 1 ? 12 : 8;
980 if(s == 3){ /* DIVU, DIVS */
981 a = amode(op >> 3, op, 1);
987 if((op & 0x100) != 0){
988 w = (s32int)r[n] % (s16int)v;
989 v = (s32int)r[n] / (s16int)v;
990 if(((s16int)w ^ (s16int)v) < 0)
992 if(v != (u32int)(s16int)v){
993 rS = rS & ~FLAGC | FLAGV;
998 w = r[n] % (u16int)v;
999 v = r[n] / (u16int)v;
1001 rS = rS & ~FLAGC | FLAGV;
1006 r[n] = (u16int)v | w << 16;
1010 if((op & 0x1f0) == 0x100){ /* SBCD */
1016 w = rmode(amode(4, m, 0), 0);
1021 r[n] = r[n] & 0xffffff00 | subbcd((u8int)r[n], (u8int)r[m]);
1026 logic: /* OR, EOR, AND */
1027 a = amode(op >> 3, op, s);
1031 case 8: v |= r[n]; break;
1032 case 11: v ^= r[n]; break;
1033 case 12: v &= r[n]; break;
1035 if((op & 0x100) == 0)
1042 if(s == 3){ /* CMPA */
1043 s = (op >> 8 & 1) + 1;
1044 a = amode(op >> 3, op, s);
1046 sub(ra[n], rmode(a, s), 0, 2);
1050 if((op & 0x138) == 0x108){ /* CMPM */
1053 sub(rmode(amode(3, n, s), s), rmode(amode(3, m, s), s), 0, s);
1054 tim += s == 2 ? 20 : 12;
1057 if((op & 0x100) == 0){ /* CMP */
1058 a = amode(op >> 3, op, s);
1060 sub(r[n], rmode(a, s), 0, s);
1061 tim += s == 2 ? 6 : 4;
1066 if(s == 3){ /* MULU, MULS */
1067 a = amode(op >> 3, op, 1);
1069 if((op & 0x100) != 0)
1072 v = (u16int)v * (u16int)r[n];
1078 if((op & 0x1f0) == 0x100){ /* ABCD */
1084 w = rmode(amode(4, m, 0), 0);
1089 r[n] = r[n] & 0xffffff00 | addbcd((u8int)r[n], (u8int)r[m]);
1095 if((op & 0x130) == 0x100){ /* EXG */
1097 if((op & 0xc8) == 0x48)
1108 if(s == 3){ /* ADDA, SUBA */
1109 if((op & 0x100) != 0){
1116 a = amode(op >> 3, op, s);
1117 if((op >> 12) == 13)
1118 ra[n] += rmode(a, s);
1120 ra[n] -= rmode(a, s);
1123 if((op & 0x130) == 0x100){ /* ADDX, SUBX */
1128 w = rmode(ra[m] -= 1<<s, s);
1129 tim += s == 2 ? 30 : 18;
1134 tim += s == 2 ? 8 : 4;
1136 if((op >> 12) == 13)
1137 v = add(v, w, (rS & FLAGX) != 0, s);
1139 v = sub(v, w, (rS & FLAGX) != 0, s);
1141 rS = rS & ~FLAGX | rS << 4 & FLAGX;
1144 a = amode(op >> 3, op, s);
1146 d = (op & 0x100) == 0;
1148 if((op >> 12) == 13)
1149 v = add(v, r[n], 0, s);
1151 v = sub(d ? r[n] : v, d ? v : r[n], 0, s);
1152 rS = rS & ~FLAGX | rS << 4 & FLAGX;
1158 case 14: /* shifts */
1163 a = amode(op >> 3, op, s);
1165 a = ~(uvlong)(op & 7);
1166 m = op >> 2 & 6 | op >> 8 & 1;
1168 if((op & 0x20) != 0)
1173 wmode(a, s, rot(rmode(a, s), m, n, s));