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