|
|
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.