|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: #include "mpu680x0.h" ! 8: #include "m680x0acc.h" ! 9: #include "m680x0bitfield.h" ! 10: #include "m68040mmu.h" ! 11: ! 12: #define OP_DEF(name) void __CONCAT(MPU680x0Device::op_,name)() ! 13: #define OP_FUNC(name) __CONCAT(op_,name)() ! 14: ! 15: #define CCR reg.ccr ! 16: #define ACC (*(m680x0ACC*)®.ccr) ! 17: ! 18: #define RegIRX ((ir >> 9) & 7) ! 19: #define RegIRY (ir & 7) ! 20: #define RegDX reg.D[RegIRX] ! 21: #define RegAX reg.A[RegIRX] ! 22: #define RegDY reg.D[RegIRY] ! 23: #define RegAY reg.A[RegIRY] ! 24: ! 25: // (エミュレータ的)未実装命令 ! 26: #define op_unimpl(cpu) \ ! 27: PANIC("unimplemented instruction! %s()", __FUNCTION__) ! 28: ! 29: // 副作用のあるマクロ ! 30: // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。 ! 31: #define SUPERVISOR_OP do { \ ! 32: if (!IsSuper()) { \ ! 33: CYCLE2(18, 20); \ ! 34: Exception(M68K::EXCEP_PRIV); \ ! 35: return; \ ! 36: } \ ! 37: } while (0) ! 38: ! 39: // %0000_000000_mmmrrr d.m+-rxw.. 034 ORI.B #<imm>,<ea> ! 40: // %0000_000000_111100 .......... 034 ORI.B #<imm>,CCR ! 41: OP_DEF(ori_b) ! 42: { ! 43: uint n = ir & 0x3f; ! 44: ! 45: uint32 src = fetch_2() & 0xff; ! 46: if (n < 8) { ! 47: // ORI.B #<imm>,Dn ! 48: CYCLE(2); ! 49: uint32 dst = (reg.D[n] & 0xff) | src; ! 50: ACC.move_8(dst); ! 51: reg.D[n] = (reg.D[n] & 0xffffff00) | dst; ! 52: } else if (n == 0b111100) { ! 53: // ORI.B #<imm>,CCR ! 54: CYCLE2(12, 14); ! 55: CCR.Set(CCR.Get() | src); ! 56: } else { ! 57: // ORI.B #<imm>,<ea> ! 58: CYCLE2(3, 4); ! 59: uint32 ea = cea_data_1(); ! 60: uint32 dst = read_1(ea); ! 61: dst |= src; ! 62: ACC.move_8(dst); ! 63: write_1(ea, dst); ! 64: } ! 65: } ! 66: ! 67: // %0000_000001_mmmrrr d.m+-rxw.. 034 ORI.W #<imm>,<ea> ! 68: // %0000_000001_111100 .......... 034 ORI.W #<imm>,SR ! 69: OP_DEF(ori_w) ! 70: { ! 71: uint n = ir & 0x3f; ! 72: ! 73: if (n < 8) { ! 74: // ORI.W #<imm>,Dn ! 75: CYCLE(2); ! 76: uint32 src = fetch_2(); ! 77: uint32 dst = (reg.D[n] & 0xffff) | src; ! 78: ACC.move_16(dst); ! 79: reg.D[n] = (reg.D[n] & 0xffff0000) | dst; ! 80: } else if (n == 0b111100) { ! 81: // ORI.W #<imm>,SR ! 82: SUPERVISOR_OP; ! 83: CYCLE2(12, 14); ! 84: uint32 src = fetch_2(); ! 85: SetSR(GetSR() | src); ! 86: } else { ! 87: // ORI.W #<imm>,<ea> ! 88: CYCLE2(3, 4); ! 89: uint32 src = fetch_2(); ! 90: uint32 ea = cea_data_2(); ! 91: uint32 dst = read_2(ea); ! 92: dst |= src; ! 93: ACC.move_16(dst); ! 94: write_2(ea, dst); ! 95: } ! 96: } ! 97: ! 98: // %0000_000010_mmmrrr d.m+-rxw.. 034 ORI.L #<imm>,<ea> ! 99: OP_DEF(ori_l) ! 100: { ! 101: uint n = ir & 0x3f; ! 102: ! 103: uint32 src = fetch_4(); ! 104: if (n < 8) { ! 105: // ORI.L #<imm>,Dn ! 106: CYCLE(2); ! 107: reg.D[n] |= src; ! 108: ACC.move_32(reg.D[n]); ! 109: } else { ! 110: // ORI.L #<imm>,<ea> ! 111: CYCLE2(3, 4); ! 112: uint32 ea = cea_data_4(); ! 113: uint32 dst = read_4(ea); ! 114: dst |= src; ! 115: ACC.move_32(dst); ! 116: write_4(ea, dst); ! 117: } ! 118: } ! 119: ! 120: // %0000_000011_mmmrrr ..m..rxwp. -34 CMP2/CHK2.B <ea>,Rn ! 121: OP_DEF(cmp2chk2_b) ! 122: { ! 123: ir2 = fetch_2(); ! 124: uint32 compare; ! 125: uint32 ea = cea_ctrl(); ! 126: uint32 lower; ! 127: uint32 upper; ! 128: ! 129: if ((ir2 & 0x8000) == 0) { ! 130: // compare が Dn ! 131: compare = (int32)(int8)(reg.R[ir2 >> 12] & 0xff); ! 132: } else { ! 133: // compare が An ! 134: compare = reg.R[ir2 >> 12]; ! 135: } ! 136: ! 137: // 本当は PC 相対ならプログラム空間アクセス、 ! 138: // それ以外はデータ空間アクセスだが、ここでは区別しない。 ! 139: lower = (int32)(int8)read_1(ea); ! 140: upper = (int32)(int8)read_1(ea + 1); ! 141: ! 142: ACC.chk2cmp2_32(compare, lower, upper); ! 143: ! 144: // サイクル数はこれは実際には全部最大値 ! 145: if ((ir2 & 0x0800)) { ! 146: // CHK2 で条件を満たしていれば例外 ! 147: if (reg.ccr.CondCS()) { ! 148: CYCLE2(40, 42); ! 149: Exception(M68K::EXCEP_CHK); ! 150: } else { ! 151: CYCLE(18); ! 152: } ! 153: } else { ! 154: // CMP2 ! 155: CYCLE(20); ! 156: } ! 157: } ! 158: ! 159: // MOVEP.[WL] (d,Ay),Dx と ! 160: // MOVEP.[WL] Dx,(d,Ay) の共通部分。 ! 161: void ! 162: MPU680x0Device::ops_movep() ! 163: { ! 164: uint32 disp = (int32)(int16)fetch_2(); ! 165: uint32 ea = RegAY + disp; ! 166: bool size_long = ((ir & 0x40) != 0); ! 167: bool reg2mem = ((ir & 0x80) != 0); ! 168: ! 169: CYCLE(14); ! 170: ! 171: if (reg2mem) { ! 172: // Dx -> memory ! 173: uint32 dx = RegDX; ! 174: if (size_long) { ! 175: write_1(ea, (dx >> 24)); ! 176: ea += 2; ! 177: write_1(ea, (dx >> 16) & 0xff); ! 178: ea += 2; ! 179: } ! 180: write_1(ea, (dx >> 8) & 0xff); ! 181: ea += 2; ! 182: write_1(ea, (dx & 0xff)); ! 183: } else { ! 184: // memory -> Dx ! 185: uint32 dx = 0; ! 186: if (size_long) { ! 187: dx = read_1(ea); ! 188: dx <<= 8; ! 189: ea += 2; ! 190: dx |= read_1(ea); ! 191: dx <<= 8; ! 192: ea += 2; ! 193: } ! 194: // word ! 195: dx |= read_1(ea); ! 196: dx <<= 8; ! 197: ea += 2; ! 198: dx |= read_1(ea); ! 199: ! 200: if (size_long) { ! 201: RegDX = dx; ! 202: } else { ! 203: RegDX = (RegDX & 0xffff0000) | (dx & 0xffff); ! 204: } ! 205: } ! 206: } ! 207: ! 208: // %0000_xxx100_mmmrrr ..m+-rxwpi 034 BTST.B Dx,<ea> ! 209: // %0000_xxx100_000yyy .......... 034 BTST.L Dx,Dy ! 210: // %0000_xxx100_001yyy .......... 034 MOVEP.W (d,Ay),Dx ! 211: OP_DEF(btst_dn_ea) ! 212: { ! 213: uint n = ir & 0x3f; ! 214: ! 215: if (n < 8) { ! 216: // BTST.L Dx,Dy ! 217: CYCLE(4); ! 218: uint bit = (RegDX & 31); ! 219: ACC.btst(RegDY, bit); ! 220: } else if (n < 16) { ! 221: // MOVEP.W (d,Ay),Dx ! 222: ops_movep(); ! 223: } else { ! 224: // BTST.B Dx,<ea> ! 225: CYCLE(4); ! 226: uint bit = (RegDX & 7); ! 227: uint32 data = fea_data_1(); ! 228: ACC.btst(data, bit); ! 229: } ! 230: } ! 231: ! 232: // %0000_xxx101_mmmrrr ..m+-rxw.. 034 BCHG.B Dx,<ea> ! 233: // %0000_xxx101_000yyy .......... 034 BCHG.L Dx,Dy ! 234: // %0000_xxx101_001yyy .......... 034 MOVEP.L (d,Ay),Dx ! 235: OP_DEF(bchg_dn_ea) ! 236: { ! 237: uint n = ir & 0x3f; ! 238: ! 239: if (n < 8) { ! 240: // BCHG.L Dx,Dy ! 241: CYCLE(6); ! 242: uint bit = (RegDX & 31); ! 243: RegDY = ACC.bchg(RegDY, bit); ! 244: } else if (n < 16) { ! 245: // MOVEP.L (d,Ay),Dx ! 246: ops_movep(); ! 247: } else { ! 248: // BCHG.B Dx,<ea> ! 249: CYCLE(6); ! 250: uint bit = (RegDX & 7); ! 251: uint32 ea = cea_data_1(); ! 252: uint32 data = read_1(ea); ! 253: data = ACC.bchg(data, bit); ! 254: write_1(ea, data); ! 255: } ! 256: } ! 257: ! 258: // %0000_xxx110_mmmrrr ..m+-rxw.. 034 BCLR.B Dx,<ea> ! 259: // %0000_xxx110_000yyy .......... 034 BCLR.L Dx,Dy ! 260: // %0000_xxx110_001yyy .......... 034 MOVEP.W Dx,(d,Ay) ! 261: OP_DEF(bclr_dn_ea) ! 262: { ! 263: uint n = ir & 0x3f; ! 264: ! 265: if (n < 8) { ! 266: // BCLR.L Dx,Dy ! 267: CYCLE(6); ! 268: uint bit = (RegDX & 31); ! 269: RegDY = ACC.bclr(RegDY, bit); ! 270: } else if (n < 16) { ! 271: // MOVEP.W Dx,(d,Ay) ! 272: ops_movep(); ! 273: } else { ! 274: // BCLR.B Dx,<ea> ! 275: CYCLE(6); ! 276: uint bit = (RegDX & 7); ! 277: uint32 ea = cea_data_1(); ! 278: uint32 data = read_1(ea); ! 279: data = ACC.bclr(data, bit); ! 280: write_1(ea, data); ! 281: } ! 282: } ! 283: ! 284: // %0000_xxx111_mmmrrr ..m+-rxw.. 034 BSET.B Dx,<ea> ! 285: // %0000_xxx111_000yyy .......... 034 BSET.L Dx,Dy ! 286: // %0000_xxx111_001yyy .......... 034 MOVEP.L Dx,(d,Ay) ! 287: OP_DEF(bset_dn_ea) ! 288: { ! 289: uint n = ir & 0x3f; ! 290: ! 291: if (n < 8) { ! 292: // BSET.L Dx,Dy ! 293: CYCLE(6); ! 294: uint bit = (RegDX & 31); ! 295: RegDY = ACC.bset(RegDY, bit); ! 296: } else if (n < 16) { ! 297: // MOVEP.L Dx,(d,Ay) ! 298: ops_movep(); ! 299: } else { ! 300: // BSET.B Dx,<ea> ! 301: CYCLE(6); ! 302: uint bit = (RegDX & 7); ! 303: uint32 ea = cea_data_1(); ! 304: uint32 data = read_1(ea); ! 305: data = ACC.bset(data, bit); ! 306: write_1(ea, data); ! 307: } ! 308: } ! 309: ! 310: // %0000_001000_mmmrrr d.m+-rxw.. 034 ANDI.B #<imm>,<ea> ! 311: // %0000_001000_111100 .......... 034 ANDI.B #<imm>,CCR ! 312: OP_DEF(andi_b) ! 313: { ! 314: uint n = ir & 0x3f; ! 315: ! 316: uint32 src = fetch_2() & 0xff; ! 317: if (n < 8) { ! 318: // ANDI.B #<imm>,Dn ! 319: CYCLE(2); ! 320: uint32 dst = reg.D[n] & 0xff; ! 321: dst &= src; ! 322: ACC.move_8(dst); ! 323: reg.D[n] = (reg.D[n] & 0xffffff00) | dst; ! 324: } else if (n == 0b111100) { ! 325: // ANDI.B #<imm>,CCR ! 326: CYCLE2(12, 14); ! 327: CCR.Set(CCR.Get() & src); ! 328: } else { ! 329: // ANDI.B #<imm>,<ea> ! 330: CYCLE2(3, 4); ! 331: uint32 ea = cea_data_1(); ! 332: uint32 dst = read_1(ea); ! 333: dst &= src; ! 334: ACC.move_8(dst); ! 335: write_1(ea, dst); ! 336: } ! 337: } ! 338: ! 339: // %0000_001001_mmmrrr d.m+-rxw.. 034 ANDI.W #<imm>,<ea> ! 340: // %0000_001001_111100 .......... 034 ANDI.W #<imm>,SR ! 341: OP_DEF(andi_w) ! 342: { ! 343: uint n = ir & 0x3f; ! 344: ! 345: if (n < 8) { ! 346: // ANDI.W #<imm>,Dn ! 347: CYCLE(2); ! 348: uint32 src = fetch_2(); ! 349: uint32 dst = reg.D[n] & 0xffff; ! 350: dst &= src; ! 351: ACC.move_16(dst); ! 352: reg.D[n] = (reg.D[n] & 0xffff0000) | dst; ! 353: } else if (n == 0b111100) { ! 354: // ANDI.W #<imm>,SR ! 355: SUPERVISOR_OP; ! 356: CYCLE2(12, 14); ! 357: uint32 src = fetch_2(); ! 358: SetSR(GetSR() & src); ! 359: } else { ! 360: // ANDI.W #<imm>,<ea> ! 361: CYCLE2(3, 4); ! 362: uint32 src = fetch_2(); ! 363: uint32 ea = cea_data_2(); ! 364: uint32 dst = read_2(ea); ! 365: dst &= src; ! 366: ACC.move_16(dst); ! 367: write_2(ea, dst); ! 368: } ! 369: } ! 370: ! 371: // %0000_001010_mmmrrr d.m+-rxw.. 034 ANDI.L #<imm>,<ea> ! 372: OP_DEF(andi_l) ! 373: { ! 374: uint n = ir & 0x3f; ! 375: ! 376: uint32 src = fetch_4(); ! 377: if (n < 8) { ! 378: // ANDI.L #<imm>,Dn ! 379: CYCLE(2); ! 380: reg.D[n] &= src; ! 381: ACC.move_32(reg.D[n]); ! 382: } else { ! 383: // ANDI.L #<imm>,<ea> ! 384: CYCLE2(3, 4); ! 385: uint32 ea = cea_data_4(); ! 386: uint32 dst = read_4(ea); ! 387: dst &= src; ! 388: ACC.move_32(dst); ! 389: write_4(ea, dst); ! 390: } ! 391: } ! 392: ! 393: // %0000_001011_mmmrrr ..m..rxwp. -34 CMP2/CHK2.W <ea>,Rn ! 394: OP_DEF(cmp2chk2_w) ! 395: { ! 396: ir2 = fetch_2(); ! 397: uint32 compare; ! 398: uint32 ea = cea_ctrl(); ! 399: uint32 lower; ! 400: uint32 upper; ! 401: ! 402: if ((ir2 & 0x8000) == 0) { ! 403: // compare が Dn ! 404: compare = (int32)(int16)(reg.R[ir2 >> 12] & 0xffff); ! 405: } else { ! 406: // compare が An ! 407: compare = reg.R[ir2 >> 12]; ! 408: } ! 409: ! 410: // 本当は PC 相対ならプログラム空間アクセス、 ! 411: // それ以外はデータ空間アクセスだが、ここでは区別しない。 ! 412: lower = (int32)(int16)read_2(ea); ! 413: upper = (int32)(int16)read_2(ea + 2); ! 414: ! 415: ACC.chk2cmp2_32(compare, lower, upper); ! 416: ! 417: // サイクル数はこれは実際には全部最大値 ! 418: if ((ir2 & 0x0800)) { ! 419: // CHK2 で条件を満たしていれば例外 ! 420: if (reg.ccr.CondCS()) { ! 421: CYCLE2(40, 42); ! 422: Exception(M68K::EXCEP_CHK); ! 423: } else { ! 424: CYCLE(18); ! 425: } ! 426: } else { ! 427: // CMP2 ! 428: CYCLE(20); ! 429: } ! 430: } ! 431: ! 432: // %0000_010000_mmmrrr d.m+-rxw.. 034 SUBI.B #<imm>,<ea> ! 433: OP_DEF(subi_b) ! 434: { ! 435: uint n = ir & 0x3f; ! 436: ! 437: uint32 src = fetch_2() & 0xff; ! 438: if (n < 8) { ! 439: // SUBI.B #<imm>,Dn ! 440: CYCLE(2); ! 441: uint32 dst = reg.D[n] & 0xff; ! 442: dst = ACC.sub_8(src, dst); ! 443: reg.D[n] = (reg.D[n] & 0xffffff00) | dst; ! 444: } else { ! 445: // SUBI.B #<imm>,<ea> ! 446: CYCLE2(3, 4); ! 447: uint32 ea = cea_data_1(); ! 448: uint32 dst = read_1(ea); ! 449: dst = ACC.sub_8(src, dst); ! 450: write_1(ea, dst); ! 451: } ! 452: } ! 453: ! 454: // %0000_010001_mmmrrr d.m+-rxw.. 034 SUBI.W #<imm>,<ea> ! 455: OP_DEF(subi_w) ! 456: { ! 457: uint n = ir & 0x3f; ! 458: ! 459: uint32 src = fetch_2(); ! 460: if (n < 8) { ! 461: // SUBI.W #<imm>,Dn ! 462: CYCLE(2); ! 463: uint32 dst = reg.D[n] & 0xffff; ! 464: dst = ACC.sub_16(src, dst); ! 465: reg.D[n] = (reg.D[n] & 0xffff0000) | dst; ! 466: } else { ! 467: // SUBI.W #<imm>,<ea> ! 468: CYCLE2(3, 4); ! 469: uint32 ea = cea_data_2(); ! 470: uint32 dst = read_2(ea); ! 471: dst = ACC.sub_16(src, dst); ! 472: write_2(ea, dst); ! 473: } ! 474: } ! 475: ! 476: // %0000_010010_mmmrrr d.m+-rxw.. 034 SUBI.L #<imm>,<ea> ! 477: OP_DEF(subi_l) ! 478: { ! 479: uint n = ir & 0x3f; ! 480: ! 481: uint32 src = fetch_4(); ! 482: if (n < 8) { ! 483: // SUBI.L #<imm>,Dn ! 484: CYCLE(2); ! 485: reg.D[n] = ACC.sub_32(src, reg.D[n]); ! 486: } else { ! 487: // SUBI.L #<imm>,<ea> ! 488: CYCLE2(3, 4); ! 489: uint32 ea = cea_data_4(); ! 490: uint32 dst = read_4(ea); ! 491: dst = ACC.sub_32(src, dst); ! 492: write_4(ea, dst); ! 493: } ! 494: } ! 495: ! 496: // %0000_010011_mmmrrr ..m..rxwp. -34 CMP2/CHK2.L <ea>,Rn ! 497: OP_DEF(cmp2chk2_l) ! 498: { ! 499: ir2 = fetch_2(); ! 500: uint32 compare = reg.R[ir2 >> 12]; ! 501: uint32 ea = cea_ctrl(); ! 502: uint32 lower; ! 503: uint32 upper; ! 504: ! 505: // 本当は PC 相対ならプログラム空間アクセス、 ! 506: // それ以外はデータ空間アクセスだが、ここでは区別しない。 ! 507: lower = read_4(ea); ! 508: upper = read_4(ea + 4); ! 509: ! 510: ACC.chk2cmp2_32(compare, lower, upper); ! 511: ! 512: // サイクル数はこれは実際には全部最大値 ! 513: if ((ir2 & 0x0800)) { ! 514: // CHK2 で条件を満たしていれば例外 ! 515: if (reg.ccr.CondCS()) { ! 516: CYCLE2(40, 42); ! 517: Exception(M68K::EXCEP_CHK); ! 518: } else { ! 519: CYCLE(18); ! 520: } ! 521: } else { ! 522: // CMP2 ! 523: CYCLE(20); ! 524: } ! 525: } ! 526: ! 527: // %0000_011000_mmmrrr d.m+-rxw.. 034 ADDI.B #<imm>,<ea> ! 528: OP_DEF(addi_b) ! 529: { ! 530: uint n = ir & 0x3f; ! 531: ! 532: uint32 src = fetch_2() & 0xff; ! 533: if (n < 8) { ! 534: // ADDI.B #<imm>,Dn ! 535: CYCLE(2); ! 536: uint32 dst = reg.D[n] & 0xff; ! 537: dst = ACC.add_8(src, dst); ! 538: reg.D[n] = (reg.D[n] & 0xffffff00) | dst; ! 539: } else { ! 540: // ADDI.B #<imm>,<ea> ! 541: CYCLE2(3, 4); ! 542: uint32 ea = cea_data_1(); ! 543: uint32 dst = read_1(ea); ! 544: dst = ACC.add_8(src, dst); ! 545: write_1(ea, dst); ! 546: } ! 547: } ! 548: ! 549: // %0000_011001_mmmrrr d.m+-rxw.. 034 ADDI.W #<imm>,<ea> ! 550: OP_DEF(addi_w) ! 551: { ! 552: uint n = ir & 0x3f; ! 553: ! 554: uint32 src = fetch_2(); ! 555: if (n < 8) { ! 556: // ADDI.W #<imm>,Dn ! 557: CYCLE(2); ! 558: uint32 dst = reg.D[n] & 0xffff; ! 559: dst = ACC.add_16(src, dst); ! 560: reg.D[n] = (reg.D[n] & 0xffff0000) | dst; ! 561: } else { ! 562: // ADDI.W #<imm>,<ea> ! 563: CYCLE2(3, 4); ! 564: uint32 ea = cea_data_2(); ! 565: uint32 dst = read_2(ea); ! 566: dst = ACC.add_16(src, dst); ! 567: write_2(ea, dst); ! 568: } ! 569: } ! 570: ! 571: // %0000_011010_mmmrrr d.m+-rxw.. 034 ADDI.L #<imm>,<ea> ! 572: OP_DEF(addi_l) ! 573: { ! 574: uint n = ir & 0x3f; ! 575: ! 576: uint32 src = fetch_4(); ! 577: if (n < 8) { ! 578: // ADDI.L #<imm>,Dn ! 579: CYCLE(2); ! 580: reg.D[n] = ACC.add_32(src, reg.D[n]); ! 581: } else { ! 582: // ADDI.L #<imm>,<ea> ! 583: CYCLE2(3, 4); ! 584: uint32 ea = cea_data_4(); ! 585: uint32 dst = read_4(ea); ! 586: dst = ACC.add_32(src, dst); ! 587: write_4(ea, dst); ! 588: } ! 589: } ! 590: ! 591: // %0000_011011_mmmrrr ..m..rxwp. 2-- CALLM #<imm>,<ea> ! 592: // %0000_011011_00nnnn .......... 2-- RTM Rn ! 593: OP_DEF(callm) ! 594: { ! 595: op_illegal(); ! 596: } ! 597: ! 598: // %0000_100000_mmmrrr ..m+-rxwp. 034 BTST.B #<imm>,<ea> ! 599: // %0000_100000_000yyy .......... 034 BTST.L #<imm>,Dy ! 600: OP_DEF(btst_imm_ea) ! 601: { ! 602: uint n = ir & 0x3f; ! 603: ! 604: if (n < 8) { ! 605: // BTST.L #<imm>,Dy ! 606: CYCLE(4); ! 607: uint bit = fetch_2() & 31; ! 608: ACC.btst(RegDY, bit); ! 609: } else if (n == 0x3c) { ! 610: // BTST.B #<imm>,<ea> の <ea> には #imm はない ! 611: op_illegal(); ! 612: } else { ! 613: // BTST.B #<imm>,<ea> ! 614: CYCLE(4); ! 615: uint bit = fetch_2() & 7; ! 616: uint32 data = fea_data_1(); ! 617: ACC.btst(data, bit); ! 618: } ! 619: } ! 620: ! 621: // %0000_100001_mmmrrr ..m+-rxw.. 034 BCHG.B #<imm>,<ea> ! 622: // %0000_100001_000yyy .......... 034 BCHG.L #<imm>,Dy ! 623: OP_DEF(bchg_imm_ea) ! 624: { ! 625: uint n = ir & 0x3f; ! 626: ! 627: if (n < 8) { ! 628: // BCHG.L #<imm>,Dy ! 629: CYCLE(6); ! 630: uint bit = fetch_2() & 31; ! 631: RegDY = ACC.bchg(RegDY, bit); ! 632: } else if (n == 0x3c) { ! 633: // BCHG.B #<imm>,<ea> の <ea> には #imm はない ! 634: op_illegal(); ! 635: } else { ! 636: // BCHG.B #<imm>,<ea> ! 637: CYCLE(6); ! 638: uint bit = fetch_2() & 7; ! 639: uint32 ea = cea_data_1(); ! 640: uint32 data = read_1(ea); ! 641: data = ACC.bchg(data, bit); ! 642: write_1(ea, data); ! 643: } ! 644: } ! 645: ! 646: // %0000_100010_mmmrrr ..m+-rxw.. 034 BCLR.B #<imm>,<ea> ! 647: // %0000_100010_000yyy .......... 034 BCLR.L #<imm>,Dy ! 648: OP_DEF(bclr_imm_ea) ! 649: { ! 650: uint n = ir & 0x3f; ! 651: ! 652: if (n < 8) { ! 653: // BCLR.L #<imm>,Dy ! 654: CYCLE(6); ! 655: uint bit = fetch_2() & 31; ! 656: RegDY = ACC.bclr(RegDY, bit); ! 657: } else if (n == 0x3c) { ! 658: // BCLR.B #<imm>,<ea> の <ea> には #imm はない ! 659: op_illegal(); ! 660: } else { ! 661: // BCLR.B #<imm>,<ea> ! 662: CYCLE(6); ! 663: uint bit = fetch_2() & 7; ! 664: uint32 ea = cea_data_1(); ! 665: uint32 data = read_1(ea); ! 666: data = ACC.bclr(data, bit); ! 667: write_1(ea, data); ! 668: } ! 669: } ! 670: ! 671: // %0000_100011_mmmrrr ..m+-rxw.. 034 BSET.B #<imm>,<ea> ! 672: // %0000_100011_000yyy .......... 034 BSET.L #<imm>,Dy ! 673: OP_DEF(bset_imm_ea) ! 674: { ! 675: uint n = ir & 0x3f; ! 676: ! 677: if (n < 8) { ! 678: // BSET.L #<imm>,Dy ! 679: CYCLE(6); ! 680: uint bit = fetch_2() & 31; ! 681: RegDY = ACC.bset(RegDY, bit); ! 682: } else if (n == 0x3c) { ! 683: // BSET.B #<imm>,<ea> の <ea> には #imm はない ! 684: op_illegal(); ! 685: } else { ! 686: // BSET.B #<imm>,<ea> ! 687: CYCLE(6); ! 688: uint bit = fetch_2() & 7; ! 689: uint32 ea = cea_data_1(); ! 690: uint32 data = read_1(ea); ! 691: data = ACC.bset(data, bit); ! 692: write_1(ea, data); ! 693: } ! 694: } ! 695: ! 696: // %0000_101000_mmmrrr d.m+-rxw.. 034 EORI.B #<imm>,<ea> ! 697: // %0000_101000_111100 .......... 034 EORI.B #<imm>,CCR ! 698: OP_DEF(eori_b) ! 699: { ! 700: uint n = ir & 0x3f; ! 701: ! 702: uint32 src = fetch_2() & 0xff; ! 703: if (n < 8) { ! 704: // EORI.B #<imm>,Dn ! 705: CYCLE(2); ! 706: uint32 dst = (reg.D[n] & 0xff) ^ src; ! 707: ACC.move_8(dst); ! 708: reg.D[n] = (reg.D[n] & 0xffffff00) | dst; ! 709: } else if (n == 0b111100) { ! 710: // EORI.B #<imm>,CCR ! 711: CYCLE2(12, 14); ! 712: CCR.Set(CCR.Get() ^ src); ! 713: } else { ! 714: // EORI.B #<imm>,<ea> ! 715: CYCLE2(3, 4); ! 716: uint32 ea = cea_data_1(); ! 717: uint32 dst = read_1(ea); ! 718: dst ^= src; ! 719: ACC.move_8(dst); ! 720: write_1(ea, dst); ! 721: } ! 722: } ! 723: ! 724: // %0000_101001_mmmrrr d.m+-rxw.. 034 EORI.W #<imm>,<ea> ! 725: // %0000_101001_111100 .......... 034 EORI.W #<imm>,SR ! 726: OP_DEF(eori_w) ! 727: { ! 728: uint n = ir & 0x3f; ! 729: ! 730: if (n < 8) { ! 731: // EORI.W #<imm>,Dn ! 732: CYCLE(2); ! 733: uint32 src = fetch_2(); ! 734: uint32 dst = (reg.D[n] & 0xffff) ^ src; ! 735: ACC.move_16(dst); ! 736: reg.D[n] = (reg.D[n] & 0xffff0000) | dst; ! 737: } else if (n == 0b111100) { ! 738: // EORI.W #<imm>,SR ! 739: SUPERVISOR_OP; ! 740: CYCLE2(12, 14); ! 741: uint32 src = fetch_2(); ! 742: SetSR(GetSR() ^ src); ! 743: } else { ! 744: // EORI.W #<imm>,<ea> ! 745: CYCLE2(3, 4); ! 746: uint32 src = fetch_2(); ! 747: uint32 ea = cea_data_2(); ! 748: uint32 dst = read_2(ea); ! 749: dst ^= src; ! 750: ACC.move_16(dst); ! 751: write_2(ea, dst); ! 752: } ! 753: } ! 754: ! 755: // %0000_101010_mmmrrr d.m+-rxw.. 034 EORI.L #<imm>,<ea> ! 756: OP_DEF(eori_l) ! 757: { ! 758: uint n = ir & 0x3f; ! 759: ! 760: uint32 src = fetch_4(); ! 761: if (n < 8) { ! 762: // EORI.L #<imm>,Dn ! 763: CYCLE(2); ! 764: reg.D[n] ^= src; ! 765: ACC.move_32(reg.D[n]); ! 766: } else { ! 767: // EORI.L #<imm>,<ea> ! 768: CYCLE2(3, 4); ! 769: uint32 ea = cea_data_4(); ! 770: uint32 dst = read_4(ea); ! 771: dst ^= src; ! 772: ACC.move_32(dst); ! 773: write_4(ea, dst); ! 774: } ! 775: } ! 776: ! 777: // %0000_101011_mmmrrr ..m+-rxw.. -34 CAS.B Dc,Du,<ea> ! 778: OP_DEF(cas_b) ! 779: { ! 780: ir2 = fetch_2(); ! 781: uint c = ir2 & 7; ! 782: uint u = (ir2 >> 6) & 7; ! 783: uint32 dc = reg.D[c] & 0xff; ! 784: uint32 du = reg.D[u] & 0xff; ! 785: uint ea = cea_data_1(); ! 786: uint32 dst = read_1(ea); ! 787: ! 788: ACC.cmp_8(dc, dst); ! 789: if (CCR.IsZ()) { ! 790: // 等しければ、Du -> dst ! 791: CYCLE(13); ! 792: write_1(ea, du); ! 793: } else { ! 794: // そうでなければ、dst -> Dc ! 795: CYCLE(11); ! 796: reg.D[c] = (reg.D[c] & 0xffffff00) | dst; ! 797: } ! 798: } ! 799: ! 800: // %0000_110000_mmmrrr d.m+-rxwp. -34 CMPI.B #<imm>,<ea> ! 801: OP_DEF(cmpi_b) ! 802: { ! 803: uint n = ir & 0x3f; ! 804: ! 805: // CMPI はデータアドレッシングだが #imm がないことに注意 ! 806: if (n == 0x3c) { ! 807: op_illegal(); ! 808: return; ! 809: } ! 810: CYCLE(2); ! 811: uint32 src = fetch_2() & 0xff; ! 812: uint32 dst = fea_data_1(); ! 813: ACC.cmp_8(src, dst); ! 814: } ! 815: ! 816: // %0000_110001_mmmrrr d.m+-rxwp. -34 CMPI.W #<imm>,<ea> ! 817: OP_DEF(cmpi_w) ! 818: { ! 819: uint n = ir & 0x3f; ! 820: ! 821: // CMPI はデータアドレッシングだが #imm がないことに注意 ! 822: if (n == 0x3c) { ! 823: op_illegal(); ! 824: return; ! 825: } ! 826: CYCLE(2); ! 827: uint32 src = fetch_2(); ! 828: uint32 dst = fea_data_2(); ! 829: ACC.cmp_16(src, dst); ! 830: } ! 831: ! 832: // %0000_110010_mmmrrr d.m+-rxwp. -34 CMPI.L #<imm>,<ea> ! 833: OP_DEF(cmpi_l) ! 834: { ! 835: uint n = ir & 0x3f; ! 836: ! 837: // CMPI はデータアドレッシングだが #imm がないことに注意 ! 838: if (n == 0x3c) { ! 839: op_illegal(); ! 840: return; ! 841: } ! 842: CYCLE(2); ! 843: uint32 src = fetch_4(); ! 844: uint32 dst = fea_data_4(); ! 845: ACC.cmp_32(src, dst); ! 846: } ! 847: ! 848: // %0000_110011_mmmrrr ..m+-rxw.. -34 CAS.W Dc,Du,<ea> ! 849: // %0000_110011_111100 .......... -34 CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) ! 850: OP_DEF(cas_w) ! 851: { ! 852: uint n = ir & 0x3f; ! 853: ! 854: if (n == 0x3c) { ! 855: // CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) ! 856: ir2 = fetch_2(); ! 857: uint32 ir3 = fetch_2(); ! 858: uint c1 = ir2 & 7; ! 859: uint u1 = (ir2 >> 6) & 7; ! 860: uint r1 = ir2 >> 12; ! 861: uint c2 = ir3 & 7; ! 862: uint u2 = (ir3 >> 6) & 7; ! 863: uint r2 = ir3 >> 12; ! 864: uint32 dc1 = reg.D[c1] & 0xffff; ! 865: uint32 du1 = reg.D[u1] & 0xffff; ! 866: uint32 ea1 = reg.R[r1]; ! 867: uint32 dc2 = reg.D[c2] & 0xffff; ! 868: uint32 du2 = reg.D[u2] & 0xffff; ! 869: uint32 ea2 = reg.R[r2]; ! 870: ! 871: uint32 dst1 = read_2(ea1); ! 872: uint32 dst2 = read_2(ea2); ! 873: ACC.cmp_16(dc1, dst1); ! 874: if (CCR.IsZ()) { ! 875: ACC.cmp_16(dc2, dst2); ! 876: if (CCR.IsZ()) { ! 877: // 更新オペランド -> デスティネーション ! 878: CYCLE2(0, 2); // これは成功時の追加分 ! 879: write_2(ea1, du1); ! 880: write_2(ea2, du2); ! 881: } ! 882: } ! 883: // デスティネーション -> 比較オペランド ! 884: CYCLE(24); // 本当はこれは最大値 ! 885: reg.D[c1] = (reg.D[c1] & 0xffff0000) | dst1; ! 886: reg.D[c2] = (reg.D[c2] & 0xffff0000) | dst2; ! 887: } else { ! 888: // CAS.W Dc,Du,<ea> ! 889: ir2 = fetch_2(); ! 890: uint c = ir2 & 7; ! 891: uint u = (ir2 >> 6) & 7; ! 892: uint32 dc = reg.D[c] & 0xffff; ! 893: uint32 du = reg.D[u] & 0xffff; ! 894: uint ea = cea_data_2(); ! 895: uint32 dst = read_2(ea); ! 896: ! 897: ACC.cmp_16(dc, dst); ! 898: if (CCR.IsZ()) { ! 899: // 等しければ、Du -> dst ! 900: CYCLE(13); ! 901: write_2(ea, du); ! 902: } else { ! 903: // そうでなければ、dst -> Dc ! 904: CYCLE(11); ! 905: reg.D[c] = (reg.D[c] & 0xffff0000) | dst; ! 906: } ! 907: } ! 908: } ! 909: ! 910: // 68040 は MOVES でのプログラム空間アクセスをデータ空間アクセスに読み替える。 ! 911: // バスエラーで報告されるのも読み替え後の FC なので、ここで差し替える。 ! 912: // MC68040UM.pdf, p3-22。 ! 913: // 68000PRM.pdf, p.6-26 の記述は逆に読めるが、誤りだと思われる。 ! 914: busaddr ! 915: MPU680x0Device::translate_fc40(busaddr xfc) ! 916: { ! 917: if (mpu_type == m680x0MPUType::M68040) { ! 918: uint32 fc = xfc.GetFC(); ! 919: if (fc == 2) { ! 920: xfc.ChangeFC(1); ! 921: } else if (fc == 6) { ! 922: xfc.ChangeFC(5); ! 923: } ! 924: } ! 925: return xfc; ! 926: } ! 927: ! 928: // %0000_111000_mmmrrr ..m+-rxw.. -34 MOVES.B <ea>,Rn ! 929: // %0000_111000_mmmrrr ..m+-rxw.. -34 MOVES.B Rn,<ea> ! 930: OP_DEF(moves_b) ! 931: { ! 932: SUPERVISOR_OP; ! 933: ! 934: ir2 = fetch_2(); ! 935: uint n = ir2 >> 12; ! 936: uint ea; ! 937: uint32 data; ! 938: ! 939: if ((ir & 0x3f) < 16) { ! 940: op_illegal(); ! 941: return; ! 942: } ! 943: ! 944: ea = cea_data_1(); ! 945: if ((ir2 & 0x0800) == 0) { ! 946: // <ea>,Rn ! 947: CYCLE(7); ! 948: busaddr sfc = translate_fc40(reg.sfc); ! 949: busaddr addr = busaddr(ea) | sfc | BusAddr::Size1; ! 950: data = read_data(addr); ! 951: if (n < 8) { // Dn ! 952: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 953: } else { // An ! 954: reg.R[n] = (int32)(int8)data; ! 955: } ! 956: } else { ! 957: // Rn,<ea> ! 958: CYCLE2(5, 6); ! 959: busaddr dfc = translate_fc40(reg.dfc); ! 960: busaddr addr = busaddr(ea) | dfc | BusAddr::Size1; ! 961: data = reg.R[n] & 0xff; ! 962: write_data(addr, data); ! 963: } ! 964: } ! 965: ! 966: // %0000_111001_mmmrrr ..m+-rxw.. -34 MOVES.W <ea>,Rn ! 967: // %0000_111001_mmmrrr ..m+-rxw.. -34 MOVES.W Rn,<ea> ! 968: OP_DEF(moves_w) ! 969: { ! 970: SUPERVISOR_OP; ! 971: ! 972: ir2 = fetch_2(); ! 973: uint n = ir2 >> 12; ! 974: uint ea; ! 975: uint32 data; ! 976: ! 977: if ((ir & 0x3f) < 16) { ! 978: op_illegal(); ! 979: return; ! 980: } ! 981: ! 982: ea = cea_data_2(); ! 983: if ((ir2 & 0x0800) == 0) { ! 984: // <ea>,Rn ! 985: CYCLE(7); ! 986: busaddr sfc = translate_fc40(reg.sfc); ! 987: busaddr addr = busaddr(ea) | sfc | BusAddr::Size2; ! 988: data = read_data(addr); ! 989: if (n < 8) { // Dn ! 990: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 991: } else { // An ! 992: reg.R[n] = (int32)(int16)data; ! 993: } ! 994: } else { ! 995: // Rn,<ea> ! 996: CYCLE2(5, 6); ! 997: busaddr dfc = translate_fc40(reg.dfc); ! 998: busaddr addr = busaddr(ea) | dfc | BusAddr::Size2; ! 999: data = reg.R[n] & 0xffff; ! 1000: write_data(addr, data); ! 1001: } ! 1002: } ! 1003: ! 1004: // %0000_111010_mmmrrr ..m+-rxw.. -34 MOVES.L <ea>,Rn ! 1005: // %0000_111010_mmmrrr ..m+-rxw.. -34 MOVES.L Rn,<ea> ! 1006: OP_DEF(moves_l) ! 1007: { ! 1008: SUPERVISOR_OP; ! 1009: ! 1010: ir2 = fetch_2(); ! 1011: uint n = ir2 >> 12; ! 1012: uint ea; ! 1013: uint32 data; ! 1014: ! 1015: if ((ir & 0x3f) < 16) { ! 1016: op_illegal(); ! 1017: return; ! 1018: } ! 1019: ! 1020: ea = cea_data_4(); ! 1021: if ((ir2 & 0x0800) == 0) { ! 1022: // <ea>,Rn ! 1023: CYCLE(7); ! 1024: busaddr sfc = translate_fc40(reg.sfc); ! 1025: busaddr addr = busaddr(ea) | sfc | BusAddr::Size4; ! 1026: data = read_data(addr); ! 1027: reg.R[n] = data; ! 1028: } else { ! 1029: // Rn,<ea> ! 1030: CYCLE2(5, 6); ! 1031: busaddr dfc = translate_fc40(reg.dfc); ! 1032: busaddr addr = busaddr(ea) | dfc | BusAddr::Size4; ! 1033: data = reg.R[n]; ! 1034: write_data(addr, data); ! 1035: } ! 1036: } ! 1037: ! 1038: // %0000_111011_mmmrrr ..m+-rxw.. -34 CAS.L Dc,Du,<ea> ! 1039: // %0000_111011_111100 .......... -34 CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) ! 1040: OP_DEF(cas_l) ! 1041: { ! 1042: uint n = ir & 0x3f; ! 1043: ! 1044: if (n == 0x3c) { ! 1045: // CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) ! 1046: ir2 = fetch_2(); ! 1047: uint32 ir3 = fetch_2(); ! 1048: uint c1 = ir2 & 7; ! 1049: uint u1 = (ir2 >> 6) & 7; ! 1050: uint r1 = ir2 >> 12; ! 1051: uint c2 = ir3 & 7; ! 1052: uint u2 = (ir3 >> 6) & 7; ! 1053: uint r2 = ir3 >> 12; ! 1054: uint32 dc1 = reg.D[c1]; ! 1055: uint32 du1 = reg.D[u1]; ! 1056: uint32 ea1 = reg.R[r1]; ! 1057: uint32 dc2 = reg.D[c2]; ! 1058: uint32 du2 = reg.D[u2]; ! 1059: uint32 ea2 = reg.R[r2]; ! 1060: ! 1061: uint32 dst1 = read_4(ea1); ! 1062: uint32 dst2 = read_4(ea2); ! 1063: ACC.cmp_32(dc1, dst1); ! 1064: if (CCR.IsZ()) { ! 1065: ACC.cmp_32(dc2, dst2); ! 1066: if (CCR.IsZ()) { ! 1067: // 更新オペランド -> デスティネーション ! 1068: CYCLE2(0, 2); // これは成功時の追加分 ! 1069: write_4(ea1, du1); ! 1070: write_4(ea2, du2); ! 1071: } ! 1072: } ! 1073: // デスティネーション -> 比較オペランド ! 1074: CYCLE(24); // 本当はこれは最大値 ! 1075: reg.D[c1] = dst1; ! 1076: reg.D[c2] = dst2; ! 1077: } else { ! 1078: // CAS.L Dc,Du,<ea> ! 1079: ir2 = fetch_2(); ! 1080: uint c = ir2 & 7; ! 1081: uint u = (ir2 >> 6) & 7; ! 1082: uint32 dc = reg.D[c]; ! 1083: uint32 du = reg.D[u]; ! 1084: uint ea = cea_data_4(); ! 1085: uint32 dst = read_4(ea); ! 1086: ! 1087: ACC.cmp_32(dc, dst); ! 1088: if (CCR.IsZ()) { ! 1089: // 等しければ、Du -> dst ! 1090: CYCLE(13); ! 1091: write_4(ea, du); ! 1092: } else { ! 1093: // そうでなければ、dst -> Dc ! 1094: CYCLE(11); ! 1095: reg.D[c] = dst; ! 1096: } ! 1097: } ! 1098: } ! 1099: ! 1100: // %0001_xxx000_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,Dx ! 1101: OP_DEF(move_b_ea_dn) ! 1102: { ! 1103: CYCLE(2); ! 1104: uint32 data = fea_all_1(); ! 1105: ACC.move_8(data); ! 1106: RegDX = (RegDX & 0xffffff00) | data; ! 1107: } ! 1108: ! 1109: // %0001_xxx010_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,(Ax) ! 1110: OP_DEF(move_b_ea_anin) ! 1111: { ! 1112: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1113: CYCLE2(4, 5); ! 1114: uint32 data = fea_all_1(); ! 1115: uint32 ea = cea_anin(RegIRX); ! 1116: ACC.move_8(data); ! 1117: write_1(ea, data); ! 1118: } ! 1119: ! 1120: // %0001_xxx011_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,(Ax)+ ! 1121: OP_DEF(move_b_ea_anpi) ! 1122: { ! 1123: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1124: CYCLE2(4, 5); ! 1125: uint32 data = fea_all_1(); ! 1126: // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 ! 1127: save_reg_pi_if(RegIRX); ! 1128: uint32 ea = cea_anpi_1(RegIRX); ! 1129: ACC.move_8(data); ! 1130: write_1(ea, data); ! 1131: } ! 1132: ! 1133: // %0001_xxx100_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,-(Ax) ! 1134: OP_DEF(move_b_ea_anpd) ! 1135: { ! 1136: // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) ! 1137: CYCLE2(4, 5); ! 1138: uint32 data = fea_all_1(); ! 1139: // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 ! 1140: save_reg_pd_if(RegIRX); ! 1141: uint32 ea = cea_anpd_1(RegIRX); ! 1142: ACC.move_8(data); ! 1143: write_1(ea, data); ! 1144: } ! 1145: ! 1146: // %0001_xxx101_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,d16(Ax) ! 1147: OP_DEF(move_b_ea_andi) ! 1148: { ! 1149: CYCLE2(4, 5); ! 1150: uint32 data = fea_all_1(); ! 1151: uint32 ea = cea_andi(RegIRX); ! 1152: ACC.move_8(data); ! 1153: write_1(ea, data); ! 1154: } ! 1155: ! 1156: // %0001_xxx110_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,(Ax,IX) ! 1157: OP_DEF(move_b_ea_anix) ! 1158: { ! 1159: // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) ! 1160: CYCLE2(16, 18); ! 1161: uint32 data = fea_all_1(); ! 1162: uint32 ea = cea_anix(RegIRX); ! 1163: ACC.move_8(data); ! 1164: write_1(ea, data); ! 1165: } ! 1166: ! 1167: // %0001_000111_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,Abs.W ! 1168: OP_DEF(move_b_ea_absw) ! 1169: { ! 1170: CYCLE2(4, 5); ! 1171: uint32 data = fea_all_1(); ! 1172: uint32 ea = cea_absw(); ! 1173: ACC.move_8(data); ! 1174: write_1(ea, data); ! 1175: } ! 1176: ! 1177: // %0001_001111_mmmrrr d.m+-rxwpi 034 MOVE.B <ea>,Abs.L ! 1178: OP_DEF(move_b_ea_absl) ! 1179: { ! 1180: CYCLE2(6, 7); ! 1181: uint32 data = fea_all_1(); ! 1182: uint32 ea = cea_absl(); ! 1183: ACC.move_8(data); ! 1184: write_1(ea, data); ! 1185: } ! 1186: ! 1187: // %0010_xxx000_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,Dx ! 1188: OP_DEF(move_l_ea_dn) ! 1189: { ! 1190: CYCLE(2); ! 1191: uint32 data = fea_all_4(); ! 1192: ACC.move_32(data); ! 1193: RegDX = data; ! 1194: } ! 1195: ! 1196: // %0010_xxx001_mmmrrr dam+-rxwpi 034 MOVEA.L <ea>,Ax ! 1197: OP_DEF(movea_l) ! 1198: { ! 1199: CYCLE(2); ! 1200: uint32 data = fea_all_4(); ! 1201: RegAX = data; ! 1202: } ! 1203: ! 1204: // %0010_xxx010_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,(Ax) ! 1205: OP_DEF(move_l_ea_anin) ! 1206: { ! 1207: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1208: CYCLE2(4, 5); ! 1209: uint32 data = fea_all_4(); ! 1210: uint32 ea = cea_anin(RegIRX); ! 1211: ACC.move_32(data); ! 1212: write_4(ea, data); ! 1213: } ! 1214: ! 1215: // %0010_xxx011_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,(Ax)+ ! 1216: OP_DEF(move_l_ea_anpi) ! 1217: { ! 1218: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1219: CYCLE2(4, 5); ! 1220: uint32 data = fea_all_4(); ! 1221: // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 ! 1222: save_reg_pi_if(RegIRX); ! 1223: uint32 ea = cea_anpi_4(RegIRX); ! 1224: ACC.move_32(data); ! 1225: write_4(ea, data); ! 1226: } ! 1227: ! 1228: // %0010_xxx100_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,-(Ax) ! 1229: OP_DEF(move_l_ea_anpd) ! 1230: { ! 1231: // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) ! 1232: CYCLE2(4, 5); ! 1233: uint32 data = fea_all_4(); ! 1234: // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 ! 1235: save_reg_pd_if(RegIRX); ! 1236: uint32 ea = cea_anpd_4(RegIRX); ! 1237: ACC.move_32(data); ! 1238: write_4(ea, data); ! 1239: } ! 1240: ! 1241: // %0010_xxx101_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,d16(Ax) ! 1242: OP_DEF(move_l_ea_andi) ! 1243: { ! 1244: CYCLE2(4, 5); ! 1245: uint32 data = fea_all_4(); ! 1246: uint32 ea = cea_andi(RegIRX); ! 1247: ACC.move_32(data); ! 1248: write_4(ea, data); ! 1249: } ! 1250: ! 1251: // %0010_xxx110_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,(Ax,IX) ! 1252: OP_DEF(move_l_ea_anix) ! 1253: { ! 1254: // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) ! 1255: CYCLE2(16, 18); ! 1256: uint32 data = fea_all_4(); ! 1257: uint32 ea = cea_anix(RegIRX); ! 1258: ACC.move_32(data); ! 1259: write_4(ea, data); ! 1260: } ! 1261: ! 1262: // %0010_000111_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,Abs.W ! 1263: OP_DEF(move_l_ea_absw) ! 1264: { ! 1265: CYCLE2(4, 5); ! 1266: uint32 data = fea_all_4(); ! 1267: uint32 ea = cea_absw(); ! 1268: ACC.move_32(data); ! 1269: write_4(ea, data); ! 1270: } ! 1271: ! 1272: // %0010_001111_mmmrrr dam+-rxwpi 034 MOVE.L <ea>,Abs.L ! 1273: OP_DEF(move_l_ea_absl) ! 1274: { ! 1275: CYCLE2(6, 7); ! 1276: uint32 data = fea_all_4(); ! 1277: uint32 ea = cea_absl(); ! 1278: ACC.move_32(data); ! 1279: write_4(ea, data); ! 1280: } ! 1281: ! 1282: // %0011_xxx000_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,Dx ! 1283: OP_DEF(move_w_ea_dn) ! 1284: { ! 1285: CYCLE(2); ! 1286: uint32 data = fea_all_2(); ! 1287: ACC.move_16(data); ! 1288: RegDX = (RegDX & 0xffff0000) | data; ! 1289: } ! 1290: ! 1291: // %0011_xxx001_mmmrrr dam+-rxwpi 034 MOVEA.W <ea>,Ax ! 1292: OP_DEF(movea_w) ! 1293: { ! 1294: CYCLE(2); ! 1295: uint32 data = (int32)(int16)fea_all_2(); ! 1296: RegAX = data; ! 1297: } ! 1298: ! 1299: // %0011_xxx010_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,(Ax) ! 1300: OP_DEF(move_w_ea_anin) ! 1301: { ! 1302: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1303: CYCLE2(4, 5); ! 1304: uint32 data = fea_all_2(); ! 1305: uint32 ea = cea_anin(RegIRX); ! 1306: ACC.move_16(data); ! 1307: write_2(ea, data); ! 1308: } ! 1309: ! 1310: // %0011_xxx011_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,(Ax)+ ! 1311: OP_DEF(move_w_ea_anpi) ! 1312: { ! 1313: // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) ! 1314: CYCLE2(4, 5); ! 1315: uint32 data = fea_all_2(); ! 1316: // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 ! 1317: save_reg_pi_if(RegIRX); ! 1318: uint32 ea = cea_anpi_2(RegIRX); ! 1319: ACC.move_16(data); ! 1320: write_2(ea, data); ! 1321: } ! 1322: ! 1323: // %0011_xxx100_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,-(Ax) ! 1324: OP_DEF(move_w_ea_anpd) ! 1325: { ! 1326: // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) ! 1327: CYCLE2(4, 5); ! 1328: uint32 data = fea_all_2(); ! 1329: // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 ! 1330: save_reg_pd_if(RegIRX); ! 1331: uint32 ea = cea_anpd_2(RegIRX); ! 1332: ACC.move_16(data); ! 1333: write_2(ea, data); ! 1334: } ! 1335: ! 1336: // %0011_xxx101_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,d16(Ax) ! 1337: OP_DEF(move_w_ea_andi) ! 1338: { ! 1339: CYCLE2(4, 5); ! 1340: uint32 data = fea_all_2(); ! 1341: uint32 ea = cea_andi(RegIRX); ! 1342: ACC.move_16(data); ! 1343: write_2(ea, data); ! 1344: } ! 1345: ! 1346: // %0011_xxx110_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,(Ax,IX) ! 1347: OP_DEF(move_w_ea_anix) ! 1348: { ! 1349: // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) ! 1350: CYCLE2(16, 18); ! 1351: uint32 data = fea_all_2(); ! 1352: uint32 ea = cea_anix(RegIRX); ! 1353: ACC.move_16(data); ! 1354: write_2(ea, data); ! 1355: } ! 1356: ! 1357: // %0011_000111_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,Abs.W ! 1358: OP_DEF(move_w_ea_absw) ! 1359: { ! 1360: CYCLE2(4, 5); ! 1361: uint32 data = fea_all_2(); ! 1362: uint32 ea = cea_absw(); ! 1363: ACC.move_16(data); ! 1364: write_2(ea, data); ! 1365: } ! 1366: ! 1367: // %0011_001111_mmmrrr dam+-rxwpi 034 MOVE.W <ea>,Abs.L ! 1368: OP_DEF(move_w_ea_absl) ! 1369: { ! 1370: CYCLE2(6, 7); ! 1371: uint32 data = fea_all_2(); ! 1372: uint32 ea = cea_absl(); ! 1373: ACC.move_16(data); ! 1374: write_2(ea, data); ! 1375: } ! 1376: ! 1377: // %0100_000000_mmmrrr d.m+-rxw.. 034 NEGX.B <ea> ! 1378: OP_DEF(negx_b) ! 1379: { ! 1380: uint n = ir & 0x3f; ! 1381: ! 1382: if (n < 8) { ! 1383: // NEGX.B Dn ! 1384: CYCLE(2); ! 1385: uint32 data = reg.D[n] & 0xff; ! 1386: data = ACC.subx_8(data, 0); ! 1387: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 1388: } else if (n < 16) { ! 1389: op_illegal(); ! 1390: } else { ! 1391: // NEGX.B <ea> ! 1392: CYCLE2(3, 4); ! 1393: uint32 ea = cea_data_1(); ! 1394: uint32 data = read_1(ea); ! 1395: data = ACC.subx_8(data, 0); ! 1396: write_1(ea, data); ! 1397: } ! 1398: } ! 1399: ! 1400: // %0100_000001_mmmrrr d.m+-rxw.. 034 NEGX.W <ea> ! 1401: OP_DEF(negx_w) ! 1402: { ! 1403: uint n = ir & 0x3f; ! 1404: ! 1405: if (n < 8) { ! 1406: // NEGX.W Dn ! 1407: CYCLE(2); ! 1408: uint32 data = reg.D[n] & 0xffff; ! 1409: data = ACC.subx_16(data, 0); ! 1410: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 1411: } else if (n < 16) { ! 1412: op_illegal(); ! 1413: } else { ! 1414: // NEGX.W <ea> ! 1415: CYCLE2(3, 4); ! 1416: uint32 ea = cea_data_2(); ! 1417: uint32 data = read_2(ea); ! 1418: data = ACC.subx_16(data, 0); ! 1419: write_2(ea, data); ! 1420: } ! 1421: } ! 1422: ! 1423: // %0100_000010_mmmrrr d.m+-rxw.. 034 NEGX.L <ea> ! 1424: OP_DEF(negx_l) ! 1425: { ! 1426: uint n = ir & 0x3f; ! 1427: ! 1428: if (n < 8) { ! 1429: // NEGX.L Dn ! 1430: CYCLE(2); ! 1431: reg.D[n] = ACC.subx_32(reg.D[n], 0); ! 1432: } else if (n < 16) { ! 1433: op_illegal(); ! 1434: } else { ! 1435: // NEGX.L <ea> ! 1436: CYCLE2(3, 4); ! 1437: uint32 ea = cea_data_4(); ! 1438: uint32 data = read_4(ea); ! 1439: data = ACC.subx_32(data, 0); ! 1440: write_4(ea, data); ! 1441: } ! 1442: } ! 1443: ! 1444: // %0100_000011_mmmrrr d.m+-rxw.. -34 MOVE.W SR,<ea> ! 1445: OP_DEF(move_sr_ea) ! 1446: { ! 1447: SUPERVISOR_OP; ! 1448: ! 1449: uint n = ir & 0x3f; ! 1450: if (n < 8) { ! 1451: // MOVE.W SR,Dn ! 1452: CYCLE(4); ! 1453: reg.D[n] = (reg.D[n] & 0xffff0000) | GetSR(); ! 1454: } else { ! 1455: // MOVE.W SR,<ea> ! 1456: CYCLE2(4, 5); ! 1457: uint32 ea = cea_data_2(); ! 1458: write_2(ea, GetSR()); ! 1459: } ! 1460: } ! 1461: ! 1462: // %0100_xxx100_mmmrrr d.m+-rxwpi -34 CHK.L <ea>,Dx ! 1463: OP_DEF(chk_l) ! 1464: { ! 1465: uint32 dst = RegDX; ! 1466: ACC.move_32(dst); ! 1467: if (CCR.IsN()) { ! 1468: // これは最大値で次の条件式が成立した時の値なので、 ! 1469: // 実際にはこれより小さい確定した値のはずだけど。 ! 1470: CYCLE2(28, 30); ! 1471: Exception(M68K::EXCEP_CHK); ! 1472: return; ! 1473: } ! 1474: // 本当はこうじゃないけど、とりあえず ! 1475: uint32 src = fea_data_4(); ! 1476: if ((int32)dst > (int32)src) { ! 1477: CYCLE2(28, 30); ! 1478: CCR.SetN(false); ! 1479: Exception(M68K::EXCEP_CHK); ! 1480: return; ! 1481: } ! 1482: CYCLE(8); ! 1483: } ! 1484: ! 1485: // %0100_xxx110_mmmrrr d.m+-rxwpi 034 CHK.W <ea>,Dx ! 1486: OP_DEF(chk_w) ! 1487: { ! 1488: uint32 dst = RegDX & 0xffff; ! 1489: ACC.move_16(dst); ! 1490: if (CCR.IsN()) { ! 1491: // これは最大値で次の条件式が成立した時の値なので、 ! 1492: // 実際にはこれより小さい確定した値のはずだけど。 ! 1493: CYCLE2(28, 30); ! 1494: Exception(M68K::EXCEP_CHK); ! 1495: return; ! 1496: } ! 1497: // 本当はこうじゃないけど、とりあえず ! 1498: uint32 src = fea_data_2(); ! 1499: if ((int16)dst > (int16)src) { ! 1500: CYCLE2(28, 30); ! 1501: CCR.SetN(false); ! 1502: Exception(M68K::EXCEP_CHK); ! 1503: return; ! 1504: } ! 1505: CYCLE(8); ! 1506: } ! 1507: ! 1508: // %0100_xxx111_mmmrrr ..m..rxwp. 034 LEA.L <ea>,Ax ! 1509: // %0100_100111_000yyy .......... -34 EXTB.L Dy ! 1510: OP_DEF(lea) ! 1511: { ! 1512: uint n = ir & 0x3f; ! 1513: ! 1514: if (n < 8) { ! 1515: // EXTB.L Dy ! 1516: CYCLE(4); ! 1517: RegDY = (int32)(int8)(RegDY & 0xff); ! 1518: ACC.move_32(RegDY); ! 1519: } else { ! 1520: // LEA.L <ea>,Ax ! 1521: CYCLE(2); ! 1522: RegAX = cea_ctrl(); ! 1523: } ! 1524: } ! 1525: ! 1526: // %0100_001000_mmmrrr d.m+-rxw.. 034 CLR.B <ea> ! 1527: OP_DEF(clr_b) ! 1528: { ! 1529: uint n = ir & 0x3f; ! 1530: ! 1531: if (n < 8) { ! 1532: // CLR.B Dn ! 1533: CYCLE(2); ! 1534: RegDY &= 0xffffff00; ! 1535: ACC.move_8(0); ! 1536: } else { ! 1537: // CLR.B <ea> ! 1538: CYCLE2(3, 4); ! 1539: uint32 ea = cea_data_1(); ! 1540: ACC.move_8(0); ! 1541: write_1(ea, 0); ! 1542: } ! 1543: } ! 1544: ! 1545: // %0100_001001_mmmrrr d.m+-rxw.. 034 CLR.W <ea> ! 1546: OP_DEF(clr_w) ! 1547: { ! 1548: uint n = ir & 0x3f; ! 1549: ! 1550: if (n < 8) { ! 1551: // CLR.W Dn ! 1552: CYCLE(2); ! 1553: RegDY &= 0xffff0000; ! 1554: ACC.move_16(0); ! 1555: } else { ! 1556: // CLR.W <ea> ! 1557: CYCLE2(3, 4); ! 1558: uint32 ea = cea_data_2(); ! 1559: ACC.move_16(0); ! 1560: write_2(ea, 0); ! 1561: } ! 1562: } ! 1563: ! 1564: // %0100_001010_mmmrrr d.m+-rxw.. 034 CLR.L <ea> ! 1565: OP_DEF(clr_l) ! 1566: { ! 1567: uint n = ir & 0x3f; ! 1568: ! 1569: if (n < 8) { ! 1570: // CLR.L Dn ! 1571: CYCLE(2); ! 1572: RegDY = 0; ! 1573: ACC.move_32(0); ! 1574: } else { ! 1575: // CLR.L <ea> ! 1576: CYCLE2(3, 4); ! 1577: uint32 ea = cea_data_4(); ! 1578: ACC.move_32(0); ! 1579: write_4(ea, 0); ! 1580: } ! 1581: } ! 1582: ! 1583: // %0100_001011_mmmrrr d.m+-rxw.. -34 MOVE.W CCR,<ea> ! 1584: OP_DEF(move_ccr_ea) ! 1585: { ! 1586: uint n = ir & 0x3f; ! 1587: ! 1588: // 転送は16ビットで行われ、上位バイトと未実装ビットは %0 になる。 ! 1589: if (n < 8) { ! 1590: // MOVE.W CCR,Dn ! 1591: CYCLE(4); ! 1592: reg.D[n] = (reg.D[n] & 0xffff0000) | CCR.Get(); ! 1593: } else if (n < 16) { ! 1594: // MOVE.W CCR,An はない ! 1595: op_illegal(); ! 1596: } else { ! 1597: // MOVE.W CCR,<ea> ! 1598: CYCLE2(4, 5); ! 1599: uint32 ea = cea_data_2(); ! 1600: write_2(ea, CCR.Get()); ! 1601: } ! 1602: } ! 1603: ! 1604: // %0100_010000_mmmrrr d.m+-rxw.. 034 NEG.B <ea> ! 1605: OP_DEF(neg_b) ! 1606: { ! 1607: uint n = ir & 0x3f; ! 1608: ! 1609: if (n < 8) { ! 1610: // NEG.B Dn ! 1611: CYCLE(2); ! 1612: uint32 data = ACC.sub_8(reg.D[n] & 0xff, 0); ! 1613: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 1614: } else { ! 1615: // NEG.B <ea> ! 1616: CYCLE2(3, 4); ! 1617: uint32 ea = cea_data_1(); ! 1618: uint32 data = read_1(ea); ! 1619: data = ACC.sub_8(data, 0); ! 1620: write_1(ea, data); ! 1621: } ! 1622: } ! 1623: ! 1624: // %0100_010001_mmmrrr d.m+-rxw.. 034 NEG.W <ea> ! 1625: OP_DEF(neg_w) ! 1626: { ! 1627: uint n = ir & 0x3f; ! 1628: ! 1629: if (n < 8) { ! 1630: // NEG.W Dn ! 1631: CYCLE(2); ! 1632: uint32 data = ACC.sub_16(reg.D[n] & 0xffff, 0); ! 1633: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 1634: } else { ! 1635: // NEG.W <ea> ! 1636: CYCLE2(3, 4); ! 1637: uint32 ea = cea_data_2(); ! 1638: uint32 data = read_2(ea); ! 1639: data = ACC.sub_16(data, 0); ! 1640: write_2(ea, data); ! 1641: } ! 1642: } ! 1643: ! 1644: // %0100_010010_mmmrrr d.m+-rxw.. 034 NEG.L <ea> ! 1645: OP_DEF(neg_l) ! 1646: { ! 1647: uint n = ir & 0x3f; ! 1648: ! 1649: if (n < 8) { ! 1650: // NEG.L Dn ! 1651: CYCLE(2); ! 1652: reg.D[n] = ACC.sub_32(reg.D[n], 0); ! 1653: } else { ! 1654: // NEG.L <ea> ! 1655: CYCLE2(3, 4); ! 1656: uint32 ea = cea_data_4(); ! 1657: uint32 data = read_4(ea); ! 1658: data = ACC.sub_32(data, 0); ! 1659: write_4(ea, data); ! 1660: } ! 1661: } ! 1662: ! 1663: // %0100_010011_mmmrrr d.m+-rxwpi 034 MOVE.W <ea>,CCR ! 1664: OP_DEF(move_ea_ccr) ! 1665: { ! 1666: uint n = ir & 0x3f; ! 1667: ! 1668: if (n < 8) { ! 1669: // MOVE.W Dn,CCR ! 1670: CYCLE(4); ! 1671: uint32 data = reg.D[n] & 0xff; ! 1672: CCR.Set(data); ! 1673: } else if (n < 16) { ! 1674: // MOVE.W An,CCR はない ! 1675: op_illegal(); ! 1676: } else { ! 1677: // MOVE.W <ea>,CCR ! 1678: CYCLE(4); ! 1679: uint32 data = fea_data_2(); ! 1680: CCR.Set(data); ! 1681: } ! 1682: } ! 1683: ! 1684: // %0100_011000_mmmrrr d.m+-rxw.. 034 NOT.B <ea> ! 1685: OP_DEF(not_b) ! 1686: { ! 1687: uint n = ir & 0x3f; ! 1688: ! 1689: if (n < 8) { ! 1690: // NOT.B Dn ! 1691: CYCLE(2); ! 1692: uint32 data = (~reg.D[n]) & 0xff; ! 1693: ACC.move_8(data); ! 1694: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 1695: } else { ! 1696: // NOT.B <ea> ! 1697: CYCLE2(3, 4); ! 1698: uint32 ea = cea_data_1(); ! 1699: uint32 data = read_1(ea); ! 1700: data = (~data) & 0xff; ! 1701: ACC.move_8(data); ! 1702: write_1(ea, data); ! 1703: } ! 1704: } ! 1705: ! 1706: // %0100_011001_mmmrrr d.m+-rxw.. 034 NOT.W <ea> ! 1707: OP_DEF(not_w) ! 1708: { ! 1709: uint n = ir & 0x3f; ! 1710: ! 1711: if (n < 8) { ! 1712: // NOT.W Dn ! 1713: CYCLE(2); ! 1714: uint32 data = (~reg.D[n]) & 0xffff; ! 1715: ACC.move_16(data); ! 1716: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 1717: } else { ! 1718: // NOT.W <ea> ! 1719: CYCLE2(3, 4); ! 1720: uint32 ea = cea_data_2(); ! 1721: uint32 data = read_2(ea); ! 1722: data = (~data) & 0xffff; ! 1723: ACC.move_16(data); ! 1724: write_2(ea, data); ! 1725: } ! 1726: } ! 1727: ! 1728: // %0100_011010_mmmrrr d.m+-rxw.. 034 NOT.L <ea> ! 1729: OP_DEF(not_l) ! 1730: { ! 1731: uint n = ir & 0x3f; ! 1732: ! 1733: if (n < 8) { ! 1734: // NOT.L Dn ! 1735: CYCLE(2); ! 1736: reg.D[n] = ~reg.D[n]; ! 1737: ACC.move_32(reg.D[n]); ! 1738: } else { ! 1739: // NOT.L <ea> ! 1740: CYCLE2(3, 4); ! 1741: uint32 ea = cea_data_4(); ! 1742: uint32 data = read_4(ea); ! 1743: data = ~data; ! 1744: ACC.move_32(data); ! 1745: write_4(ea, data); ! 1746: } ! 1747: } ! 1748: ! 1749: // %0100_011011_mmmrrr d.m+-rxwpi 034 MOVE.W <ea>,SR ! 1750: OP_DEF(move_ea_sr) ! 1751: { ! 1752: SUPERVISOR_OP; ! 1753: ! 1754: CYCLE2(8, 10); ! 1755: uint16 data = fea_data_2(); ! 1756: SetSR(data); ! 1757: } ! 1758: ! 1759: // LINK.W, LINK.L は即値の取り出しが違うだけ。 ! 1760: void ! 1761: MPU680x0Device::ops_link(int32 imm) ! 1762: { ! 1763: // ページフォルトに備えて保存する。 ! 1764: save_reg_pd(7); ! 1765: push_4(RegAY); ! 1766: RegAY = reg.A[7]; ! 1767: reg.A[7] += imm; ! 1768: } ! 1769: ! 1770: // %0100_100000_mmmrrr d.m+-rxw.. 034 NBCD.B <ea> ! 1771: // %0100_100000_001yyy .......... -34 LINK.L Ay,#<imm> ! 1772: OP_DEF(nbcd) ! 1773: { ! 1774: uint n = ir & 0x3f; ! 1775: ! 1776: if (n < 8) { ! 1777: // NBCD.B Dn ! 1778: CYCLE(6); ! 1779: uint32 dst = RegDY & 0xff; ! 1780: dst = ACC.sbcd_8(dst, 0); ! 1781: RegDY = (RegDY & 0xffffff00) | dst; ! 1782: } else if (n < 16) { ! 1783: // LINK.L An,#<imm> ! 1784: CYCLE2(6, 7); ! 1785: // レジスタやスタックを変更する前にフェッチしないと、 ! 1786: // ページフォルトで再実行できなくなる ! 1787: int32 imm = fetch_4(); ! 1788: ops_link(imm); ! 1789: } else { ! 1790: // NBCD.B <ea> ! 1791: CYCLE(6); ! 1792: uint32 ea = cea_data_1(); ! 1793: uint32 dst = read_1(ea); ! 1794: dst = ACC.sbcd_8(dst, 0); ! 1795: write_1(ea, dst); ! 1796: } ! 1797: } ! 1798: ! 1799: // %0100_100001_mmmrrr ..m..rxwp. 034 PEA.L <ea> ! 1800: // %0100_100001_000yyy .......... 034 SWAP.W Dy ! 1801: // %0100_100001_001nnn .......... -34 BKPT #<imm> ! 1802: OP_DEF(pea) ! 1803: { ! 1804: uint n = ir & 0x3f; ! 1805: ! 1806: if (n < 8) { ! 1807: // SWAP.W Dy ! 1808: CYCLE(4); ! 1809: reg.D[n] = (reg.D[n] << 16) | (reg.D[n] >> 16); ! 1810: ACC.move_32(reg.D[n]); ! 1811: } else if (n < 16) { ! 1812: // BKPT #<imm> ! 1813: // ブレークポイント・アクノリッジサイクルに応答するデバイスはないので ! 1814: // 常に不当命令にする。 ! 1815: CYCLE(9); // ? ! 1816: op_illegal(); ! 1817: } else { ! 1818: // PEA.L <ea> ! 1819: CYCLE(4); ! 1820: uint32 ea = cea_ctrl(); ! 1821: // ページフォルトに備えて保存する ! 1822: save_reg_pd(7); ! 1823: push_4(ea); ! 1824: } ! 1825: } ! 1826: ! 1827: // MOVEM.[WL] <list>,<ea> の共通部分。 ! 1828: // bytesize は1レジスタ分のサイズ、.Wなら2、.Lなら4。 ! 1829: // 本当はテンプレートにしたい。 ! 1830: void ! 1831: MPU680x0Device::ops_movem_list_ea(int bytesize) ! 1832: { ! 1833: uint32 ea; ! 1834: int regcount; ! 1835: ! 1836: // 不当な第1ワードを弾く ! 1837: #define INVALID(x) (0xffULL << (56 - ((x) * 8))) ! 1838: const uint64 valid = ! 1839: INVALID(0) // Dn ! 1840: | INVALID(1) // An ! 1841: | INVALID(3) // (An)+ ! 1842: | 0x3fL; // (PC)... ! 1843: if ((int64)(valid << (ir & 0x3f)) < 0) { ! 1844: op_illegal(); ! 1845: return; ! 1846: } ! 1847: ! 1848: // 第2ワードは EA が正当な場合のみ EA より先にフェッチ ! 1849: ir2 = fetch_2(); ! 1850: ! 1851: // EA 取得。MOVEM だけ別対応 ! 1852: // | M -WXZ | MOVEM list,<ea> ! 1853: // だが、不当 EA はすでに弾いてあるので cea_data でいい ! 1854: if (bytesize == 2) { ! 1855: ea = cea_data_2(); ! 1856: } else { ! 1857: ea = cea_data_4(); ! 1858: } ! 1859: ! 1860: regcount = 0; ! 1861: uint list = ir2; ! 1862: if (eamode(ir) == 4/*-(An)*/) { ! 1863: // -(An) の場合 reglist の格納順が逆(転送順は LSB から) ! 1864: // bit15 bit0 ! 1865: // D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 A4 A5 A6 A7 ! 1866: while (list) { ! 1867: int ctz = __builtin_ctz(list); ! 1868: if (bytesize == 2) { ! 1869: write_2(ea, reg.R[15 - ctz] & 0xffff); ! 1870: } else { ! 1871: write_4(ea, reg.R[15 - ctz]); ! 1872: } ! 1873: ea -= bytesize; ! 1874: regcount++; ! 1875: // 処理した最下位ビットを落とす ! 1876: list &= list - 1; ! 1877: } ! 1878: // ea は一つ行き過ぎるので補正 ! 1879: RegAY = ea + bytesize; ! 1880: } else { ! 1881: // LSB 側から転送 ! 1882: // bit15 bit0 ! 1883: // A7 A6 A5 A4 A4 A2 A1 A0 D7 D6 D5 D4 D3 D2 D1 D0 ! 1884: while (list) { ! 1885: int ctz = __builtin_ctz(list); ! 1886: if (bytesize == 2) { ! 1887: write_2(ea, reg.R[ctz] & 0xffff); ! 1888: } else { ! 1889: write_4(ea, reg.R[ctz]); ! 1890: } ! 1891: ea += bytesize; ! 1892: regcount++; ! 1893: // 処理した最下位ビットを落とす ! 1894: list &= list - 1; ! 1895: } ! 1896: } ! 1897: ! 1898: CYCLE(4 + 2 * regcount); ! 1899: } ! 1900: ! 1901: // %0100_100010_mmmrrr ..m.-rxw.. 034 MOVEM.W <list>,<ea> ! 1902: // %0100_100010_000yyy .......... 034 EXT.W Dy ! 1903: OP_DEF(movem_w_mem) ! 1904: { ! 1905: uint n = ir & 0x3f; ! 1906: ! 1907: if (n < 8) { ! 1908: // EXT.W Dy ! 1909: CYCLE(4); ! 1910: uint16 data = (int16)(int8)(RegDY & 0xff); ! 1911: ACC.move_16(data); ! 1912: RegDY = (RegDY & 0xffff0000) | data; ! 1913: } else { ! 1914: // MOVEM.W <list>,<ea> ! 1915: ops_movem_list_ea(2); ! 1916: } ! 1917: } ! 1918: ! 1919: // %0100_100011_mmmrrr ..m.-rxw.. 034 MOVEM.L <list>,<ea> ! 1920: // %0100_100011_000yyy .......... 034 EXT.L Dy ! 1921: OP_DEF(movem_l_mem) ! 1922: { ! 1923: uint n = ir & 0x3f; ! 1924: ! 1925: if (n < 8) { ! 1926: // EXT.L Dy ! 1927: CYCLE(4); ! 1928: RegDY = (int32)(int16)(RegDY & 0x0000ffff); ! 1929: ACC.move_32(RegDY); ! 1930: } else { ! 1931: // MOVEM.L <list>,<ea> ! 1932: ops_movem_list_ea(4); ! 1933: } ! 1934: } ! 1935: ! 1936: // %0100_101000_mmmrrr dam+-rxwpi -34 TST.B <ea> ! 1937: OP_DEF(tst_b) ! 1938: { ! 1939: CYCLE(2); ! 1940: uint32 data = fea_all_1(); ! 1941: ACC.move_8(data); ! 1942: } ! 1943: ! 1944: // %0100_101001_mmmrrr dam+-rxwpi -34 TST.W <ea> ! 1945: OP_DEF(tst_w) ! 1946: { ! 1947: CYCLE(2); ! 1948: uint32 data = fea_all_2(); ! 1949: ACC.move_16(data); ! 1950: } ! 1951: ! 1952: // %0100_101010_mmmrrr dam+-rxwpi -34 TST.L <ea> ! 1953: OP_DEF(tst_l) ! 1954: { ! 1955: CYCLE(2); ! 1956: uint32 data = fea_all_4(); ! 1957: ACC.move_32(data); ! 1958: } ! 1959: ! 1960: // %0100_101011_mmmrrr d.m+-rxw.. 034 TAS.B <ea> ! 1961: // %0100_101011_111100 .......... 034 ILLEGAL ! 1962: OP_DEF(tas) ! 1963: { ! 1964: uint n = ir & 0x3f; ! 1965: ! 1966: if (n < 8) { ! 1967: // TAS.B Dn ! 1968: // リード・モディファイ・ライトという概念はない ! 1969: CYCLE(4); ! 1970: uint32 data = reg.D[n]; ! 1971: ACC.move_8(data); ! 1972: reg.D[n] |= 0x80; ! 1973: } else if (n == 0x3c) { ! 1974: // ILLEGAL ! 1975: op_illegal(); ! 1976: } else { ! 1977: // TAS.B <ea> ! 1978: // リード・モディファイ・ライトという概念はない ! 1979: CYCLE(12); ! 1980: uint32 ea = cea_data_1(); ! 1981: uint32 data = read_1(ea); ! 1982: ACC.move_8(data); ! 1983: write_1(ea, (data | 0x80)); ! 1984: } ! 1985: } ! 1986: ! 1987: // %0100_110000_mmmrrr d.m+-rxwpi -34 MULS.L <ea>,Dl ! 1988: // %0100_110000_mmmrrr d.m+-rxwpi -34 MULS.L <ea>,Dh:Dl ! 1989: // %0100_110000_mmmrrr d.m+-rxwpi -34 MULU.L <ea>,Dl ! 1990: // %0100_110000_mmmrrr d.m+-rxwpi -34 MULU.L <ea>,Dh:Dl ! 1991: OP_DEF(mul) ! 1992: { ! 1993: // 2ワード目 ! 1994: // %0LLL_Ss0000_000HHH ! 1995: // +++ || +++- Dh ! 1996: // | |+------------ %1:64bit, %0:32bit ! 1997: // | +------------- %1:MULS, %0:MULU ! 1998: // +---------------- Dl ! 1999: ir2 = fetch_2(); ! 2000: uint h = ir2 & 7; ! 2001: uint l = (ir2 >> 12) & 7; ! 2002: ! 2003: CYCLE(44); // XXX これは本当は最大値だけど ! 2004: switch ((ir2 >> 10) & 3) { ! 2005: case 0: ! 2006: { ! 2007: // MULU.L <ea>,Dl ! 2008: uint32 src = fea_data_4(); ! 2009: uint32 dst = reg.D[l]; ! 2010: reg.D[l] = ACC.mulu_32(src, dst); ! 2011: break; ! 2012: } ! 2013: ! 2014: case 1: ! 2015: { ! 2016: // MULU.L <ea>,Dh:Dl ! 2017: uint32 src = fea_data_4(); ! 2018: uint32 dst = reg.D[l]; ! 2019: uint64 res = ACC.mulu_64(src, dst); ! 2020: // h == l の時は未定義なので考えない。 ! 2021: reg.D[h] = res >> 32; ! 2022: reg.D[l] = res; ! 2023: break; ! 2024: } ! 2025: ! 2026: case 2: ! 2027: { ! 2028: // MULS.L <ea>,Dl ! 2029: uint32 src = fea_data_4(); ! 2030: uint32 dst = reg.D[l]; ! 2031: reg.D[l] = ACC.muls_32(src, dst); ! 2032: break; ! 2033: } ! 2034: ! 2035: case 3: ! 2036: { ! 2037: // MULS.L <ea>,Dh:Dl ! 2038: uint32 src = fea_data_4(); ! 2039: uint32 dst = reg.D[l]; ! 2040: uint64 res = ACC.muls_64(src, dst); ! 2041: // h == l の時は未定義なので考えない。 ! 2042: reg.D[h] = res >> 32; ! 2043: reg.D[l] = res; ! 2044: break; ! 2045: } ! 2046: ! 2047: default: ! 2048: __unreachable(); ! 2049: } ! 2050: } ! 2051: ! 2052: // DIVU.L <ea>,Dq ! 2053: // DIVUL.L <ea>,Dr:Dq ! 2054: void ! 2055: MPU680x0Device::ops_divu_32_32(uint r, uint q) ! 2056: { ! 2057: CYCLE(78); // XXX これは本当は最大値だけど ! 2058: ! 2059: uint32 src = fea_data_4(); ! 2060: uint32 dst = reg.D[q]; ! 2061: ! 2062: if (src == 0) { ! 2063: // ゼロ除算の場合、 ! 2064: // X は変化しない ! 2065: // C は常にクリア ! 2066: // N,Z,V は未定義 ! 2067: CCR.SetC(false); ! 2068: Exception(M68K::EXCEP_ZERODIV); ! 2069: return; ! 2070: } ! 2071: uint32 quo = dst / src; ! 2072: uint32 rem = dst % src; ! 2073: // このケースでオーバーフローは起きないはず ! 2074: ! 2075: // 正常の場合、 ! 2076: // X は変化しない ! 2077: // V, C はクリア ! 2078: // N, Z は quo の結果。 ! 2079: // r == q の場合 quo が残るので、rem を先に書く ! 2080: reg.D[r] = rem; ! 2081: reg.D[q] = quo; ! 2082: ACC.move_32(quo); ! 2083: } ! 2084: ! 2085: // DIVU.L <ea>,Dr:Dq ! 2086: void ! 2087: MPU680x0Device::ops_divu_64_32(uint r, uint q) ! 2088: { ! 2089: CYCLE(78); // XXX これは本当は最大値だけど ! 2090: ! 2091: uint32 src = fea_data_4(); ! 2092: uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; ! 2093: ! 2094: if (src == 0) { ! 2095: // ゼロ除算の場合、 ! 2096: // X は変化しない ! 2097: // C は常にクリア ! 2098: // N,Z,V は未定義 ! 2099: CCR.SetC(false); ! 2100: Exception(M68K::EXCEP_ZERODIV); ! 2101: return; ! 2102: } ! 2103: uint64 q64 = dst / src; ! 2104: if (q64 > 0xffffffffUL) { ! 2105: // オーバーフローの場合、 ! 2106: // X は変化しない ! 2107: // N,Z は未定義 ! 2108: // V はセット ! 2109: // C は常にクリア ! 2110: CCR.SetV(true); ! 2111: CCR.SetC(false); ! 2112: return; ! 2113: } ! 2114: uint32 quo = q64; ! 2115: uint32 rem = dst % src; ! 2116: ! 2117: // 正常の場合、 ! 2118: // X は変化しない ! 2119: // V, C はクリア ! 2120: // N, Z は quo の結果。 ! 2121: // r == q の場合 quo が残るので、rem を先に書く ! 2122: reg.D[r] = rem; ! 2123: reg.D[q] = quo; ! 2124: ACC.move_32(quo); ! 2125: } ! 2126: ! 2127: // DIVS.L <ea>,Dq ! 2128: // DIVSL.L <ea>,Dr:Dq ! 2129: void ! 2130: MPU680x0Device::ops_divs_32_32(uint r, uint q) ! 2131: { ! 2132: CYCLE(90); // XXX これは本当は最大値だけど ! 2133: ! 2134: uint32 src = fea_data_4(); ! 2135: uint32 dst = reg.D[q]; ! 2136: ! 2137: if (src == 0) { ! 2138: // ゼロ除算の場合、 ! 2139: // X は変化しない ! 2140: // C は常にクリア ! 2141: // N,Z,V は未定義 ! 2142: CCR.SetC(false); ! 2143: Exception(M68K::EXCEP_ZERODIV); ! 2144: return; ! 2145: } ! 2146: ! 2147: // ホストでオーバーフローが起きるのはこのケースのみ ! 2148: if (dst == INT32_MIN && src == -1) { ! 2149: // オーバーフローの場合、 ! 2150: // X は変化しない ! 2151: // N,Z は未定義 ! 2152: // V はセット ! 2153: // C は常にクリア ! 2154: CCR.SetV(true); ! 2155: CCR.SetC(false); ! 2156: return; ! 2157: } ! 2158: ! 2159: uint32 quo = (int32)dst / (int32)src; ! 2160: uint32 rem = (int32)dst % (int32)src; ! 2161: // ここでオーバーフローは起きない ! 2162: ! 2163: // 正常の場合、 ! 2164: // X は変化しない ! 2165: // V, C はクリア ! 2166: // N, Z は quo の結果。 ! 2167: // r == q の場合 quo が残るので、rem を先に書く ! 2168: reg.D[r] = rem; ! 2169: reg.D[q] = quo; ! 2170: ACC.move_32(quo); ! 2171: } ! 2172: ! 2173: // DIVSL.L ! 2174: void ! 2175: MPU680x0Device::ops_divs_64_32(uint r, uint q) ! 2176: { ! 2177: CYCLE(90); // XXX これは本当は最大値だけど ! 2178: ! 2179: uint32 src = fea_data_4(); ! 2180: uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; ! 2181: ! 2182: if (src == 0) { ! 2183: // ゼロ除算の場合、 ! 2184: // X は変化しない ! 2185: // C は常にクリア ! 2186: // N,Z,V は未定義 ! 2187: CCR.SetC(false); ! 2188: Exception(M68K::EXCEP_ZERODIV); ! 2189: return; ! 2190: } ! 2191: ! 2192: // ホストでオーバーフローが起きるのはこのケースのみ ! 2193: if (dst == INT64_MIN && src == -1) { ! 2194: // オーバーフローの場合、 ! 2195: // X は変化しない ! 2196: // N,Z は未定義 ! 2197: // V はセット ! 2198: // C は常にクリア ! 2199: CCR.SetV(true); ! 2200: CCR.SetC(false); ! 2201: return; ! 2202: } ! 2203: ! 2204: int64 sq64 = (int64)dst / (int32)src; ! 2205: if ((int32)sq64 != sq64) { ! 2206: // オーバーフロー ! 2207: CCR.SetV(true); ! 2208: CCR.SetC(false); ! 2209: return; ! 2210: } ! 2211: uint32 quo = (uint32)sq64; ! 2212: uint32 rem = (int64)dst % (int32)src; ! 2213: ! 2214: // 正常の場合、 ! 2215: // X は変化しない ! 2216: // V, C はクリア ! 2217: // N, Z は quo の結果。 ! 2218: // r == q の場合 quo が残るので、rem を先に書く ! 2219: reg.D[r] = rem; ! 2220: reg.D[q] = quo; ! 2221: ACC.move_32(quo); ! 2222: } ! 2223: ! 2224: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVS.L <ea>,Dq ! 2225: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVS.L <ea>,Dr:Dq ! 2226: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVSL.L <ea>,Dr:Dq ! 2227: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVU.L <ea>,Dq ! 2228: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVU.L <ea>,Dr:Dq ! 2229: // %0100_110001_mmmrrr d.m+-rxwpi -34 DIVUL.L <ea>,Dr:Dq ! 2230: OP_DEF(div) ! 2231: { ! 2232: // 2ワード目 ! 2233: // %0QQQ_Ss0000_000RRR ! 2234: // +++ || +++- Dr ! 2235: // | |+------------ %1:64bit, %0:32bit ! 2236: // | +------------- %1:DIVS, %0:DIVU ! 2237: // +---------------- Dq ! 2238: ir2 = fetch_2(); ! 2239: uint r = ir2 & 7; ! 2240: uint q = (ir2 >> 12) & 7; ! 2241: ! 2242: switch ((ir2 >> 10) & 3) { ! 2243: case 0: ! 2244: ops_divu_32_32(r, q); ! 2245: break; ! 2246: case 1: ! 2247: ops_divu_64_32(r, q); ! 2248: break; ! 2249: case 2: ! 2250: ops_divs_32_32(r, q); ! 2251: break; ! 2252: case 3: ! 2253: ops_divs_64_32(r, q); ! 2254: break; ! 2255: default: ! 2256: __unreachable(); ! 2257: } ! 2258: } ! 2259: ! 2260: void ! 2261: MPU680x0Device::ops_movem_ea_list(int bytesize) ! 2262: { ! 2263: uint32 ea; ! 2264: int regcount; ! 2265: bool anpi = false; ! 2266: ! 2267: ir2 = fetch_2(); ! 2268: ! 2269: // EA 取得。MOVEM だけ別対応 ! 2270: // | M+ WXZP | MOVEM <ea>,list ! 2271: switch (eamode(ir)) { ! 2272: case 2: // (An) ! 2273: ea = cea_anin(eanum(ir)); ! 2274: break; ! 2275: case 3: // (An)+ ! 2276: save_reg_pi(eanum(ir)); ! 2277: if (bytesize == 2) { ! 2278: ea = cea_anpi_2(eanum(ir)); ! 2279: } else { ! 2280: ea = cea_anpi_4(eanum(ir)); ! 2281: } ! 2282: anpi = true; ! 2283: break; ! 2284: case 5: // d16(An) ! 2285: ea = cea_andi(eanum(ir)); ! 2286: break; ! 2287: case 6: // (An,IX) ! 2288: ea = cea_anix(eanum(ir)); ! 2289: break; ! 2290: case 7: ! 2291: switch (eanum(ir)) { ! 2292: case 0: // Abs.W ! 2293: ea = cea_absw(); ! 2294: break; ! 2295: case 1: // Abs.L ! 2296: ea = cea_absl(); ! 2297: break; ! 2298: case 2: // d16(PC) ! 2299: ea = cea_pcdi(); ! 2300: break; ! 2301: case 3: // (PC,IX) ! 2302: ea = cea_pcix(); ! 2303: break; ! 2304: default: ! 2305: op_illegal(); ! 2306: return; ! 2307: } ! 2308: break; ! 2309: default: ! 2310: op_illegal(); ! 2311: return; ! 2312: } ! 2313: ! 2314: // XXX レジスタリストに表れて、ea オペランドに出てくる ! 2315: // レジスタは Dn、IX も含めて全部保存しておく必要がある。 ! 2316: ! 2317: regcount = 0; ! 2318: uint list = ir2; ! 2319: while (list) { ! 2320: uint32 data; ! 2321: if (bytesize == 2) { ! 2322: data = (int32)(int16)read_2(ea); ! 2323: } else { ! 2324: data = read_4(ea); ! 2325: } ! 2326: ea += bytesize; ! 2327: regcount++; ! 2328: int ctz = __builtin_ctz(list); ! 2329: reg.R[ctz] = data; ! 2330: // clear LSB bits ! 2331: list &= ((~1U) << ctz); ! 2332: } ! 2333: // (An)+ なら An を更新 ! 2334: if (anpi) { ! 2335: RegAY = ea; ! 2336: } ! 2337: ! 2338: CYCLE(8 + 4 * regcount); ! 2339: } ! 2340: ! 2341: // %0100_110010_mmmrrr ..m+.rxwp. 034 MOVEM.W <ea>,<list> ! 2342: OP_DEF(movem_w) ! 2343: { ! 2344: ops_movem_ea_list(2); ! 2345: } ! 2346: ! 2347: // %0100_110011_mmmrrr ..m+.rxwp. 034 MOVEM.L <ea>,<list> ! 2348: OP_DEF(movem_l) ! 2349: { ! 2350: ops_movem_ea_list(4); ! 2351: } ! 2352: ! 2353: // 制御レジスタ: ! 2354: // MPU ! 2355: // $000 SFC 234 ! 2356: // $001 DFC 234 ! 2357: // $002 CACR 234 ! 2358: // $003 TC --4 ! 2359: // $004 ITT0 --4 ! 2360: // $005 ITT1 --4 ! 2361: // $006 DTT0 --4 ! 2362: // $007 DTT1 --4 ! 2363: // $800 USP 234 ! 2364: // $801 VBR 234 ! 2365: // $802 CAAR 23- ! 2366: // $803 MSP 234 ! 2367: // $804 ISP 234 ! 2368: // $805 MMUSR --4 ! 2369: // $806 URP --4 ! 2370: // $807 SRP --4 ! 2371: ! 2372: // MOVEC.L Rc,Rn ! 2373: void ! 2374: MPU680x0Device::ops_movec_rc_rn() ! 2375: { ! 2376: SUPERVISOR_OP; ! 2377: ! 2378: CYCLE(6); ! 2379: ir2 = fetch_2(); ! 2380: uint n = ir2 >> 12; ! 2381: uint c = ir2 & 0xfff; ! 2382: ! 2383: // まず CPU 固有レジスタを試す。 ! 2384: if (ops_movec_rc_rn_cpu(c, n)) { ! 2385: return; ! 2386: } ! 2387: ! 2388: // なければ共通レジスタを試す。 ! 2389: switch (c) { ! 2390: case 0x000: ! 2391: reg.R[n] = reg.GetSFC(); ! 2392: return; ! 2393: case 0x001: ! 2394: reg.R[n] = reg.GetDFC(); ! 2395: return; ! 2396: case 0x002: ! 2397: reg.R[n] = reg.cacr; ! 2398: return; ! 2399: case 0x800: ! 2400: reg.R[n] = reg.usp; ! 2401: return; ! 2402: case 0x801: ! 2403: reg.R[n] = reg.vbr; ! 2404: return; ! 2405: case 0x803: ! 2406: if (reg.m) { ! 2407: reg.R[n] = reg.A[7]; ! 2408: } else { ! 2409: reg.R[n] = reg.msp; ! 2410: } ! 2411: return; ! 2412: case 0x804: ! 2413: if (reg.m) { ! 2414: reg.R[n] = reg.isp; ! 2415: } else { ! 2416: reg.R[n] = reg.A[7]; ! 2417: } ! 2418: return; ! 2419: default: ! 2420: break; ! 2421: } ! 2422: op_illegal(); ! 2423: } ! 2424: ! 2425: // MOVEC.L Rc,Rn (68030 固有) ! 2426: bool ! 2427: MPU68030Device::ops_movec_rc_rn_cpu(uint c, uint n) ! 2428: { ! 2429: switch (c) { ! 2430: case 0x802: ! 2431: reg.R[n] = reg.caar; ! 2432: return true; ! 2433: default: ! 2434: break; ! 2435: } ! 2436: return false; ! 2437: } ! 2438: ! 2439: // MOVEC.L Rc,Rn (68040 固有) ! 2440: bool ! 2441: MPU68040Device::ops_movec_rc_rn_cpu(uint c, uint n) ! 2442: { ! 2443: switch (c) { ! 2444: case 0x003: ! 2445: reg.R[n] = reg.tc40; ! 2446: return true; ! 2447: case 0x004: ! 2448: reg.R[n] = reg.itt[0]; ! 2449: return true; ! 2450: case 0x005: ! 2451: reg.R[n] = reg.itt[1]; ! 2452: return true; ! 2453: case 0x006: ! 2454: reg.R[n] = reg.dtt[0]; ! 2455: return true; ! 2456: case 0x007: ! 2457: reg.R[n] = reg.dtt[1]; ! 2458: return true; ! 2459: case 0x805: ! 2460: reg.R[n] = reg.mmusr40; ! 2461: return true; ! 2462: case 0x806: ! 2463: reg.R[n] = reg.urp40; ! 2464: return true; ! 2465: case 0x807: ! 2466: reg.R[n] = reg.srp40; ! 2467: return true; ! 2468: default: ! 2469: break; ! 2470: } ! 2471: return false; ! 2472: } ! 2473: ! 2474: // MOVEC.L Rn,Rc ! 2475: void ! 2476: MPU680x0Device::ops_movec_rn_rc() ! 2477: { ! 2478: SUPERVISOR_OP; ! 2479: ! 2480: ir2 = fetch_2(); ! 2481: uint n = ir2 >> 12; ! 2482: uint c = ir2 & 0xfff; ! 2483: ! 2484: // まず CPU 固有レジスタを試す。 ! 2485: if (ops_movec_rn_rc_cpu(c, n)) { ! 2486: return; ! 2487: } ! 2488: ! 2489: // なければ共通レジスタを試す。 ! 2490: switch (c) { ! 2491: case 0x000: ! 2492: CYCLE(12); ! 2493: reg.sfc = busaddr::FC(reg.R[n] & 7) | BusAddr::R; ! 2494: return; ! 2495: case 0x001: ! 2496: CYCLE(12); ! 2497: reg.dfc = busaddr::FC(reg.R[n] & 7) | BusAddr::W; ! 2498: return; ! 2499: case 0x002: ! 2500: CYCLE(12); ! 2501: SetCACR(reg.R[n]); ! 2502: return; ! 2503: case 0x800: ! 2504: CYCLE(6); ! 2505: reg.usp = reg.R[n]; ! 2506: return; ! 2507: case 0x801: ! 2508: CYCLE(6); ! 2509: reg.vbr = reg.R[n]; ! 2510: return; ! 2511: case 0x803: ! 2512: CYCLE(6); ! 2513: if (reg.m) { ! 2514: reg.A[7] = reg.R[n]; ! 2515: } else { ! 2516: reg.msp = reg.R[n]; ! 2517: } ! 2518: return; ! 2519: case 0x804: ! 2520: CYCLE(6); ! 2521: if (reg.m) { ! 2522: reg.isp = reg.R[n]; ! 2523: } else { ! 2524: reg.A[7] = reg.R[n]; ! 2525: } ! 2526: return; ! 2527: default: ! 2528: break; ! 2529: } ! 2530: op_illegal(); ! 2531: } ! 2532: ! 2533: // MOVEC.L Rn,Rc (68030 固有) ! 2534: bool ! 2535: MPU68030Device::ops_movec_rn_rc_cpu(uint c, uint n) ! 2536: { ! 2537: switch (c) { ! 2538: case 0x802: ! 2539: CYCLE(6); ! 2540: reg.caar = reg.R[n]; ! 2541: return true; ! 2542: default: ! 2543: break; ! 2544: } ! 2545: return false; ! 2546: } ! 2547: ! 2548: // MOVEC.L Rn,Rc (68040 固有) ! 2549: bool ! 2550: MPU68040Device::ops_movec_rn_rc_cpu(uint c, uint n) ! 2551: { ! 2552: switch (c) { ! 2553: case 0x003: ! 2554: SetTC(reg.R[n]); ! 2555: return true; ! 2556: case 0x004: ! 2557: SetTT(mmu_itt[0].get(), reg.R[n]); ! 2558: return true; ! 2559: case 0x005: ! 2560: SetTT(mmu_itt[1].get(), reg.R[n]); ! 2561: return true; ! 2562: case 0x006: ! 2563: SetTT(mmu_dtt[0].get(), reg.R[n]); ! 2564: return true; ! 2565: case 0x007: ! 2566: SetTT(mmu_dtt[1].get(), reg.R[n]); ! 2567: return true; ! 2568: case 0x805: ! 2569: // 書き込める? ! 2570: //SetMMUSR(reg.R[n]); ! 2571: OP_FUNC(unimpl); ! 2572: return true; ! 2573: case 0x806: ! 2574: SetURP(reg.R[n]); ! 2575: return true; ! 2576: case 0x807: ! 2577: SetSRP(reg.R[n]); ! 2578: return true; ! 2579: default: ! 2580: break; ! 2581: } ! 2582: return false; ! 2583: } ! 2584: ! 2585: // %0100_111001_00nnnn .......... 034 TRAP #<vector> ! 2586: // %0100_111001_010yyy .......... 034 LINK.W Ay,#<imm> ! 2587: // %0100_111001_011yyy .......... 034 UNLK Ay ! 2588: // %0100_111001_100yyy .......... 034 MOVE.L Ay,USP ! 2589: // %0100_111001_101yyy .......... 034 MOVE.L USP,Ay ! 2590: // %0100_111001_110000 .......... 034 RESET ! 2591: // %0100_111001_110001 .......... 034 NOP ! 2592: // %0100_111001_110010 .......... 034 STOP #<imm> ! 2593: // %0100_111001_110011 .......... 034 RTE ! 2594: // %0100_111001_110100 .......... -34 RTD #<imm> ! 2595: // %0100_111001_110101 .......... 034 RTS ! 2596: // %0100_111001_110110 .......... 034 TRAPV ! 2597: // %0100_111001_110111 .......... 034 RTR ! 2598: // %0100_111001_111010 .......... -34 MOVEC.L Rc,Rn ! 2599: // %0100_111001_111011 .......... -34 MOVEC.L Rn,Rc ! 2600: OP_DEF(trap) ! 2601: { ! 2602: uint n = ir & 0x3f; ! 2603: ! 2604: switch (n) { ! 2605: case 0x00 ... 0x0e:// TRAP #<vector> ! 2606: CYCLE2(18, 20); ! 2607: // TRAP#N 例外 ! 2608: Exception(M68K::EXCEP_TRAP0 + n); ! 2609: return; ! 2610: ! 2611: case 0x0f: // TRAP #15 ! 2612: CYCLE2(18, 20); ! 2613: // TRAP#15 例外 (IOCS コール表示のためこれだけ別処理) ! 2614: ExceptionTrap15(); ! 2615: return; ! 2616: ! 2617: case 0x10: ! 2618: case 0x11: ! 2619: case 0x12: ! 2620: case 0x13: ! 2621: case 0x14: ! 2622: case 0x15: ! 2623: case 0x16: ! 2624: case 0x17: // LINK.W Ay,#<imm> ! 2625: { ! 2626: CYCLE2(4, 5); ! 2627: // レジスタやスタックを変更する前にフェッチとセーブをしないと、 ! 2628: // ページフォルトで再実行できなくなる ! 2629: int32 imm = (int32)(int16)fetch_2(); ! 2630: ops_link(imm); ! 2631: return; ! 2632: } ! 2633: ! 2634: case 0x18: ! 2635: case 0x19: ! 2636: case 0x1a: ! 2637: case 0x1b: ! 2638: case 0x1c: ! 2639: case 0x1d: ! 2640: case 0x1e: ! 2641: case 0x1f: // UNLK Ay ! 2642: CYCLE(5); ! 2643: // ページフォルトに備えて保存する ! 2644: save_reg_pi(7); ! 2645: reg.A[7] = RegAY; ! 2646: RegAY = pop_4(); ! 2647: return; ! 2648: ! 2649: case 0x20: ! 2650: case 0x21: ! 2651: case 0x22: ! 2652: case 0x23: ! 2653: case 0x24: ! 2654: case 0x25: ! 2655: case 0x26: ! 2656: case 0x27: // MOVE.L Ay,USP ! 2657: SUPERVISOR_OP; ! 2658: CYCLE(4); ! 2659: reg.usp = RegAY; ! 2660: return; ! 2661: ! 2662: case 0x28: ! 2663: case 0x29: ! 2664: case 0x2a: ! 2665: case 0x2b: ! 2666: case 0x2c: ! 2667: case 0x2d: ! 2668: case 0x2e: ! 2669: case 0x2f: // MOVE.L USP,Ay ! 2670: SUPERVISOR_OP; ! 2671: CYCLE(4); ! 2672: RegAY = reg.usp; ! 2673: return; ! 2674: ! 2675: case 0x30: // RESET ! 2676: CYCLE(518); ! 2677: ops_reset(); ! 2678: return; ! 2679: ! 2680: case 0x31: // NOP ! 2681: CYCLE(2); ! 2682: // XXX ほんとは何かするらしいけど ! 2683: return; ! 2684: ! 2685: case 0x32: // STOP #<imm> ! 2686: SUPERVISOR_OP; ! 2687: CYCLE(8); ! 2688: ops_stop(); ! 2689: return; ! 2690: ! 2691: case 0x33: // RTE ! 2692: SUPERVISOR_OP; ! 2693: ops_rte(); ! 2694: return; ! 2695: ! 2696: case 0x34: // RTD #<imm> ! 2697: { ! 2698: CYCLE2(10, 12); ! 2699: // ページフォルトに備えて保存する ! 2700: save_reg_pi(7); ! 2701: uint32 disp = fetch_2(); ! 2702: Jump(pop_4()); ! 2703: reg.A[7] += (int32)(int16)disp; ! 2704: return; ! 2705: } ! 2706: ! 2707: case 0x35: // RTS ! 2708: CYCLE2(9, 11); ! 2709: // ページフォルトに備えて保存する ! 2710: save_reg_pi(7); ! 2711: Jump(pop_4()); ! 2712: return; ! 2713: ! 2714: case 0x36: // TRAPV ! 2715: if (CCR.IsV()) { ! 2716: CYCLE2(22, 24); ! 2717: Exception(M68K::EXCEP_TRAPV); ! 2718: } else { ! 2719: CYCLE(4); ! 2720: } ! 2721: return; ! 2722: ! 2723: case 0x37: // RTR ! 2724: CYCLE2(12, 14); ! 2725: // ページフォルトに備えて保存する ! 2726: save_reg_pi(7); ! 2727: CCR.Set(pop_2()); ! 2728: Jump(pop_4()); ! 2729: return; ! 2730: ! 2731: case 0x3a: // MOVEC.L Rc,Rn ! 2732: ops_movec_rc_rn(); ! 2733: return; ! 2734: ! 2735: case 0x3b: // MOVEC.L Rn,Rc ! 2736: ops_movec_rn_rc(); ! 2737: return; ! 2738: ! 2739: default: ! 2740: op_illegal(); ! 2741: return; ! 2742: } ! 2743: } ! 2744: ! 2745: // %0100_111010_mmmrrr ..m..rxwp. 034 JSR <ea> ! 2746: OP_DEF(jsr) ! 2747: { ! 2748: CYCLE2(4, 7); ! 2749: uint32 ea = cea_ctrl(); ! 2750: uint32 return_addr = reg.pc; ! 2751: ! 2752: // ページフォルトに備えて保存する。 ! 2753: save_reg_pd(7); ! 2754: push_4(return_addr); ! 2755: Jump(ea); ! 2756: } ! 2757: ! 2758: // %0100_111011_mmmrrr ..m..rxwp. 034 JMP <ea> ! 2759: OP_DEF(jmp) ! 2760: { ! 2761: CYCLE2(4, 6); ! 2762: // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか ! 2763: uint32 ea = cea_ctrl(); ! 2764: Jump(ea); ! 2765: } ! 2766: ! 2767: // %0101_qqq000_mmmrrr d.m+-rxw.. 034 ADDQ.B #qqq,<ea> ! 2768: OP_DEF(addq_b) ! 2769: { ! 2770: uint n = ir & 0x3f; ! 2771: ! 2772: uint32 src = RegIRX; ! 2773: src = (src == 0) ? 8 : src; ! 2774: if (n < 8) { ! 2775: // ADDQ.B #qqq,Dn ! 2776: CYCLE(2); ! 2777: uint32 data = ACC.add_8(src, reg.D[n] & 0xff); ! 2778: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 2779: } else { ! 2780: // ADDQ.B #qqq,<ea> ! 2781: CYCLE2(3, 4); ! 2782: uint32 ea = cea_data_1(); ! 2783: uint32 data = read_1(ea); ! 2784: data = ACC.add_8(src, data); ! 2785: write_1(ea, data); ! 2786: } ! 2787: } ! 2788: ! 2789: // %0101_qqq001_mmmrrr d.m+-rxw.. 034 ADDQ.W #qqq,<ea> ! 2790: // %0101_qqq001_001yyy .a........ 034 ADDQ.W #qqq,Ay (.Lと等価) ! 2791: OP_DEF(addq_w) ! 2792: { ! 2793: uint n = ir & 0x3f; ! 2794: ! 2795: uint32 src = RegIRX; ! 2796: src = (src == 0) ? 8 : src; ! 2797: if (n < 8) { ! 2798: // ADDQ.W #qqq,Dn ! 2799: CYCLE(2); ! 2800: uint32 data = ACC.add_16(src, reg.D[n] & 0xffff); ! 2801: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 2802: } else if (n < 16) { ! 2803: // ADDQ.W #qqq,An は ADDQ.L と等価 ! 2804: // フラグは変化しない ! 2805: CYCLE(2); ! 2806: reg.R[n] += src; ! 2807: } else { ! 2808: // ADDQ.W #qqq,<ea> ! 2809: CYCLE2(3, 4); ! 2810: uint32 ea = cea_data_2(); ! 2811: uint32 data = read_2(ea); ! 2812: data = ACC.add_16(src, data); ! 2813: write_2(ea, data); ! 2814: } ! 2815: } ! 2816: ! 2817: // %0101_qqq010_mmmrrr d.m+-rxw.. 034 ADDQ.L #qqq,<ea> ! 2818: // %0101_qqq010_001yyy .a........ 034 ADDQ.L #qqq,Ay ! 2819: OP_DEF(addq_l) ! 2820: { ! 2821: uint n = ir & 0x3f; ! 2822: ! 2823: uint32 src = RegIRX; ! 2824: src = (src == 0) ? 8 : src; ! 2825: if (n < 8) { ! 2826: // ADDQ.L #qqq,Dn ! 2827: CYCLE(2); ! 2828: reg.D[n] = ACC.add_32(src, reg.D[n]); ! 2829: } else if (n < 16) { ! 2830: // ADDQ.L #qqq,An ! 2831: // フラグは変化しない ! 2832: CYCLE(2); ! 2833: reg.R[n] += src; ! 2834: } else { ! 2835: // ADDQ.L #qqq,<ea> ! 2836: CYCLE2(3, 4); ! 2837: uint32 ea = cea_data_4(); ! 2838: uint32 data = read_4(ea); ! 2839: data = ACC.add_32(src, data); ! 2840: write_4(ea, data); ! 2841: } ! 2842: } ! 2843: ! 2844: // TRAPcc の共通部分。 ! 2845: void ! 2846: MPU680x0Device::ops_trapcc(uint cond) ! 2847: { ! 2848: // 条件成立すれば例外。成立しなければ何もしない。 ! 2849: // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。 ! 2850: if (CCR.Cond(cond)) { ! 2851: CYCLE2(22, 24); ! 2852: Exception(M68K::EXCEP_TRAPV); ! 2853: } else { ! 2854: // サイクルを消費するだけ ! 2855: CYCLE(4); ! 2856: } ! 2857: } ! 2858: ! 2859: // %0101_cccc11_mmmrrr d.m+-rxw.. 034 Scc.B <ea> ! 2860: // %0101_cccc11_001yyy .......... 034 DBcc.W Dy,<label> ! 2861: // %0101_cccc11_111010 .......... -34 TRAPcc.W #<imm> ! 2862: // %0101_cccc11_111011 .......... -34 TRAPcc.L #<imm> ! 2863: // %0101_cccc11_111100 .......... -34 TRAPcc ! 2864: // %0101_000111_001yyy .......... 034 DBRA.W Dy,<label> ! 2865: OP_DEF(scc) ! 2866: { ! 2867: uint n = ir & 0x3f; ! 2868: uint cond = (ir >> 8) & 0x0f; ! 2869: ! 2870: switch (n) { ! 2871: case 0b000000 ... 0b000111: // Scc.B Dn ! 2872: CYCLE(4); ! 2873: if (CCR.Cond(cond)) { ! 2874: RegDY |= 0xff; ! 2875: } else { ! 2876: RegDY &= ~0xff; ! 2877: } ! 2878: return; ! 2879: ! 2880: case 0b001000 ... 0b001111: // DBcc.W Dy,<label> ! 2881: if (CCR.Cond(cond)) { ! 2882: // 真なら何もしない。disp を読み飛ばして次へ。 ! 2883: CYCLE2(6, 8); ! 2884: fetch_2(); ! 2885: } else { ! 2886: // 偽の場合 ! 2887: ! 2888: // Dy.W を減算して(下位ワードに)書き戻し、Dy.W が -1 だったら ! 2889: // ループ終了。だが最適化のため、減算前の Dy.W が 0 の時は ! 2890: // 下位ワードを 0xffff にしてループ終了、そうでなければ Dy.L を ! 2891: // 減算するだけでいいはず。 ! 2892: ! 2893: uint16 data = RegDY; ! 2894: if (data == 0) { ! 2895: // ループ終了。disp を読み飛ばす ! 2896: CYCLE2(10, 13); ! 2897: RegDY |= 0x0000ffff; ! 2898: fetch_2(); ! 2899: } else { ! 2900: CYCLE2(6, 8); ! 2901: RegDY--; ! 2902: uint32 origin = reg.pc; ! 2903: int32 disp = (int32)(int16)fetch_2(); ! 2904: Jump(origin + disp); ! 2905: } ! 2906: } ! 2907: return; ! 2908: ! 2909: case 0b010000 ... 0b010111: // Scc.B <ea> ! 2910: case 0b011000 ... 0b011111: // Scc.B <ea> ! 2911: case 0b100000 ... 0b100111: // Scc.B <ea> ! 2912: case 0b101000 ... 0b101111: // Scc.B <ea> ! 2913: case 0b110000 ... 0b110111: // Scc.B <ea> ! 2914: case 0b111000: // Scc.B <ea> ! 2915: case 0b111001: // Scc.B <ea> ! 2916: { ! 2917: CYCLE(5); ! 2918: // 条件成立可否に関わらず EA は取得しないといけない ! 2919: uint32 ea = cea_data_1(); ! 2920: uint32 data; ! 2921: if (CCR.Cond(cond)) { ! 2922: data = 0xff; ! 2923: } else { ! 2924: data = 0; ! 2925: } ! 2926: write_1(ea, data); ! 2927: return; ! 2928: } ! 2929: ! 2930: case 0b111010: // TRAPcc.W #<imm> ! 2931: // オペランドなしTRAPccに比べてすべてのケースで2サイクル多い ! 2932: CYCLE(2); ! 2933: fetch_2(); ! 2934: ops_trapcc(cond); ! 2935: return; ! 2936: ! 2937: case 0b111011: // TRAPcc.L #<imm> ! 2938: // オペランドなしTRAPccに比べてすべてのケースで4サイクル多い ! 2939: CYCLE(4); ! 2940: fetch_4(); ! 2941: ops_trapcc(cond); ! 2942: return; ! 2943: ! 2944: case 0b111100: // TRAPcc ! 2945: ops_trapcc(cond); ! 2946: return; ! 2947: ! 2948: default: ! 2949: OP_FUNC(illegal); ! 2950: return; ! 2951: } ! 2952: } ! 2953: ! 2954: // %0101_qqq100_mmmrrr d.m+-rxw.. 034 SUBQ.B #qqq,<ea> ! 2955: OP_DEF(subq_b) ! 2956: { ! 2957: uint n = ir & 0x3f; ! 2958: ! 2959: uint32 src = RegIRX; ! 2960: src = (src == 0) ? 8 : src; ! 2961: if (n < 8) { ! 2962: // SUBQ.B #qqq,Dn ! 2963: CYCLE(2); ! 2964: uint32 data = ACC.sub_8(src, reg.D[n] & 0xff); ! 2965: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 2966: } else { ! 2967: // SUBQ.B #qqq,<ea> ! 2968: CYCLE2(3, 4); ! 2969: uint32 ea = cea_data_1(); ! 2970: uint32 data = read_1(ea); ! 2971: data = ACC.sub_8(src, data); ! 2972: write_1(ea, data); ! 2973: } ! 2974: } ! 2975: ! 2976: // %0101_qqq101_mmmrrr d.m+-rxw.. 034 SUBQ.W #qqq,<ea> ! 2977: // %0101_qqq101_001yyy .a........ 034 SUBQ.W #qqq,Ay (.Lと等価) ! 2978: OP_DEF(subq_w) ! 2979: { ! 2980: uint n = ir & 0x3f; ! 2981: ! 2982: uint32 src = RegIRX; ! 2983: src = (src == 0) ? 8 : src; ! 2984: if (n < 8) { ! 2985: // SUBQ.W #qqq,Dn ! 2986: CYCLE(2); ! 2987: uint32 data = ACC.sub_16(src, reg.D[n] & 0xffff); ! 2988: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 2989: } else if (n < 16) { ! 2990: // SUBQ.W #qqq,An は SUBQ.L と等価 ! 2991: // フラグは変化しない ! 2992: CYCLE(2); ! 2993: reg.R[n] -= src; ! 2994: } else { ! 2995: // SUBQ.W #qqq,<ea> ! 2996: CYCLE2(3, 4); ! 2997: uint32 ea = cea_data_2(); ! 2998: uint32 data = read_2(ea); ! 2999: data = ACC.sub_16(src, data); ! 3000: write_2(ea, data); ! 3001: } ! 3002: } ! 3003: ! 3004: // %0101_qqq110_mmmrrr d.m+-rxw.. 034 SUBQ.L #qqq,<ea> ! 3005: // %0101_qqq110_001yyy .a........ 034 SUBQ.L #qqq,Ay ! 3006: OP_DEF(subq_l) ! 3007: { ! 3008: uint n = ir & 0x3f; ! 3009: ! 3010: uint32 src = RegIRX; ! 3011: src = (src == 0) ? 8 : src; ! 3012: if (n < 8) { ! 3013: // SUBQ.L #qqq,Dn ! 3014: CYCLE(2); ! 3015: reg.D[n] = ACC.sub_32(src, reg.D[n]); ! 3016: } else if (n < 16) { ! 3017: // SUBQ.L #qqq,An ! 3018: // フラグは変化しない ! 3019: CYCLE(2); ! 3020: reg.R[n] -= src; ! 3021: } else { ! 3022: // SUBQ.L #qqq,<ea> ! 3023: CYCLE2(3, 4); ! 3024: uint32 ea = cea_data_4(); ! 3025: uint32 data = read_4(ea); ! 3026: data = ACC.sub_32(src, data); ! 3027: write_4(ea, data); ! 3028: } ! 3029: } ! 3030: ! 3031: inline void ! 3032: MPU680x0Device::ops_bra() ! 3033: { ! 3034: CYCLE2(6, 8); ! 3035: ! 3036: uint32 origin = reg.pc; ! 3037: int32 disp = (int32)(int8)(ir & 0xff); ! 3038: if (disp == -1) { ! 3039: // Bcc.L ! 3040: disp = (int32)fetch_4(); ! 3041: } else if (disp == 0) { ! 3042: // Bcc.W ! 3043: disp = (int32)(int16)fetch_2(); ! 3044: } ! 3045: Jump(origin + disp); ! 3046: } ! 3047: ! 3048: // %0110_0000nn_nnnnnn .......... 034 BRA.B <label> ! 3049: // %0110_000000_000000 .......... 034 BRA.W <label> ! 3050: // %0110_000011_111111 .......... -34 BRA.L <label> ! 3051: OP_DEF(bra) ! 3052: { ! 3053: ops_bra(); ! 3054: } ! 3055: ! 3056: // %0110_0001nn_nnnnnn .......... 034 BSR.B <label> ! 3057: // %0110_000100_000000 .......... 034 BSR.W <label> ! 3058: // %0110_000111_111111 .......... -34 BSR.L <label> ! 3059: OP_DEF(bsr) ! 3060: { ! 3061: CYCLE2(6, 9); ! 3062: uint32 origin = reg.pc; ! 3063: int32 disp = (int32)(int8)(ir & 0xff); ! 3064: if (disp == -1) { ! 3065: // BSR.L <label> ! 3066: disp = (int32)fetch_4(); ! 3067: } else if (disp == 0) { ! 3068: // BSR.W <label> ! 3069: disp = (int32)(int16)fetch_2(); ! 3070: } ! 3071: ! 3072: // ページフォルトに備えて保存する。 ! 3073: save_reg_pd(7); ! 3074: push_4(reg.pc); ! 3075: Jump(origin + disp); ! 3076: } ! 3077: ! 3078: // %0110_ccccnn_nnnnnn .......... 034 Bcc.B <label> ! 3079: // %0110_cccc00_000000 .......... 034 Bcc.W <label> ! 3080: // %0110_cccc11_111111 .......... -34 Bcc.L <label> ! 3081: OP_DEF(bcc) ! 3082: { ! 3083: // ブランチするかどうかでサイクルが変わるので先に条件を調べる ! 3084: uint cond = (ir >> 8) & 0x0f; ! 3085: if (CCR.Cond(cond)) { ! 3086: // Bcc (taken) ! 3087: ops_bra(); ! 3088: } else { ! 3089: int32 disp = (int32)(int8)(ir & 0xff); ! 3090: if (disp == -1) { ! 3091: // Bcc.L (not taken) ! 3092: CYCLE(8); ! 3093: fetch_4(); ! 3094: } else if (disp == 0) { ! 3095: // Bcc.W (not taken) ! 3096: CYCLE(6); ! 3097: fetch_2(); ! 3098: } else { ! 3099: // Bcc.B (not taken) ! 3100: CYCLE(4); ! 3101: } ! 3102: } ! 3103: } ! 3104: ! 3105: // %0111_xxx0nn_nnnnnn .......... 034 MOVEQ.L #<imm>,Dx ! 3106: OP_DEF(moveq) ! 3107: { ! 3108: CYCLE(2); ! 3109: RegDX = (int32)(int8)(ir & 0xff); ! 3110: ACC.move_32(RegDX); ! 3111: } ! 3112: ! 3113: // %1000_xxx000_mmmrrr d.m+-rxwpi 034 OR.B <ea>,Dx ! 3114: OP_DEF(or_b_ea_dn) ! 3115: { ! 3116: uint n = ir & 0x3f; ! 3117: ! 3118: CYCLE(2); ! 3119: uint x = RegIRX; ! 3120: if (n < 8) { ! 3121: // OR.B Dn,Dx ! 3122: uint32 data = (reg.D[x] | reg.D[n]) & 0xff; ! 3123: ACC.move_8(data); ! 3124: reg.D[x] = (reg.D[x] & 0xffffff00) | data; ! 3125: } else { ! 3126: // OR.B <ea>,Dx ! 3127: uint32 src = fea_data_1(); ! 3128: uint32 data = (reg.D[x] | src) & 0xff; ! 3129: ACC.move_8(data); ! 3130: reg.D[x] = (reg.D[x] & 0xffffff00) | data; ! 3131: } ! 3132: } ! 3133: ! 3134: // %1000_xxx001_mmmrrr d.m+-rxwpi 034 OR.W <ea>,Dx ! 3135: OP_DEF(or_w_ea_dn) ! 3136: { ! 3137: uint n = ir & 0x3f; ! 3138: ! 3139: CYCLE(2); ! 3140: uint x = RegIRX; ! 3141: if (n < 8) { ! 3142: // OR.W Dn,Dx ! 3143: uint32 data = (reg.D[x] | reg.D[n]) & 0xffff; ! 3144: ACC.move_16(data); ! 3145: reg.D[x] = (reg.D[x] & 0xffff0000) | data; ! 3146: } else { ! 3147: // OR.W <ea>,Dx ! 3148: uint32 src = fea_data_2(); ! 3149: uint32 data = (reg.D[x] | src) & 0xffff; ! 3150: ACC.move_16(data); ! 3151: reg.D[x] = (reg.D[x] & 0xffff0000) | data; ! 3152: } ! 3153: } ! 3154: ! 3155: // %1000_xxx010_mmmrrr d.m+-rxwpi 034 OR.L <ea>,Dx ! 3156: OP_DEF(or_l_ea_dn) ! 3157: { ! 3158: uint n = ir & 0x3f; ! 3159: ! 3160: CYCLE(2); ! 3161: uint x = RegIRX; ! 3162: if (n < 8) { ! 3163: // OR.L Dn,Dx ! 3164: reg.D[x] |= reg.D[n]; ! 3165: ACC.move_32(reg.D[x]); ! 3166: } else { ! 3167: // OR.L <ea>,Dx ! 3168: uint32 src = fea_data_4(); ! 3169: uint32 data = reg.D[x] | src; ! 3170: ACC.move_32(data); ! 3171: reg.D[x] = data; ! 3172: } ! 3173: } ! 3174: ! 3175: // %1000_xxx011_mmmrrr d.m+-rxwpi 034 DIVU.W <ea>,Dx ! 3176: OP_DEF(divu_w) ! 3177: { ! 3178: CYCLE(44); // XXX これは本当は最大値だけど ! 3179: ! 3180: uint16 src = fea_data_2(); ! 3181: uint32 dst = RegDX; ! 3182: ! 3183: if (src == 0) { ! 3184: // ゼロ除算の場合、 ! 3185: // X は変化しない ! 3186: // C は常にクリア ! 3187: // N,Z,V は未定義 ! 3188: CCR.SetC(false); ! 3189: Exception(M68K::EXCEP_ZERODIV); ! 3190: return; ! 3191: } ! 3192: ! 3193: uint32 quo = dst / src; ! 3194: uint32 rem = dst % src; ! 3195: if (quo > 0xffff) { ! 3196: // オーバーフローの場合、 ! 3197: // X は変化しない ! 3198: // N,Z は未定義 ! 3199: // V はセット ! 3200: // C は常にクリア ! 3201: CCR.SetV(true); ! 3202: CCR.SetC(false); ! 3203: return; ! 3204: } ! 3205: ! 3206: // 正常の場合、 ! 3207: // X は変化しない ! 3208: // V, C はクリア ! 3209: // N, Z は quo の結果。 ! 3210: RegDX = (rem << 16) | quo; ! 3211: ACC.move_16(quo); ! 3212: } ! 3213: ! 3214: // %1000_xxx100_mmmrrr ..m+-rxw.. 034 OR.B Dx,<ea> ! 3215: // %1000_xxx100_000yyy .......... 034 SBCD.B Dy,Dx ! 3216: // %1000_xxx100_001yyy .......... 034 SBCD.B -(Ay),-(Ax) ! 3217: OP_DEF(or_b_dn_ea) ! 3218: { ! 3219: uint n = ir & 0x3f; ! 3220: ! 3221: if (n < 8) { ! 3222: // SBCD.B Dy,Dx ! 3223: CYCLE(4); ! 3224: uint32 src = RegDY & 0xff; ! 3225: uint32 dst = RegDX & 0xff; ! 3226: dst = ACC.sbcd_8(src, dst); ! 3227: RegDX &= 0xffffff00; ! 3228: RegDX |= dst; ! 3229: } else if (n < 16) { ! 3230: // SBCD.B -(Ay),-(Ax) ! 3231: CYCLE2(13, 14); ! 3232: save_reg_pd_if(RegIRY); ! 3233: save_reg_pd_if(RegIRX); ! 3234: uint32 srcea = internal_ea_anpd_1(RegIRY); ! 3235: uint32 dstea = internal_ea_anpd_1(RegIRX); ! 3236: uint32 src = read_1(srcea); ! 3237: uint32 dst = read_1(dstea); ! 3238: dst = ACC.sbcd_8(src, dst); ! 3239: write_1(dstea, dst); ! 3240: } else { ! 3241: // OR.B Dx,<ea> ! 3242: CYCLE2(3, 4); ! 3243: uint32 ea = cea_data_1(); ! 3244: uint8 data = read_1(ea); ! 3245: data |= RegDX; ! 3246: ACC.move_8(data); ! 3247: write_1(ea, data); ! 3248: } ! 3249: } ! 3250: ! 3251: // %1000_xxx101_mmmrrr ..m+-rxw.. 034 OR.W Dx,<ea> ! 3252: // %1000_xxx101_000yyy .......... -34 PACK Dy,Dx,#<imm> ! 3253: // %1000_xxx101_001yyy .......... -34 PACK -(Ay),-(Ax),#<imm> ! 3254: OP_DEF(or_w_dn_ea) ! 3255: { ! 3256: uint n = ir & 0x3f; ! 3257: ! 3258: if (n < 8) { ! 3259: // PACK Dy,Dx,#<imm> ! 3260: CYCLE(6); ! 3261: uint32 imm = fetch_2(); ! 3262: uint32 src = RegDY + imm; ! 3263: RegDX = (RegDX & 0xffffff00) | ((src >> 4) & 0x00f0) | (src & 0x000f); ! 3264: } else if (n < 16) { ! 3265: // PACK -(Ay),-(Ax),#<imm> ! 3266: CYCLE(11); ! 3267: uint32 imm = fetch_2(); ! 3268: uint32 srcea; ! 3269: uint32 src; ! 3270: // -(Ay) を2回行う ! 3271: save_reg_pd(RegIRY); ! 3272: srcea = internal_ea_anpd_1(RegIRY); ! 3273: src = read_1(srcea); ! 3274: srcea = internal_ea_anpd_1(RegIRY); ! 3275: src |= (read_1(srcea) << 8); ! 3276: src += imm; ! 3277: uint32 dst = ((src >> 4) & 0x00f0) | (src & 0x000f); ! 3278: save_reg_pd_if(RegIRX); ! 3279: uint32 dstea = internal_ea_anpd_1(RegIRX); ! 3280: write_1(dstea, dst); ! 3281: } else { ! 3282: // OR.W Dx,<ea> ! 3283: CYCLE2(3, 4); ! 3284: uint32 ea = cea_data_2(); ! 3285: uint16 data = read_2(ea); ! 3286: data |= RegDX; ! 3287: ACC.move_16(data); ! 3288: write_2(ea, data); ! 3289: } ! 3290: } ! 3291: ! 3292: // %1000_xxx110_mmmrrr ..m+-rxw.. 034 OR.L Dx,<ea> ! 3293: // %1000_xxx110_000yyy .......... -34 UNPK Dy,Dx,#<imm> ! 3294: // %1000_xxx110_001yyy .......... -34 UNPK -(Ay),-(Ax),#<imm> ! 3295: OP_DEF(or_l_dn_ea) ! 3296: { ! 3297: uint n = ir & 0x3f; ! 3298: ! 3299: if (n < 8) { ! 3300: // UNPK Dy,Dx,#<imm> ! 3301: CYCLE(8); ! 3302: uint32 imm = fetch_2(); ! 3303: uint16 src = RegDY; ! 3304: src = ((src & 0x00f0) << 4) | (src & 0x000f); ! 3305: src += imm; ! 3306: RegDX = (RegDX & 0xffff0000) | src; ! 3307: } else if (n < 16) { ! 3308: // UNPK -(Ay),-(Ax),#<imm> ! 3309: CYCLE(11); ! 3310: uint32 imm = fetch_2(); ! 3311: save_reg_pd(RegIRY); ! 3312: uint32 srcea = internal_ea_anpd_1(RegIRY); ! 3313: uint16 src = read_1(srcea); ! 3314: src = ((src & 0x00f0) << 4) | (src & 0x000f); ! 3315: src += imm; ! 3316: // -(Ax) を2回行う ! 3317: save_reg_pd_if(RegIRX); ! 3318: uint32 dstea; ! 3319: dstea = internal_ea_anpd_1(RegIRX); ! 3320: write_1(dstea, (src & 0xff)); ! 3321: dstea = internal_ea_anpd_1(RegIRX); ! 3322: write_1(dstea, src >> 8); ! 3323: } else { ! 3324: // OR.L Dx,<ea> ! 3325: CYCLE2(3, 4); ! 3326: uint32 ea = cea_data_4(); ! 3327: uint32 data = read_4(ea); ! 3328: data |= RegDX; ! 3329: ACC.move_32(data); ! 3330: write_4(ea, data); ! 3331: } ! 3332: } ! 3333: ! 3334: // %1000_xxx111_mmmrrr d.m+-rxwpi 034 DIVS.W <ea>,Dx ! 3335: OP_DEF(divs_w) ! 3336: { ! 3337: CYCLE(56); // XXX これは本当は最大値だけど ! 3338: ! 3339: uint16 src = fea_data_2(); ! 3340: uint32 dst = RegDX; ! 3341: ! 3342: if (src == 0) { ! 3343: // ゼロ除算の場合、 ! 3344: // X は変化しない ! 3345: // C は常にクリア ! 3346: // N,Z,V は未定義 ! 3347: CCR.SetC(false); ! 3348: Exception(M68K::EXCEP_ZERODIV); ! 3349: return; ! 3350: } ! 3351: ! 3352: // ホストでオーバーフローが起きるのはこのケースのみ ! 3353: if (dst == 0x80000000 && src == 0xffff) { ! 3354: // オーバーフローの場合、 ! 3355: // X は変化しない ! 3356: // N,Z は未定義 ! 3357: // V はセット ! 3358: // C は常にクリア ! 3359: CCR.SetV(true); ! 3360: CCR.SetC(false); ! 3361: return; ! 3362: } ! 3363: ! 3364: int32 squo = (int32)dst / (int32)(int16)src; ! 3365: int32 srem = (int32)dst % (int32)(int16)src; ! 3366: if ((int16)squo != squo) { ! 3367: // オーバーフローの場合 ! 3368: CCR.SetV(true); ! 3369: CCR.SetC(false); ! 3370: return; ! 3371: } ! 3372: // 正常の場合、 ! 3373: // X は変化しない ! 3374: // V, C はクリア ! 3375: // N, Z は quo の結果。 ! 3376: uint32 quo = (uint32)squo & 0xffff; ! 3377: uint32 rem = (uint32)srem & 0xffff; ! 3378: RegDX = (rem << 16) | quo; ! 3379: ACC.move_16(quo); ! 3380: } ! 3381: ! 3382: // %1001_xxx000_mmmrrr dam+-rxwpi 034 SUB.B <ea>,Dx ! 3383: OP_DEF(sub_b_ea_dn) ! 3384: { ! 3385: CYCLE(2); ! 3386: uint32 src = fea_all_1(); ! 3387: uint32 data = ACC.sub_8(src, RegDX & 0xff); ! 3388: RegDX = (RegDX & 0xffffff00) | data; ! 3389: } ! 3390: ! 3391: // %1001_xxx001_mmmrrr dam+-rxwpi 034 SUB.W <ea>,Dx ! 3392: OP_DEF(sub_w_ea_dn) ! 3393: { ! 3394: CYCLE(2); ! 3395: uint32 src = fea_all_2(); ! 3396: uint32 data = ACC.sub_16(src, RegDX & 0xffff); ! 3397: RegDX = (RegDX & 0xffff0000) | data; ! 3398: } ! 3399: ! 3400: // %1001_xxx010_mmmrrr dam+-rxwpi 034 SUB.L <ea>,Dx ! 3401: OP_DEF(sub_l_ea_dn) ! 3402: { ! 3403: CYCLE(2); ! 3404: uint32 src = fea_all_4(); ! 3405: RegDX = ACC.sub_32(src, RegDX); ! 3406: } ! 3407: ! 3408: // %1001_xxx011_mmmrrr dam+-rxwpi 034 SUBA.W <ea>,Ax ! 3409: OP_DEF(suba_w) ! 3410: { ! 3411: CYCLE(4); ! 3412: uint32 src = (int32)(int16)fea_all_2(); ! 3413: RegAX -= src; ! 3414: } ! 3415: ! 3416: // %1001_xxx100_mmmrrr ..m+-rxw.. 034 SUB.B Dx,<ea> ! 3417: // %1001_xxx100_000yyy .......... 034 SUBX.B Dy,Dx ! 3418: // %1001_xxx100_001yyy .......... 034 SUBX.B -(Ay),-(Ax) ! 3419: OP_DEF(sub_b_dn_ea) ! 3420: { ! 3421: uint n = ir & 0x3f; ! 3422: ! 3423: if (n < 8) { ! 3424: // SUBX.B Dy,Dx ! 3425: CYCLE(2); ! 3426: uint32 src = RegDY & 0xff; ! 3427: uint32 dst = RegDX & 0xff; ! 3428: dst = ACC.subx_8(src, dst); ! 3429: RegDX = (RegDX & 0xffffff00) | dst; ! 3430: } else if (n < 16) { ! 3431: // SUBX.B -(Ay),-(Ax) ! 3432: CYCLE2(9, 10); ! 3433: save_reg_pd_if(RegIRY); ! 3434: save_reg_pd_if(RegIRX); ! 3435: uint32 srcea = internal_ea_anpd_1(RegIRY); ! 3436: uint32 dstea = internal_ea_anpd_1(RegIRX); ! 3437: uint32 src = read_1(srcea); ! 3438: uint32 dst = read_1(dstea); ! 3439: dst = ACC.subx_8(src, dst); ! 3440: write_1(dstea, dst); ! 3441: } else { ! 3442: // SUB.B Dx,<ea> ! 3443: CYCLE2(3, 4); ! 3444: uint32 ea = cea_data_1(); ! 3445: uint32 data = read_1(ea); ! 3446: data = ACC.sub_8(RegDX & 0xff, data); ! 3447: write_1(ea, data); ! 3448: } ! 3449: } ! 3450: ! 3451: // %1001_xxx101_mmmrrr ..m+-rxw.. 034 SUB.W Dx,<ea> ! 3452: // %1001_xxx101_000yyy .......... 034 SUBX.W Dy,Dx ! 3453: // %1001_xxx101_001yyy .......... 034 SUBX.W -(Ay),-(Ax) ! 3454: OP_DEF(sub_w_dn_ea) ! 3455: { ! 3456: uint n = ir & 0x3f; ! 3457: ! 3458: if (n < 8) { ! 3459: // SUBX.W Dy,Dx ! 3460: CYCLE(2); ! 3461: uint32 src = RegDY & 0xffff; ! 3462: uint32 dst = RegDX & 0xffff; ! 3463: dst = ACC.subx_16(src, dst); ! 3464: RegDX = (RegDX & 0xffff0000) | dst; ! 3465: } else if (n < 16) { ! 3466: // SUBX.W -(Ay),-(Ax) ! 3467: CYCLE2(9, 10); ! 3468: save_reg_pd_if(RegIRY); ! 3469: save_reg_pd_if(RegIRX); ! 3470: uint32 srcea = internal_ea_anpd_2(RegIRY); ! 3471: uint32 dstea = internal_ea_anpd_2(RegIRX); ! 3472: uint32 src = read_2(srcea); ! 3473: uint32 dst = read_2(dstea); ! 3474: dst = ACC.subx_16(src, dst); ! 3475: write_2(dstea, dst); ! 3476: } else { ! 3477: // SUB.W Dx,<ea> ! 3478: CYCLE2(3, 4); ! 3479: uint32 ea = cea_data_2(); ! 3480: uint32 data = read_2(ea); ! 3481: data = ACC.sub_16(RegDX & 0xffff, data); ! 3482: write_2(ea, data); ! 3483: } ! 3484: } ! 3485: ! 3486: // %1001_xxx110_mmmrrr ..m+-rxw.. 034 SUB.L Dx,<ea> ! 3487: // %1001_xxx110_000yyy .......... 034 SUBX.L Dy,Dx ! 3488: // %1001_xxx110_001yyy .......... 034 SUBX.L -(Ay),-(Ax) ! 3489: OP_DEF(sub_l_dn_ea) ! 3490: { ! 3491: uint n = ir & 0x3f; ! 3492: ! 3493: if (n < 8) { ! 3494: // SUBX.L Dy,Dx ! 3495: CYCLE(2); ! 3496: uint32 src = RegDY; ! 3497: uint32 dst = RegDX; ! 3498: RegDX = ACC.subx_32(src, dst); ! 3499: } else if (n < 16) { ! 3500: // SUBX.L -(Ay),-(Ax) ! 3501: CYCLE2(9, 10); ! 3502: save_reg_pd_if(RegIRY); ! 3503: save_reg_pd_if(RegIRX); ! 3504: uint32 srcea = internal_ea_anpd_4(RegIRY); ! 3505: uint32 dstea = internal_ea_anpd_4(RegIRX); ! 3506: uint32 src = read_4(srcea); ! 3507: uint32 dst = read_4(dstea); ! 3508: dst = ACC.subx_32(src, dst); ! 3509: write_4(dstea, dst); ! 3510: } else { ! 3511: // SUB.L Dx,<ea> ! 3512: CYCLE2(3, 4); ! 3513: uint32 ea = cea_data_4(); ! 3514: uint32 data = read_4(ea); ! 3515: data = ACC.sub_32(RegDX, data); ! 3516: write_4(ea, data); ! 3517: } ! 3518: } ! 3519: ! 3520: // %1001_xxx111_mmmrrr dam+-rxwpi 034 SUBA.L <ea>,Ax ! 3521: OP_DEF(suba_l) ! 3522: { ! 3523: CYCLE(2); ! 3524: uint32 src = fea_all_4(); ! 3525: RegAX -= src; ! 3526: } ! 3527: ! 3528: // %1010_nnnnnn_nnnnnn .......... 034 A-Line ! 3529: OP_DEF(aline) ! 3530: { ! 3531: if (aline_callback) { ! 3532: if (aline_callback(this, aline_arg)) { ! 3533: return; ! 3534: } ! 3535: } ! 3536: // A系列命令例外 ! 3537: Exception(M68K::EXCEP_ALINE); ! 3538: } ! 3539: ! 3540: // %1011_xxx000_mmmrrr d.m+-rxwpi 034 CMP.B <ea>,Dx ! 3541: OP_DEF(cmp_b) ! 3542: { ! 3543: CYCLE(2); ! 3544: uint32 src = fea_all_1(); ! 3545: uint32 dst = RegDX & 0xff; ! 3546: ACC.cmp_8(src, dst); ! 3547: } ! 3548: ! 3549: // %1011_xxx001_mmmrrr d.m+-rxwpi 034 CMP.W <ea>,Dx ! 3550: OP_DEF(cmp_w) ! 3551: { ! 3552: CYCLE(2); ! 3553: uint32 src = fea_all_2(); ! 3554: uint32 dst = RegDX & 0xffff; ! 3555: ACC.cmp_16(src, dst); ! 3556: } ! 3557: ! 3558: // %1011_xxx010_mmmrrr d.m+-rxwpi 034 CMP.L <ea>,Dx ! 3559: OP_DEF(cmp_l) ! 3560: { ! 3561: CYCLE(2); ! 3562: uint32 src = fea_all_4(); ! 3563: ACC.cmp_32(src, RegDX); ! 3564: } ! 3565: ! 3566: // %1011_xxx011_mmmrrr dam+-rxwpi 034 CMPA.W <ea>,Ax ! 3567: OP_DEF(cmpa_w) ! 3568: { ! 3569: CYCLE(4); ! 3570: uint32 src = (uint32)(int32)(int16)fea_all_2(); ! 3571: ACC.cmp_32(src, RegAX); ! 3572: } ! 3573: ! 3574: // %1011_xxx100_mmmrrr d.m+-rxw.. 034 EOR.B Dx,<ea> ! 3575: // %1011_xxx100_001yyy .......... 034 CMPM.B (Ay)+,(Ax)+ ! 3576: OP_DEF(eor_b) ! 3577: { ! 3578: uint n = ir & 0x3f; ! 3579: ! 3580: if (n < 8) { ! 3581: // EOR.B Dx,Dy ! 3582: CYCLE(2); ! 3583: uint32 data = (reg.D[n] ^ RegDX) & 0xff; ! 3584: reg.D[n] = (reg.D[n] & 0xffffff00) | data; ! 3585: ACC.move_8(data); ! 3586: } else if (n < 16) { ! 3587: // CMPM.B (Ay)+,(Ax)+ ! 3588: CYCLE(8); ! 3589: save_reg_pi_if(RegIRY); ! 3590: save_reg_pi_if(RegIRX); ! 3591: uint32 srcea = internal_ea_anpi_1(RegIRY); ! 3592: uint32 dstea = internal_ea_anpi_1(RegIRX); ! 3593: uint32 src = read_1(srcea); ! 3594: uint32 dst = read_1(dstea); ! 3595: ACC.cmp_8(src, dst); ! 3596: } else { ! 3597: // EOR.B Dx,<ea> ! 3598: CYCLE2(3, 4); ! 3599: uint32 ea = cea_data_1(); ! 3600: uint32 data = read_1(ea); ! 3601: data ^= (RegDX & 0xff); ! 3602: write_1(ea, data); ! 3603: ACC.move_8(data); ! 3604: } ! 3605: } ! 3606: ! 3607: // %1011_xxx101_mmmrrr d.m+-rxw.. 034 EOR.W Dx,<ea> ! 3608: // %1011_xxx101_001yyy .......... 034 CMPM.W (Ay)+,(Ax)+ ! 3609: OP_DEF(eor_w) ! 3610: { ! 3611: uint n = ir & 0x3f; ! 3612: ! 3613: if (n < 8) { ! 3614: // EOR.W Dx,Dy ! 3615: CYCLE(2); ! 3616: uint32 data = (reg.D[n] ^ RegDX) & 0xffff; ! 3617: reg.D[n] = (reg.D[n] & 0xffff0000) | data; ! 3618: ACC.move_16(data); ! 3619: } else if (n < 16) { ! 3620: // CMPM.W (Ay)+,(Ax)+ ! 3621: CYCLE(8); ! 3622: save_reg_pi_if(RegIRY); ! 3623: save_reg_pi_if(RegIRX); ! 3624: uint32 srcea = internal_ea_anpi_2(RegIRY); ! 3625: uint32 dstea = internal_ea_anpi_2(RegIRX); ! 3626: uint32 src = read_2(srcea); ! 3627: uint32 dst = read_2(dstea); ! 3628: ACC.cmp_16(src, dst); ! 3629: } else { ! 3630: // EOR.W Dx,<ea> ! 3631: CYCLE2(3, 4); ! 3632: uint32 ea = cea_data_2(); ! 3633: uint32 data = read_2(ea); ! 3634: data ^= (RegDX & 0xffff); ! 3635: write_2(ea, data); ! 3636: ACC.move_16(data); ! 3637: } ! 3638: } ! 3639: ! 3640: // %1011_xxx110_mmmrrr d.m+-rxw.. 034 EOR.L Dx,<ea> ! 3641: // %1011_xxx110_001yyy .......... 034 CMPM.L (Ay)+,(Ax)+ ! 3642: OP_DEF(eor_l) ! 3643: { ! 3644: uint n = ir & 0x3f; ! 3645: ! 3646: if (n < 8) { ! 3647: // EOR.L Dx,Dy ! 3648: CYCLE(2); ! 3649: reg.D[n] ^= RegDX; ! 3650: ACC.move_32(reg.D[n]); ! 3651: } else if (n < 16) { ! 3652: // CMPM.L (Ay)+,(Ax)+ ! 3653: CYCLE(8); ! 3654: save_reg_pi_if(RegIRY); ! 3655: save_reg_pi_if(RegIRX); ! 3656: uint32 srcea = internal_ea_anpi_4(RegIRY); ! 3657: uint32 dstea = internal_ea_anpi_4(RegIRX); ! 3658: uint32 src = read_4(srcea); ! 3659: uint32 dst = read_4(dstea); ! 3660: ACC.cmp_32(src, dst); ! 3661: } else { ! 3662: // EOR.L Dx,<ea> ! 3663: CYCLE2(3, 4); ! 3664: uint32 ea = cea_data_4(); ! 3665: uint32 data = read_4(ea); ! 3666: data ^= RegDX; ! 3667: write_4(ea, data); ! 3668: ACC.move_32(data); ! 3669: } ! 3670: } ! 3671: ! 3672: // %1011_xxx111_mmmrrr dam+-rxwpi 034 CMPA.L <ea>,Ax ! 3673: OP_DEF(cmpa_l) ! 3674: { ! 3675: CYCLE(4); ! 3676: uint32 src = fea_all_4(); ! 3677: ACC.cmp_32(src, RegAX); ! 3678: } ! 3679: ! 3680: // %1100_xxx000_mmmrrr d.m+-rxwpi 034 AND.B <ea>,Dx ! 3681: OP_DEF(and_b_ea_dn) ! 3682: { ! 3683: CYCLE(2); ! 3684: uint32 src = fea_data_1(); ! 3685: uint32 dst = (RegDX & 0x000000ff) & src; ! 3686: ACC.move_8(dst); ! 3687: RegDX = (RegDX & 0xffffff00) | dst; ! 3688: } ! 3689: ! 3690: // %1100_xxx001_mmmrrr d.m+-rxwpi 034 AND.W <ea>,Dx ! 3691: OP_DEF(and_w_ea_dn) ! 3692: { ! 3693: CYCLE(2); ! 3694: uint32 src = fea_data_2(); ! 3695: uint32 dst = (RegDX & 0x0000ffff) & src; ! 3696: ACC.move_16(dst); ! 3697: RegDX = (RegDX & 0xffff0000) | dst; ! 3698: } ! 3699: ! 3700: // %1100_xxx010_mmmrrr d.m+-rxwpi 034 AND.L <ea>,Dx ! 3701: OP_DEF(and_l_ea_dn) ! 3702: { ! 3703: CYCLE(2); ! 3704: uint32 src = fea_data_4(); ! 3705: RegDX = RegDX & src; ! 3706: ACC.move_32(RegDX); ! 3707: } ! 3708: ! 3709: // %1100_xxx011_mmmrrr d.m+-rxwpi 034 MULU.W <ea>,Dx ! 3710: OP_DEF(mulu_w) ! 3711: { ! 3712: CYCLE(28); // 実際にはこれは最大値 ! 3713: uint32 src = fea_data_2(); ! 3714: uint32 dst = RegDX & 0xffff; ! 3715: RegDX = ACC.mulu_16(src, dst); ! 3716: } ! 3717: ! 3718: // %1100_xxx100_mmmrrr ..m+-rxw.. 034 AND.B Dx,<ea> ! 3719: // %1100_xxx100_000yyy .......... 034 ABCD.B Dy,Dx ! 3720: // %1100_xxx100_001yyy .......... 034 ABCD.B -(Ay),-(Ax) ! 3721: OP_DEF(and_b_dn_ea) ! 3722: { ! 3723: uint n = ir & 0x3f; ! 3724: ! 3725: if (n < 8) { ! 3726: // ABCD.B Dy,Dx ! 3727: CYCLE(4); ! 3728: uint32 src = RegDY & 0xff; ! 3729: uint32 dst = RegDX & 0xff; ! 3730: dst = ACC.abcd_8(src, dst); ! 3731: RegDX &= 0xffffff00; ! 3732: RegDX |= dst; ! 3733: return; ! 3734: } else if (n < 16) { ! 3735: // ABCD.B -(Ay),-(Ax) ! 3736: CYCLE2(13, 14); ! 3737: save_reg_pd_if(RegIRY); ! 3738: save_reg_pd_if(RegIRX); ! 3739: uint32 srcea = internal_ea_anpd_1(RegIRY); ! 3740: uint32 dstea = internal_ea_anpd_1(RegIRX); ! 3741: uint32 src = read_1(srcea); ! 3742: uint32 dst = read_1(dstea); ! 3743: dst = ACC.abcd_8(src, dst); ! 3744: write_1(dstea, dst); ! 3745: return; ! 3746: } else { ! 3747: // AND.B Dx,<ea> ! 3748: CYCLE2(3, 4); ! 3749: uint32 ea = cea_data_1(); ! 3750: uint32 dst = read_1(ea); ! 3751: dst &= RegDX & 0xff; ! 3752: ACC.move_8(dst); ! 3753: write_1(ea, dst); ! 3754: } ! 3755: } ! 3756: ! 3757: // %1100_xxx101_mmmrrr ..m+-rxw.. 034 AND.W Dx,<ea> ! 3758: // %1100_xxx101_000yyy .......... 034 EXG.L Dx,Dy ! 3759: // %1100_xxx101_001yyy .......... 034 EXG.L Ax,Ay ! 3760: OP_DEF(and_w_dn_ea) ! 3761: { ! 3762: uint n = ir & 0x3f; ! 3763: ! 3764: if (n < 8) { ! 3765: // EXG.L Dx,Dy ! 3766: CYCLE(4); ! 3767: uint x = RegIRX; ! 3768: uint y = n; ! 3769: uint32 tmp = reg.D[x]; ! 3770: reg.D[x] = reg.D[y]; ! 3771: reg.D[y] = tmp; ! 3772: return; ! 3773: } else if (n < 16) { ! 3774: // EXG.L Ax,Ay ! 3775: // ここでは x は 0..7 で A(x)、y は 8..15 で R(y) ! 3776: CYCLE(4); ! 3777: uint x = RegIRX; ! 3778: uint y = n; ! 3779: uint32 tmp = reg.A[x]; ! 3780: reg.A[x] = reg.R[y]; ! 3781: reg.R[y] = tmp; ! 3782: return; ! 3783: } else { ! 3784: // AND.W Dx,<ea> ! 3785: CYCLE2(3, 4); ! 3786: uint32 ea = cea_data_2(); ! 3787: uint32 dst = read_2(ea); ! 3788: dst &= RegDX & 0xffff; ! 3789: ACC.move_16(dst); ! 3790: write_2(ea, dst); ! 3791: } ! 3792: } ! 3793: ! 3794: // %1100_xxx110_mmmrrr ..m+-rxw.. 034 AND.L Dx,<ea> ! 3795: // %1100_xxx110_001yyy .......... 034 EXG.L Dx,Ay ! 3796: OP_DEF(and_l_dn_ea) ! 3797: { ! 3798: uint n = ir & 0x3f; ! 3799: ! 3800: if (n < 8) { ! 3801: op_illegal(); ! 3802: return; ! 3803: } else if (n < 16) { ! 3804: // EXG.L Dx,Ay ! 3805: // ここでは x は 0..7 で D(x)、y は 8..15 で R(y) ! 3806: CYCLE(4); ! 3807: uint x = RegIRX; ! 3808: uint y = n; ! 3809: uint32 tmp = reg.D[x]; ! 3810: reg.D[x] = reg.R[y]; ! 3811: reg.R[y] = tmp; ! 3812: return; ! 3813: } else { ! 3814: // AND.L Dx,<ea> ! 3815: CYCLE2(3, 4); ! 3816: uint32 ea = cea_data_4(); ! 3817: uint32 dst = read_4(ea); ! 3818: dst &= RegDX; ! 3819: ACC.move_32(dst); ! 3820: write_4(ea, dst); ! 3821: } ! 3822: } ! 3823: ! 3824: // %1100_xxx111_mmmrrr d.m+-rxwpi 034 MULS.W <ea>,Dx ! 3825: OP_DEF(muls_w) ! 3826: { ! 3827: CYCLE(28); // 実際にはこれは最大値 ! 3828: uint32 src = fea_data_2(); ! 3829: uint32 dst = RegDX & 0xffff; ! 3830: RegDX = ACC.muls_16(src, dst); ! 3831: } ! 3832: ! 3833: // %1101_xxx000_mmmrrr dam+-rxwpi 034 ADD.B <ea>,Dx ! 3834: OP_DEF(add_b_ea_dn) ! 3835: { ! 3836: CYCLE(2); ! 3837: uint32 src = fea_all_1(); ! 3838: uint32 data = ACC.add_8(src, RegDX & 0xff); ! 3839: RegDX = (RegDX & 0xffffff00) | data; ! 3840: } ! 3841: ! 3842: // %1101_xxx001_mmmrrr dam+-rxwpi 034 ADD.W <ea>,Dx ! 3843: OP_DEF(add_w_ea_dn) ! 3844: { ! 3845: CYCLE(2); ! 3846: uint32 src = fea_all_2(); ! 3847: uint32 data = ACC.add_16(src, RegDX & 0xffff); ! 3848: RegDX = (RegDX & 0xffff0000) | data; ! 3849: } ! 3850: ! 3851: // %1101_xxx010_mmmrrr dam+-rxwpi 034 ADD.L <ea>,Dx ! 3852: OP_DEF(add_l_ea_dn) ! 3853: { ! 3854: CYCLE(2); ! 3855: uint32 src = fea_all_4(); ! 3856: RegDX = ACC.add_32(src, RegDX); ! 3857: } ! 3858: ! 3859: // %1101_xxx011_mmmrrr dam+-rxwpi 034 ADDA.W <ea>,Ax ! 3860: OP_DEF(adda_w) ! 3861: { ! 3862: CYCLE(4); ! 3863: uint32 src = (int32)(int16)fea_all_2(); ! 3864: RegAX += src; ! 3865: } ! 3866: ! 3867: // %1101_xxx100_mmmrrr ..m+-rxw.. 034 ADD.B Dx,<ea> ! 3868: // %1101_xxx100_000yyy .......... 034 ADDX.B Dy,Dx ! 3869: // %1101_xxx100_001yyy .......... 034 ADDX.B -(Ay),-(Ax) ! 3870: OP_DEF(add_b_dn_ea) ! 3871: { ! 3872: uint n = ir & 0x3f; ! 3873: ! 3874: if (n < 8) { ! 3875: // ADDX.B Dy,Dx ! 3876: CYCLE(2); ! 3877: uint32 src = RegDY & 0xff; ! 3878: uint32 dst = RegDX & 0xff; ! 3879: dst = ACC.addx_8(src, dst); ! 3880: RegDX = (RegDX & 0xffffff00) | dst; ! 3881: } else if (n < 16) { ! 3882: // ADDX.B -(Ay),-(Ax) ! 3883: CYCLE2(9, 10); ! 3884: save_reg_pd_if(RegIRY); ! 3885: save_reg_pd_if(RegIRX); ! 3886: uint32 srcea = internal_ea_anpd_1(RegIRY); ! 3887: uint32 dstea = internal_ea_anpd_1(RegIRX); ! 3888: uint32 src = read_1(srcea); ! 3889: uint32 dst = read_1(dstea); ! 3890: dst = ACC.addx_8(src, dst); ! 3891: write_1(dstea, dst); ! 3892: } else { ! 3893: // ADD.B Dx,<ea> ! 3894: CYCLE2(3, 4); ! 3895: uint32 ea = cea_data_1(); ! 3896: uint32 data = read_1(ea); ! 3897: data = ACC.add_8(RegDX & 0xff, data); ! 3898: write_1(ea, data); ! 3899: } ! 3900: } ! 3901: ! 3902: // %1101_xxx101_mmmrrr ..m+-rxw.. 034 ADD.W Dx,<ea> ! 3903: // %1101_xxx101_000yyy .......... 034 ADDX.W Dy,Dx ! 3904: // %1101_xxx101_001yyy .......... 034 ADDX.W -(Ay),-(Ax) ! 3905: OP_DEF(add_w_dn_ea) ! 3906: { ! 3907: uint n = ir & 0x3f; ! 3908: ! 3909: if (n < 8) { ! 3910: // ADDX.W Dy,Dx ! 3911: CYCLE(2); ! 3912: uint32 src = RegDY & 0xffff; ! 3913: uint32 dst = RegDX & 0xffff; ! 3914: dst = ACC.addx_16(src, dst); ! 3915: RegDX = (RegDX & 0xffff0000) | dst; ! 3916: } else if (n < 16) { ! 3917: // ADDX.W -(Ay),-(Ax) ! 3918: CYCLE2(9, 10); ! 3919: save_reg_pd_if(RegIRY); ! 3920: save_reg_pd_if(RegIRX); ! 3921: uint32 srcea = internal_ea_anpd_2(RegIRY); ! 3922: uint32 dstea = internal_ea_anpd_2(RegIRX); ! 3923: uint32 src = read_2(srcea); ! 3924: uint32 dst = read_2(dstea); ! 3925: dst = ACC.addx_16(src, dst); ! 3926: write_2(dstea, dst); ! 3927: } else { ! 3928: // ADD.W Dx,<ea> ! 3929: CYCLE2(3, 4); ! 3930: uint32 ea = cea_data_2(); ! 3931: uint32 data = read_2(ea); ! 3932: data = ACC.add_16(RegDX & 0xffff, data); ! 3933: write_2(ea, data); ! 3934: } ! 3935: } ! 3936: ! 3937: // %1101_xxx110_mmmrrr ..m+-rxw.. 034 ADD.L Dx,<ea> ! 3938: // %1101_xxx110_000yyy .......... 034 ADDX.L Dy,Dx ! 3939: // %1101_xxx110_001yyy .......... 034 ADDX.L -(Ay),-(Ax) ! 3940: OP_DEF(add_l_dn_ea) ! 3941: { ! 3942: uint n = ir & 0x3f; ! 3943: ! 3944: if (n < 8) { ! 3945: // ADDX.L Dy,Dx ! 3946: CYCLE(2); ! 3947: uint32 src = RegDY; ! 3948: uint32 dst = RegDX; ! 3949: RegDX = ACC.addx_32(src, dst); ! 3950: } else if (n < 16) { ! 3951: // ADDX.L -(Ay),-(Ax) ! 3952: CYCLE2(9, 10); ! 3953: save_reg_pd_if(RegIRY); ! 3954: save_reg_pd_if(RegIRX); ! 3955: uint32 srcea = internal_ea_anpd_4(RegIRY); ! 3956: uint32 dstea = internal_ea_anpd_4(RegIRX); ! 3957: uint32 src = read_4(srcea); ! 3958: uint32 dst = read_4(dstea); ! 3959: dst = ACC.addx_32(src, dst); ! 3960: write_4(dstea, dst); ! 3961: } else { ! 3962: // ADD.L Dx,<ea> ! 3963: CYCLE2(3, 4); ! 3964: uint32 ea = cea_data_4(); ! 3965: uint32 data = read_4(ea); ! 3966: data = ACC.add_32(RegDX, data); ! 3967: write_4(ea, data); ! 3968: } ! 3969: } ! 3970: ! 3971: // %1101_xxx111_mmmrrr dam+-rxwpi 034 ADDA.L <ea>,Ax ! 3972: OP_DEF(adda_l) ! 3973: { ! 3974: CYCLE(2); ! 3975: uint32 src = fea_all_4(); ! 3976: RegAX += src; ! 3977: } ! 3978: ! 3979: // %1110_qqq000_000yyy .......... 034 ASR.B #qqq,Dy ! 3980: // %1110_qqq000_001yyy .......... 034 LSR.B #qqq,Dy ! 3981: // %1110_qqq000_010yyy .......... 034 ROXR.B #qqq,Dy ! 3982: // %1110_qqq000_011yyy .......... 034 ROR.B #qqq,Dy ! 3983: // %1110_xxx000_100yyy .......... 034 ASR.B Dx,Dy ! 3984: // %1110_xxx000_101yyy .......... 034 LSR.B Dx,Dy ! 3985: // %1110_xxx000_110yyy .......... 034 ROXR.B Dx,Dy ! 3986: // %1110_xxx000_111yyy .......... 034 ROR.B Dx,Dy ! 3987: OP_DEF(asr_b_imm) ! 3988: { ! 3989: int count; ! 3990: uint32 data; ! 3991: switch (eamode(ir)) { ! 3992: case 0: // ASR.B #qqq,Dy ! 3993: CYCLE(4); ! 3994: count = RegIRX; ! 3995: count = (count == 0) ? 8 : count; ! 3996: __assume(1 <= count && count <= 8); ! 3997: data = ACC.asr_8(RegDY & 0xff, count); ! 3998: RegDY = (RegDY & 0xffffff00) | data; ! 3999: return; ! 4000: case 1: // LSR.B #qqq,Dy ! 4001: CYCLE(4); ! 4002: count = RegIRX; ! 4003: count = (count == 0) ? 8 : count; ! 4004: __assume(1 <= count && count <= 8); ! 4005: data = ACC.lsr_8(RegDY & 0xff, count); ! 4006: RegDY = (RegDY & 0xffffff00) | data; ! 4007: return; ! 4008: case 2: // ROXR.B #qqq,Dy ! 4009: CYCLE(12); ! 4010: count = RegIRX; ! 4011: count = (count == 0) ? 8 : count; ! 4012: __assume(1 <= count && count <= 8); ! 4013: data = ACC.roxr_8(RegDY & 0xff, count); ! 4014: RegDY = (RegDY & 0xffffff00) | data; ! 4015: return; ! 4016: case 3: // ROR.B #qqq,Dy ! 4017: CYCLE(6); ! 4018: count = RegIRX; ! 4019: count = (count == 0) ? 8 : count; ! 4020: __assume(1 <= count && count <= 8); ! 4021: data = ACC.ror_8(RegDY & 0xff, count); ! 4022: RegDY = (RegDY & 0xffffff00) | data; ! 4023: return; ! 4024: case 4: // ASR.B Dx,Dy ! 4025: count = RegDX & 63; ! 4026: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4027: CYCLE(count <= 8 ? 6 : 10); ! 4028: __assume(0 <= count && count < 64); ! 4029: data = ACC.asr_8(RegDY & 0xff, count); ! 4030: RegDY = (RegDY & 0xffffff00) | data; ! 4031: return; ! 4032: case 5: // LSR.B Dx,Dy ! 4033: count = RegDX & 63; ! 4034: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4035: CYCLE(count <= 8 ? 6 : 8); ! 4036: __assume(0 <= count && count < 64); ! 4037: data = ACC.lsr_8(RegDY & 0xff, count); ! 4038: RegDY = (RegDY & 0xffffff00) | data; ! 4039: return; ! 4040: case 6: // ROXR.B Dx,Dy ! 4041: CYCLE(12); ! 4042: count = RegDX & 63; ! 4043: __assume(0 <= count && count < 64); ! 4044: data = ACC.roxr_8(RegDY & 0xff, count); ! 4045: RegDY = (RegDY & 0xffffff00) | data; ! 4046: return; ! 4047: case 7: // ROR.B Dx,Dy ! 4048: CYCLE(8); ! 4049: count = RegDX & 63; ! 4050: __assume(0 <= count && count < 64); ! 4051: data = ACC.ror_8(RegDY & 0xff, count); ! 4052: RegDY = (RegDY & 0xffffff00) | data; ! 4053: return; ! 4054: } ! 4055: } ! 4056: ! 4057: // %1110_qqq001_000yyy .......... 034 ASR.W #qqq,Dy ! 4058: // %1110_qqq001_001yyy .......... 034 LSR.W #qqq,Dy ! 4059: // %1110_qqq001_010yyy .......... 034 ROXR.W #qqq,Dy ! 4060: // %1110_qqq001_011yyy .......... 034 ROR.W #qqq,Dy ! 4061: // %1110_xxx001_100yyy .......... 034 ASR.W Dx,Dy ! 4062: // %1110_xxx001_101yyy .......... 034 LSR.W Dx,Dy ! 4063: // %1110_xxx001_110yyy .......... 034 ROXR.W Dx,Dy ! 4064: // %1110_xxx001_111yyy .......... 034 ROR.W Dx,Dy ! 4065: OP_DEF(asr_w_imm) ! 4066: { ! 4067: int count; ! 4068: uint32 data; ! 4069: switch (eamode(ir)) { ! 4070: case 0: // ASR.W #qqq,Dy ! 4071: CYCLE(4); ! 4072: count = RegIRX; ! 4073: count = (count == 0) ? 8 : count; ! 4074: __assume(1 <= count && count <= 8); ! 4075: data = ACC.asr_16(RegDY & 0xffff, count); ! 4076: RegDY = (RegDY & 0xffff0000) | data; ! 4077: return; ! 4078: case 1: // LSR.W #qqq,Dy ! 4079: CYCLE(4); ! 4080: count = RegIRX; ! 4081: count = (count == 0) ? 8 : count; ! 4082: __assume(1 <= count && count <= 8); ! 4083: data = ACC.lsr_16(RegDY & 0xffff, count); ! 4084: RegDY = (RegDY & 0xffff0000) | data; ! 4085: return; ! 4086: case 2: // ROXR.W #qqq,Dy ! 4087: CYCLE(12); ! 4088: count = RegIRX; ! 4089: count = (count == 0) ? 8 : count; ! 4090: __assume(1 <= count && count <= 8); ! 4091: data = ACC.roxr_16(RegDY & 0xffff, count); ! 4092: RegDY = (RegDY & 0xffff0000) | data; ! 4093: return; ! 4094: case 3: // ROR.W #qqq,Dy ! 4095: CYCLE(6); ! 4096: count = RegIRX; ! 4097: count = (count == 0) ? 8 : count; ! 4098: __assume(1 <= count && count <= 8); ! 4099: data = ACC.ror_16(RegDY & 0xffff, count); ! 4100: RegDY = (RegDY & 0xffff0000) | data; ! 4101: return; ! 4102: case 4: // ASR.W Dx,Dy ! 4103: count = RegDX & 63; ! 4104: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4105: CYCLE(count <= 16 ? 6 : 10); ! 4106: __assume(0 <= count && count < 64); ! 4107: data = ACC.asr_16(RegDY & 0xffff, count); ! 4108: RegDY = (RegDY & 0xffff0000) | data; ! 4109: return; ! 4110: case 5: // LSR.W Dx,Dy ! 4111: count = RegDX & 63; ! 4112: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4113: CYCLE(count <= 16 ? 6 : 8); ! 4114: __assume(0 <= count && count < 64); ! 4115: data = ACC.lsr_16(RegDY & 0xffff, count); ! 4116: RegDY = (RegDY & 0xffff0000) | data; ! 4117: return; ! 4118: case 6: // ROXR.W Dx,Dy ! 4119: CYCLE(12); ! 4120: count = RegDX & 63; ! 4121: __assume(0 <= count && count < 64); ! 4122: data = ACC.roxr_16(RegDY & 0xffff, count); ! 4123: RegDY = (RegDY & 0xffff0000) | data; ! 4124: return; ! 4125: case 7: // ROR.W Dx,Dy ! 4126: CYCLE(8); ! 4127: count = RegDX & 63; ! 4128: __assume(0 <= count && count < 64); ! 4129: data = ACC.ror_16(RegDY & 0xffff, count); ! 4130: RegDY = (RegDY & 0xffff0000) | data; ! 4131: return; ! 4132: } ! 4133: } ! 4134: ! 4135: // %1110_qqq010_000yyy .......... 034 ASR.L #qqq,Dy ! 4136: // %1110_qqq010_001yyy .......... 034 LSR.L #qqq,Dy ! 4137: // %1110_qqq010_010yyy .......... 034 ROXR.L #qqq,Dy ! 4138: // %1110_qqq010_011yyy .......... 034 ROR.L #qqq,Dy ! 4139: // %1110_xxx010_100yyy .......... 034 ASR.L Dx,Dy ! 4140: // %1110_xxx010_101yyy .......... 034 LSR.L Dx,Dy ! 4141: // %1110_xxx010_110yyy .......... 034 ROXR.L Dx,Dy ! 4142: // %1110_xxx010_111yyy .......... 034 ROR.L Dx,Dy ! 4143: OP_DEF(asr_l_imm) ! 4144: { ! 4145: int count; ! 4146: switch (eamode(ir)) { ! 4147: case 0: // ASR.L #qqq,Dy ! 4148: CYCLE(4); ! 4149: count = RegIRX; ! 4150: count = (count == 0) ? 8 : count; ! 4151: __assume(1 <= count && count <= 8); ! 4152: RegDY = ACC.asr_32(RegDY, count); ! 4153: return; ! 4154: case 1: // LSR.L #qqq,Dy ! 4155: CYCLE(4); ! 4156: count = RegIRX; ! 4157: count = (count == 0) ? 8 : count; ! 4158: __assume(1 <= count && count <= 8); ! 4159: RegDY = ACC.lsr_32(RegDY, count); ! 4160: return; ! 4161: case 2: // ROXR.L #qqq,Dy ! 4162: CYCLE(12); ! 4163: count = RegIRX; ! 4164: count = (count == 0) ? 8 : count; ! 4165: __assume(1 <= count && count <= 8); ! 4166: RegDY = ACC.roxr_32(RegDY, count); ! 4167: return; ! 4168: case 3: // ROR.L #qqq,Dy ! 4169: CYCLE(6); ! 4170: count = RegIRX; ! 4171: count = (count == 0) ? 8 : count; ! 4172: __assume(1 <= count && count <= 8); ! 4173: RegDY = ACC.ror_32(RegDY, count); ! 4174: return; ! 4175: case 4: // ASR.L Dx,Dy ! 4176: count = RegDX & 63; ! 4177: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4178: CYCLE(count <= 32 ? 6 : 10); ! 4179: __assume(0 <= count && count < 64); ! 4180: RegDY = ACC.asr_32(RegDY, count); ! 4181: return; ! 4182: case 5: // LSR.L Dx,Dy ! 4183: count = RegDX & 63; ! 4184: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4185: CYCLE(count <= 32 ? 6 : 8); ! 4186: __assume(0 <= count && count < 64); ! 4187: RegDY = ACC.lsr_32(RegDY, count); ! 4188: return; ! 4189: case 6: // ROXR.L Dx,Dy ! 4190: CYCLE(12); ! 4191: count = RegDX & 63; ! 4192: __assume(0 <= count && count < 64); ! 4193: RegDY = ACC.roxr_32(RegDY, count); ! 4194: return; ! 4195: case 7: // ROR.L Dx,Dy ! 4196: CYCLE(8); ! 4197: count = RegDX & 63; ! 4198: __assume(0 <= count && count < 64); ! 4199: RegDY = ACC.ror_32(RegDY, count); ! 4200: return; ! 4201: } ! 4202: } ! 4203: ! 4204: // %1110_000011_mmmrrr ..m+-rxw.. 034 ASR.W <ea> ! 4205: OP_DEF(asr_w) ! 4206: { ! 4207: CYCLE(4); ! 4208: uint32 ea = cea_data_2(); ! 4209: uint32 data = read_2(ea); ! 4210: data = ACC.asr_16(data, 1); ! 4211: write_2(ea, data); ! 4212: } ! 4213: ! 4214: // %1110_qqq100_000yyy .......... 034 ASL.B #qqq,Dy ! 4215: // %1110_qqq100_001yyy .......... 034 LSL.B #qqq,Dy ! 4216: // %1110_qqq100_010yyy .......... 034 ROXL.B #qqq,Dy ! 4217: // %1110_qqq100_011yyy .......... 034 ROL.B #qqq,Dy ! 4218: // %1110_xxx100_100yyy .......... 034 ASL.B Dx,Dy ! 4219: // %1110_xxx100_101yyy .......... 034 LSL.B Dx,Dy ! 4220: // %1110_xxx100_110yyy .......... 034 ROXL.B Dx,Dy ! 4221: // %1110_xxx100_111yyy .......... 034 ROL.B Dx,Dy ! 4222: OP_DEF(asl_b_imm) ! 4223: { ! 4224: int count; ! 4225: uint32 data; ! 4226: switch (eamode(ir)) { ! 4227: case 0: // ASL.B #qqq,Dy ! 4228: CYCLE(6); ! 4229: count = RegIRX; ! 4230: count = (count == 0) ? 8 : count; ! 4231: __assume(1 <= count && count <= 8); ! 4232: data = ACC.asl_8(RegDY & 0xff, count); ! 4233: RegDY = (RegDY & 0xffffff00) | data; ! 4234: return; ! 4235: case 1: // LSL.B #qqq,Dy ! 4236: CYCLE(4); ! 4237: count = RegIRX; ! 4238: count = (count == 0) ? 8 : count; ! 4239: __assume(1 <= count && count <= 8); ! 4240: data = ACC.lsl_8(RegDY & 0xff, count); ! 4241: RegDY = (RegDY & 0xffffff00) | data; ! 4242: return; ! 4243: case 2: // ROXL.B #qqq,Dy ! 4244: CYCLE(12); ! 4245: count = RegIRX; ! 4246: count = (count == 0) ? 8 : count; ! 4247: __assume(1 <= count && count <= 8); ! 4248: data = ACC.roxl_8(RegDY & 0xff, count); ! 4249: RegDY = (RegDY & 0xffffff00) | data; ! 4250: return; ! 4251: case 3: // ROL.B #qqq,Dy ! 4252: CYCLE(6); ! 4253: count = RegIRX; ! 4254: count = (count == 0) ? 8 : count; ! 4255: __assume(1 <= count && count <= 8); ! 4256: data = ACC.rol_8(RegDY & 0xff, count); ! 4257: RegDY = (RegDY & 0xffffff00) | data; ! 4258: return; ! 4259: case 4: // ASL.B Dx,Dy ! 4260: CYCLE(8); ! 4261: count = RegDX & 63; ! 4262: __assume(0 <= count && count < 64); ! 4263: data = ACC.asl_8(RegDY & 0xff, count); ! 4264: RegDY = (RegDY & 0xffffff00) | data; ! 4265: return; ! 4266: case 5: // LSL.B Dx,Dy ! 4267: count = RegDX & 63; ! 4268: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4269: CYCLE(count <= 8 ? 6 : 8); ! 4270: __assume(0 <= count && count < 64); ! 4271: data = ACC.lsl_8(RegDY & 0xff, count); ! 4272: RegDY = (RegDY & 0xffffff00) | data; ! 4273: return; ! 4274: case 6: // ROXL.B Dx,Dy ! 4275: CYCLE(12); ! 4276: count = RegDX & 63; ! 4277: __assume(0 <= count && count < 64); ! 4278: data = ACC.roxl_8(RegDY & 0xff, count); ! 4279: RegDY = (RegDY & 0xffffff00) | data; ! 4280: return; ! 4281: case 7: // ROL.B Dx,Dy ! 4282: CYCLE(8); ! 4283: count = RegDX & 63; ! 4284: __assume(0 <= count && count < 64); ! 4285: data = ACC.rol_8(RegDY & 0xff, count); ! 4286: RegDY = (RegDY & 0xffffff00) | data; ! 4287: return; ! 4288: } ! 4289: } ! 4290: ! 4291: // %1110_qqq101_000yyy .......... 034 ASL.W #qqq,Dy ! 4292: // %1110_qqq101_001yyy .......... 034 LSL.W #qqq,Dy ! 4293: // %1110_qqq101_010yyy .......... 034 ROXL.W #qqq,Dy ! 4294: // %1110_qqq101_011yyy .......... 034 ROL.W #qqq,Dy ! 4295: // %1110_xxx101_100yyy .......... 034 ASL.W Dx,Dy ! 4296: // %1110_xxx101_101yyy .......... 034 LSL.W Dx,Dy ! 4297: // %1110_xxx101_110yyy .......... 034 ROXL.W Dx,Dy ! 4298: // %1110_xxx101_111yyy .......... 034 ROL.W Dx,Dy ! 4299: OP_DEF(asl_w_imm) ! 4300: { ! 4301: int count; ! 4302: uint32 data; ! 4303: switch (eamode(ir)) { ! 4304: case 0: // ASL.W #qqq,Dy ! 4305: CYCLE(6); ! 4306: count = RegIRX; ! 4307: count = (count == 0) ? 8 : count; ! 4308: __assume(1 <= count && count <= 8); ! 4309: data = ACC.asl_16(RegDY & 0xffff, count); ! 4310: RegDY = (RegDY & 0xffff0000) | data; ! 4311: return; ! 4312: case 1: // LSL.W #qqq,Dy ! 4313: CYCLE(4); ! 4314: count = RegIRX; ! 4315: count = (count == 0) ? 8 : count; ! 4316: __assume(1 <= count && count <= 8); ! 4317: data = ACC.lsl_16(RegDY & 0xffff, count); ! 4318: RegDY = (RegDY & 0xffff0000) | data; ! 4319: return; ! 4320: case 2: // ROXL.W #qqq,Dy ! 4321: CYCLE(12); ! 4322: count = RegIRX; ! 4323: count = (count == 0) ? 8 : count; ! 4324: __assume(1 <= count && count <= 8); ! 4325: data = ACC.roxl_16(RegDY & 0xffff, count); ! 4326: RegDY = (RegDY & 0xffff0000) | data; ! 4327: return; ! 4328: case 3: // ROL.W #qqq,Dy ! 4329: CYCLE(6); ! 4330: count = RegIRX; ! 4331: count = (count == 0) ? 8 : count; ! 4332: __assume(1 <= count && count <= 8); ! 4333: data = ACC.rol_16(RegDY & 0xffff, count); ! 4334: RegDY = (RegDY & 0xffff0000) | data; ! 4335: return; ! 4336: case 4: // ASL.W Dx,Dy ! 4337: CYCLE(8); ! 4338: count = RegDX & 63; ! 4339: __assume(0 <= count && count < 64); ! 4340: data = ACC.asl_16(RegDY & 0xffff, count); ! 4341: RegDY = (RegDY & 0xffff0000) | data; ! 4342: return; ! 4343: case 5: // LSL.W Dx,Dy ! 4344: count = RegDX & 63; ! 4345: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4346: CYCLE(count <= 16 ? 6 : 8); ! 4347: __assume(0 <= count && count < 64); ! 4348: data = ACC.lsl_16(RegDY & 0xffff, count); ! 4349: RegDY = (RegDY & 0xffff0000) | data; ! 4350: return; ! 4351: case 6: // ROXL.W Dx,Dy ! 4352: CYCLE(12); ! 4353: count = RegDX & 63; ! 4354: __assume(0 <= count && count < 64); ! 4355: data = ACC.roxl_16(RegDY & 0xffff, count); ! 4356: RegDY = (RegDY & 0xffff0000) | data; ! 4357: return; ! 4358: case 7: // ROL.W Dx,Dy ! 4359: CYCLE(8); ! 4360: count = RegDX & 63; ! 4361: __assume(0 <= count && count < 64); ! 4362: data = ACC.rol_16(RegDY & 0xffff, count); ! 4363: RegDY = (RegDY & 0xffff0000) | data; ! 4364: return; ! 4365: } ! 4366: } ! 4367: ! 4368: // %1110_qqq110_000yyy .......... 034 ASL.L #qqq,Dy ! 4369: // %1110_qqq110_001yyy .......... 034 LSL.L #qqq,Dy ! 4370: // %1110_qqq110_010yyy .......... 034 ROXL.L #qqq,Dy ! 4371: // %1110_qqq110_011yyy .......... 034 ROL.L #qqq,Dy ! 4372: // %1110_xxx110_100yyy .......... 034 ASL.L Dx,Dy ! 4373: // %1110_xxx110_101yyy .......... 034 LSL.L Dx,Dy ! 4374: // %1110_xxx110_110yyy .......... 034 ROXL.L Dx,Dy ! 4375: // %1110_xxx110_111yyy .......... 034 ROL.L Dx,Dy ! 4376: OP_DEF(asl_l_imm) ! 4377: { ! 4378: int count; ! 4379: switch (eamode(ir)) { ! 4380: case 0: // ASL.L #qqq,Dy ! 4381: CYCLE(6); ! 4382: count = RegIRX; ! 4383: count = (count == 0) ? 8 : count; ! 4384: __assume(1 <= count && count <= 8); ! 4385: RegDY = ACC.asl_32(RegDY, count); ! 4386: return; ! 4387: case 1: // LSL.L #qqq,Dy ! 4388: CYCLE(4); ! 4389: count = RegIRX; ! 4390: count = (count == 0) ? 8 : count; ! 4391: __assume(1 <= count && count <= 8); ! 4392: RegDY = ACC.lsl_32(RegDY, count); ! 4393: return; ! 4394: case 2: // ROXL.L #qqq,Dy ! 4395: CYCLE(12); ! 4396: count = RegIRX; ! 4397: count = (count == 0) ? 8 : count; ! 4398: __assume(1 <= count && count <= 8); ! 4399: RegDY = ACC.roxl_32(RegDY, count); ! 4400: return; ! 4401: case 3: // ROL.L #qqq,Dy ! 4402: CYCLE(6); ! 4403: count = RegIRX; ! 4404: count = (count == 0) ? 8 : count; ! 4405: __assume(1 <= count && count <= 8); ! 4406: RegDY = ACC.rol_32(RegDY, count); ! 4407: return; ! 4408: case 4: // ASL.L Dx,Dy ! 4409: CYCLE(8); ! 4410: count = RegDX & 63; ! 4411: __assume(0 <= count && count < 64); ! 4412: RegDY = ACC.asl_32(RegDY, count); ! 4413: return; ! 4414: case 5: // LSL.L Dx,Dy ! 4415: count = RegDX & 63; ! 4416: // シフト数がデータサイズを越えるかどうかでサイクルが違う ! 4417: CYCLE(count <= 32 ? 6 : 8); ! 4418: __assume(0 <= count && count < 64); ! 4419: RegDY = ACC.lsl_32(RegDY, count); ! 4420: return; ! 4421: case 6: // ROXL.L Dx,Dy ! 4422: CYCLE(12); ! 4423: count = RegDX & 63; ! 4424: __assume(0 <= count && count < 64); ! 4425: RegDY = ACC.roxl_32(RegDY, count); ! 4426: return; ! 4427: case 7: // ROL.L Dx,Dy ! 4428: CYCLE(8); ! 4429: count = RegDX & 63; ! 4430: __assume(0 <= count && count < 64); ! 4431: RegDY = ACC.rol_32(RegDY, count); ! 4432: return; ! 4433: } ! 4434: } ! 4435: ! 4436: // %1110_000111_mmmrrr ..m+-rxw.. 034 ASL.W <ea> ! 4437: OP_DEF(asl_w) ! 4438: { ! 4439: CYCLE(6); ! 4440: uint32 ea = cea_data_2(); ! 4441: uint32 data = read_2(ea); ! 4442: data = ACC.asl_16(data, 1); ! 4443: write_2(ea, data); ! 4444: } ! 4445: ! 4446: // %1110_001011_mmmrrr ..m+-rxw.. 034 LSR.W <ea> ! 4447: OP_DEF(lsr_w) ! 4448: { ! 4449: CYCLE(4); ! 4450: uint32 ea = cea_data_2(); ! 4451: uint32 data = read_2(ea); ! 4452: data = ACC.lsr_16(data, 1); ! 4453: write_2(ea, data); ! 4454: } ! 4455: ! 4456: // %1110_001111_mmmrrr ..m+-rxw.. 034 LSL.W <ea> ! 4457: OP_DEF(lsl_w) ! 4458: { ! 4459: CYCLE(4); ! 4460: uint32 ea = cea_data_2(); ! 4461: uint32 data = read_2(ea); ! 4462: data = ACC.lsl_16(data, 1); ! 4463: write_2(ea, data); ! 4464: } ! 4465: ! 4466: // %1110_010011_mmmrrr ..m+-rxw.. 034 ROXR.W <ea> ! 4467: OP_DEF(roxr_w) ! 4468: { ! 4469: CYCLE(4); ! 4470: uint32 ea = cea_data_2(); ! 4471: uint32 data = read_2(ea); ! 4472: data = ACC.roxr_16(data, 1); ! 4473: write_2(ea, data); ! 4474: } ! 4475: ! 4476: // %1110_010111_mmmrrr ..m+-rxw.. 034 ROXL.W <ea> ! 4477: OP_DEF(roxl_w) ! 4478: { ! 4479: CYCLE(4); ! 4480: uint32 ea = cea_data_2(); ! 4481: uint32 data = read_2(ea); ! 4482: data = ACC.roxl_16(data, 1); ! 4483: write_2(ea, data); ! 4484: } ! 4485: ! 4486: // %1110_011011_mmmrrr ..m+-rxw.. 034 ROR.W <ea> ! 4487: OP_DEF(ror_w) ! 4488: { ! 4489: CYCLE(6); ! 4490: uint32 ea = cea_data_2(); ! 4491: uint32 data = read_2(ea); ! 4492: data = ACC.ror_16(data, 1); ! 4493: write_2(ea, data); ! 4494: } ! 4495: ! 4496: // %1110_011111_mmmrrr ..m+-rxw.. 034 ROL.W <ea> ! 4497: OP_DEF(rol_w) ! 4498: { ! 4499: CYCLE(6); ! 4500: uint32 ea = cea_data_2(); ! 4501: uint32 data = read_2(ea); ! 4502: data = ACC.rol_16(data, 1); ! 4503: write_2(ea, data); ! 4504: } ! 4505: ! 4506: // %1110_100011_mmmrrr d.m..rxwp. -34 BFTST <ea>{#o:#w} ! 4507: OP_DEF(bftst) ! 4508: { ! 4509: uint n = ir & 0x3f; ! 4510: ir2 = fetch_2(); ! 4511: ! 4512: acc_bf bf(this); ! 4513: if (n < 8) { ! 4514: // BFTST Dn{#o:#w} ! 4515: bf.LoadReg(n); ! 4516: } else { ! 4517: // BFTST <ea>{#o:#w} ! 4518: uint32 ea = cea_ctrl(); ! 4519: bf.LoadMem(ea); ! 4520: } ! 4521: ACC.move_32(bf.data); ! 4522: } ! 4523: ! 4524: // %1110_100111_mmmrrr d.m..rxwp. -34 BFEXTU <ea>{#o:#w},Dn ! 4525: OP_DEF(bfextu) ! 4526: { ! 4527: uint n = ir & 0x3f; ! 4528: ir2 = fetch_2(); ! 4529: uint dn = ir2 >> 12; ! 4530: ! 4531: acc_bf bf(this); ! 4532: if (n < 8) { ! 4533: // BFEXTU Dn{#o:#w},Dn ! 4534: bf.LoadReg(n); ! 4535: } else { ! 4536: // BFEXTU <ea>{#o:#w},Dn ! 4537: uint32 ea = cea_ctrl(); ! 4538: bf.LoadMem(ea); ! 4539: } ! 4540: // CCR は操作前のビットフィールドに対して ! 4541: ACC.move_32(bf.data); ! 4542: // 符号なしシフト ! 4543: reg.D[dn] = bf.data >> (32 - bf.width); ! 4544: } ! 4545: ! 4546: // %1110_101011_mmmrrr d.m..rxw.. -34 BFCHG <ea>{#o:#w} ! 4547: OP_DEF(bfchg) ! 4548: { ! 4549: uint n = ir & 0x3f; ! 4550: ir2 = fetch_2(); ! 4551: ! 4552: acc_bf bf(this); ! 4553: if (n < 8) { ! 4554: // BFCHG Dn{#o:#w} ! 4555: bf.LoadReg(n); ! 4556: } else if (n >= 0x3a) { ! 4557: // BFCHG <ea> に PC 相対(と #imm) はない ! 4558: op_illegal(); ! 4559: } else { ! 4560: // BFCHG <ea>{#o:#w} ! 4561: uint32 ea = cea_ctrl(); ! 4562: bf.LoadMem(ea); ! 4563: } ! 4564: // CCR は操作前のビットフィールドに対して ! 4565: ACC.move_32(bf.data); ! 4566: bf.data = ~bf.data; ! 4567: bf.Store(n); ! 4568: } ! 4569: ! 4570: // %1110_101111_mmmrrr d.m..rxwp. -34 BFEXTS <ea>{#o:#w},Dn ! 4571: OP_DEF(bfexts) ! 4572: { ! 4573: uint n = ir & 0x3f; ! 4574: ir2 = fetch_2(); ! 4575: uint dn = ir2 >> 12; ! 4576: ! 4577: acc_bf bf(this); ! 4578: if (n < 8) { ! 4579: // BFEXTS Dn{#o:#w},Dn ! 4580: bf.LoadReg(n); ! 4581: } else { ! 4582: // BFEXTS <ea>{#o:#w},Dn ! 4583: uint32 ea = cea_ctrl(); ! 4584: bf.LoadMem(ea); ! 4585: } ! 4586: // CCR は操作前のビットフィールドに対して ! 4587: ACC.move_32(bf.data); ! 4588: // 符号付きシフト ! 4589: // XXX 負数の右シフト ! 4590: reg.D[dn] = ((int32)bf.data) >> (32 - bf.width); ! 4591: } ! 4592: ! 4593: // %1110_110011_mmmrrr d.m..rxw.. -34 BFCLR <ea>{#o:#w} ! 4594: OP_DEF(bfclr) ! 4595: { ! 4596: uint n = ir & 0x3f; ! 4597: ir2 = fetch_2(); ! 4598: ! 4599: acc_bf bf(this); ! 4600: if (n < 8) { ! 4601: // BFCLR Dn{#o:#w} ! 4602: bf.LoadReg(n); ! 4603: } else if (n >= 0x3a) { ! 4604: // BFCLR <ea> に PC 相対(と #imm) はない ! 4605: op_illegal(); ! 4606: } else { ! 4607: // BFCLR <ea>{#o:#w} ! 4608: uint32 ea = cea_ctrl(); ! 4609: bf.LoadMem(ea); ! 4610: } ! 4611: // CCR は操作前のビットフィールドに対して ! 4612: ACC.move_32(bf.data); ! 4613: bf.data = 0; ! 4614: bf.Store(n); ! 4615: } ! 4616: ! 4617: // %1110_110111_mmmrrr d.m..rxwp. -34 BFFFO <ea>{#o:#w},Dn ! 4618: OP_DEF(bfffo) ! 4619: { ! 4620: uint n = ir & 0x3f; ! 4621: ir2 = fetch_2(); ! 4622: uint dn = ir2 >> 12; ! 4623: ! 4624: acc_bf bf(this); ! 4625: if (n < 8) { ! 4626: // BFFFO Dn{#o:#w},Dn ! 4627: bf.LoadReg(n); ! 4628: } else { ! 4629: // BFFFO <ea>{#o:#w},Dn ! 4630: uint32 ea = cea_ctrl(); ! 4631: bf.LoadMem(ea); ! 4632: } ! 4633: // CCR は操作前のビットフィールドに対して ! 4634: ACC.move_32(bf.data); ! 4635: // 1 になっているビットを探す ! 4636: for (; (int)bf.width-- > 0 && (int32)bf.data >= 0; bf.data <<= 1) { ! 4637: bf.offset++; ! 4638: } ! 4639: reg.D[dn] = bf.offset; ! 4640: } ! 4641: ! 4642: // %1110_111011_mmmrrr d.m..rxw.. -34 BFSET <ea>{#o:#w} ! 4643: OP_DEF(bfset) ! 4644: { ! 4645: uint n = ir & 0x3f; ! 4646: ir2 = fetch_2(); ! 4647: ! 4648: acc_bf bf(this); ! 4649: if (n < 8) { ! 4650: // BFSET Dn{#o:#w} ! 4651: bf.LoadReg(n); ! 4652: } else if (n >= 0x3a) { ! 4653: // BFSET <ea> に PC 相対(と #imm) はない ! 4654: op_illegal(); ! 4655: } else { ! 4656: // BFSET <ea>{#o:#w} ! 4657: uint32 ea = cea_ctrl(); ! 4658: bf.LoadMem(ea); ! 4659: } ! 4660: // CCR は操作前のビットフィールドに対して ! 4661: ACC.move_32(bf.data); ! 4662: bf.data = 0xffffffff; ! 4663: bf.Store(n); ! 4664: } ! 4665: ! 4666: // %1110_111111_mmmrrr d.m..rxw.. -34 BFINS Dn,<ea>{#o:#w} ! 4667: OP_DEF(bfins) ! 4668: { ! 4669: uint n = ir & 0x3f; ! 4670: ir2 = fetch_2(); ! 4671: uint dn = ir2 >> 12; ! 4672: ! 4673: acc_bf bf(this); ! 4674: if (n < 8) { ! 4675: // BFINS Dm,Dn{#o:#w} ! 4676: bf.LoadReg(n); ! 4677: } else if (n >= 0x3a) { ! 4678: // BFINS Dn,<ea> に PC 相対(と #imm) はない ! 4679: op_illegal(); ! 4680: } else { ! 4681: // BFINS Dn,<ea>{#o:#w} ! 4682: uint32 ea = cea_ctrl(); ! 4683: bf.LoadMem(ea); ! 4684: } ! 4685: bf.data = reg.D[dn] << (32 - bf.width); ! 4686: // BFINS のみ CCR は操作後のビットフィールドに対して ! 4687: ACC.move_32(bf.data); ! 4688: bf.Store(n); ! 4689: } ! 4690: ! 4691: // %1111_000nnn_nnnnnn .......... -3- MMU_OP ! 4692: OP_DEF(mmuop) ! 4693: { ! 4694: // CPU ごとの virtual 関数になっている。 ! 4695: ops_mmu30(); ! 4696: } ! 4697: ! 4698: // 68030 MMU 命令跡地は 68040 では全部 F ライン例外。 ! 4699: void ! 4700: MPU68040Device::ops_mmu30() ! 4701: { ! 4702: op_illegal(); ! 4703: } ! 4704: ! 4705: // 68030 MMU 命令。 ! 4706: void ! 4707: MPU68030Device::ops_mmu30() ! 4708: { ! 4709: ir2 = fetch_2(); ! 4710: switch ((ir2 >> 8) & 0xff) { ! 4711: case (0x0800 >> 8): ! 4712: case (0x0900 >> 8): ! 4713: case (0x0c00 >> 8): ! 4714: case (0x0d00 >> 8): ! 4715: // %000_01n00_000_00000 PMOVE.L <ea>,TTn ! 4716: // %000_01n01_000_00000 PMOVEFD.L <ea>,TTn ! 4717: { ! 4718: CYCLE2(12, 14); ! 4719: uint32 ea = cea_copro(); ! 4720: uint32 data = read_4(ea); ! 4721: uint n = (ir2 >> 10) & 1; ! 4722: SetTT(n, data); ! 4723: if ((ir2 & 0x0100) == 0) ! 4724: atc.flush(); ! 4725: break; ! 4726: } ! 4727: case (0x0a00 >> 8): ! 4728: case (0x0e00 >> 8): ! 4729: // %000_01n10_000_00000 PMOVE.L TTn,<ea> ! 4730: { ! 4731: CYCLE(8); ! 4732: uint32 ea = cea_copro(); ! 4733: uint n = (ir2 >> 10) & 1; ! 4734: write_4(ea, GetTT(n)); ! 4735: break; ! 4736: } ! 4737: case (0x2000 >> 8): ! 4738: // %001_00000_000_00000 PLOADW SFC,<ea> ! 4739: // %001_00000_000_00001 PLOADW DFC,<ea> ! 4740: // %001_00000_000_01yyy PLOADW Dy,<ea> ! 4741: // %001_00000_000_10nnn PLOADW #<imm>,<ea> ! 4742: { ! 4743: putlog(0, "ploadw"); ! 4744: mmu_op_pload(); ! 4745: break; ! 4746: } ! 4747: case (0x2200 >> 8): ! 4748: // %001_00010_000_00000 PLOADR SFC,<ea> ! 4749: // %001_00010_000_00001 PLOADR DFC,<ea> ! 4750: // %001_00010_000_01yyy PLOADR Dy,<ea> ! 4751: // %001_00010_000_10nnn PLOADR #<imm>,<ea> ! 4752: { ! 4753: putlog(0, "ploadr"); ! 4754: mmu_op_pload(); ! 4755: break; ! 4756: } ! 4757: case (0x2400 >> 8): ! 4758: // %001_00100_000_00000 PFLUSHA ! 4759: { ! 4760: CYCLE2(12, 14); ! 4761: atc.flush(); ! 4762: break; ! 4763: } ! 4764: case (0x3000 >> 8): ! 4765: // %001_10000_nnn_00000 PFLUSH SFC,#<mask> ! 4766: // %001_10000_nnn_00001 PFLUSH DFC,#<mask> ! 4767: // %001_10000_nnn_01yyy PFLUSH Dy,#<mask> ! 4768: // %001_10000_nnn_10nnn PFLUSH #<imm>,#<mask> ! 4769: { ! 4770: mmu_op_pflush(); ! 4771: break; ! 4772: } ! 4773: case (0x3800 >> 8): ! 4774: // %001_11000_nnn_00000 PFLUSH SFC,#<mask>,<ea> ! 4775: // %001_11000_nnn_00001 PFLUSH DFC,#<mask>,<ea> ! 4776: // %001_11000_nnn_01yyy PFLUSH Dy,#<mask>,<ea> ! 4777: // %001_11000_nnn_10nnn PFLUSH #<imm>,#<mask>,<ea> ! 4778: { ! 4779: mmu_op_pflush_ea(); ! 4780: break; ! 4781: } ! 4782: case (0x4000 >> 8): ! 4783: case (0x4100 >> 8): ! 4784: // %010_00000_000_00000 PMOVE.L <ea>,TC ! 4785: // %010_00001_000_00000 PMOVEFD.L <ea>,TC ! 4786: { ! 4787: // たぶん ! 4788: // 無効→有効が (38, 40) ! 4789: // 有効→無効が (56, 58) ! 4790: // 無効→無効が (14, 16) ってことだと思うんだけど。 ! 4791: CYCLE2(14, 16); ! 4792: uint32 ea = cea_copro(); ! 4793: uint32 data = read_4(ea); ! 4794: if (SetTC(data) == false) { ! 4795: Exception(M68K::EXCEP_MMU_CONFIG); ! 4796: break; ! 4797: } ! 4798: if ((ir2 & 0x0100) == 0) ! 4799: atc.flush(); ! 4800: break; ! 4801: } ! 4802: case (0x4200 >> 8): ! 4803: // %010_00010_000_00000 PMOVE.L TC,<ea> ! 4804: { ! 4805: CYCLE2(4, 5); ! 4806: uint32 ea = cea_copro(); ! 4807: write_4(ea, GetTC()); ! 4808: break; ! 4809: } ! 4810: case (0x4800 >> 8): ! 4811: case (0x4900 >> 8): ! 4812: // %010_01000_000_00000 PMOVE.Q <ea>,SRP ! 4813: // %010_01001_000_00000 PMOVEFD.Q <ea>,SRP ! 4814: { ! 4815: // たぶん有効になる時が (12, 14) ! 4816: // それ以外が (28, 30) ってことかな。 ! 4817: CYCLE2(28, 30); ! 4818: uint32 ea = cea_copro(); ! 4819: uint32 h = read_4(ea); ! 4820: uint32 l = read_4(ea + 4); ! 4821: if (SetSRP(h, l) == false) { ! 4822: Exception(M68K::EXCEP_MMU_CONFIG); ! 4823: break; ! 4824: } ! 4825: if ((ir2 & 0x0100) == 0) ! 4826: atc.flush(); ! 4827: break; ! 4828: } ! 4829: case (0x4a00 >> 8): ! 4830: // %010_01010_000_00000 PMOVE.Q SRP,<ea> ! 4831: { ! 4832: CYCLE2(4, 5); ! 4833: uint32 ea = cea_copro(); ! 4834: write_4(ea, GetSRPh()); ! 4835: write_4(ea + 4, GetSRPl()); ! 4836: break; ! 4837: } ! 4838: case (0x4c00 >> 8): ! 4839: case (0x4d00 >> 8): ! 4840: // %010_01100_000_00000 PMOVE.Q <ea>,CRP ! 4841: // %010_01101_000_00000 PMOVEFD.Q <ea>,CRP ! 4842: { ! 4843: // たぶん有効になる時が (12, 14) ! 4844: // それ以外が (28, 30) ってことかな。 ! 4845: CYCLE2(28, 30); ! 4846: uint32 ea = cea_copro(); ! 4847: uint32 h = read_4(ea); ! 4848: uint32 l = read_4(ea + 4); ! 4849: if (SetCRP(h, l) == false) { ! 4850: Exception(M68K::EXCEP_MMU_CONFIG); ! 4851: break; ! 4852: } ! 4853: if ((ir2 & 0x0100) == 0) ! 4854: atc.flush(); ! 4855: break; ! 4856: } ! 4857: case (0x4e00 >> 8): ! 4858: // %010_01110_000_00000 PMOVE.Q CRP,<ea> ! 4859: { ! 4860: CYCLE2(4, 5); ! 4861: uint32 ea = cea_copro(); ! 4862: write_4(ea, GetCRPh()); ! 4863: write_4(ea + 4, GetCRPl()); ! 4864: break; ! 4865: } ! 4866: case (0x6000 >> 8): ! 4867: // %011_00000_000_00000 PMOVE.W <ea>,MMUSR ! 4868: { ! 4869: CYCLE(6); ! 4870: uint32 ea = cea_copro(); ! 4871: uint16 data = read_2(ea); ! 4872: SetMMUSR(data); ! 4873: break; ! 4874: } ! 4875: case (0x6200 >> 8): ! 4876: // %011_00010_000_00000 PMOVE.W MMUSR,<ea> ! 4877: { ! 4878: CYCLE2(4, 5); ! 4879: uint32 ea = cea_copro(); ! 4880: write_2(ea, GetMMUSR()); ! 4881: break; ! 4882: } ! 4883: case (0x8000 >> 8): ! 4884: case (0x8400 >> 8): ! 4885: case (0x8800 >> 8): ! 4886: case (0x8c00 >> 8): ! 4887: case (0x9000 >> 8): ! 4888: case (0x9400 >> 8): ! 4889: case (0x9800 >> 8): ! 4890: case (0x9c00 >> 8): ! 4891: // %100_nnn00_000_00000 PTESTW SFC,<ea>,#<level> ! 4892: // %100_nnn00_000_00001 PTESTW DFC,<ea>,#<level> ! 4893: // %100_nnn00_000_01yyy PTESTW Dy,<ea>,#<level> ! 4894: // %100_nnn00_000_10nnn PTESTW #<imm>,<ea>,#<level> ! 4895: { ! 4896: mmu_op_ptest(); ! 4897: break; ! 4898: } ! 4899: case (0x8100 >> 8): ! 4900: case (0x8500 >> 8): ! 4901: case (0x8900 >> 8): ! 4902: case (0x8d00 >> 8): ! 4903: case (0x9100 >> 8): ! 4904: case (0x9500 >> 8): ! 4905: case (0x9900 >> 8): ! 4906: case (0x9d00 >> 8): ! 4907: // %100_nnn01_nnn_00000 PTESTW SFC,<ea>,#<level>,An ! 4908: // %100_nnn01_nnn_00001 PTESTW DFC,<ea>,#<level>,An ! 4909: // %100_nnn01_nnn_01yyy PTESTW Dy,<ea>,#<level>,An ! 4910: // %100_nnn01_nnn_10nnn PTESTW #<imm>,<ea>,#<level>,An ! 4911: { ! 4912: mmu_op_ptest(); ! 4913: break; ! 4914: } ! 4915: case (0x8200 >> 8): ! 4916: case (0x8600 >> 8): ! 4917: case (0x8a00 >> 8): ! 4918: case (0x8e00 >> 8): ! 4919: case (0x9200 >> 8): ! 4920: case (0x9600 >> 8): ! 4921: case (0x9a00 >> 8): ! 4922: case (0x9e00 >> 8): ! 4923: // %100_nnn10_000_00000 PTESTR SFC,<ea>,#<level> ! 4924: // %100_nnn10_000_00001 PTESTR DFC,<ea>,#<level> ! 4925: // %100_nnn10_000_01yyy PTESTR Dy,<ea>,#<level> ! 4926: // %100_nnn10_000_10nnn PTESTR #<imm>,<ea>,#<level> ! 4927: { ! 4928: mmu_op_ptest(); ! 4929: break; ! 4930: } ! 4931: case (0x8300 >> 8): ! 4932: case (0x8700 >> 8): ! 4933: case (0x8b00 >> 8): ! 4934: case (0x8f00 >> 8): ! 4935: case (0x9300 >> 8): ! 4936: case (0x9700 >> 8): ! 4937: case (0x9b00 >> 8): ! 4938: case (0x9f00 >> 8): ! 4939: // %100_nnn11_nnn_00000 PTESTR SFC,<ea>,#<level>,An ! 4940: // %100_nnn11_nnn_00001 PTESTR DFC,<ea>,#<level>,An ! 4941: // %100_nnn11_nnn_01yyy PTESTR Dy,<ea>,#<level>,An ! 4942: // %100_nnn11_nnn_10nnn PTESTR #<imm>,<ea>,#<level>,An ! 4943: { ! 4944: mmu_op_ptest(); ! 4945: break; ! 4946: } ! 4947: default: ! 4948: OP_FUNC(illegal); ! 4949: break; ! 4950: } ! 4951: } ! 4952: ! 4953: // 現在の FPCR/FPSR を fe 構造体にコピー。 ! 4954: // ! 4955: // fe.fe_{fpcr,fpsr} のほうはこの fpe 用の内部ワークなので破壊してよい。 ! 4956: // 命令実行の結果、FPSR レジスタの値を更新する際は fpu_upd_fpsr() を ! 4957: // 呼ぶこと。これを使わず独自に更新する場合は fe.fe_fpframe->fpf_fpsr ! 4958: // (こっちがレジスタ値) と fe.fe_fpsr (FPE 用) を同時に更新すること。 ! 4959: // FPCR のほうは FMOVE-to-FPCR 命令以外で変更されることはないはず。 ! 4960: #define INIT_FE() do { \ ! 4961: fe.fe_fpcr = RegFPCR; \ ! 4962: fe.fe_fpsr = RegFPSR; \ ! 4963: } while (0) ! 4964: ! 4965: // ステートを (NULL なら) IDLE に変える。 ! 4966: // 6888x では非条件命令、条件命令どちらでも IDLE になる。 ! 4967: // 68040 では非条件命令でだけ IDLE になる。 ! 4968: // 非条件命令はここでは1ワード目の opclass が 1,2,3 の命令。 ! 4969: #define SET_IDLE() do { \ ! 4970: if (fpu_state == FPU_STATE_NULL) \ ! 4971: fpu_state = FPU_STATE_IDLE; \ ! 4972: } while (0) ! 4973: ! 4974: // %1111_001000_nnnnnn .......... -34 FPGEN ! 4975: OP_DEF(fpgen) ! 4976: { ! 4977: if (GetFPUType().IsNoFPU()) { ! 4978: op_illegal(); ! 4979: return; ! 4980: } ! 4981: ! 4982: INIT_FE(); ! 4983: SET_IDLE(); ! 4984: ! 4985: ir2 = fetch_2(); ! 4986: switch (ir2 >> 13) { ! 4987: case 0: ! 4988: fpu_op_fgen_reg(); ! 4989: break; ! 4990: case 1: ! 4991: fpu_op_illg(); ! 4992: break; ! 4993: case 2: ! 4994: fpu_op_fgen_mem(); ! 4995: break; ! 4996: case 3: ! 4997: fpu_op_fmove_to_mem(); ! 4998: break; ! 4999: case 4: ! 5000: fpu_op_fmovem_ea2ctl(); ! 5001: break; ! 5002: case 5: ! 5003: fpu_op_fmovem_ctl2ea(); ! 5004: break; ! 5005: case 6: ! 5006: fpu_op_fmovem_ea2reg(); ! 5007: break; ! 5008: case 7: ! 5009: fpu_op_fmovem_reg2ea(); ! 5010: break; ! 5011: } ! 5012: } ! 5013: ! 5014: // %1111_001001_mmmrrr d.m+-rxw.. -34 FScc.B <ea> ! 5015: // %1111_001001_001yyy .......... -34 FDBcc Dy,<label> ! 5016: // %1111_001001_111010 .......... -34 FTRAPcc.W #<imm> ! 5017: // %1111_001001_111011 .......... -34 FTRAPcc.L #<imm> ! 5018: // %1111_001001_111100 .......... -34 FTRAPcc ! 5019: OP_DEF(fxcc) ! 5020: { ! 5021: if (GetFPUType().IsNoFPU()) { ! 5022: op_illegal(); ! 5023: return; ! 5024: } ! 5025: ! 5026: if ((ir & 077) >= 075) { ! 5027: op_illegal(); ! 5028: return; ! 5029: } ! 5030: ! 5031: INIT_FE(); ! 5032: if (GetFPUType().Is6888x()) { ! 5033: SET_IDLE(); ! 5034: } ! 5035: ! 5036: // ここまで来ると共通で ir2 に cc が来る。 ! 5037: ir2 = fetch_2(); ! 5038: switch (ir & 077) { ! 5039: case 010 ... 017: // FDBcc ! 5040: fpu_op_fdbcc(); ! 5041: break; ! 5042: case 000 ... 007: // FScc ! 5043: case 020 ... 027: ! 5044: case 030 ... 037: ! 5045: case 040 ... 047: ! 5046: case 050 ... 057: ! 5047: case 060 ... 067: ! 5048: case 070 ... 071: ! 5049: fpu_op_fscc(); ! 5050: break; ! 5051: case 072: // FTRAPcc.W ! 5052: fpu_op_ftrapcc_w(); ! 5053: break; ! 5054: case 073: // FTRAPcc.L ! 5055: fpu_op_ftrapcc_l(); ! 5056: break; ! 5057: case 074: // FTRAPcc ! 5058: fpu_op_ftrapcc(); ! 5059: break; ! 5060: default: ! 5061: __unreachable(); ! 5062: } ! 5063: } ! 5064: ! 5065: // %1111_001010_nnnnnn .......... -34 FBcc.W <label> ! 5066: OP_DEF(fbcc_w) ! 5067: { ! 5068: if (GetFPUType().IsNoFPU()) { ! 5069: op_illegal(); ! 5070: return; ! 5071: } ! 5072: ! 5073: INIT_FE(); ! 5074: if (GetFPUType().Is6888x()) { ! 5075: SET_IDLE(); ! 5076: } ! 5077: ! 5078: fpu_op_fbcc_w(); ! 5079: } ! 5080: ! 5081: // %1111_001011_nnnnnn .......... -34 FBcc.L <label> ! 5082: OP_DEF(fbcc_l) ! 5083: { ! 5084: if (GetFPUType().IsNoFPU()) { ! 5085: op_illegal(); ! 5086: return; ! 5087: } ! 5088: ! 5089: INIT_FE(); ! 5090: if (GetFPUType().Is6888x()) { ! 5091: SET_IDLE(); ! 5092: } ! 5093: ! 5094: fpu_op_fbcc_l(); ! 5095: } ! 5096: ! 5097: // %1111_001100_mmmrrr ..m.-rxw.. -34 FSAVE <ea> ! 5098: OP_DEF(fsave) ! 5099: { ! 5100: if (GetFPUType().IsNoFPU()) { ! 5101: op_illegal(); ! 5102: return; ! 5103: } ! 5104: ! 5105: SUPERVISOR_OP; ! 5106: ! 5107: fpu_op_fsave(); ! 5108: } ! 5109: ! 5110: // %1111_001101_mmmrrr ..m+.rxw.. -34 FRESTORE <ea> ! 5111: OP_DEF(frestore) ! 5112: { ! 5113: if (GetFPUType().IsNoFPU()) { ! 5114: op_illegal(); ! 5115: return; ! 5116: } ! 5117: ! 5118: SUPERVISOR_OP; ! 5119: ! 5120: fpu_op_frestore(); ! 5121: } ! 5122: ! 5123: // %1111_0100nn_001yyy .......... --4 CINVL <caches>,(Ay) ! 5124: // %1111_0100nn_010yyy .......... --4 CINVP <caches>,(Ay) ! 5125: // %1111_0100nn_011000 .......... --4 CINVA <caches> ! 5126: // %1111_0100nn_101yyy .......... --4 CPUSHL <caches>,(Ay) ! 5127: // %1111_0100nn_110yyy .......... --4 CPUSHP <caches>,(Ay) ! 5128: // %1111_0100nn_111000 .......... --4 CPUSHA <caches> ! 5129: OP_DEF(cinv) ! 5130: { ! 5131: if (mpu_type != m680x0MPUType::M68040) { ! 5132: op_illegal(); ! 5133: return; ! 5134: } ! 5135: // putlog(1, "cinv*/cpush* (NOT IMPLEMENTED)"); ! 5136: } ! 5137: ! 5138: // %1111_010100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5139: // %1111_010100_000yyy .......... --4 PFLUSHN (Ay) ! 5140: // %1111_010100_001yyy .......... --4 PFLUSH (Ay) ! 5141: // %1111_010100_010000 .......... --4 PFLUSHAN ! 5142: // %1111_010100_011000 .......... --4 PFLUSHA ! 5143: OP_DEF(pflush) ! 5144: { ! 5145: // CPU ごとの virtual 関数になっている。 ! 5146: ops_mmu40_pflush(); ! 5147: } ! 5148: ! 5149: // 68030 では 68040 MMU 命令の位置は全部 cpSAVE。 ! 5150: void ! 5151: MPU68030Device::ops_mmu40_pflush() ! 5152: { ! 5153: op_cpsave(); ! 5154: } ! 5155: ! 5156: // 68040 MMU 命令。 ! 5157: void ! 5158: MPU68040Device::ops_mmu40_pflush() ! 5159: { ! 5160: SUPERVISOR_OP; ! 5161: ! 5162: // DFC は 1,2,5,6 の場合のみ有効で、0,3,4,7 なら動作不定。 ! 5163: // 68000PRM.pdf, p6-35。 ! 5164: // ここでは FC2 だけで判定する。 ! 5165: ! 5166: switch (ir & 077) { ! 5167: case 000 ... 007: // PFLUSHN (Ay) ! 5168: { ! 5169: busaddr addr = busaddr(RegAY) | reg.dfc; ! 5170: atc_inst->Flush(addr, false); ! 5171: atc_data->Flush(addr, false); ! 5172: break; ! 5173: } ! 5174: ! 5175: case 010 ... 017: // PFLUSH (Ay) ! 5176: { ! 5177: busaddr addr = busaddr(RegAY) | reg.dfc; ! 5178: atc_inst->Flush(addr, true); ! 5179: atc_data->Flush(addr, true); ! 5180: break; ! 5181: } ! 5182: ! 5183: case 020: // PFLUSHAN ! 5184: { ! 5185: bool s = reg.dfc.IsSuper(); ! 5186: atc_inst->Flush(s, false); ! 5187: atc_data->Flush(s, false); ! 5188: break; ! 5189: } ! 5190: ! 5191: case 030: // PFLUSHA ! 5192: { ! 5193: bool s = reg.dfc.IsSuper(); ! 5194: atc_inst->Flush(s, true); ! 5195: atc_data->Flush(s, true); ! 5196: break; ! 5197: } ! 5198: ! 5199: default: ! 5200: op_illegal(); ! 5201: return; ! 5202: } ! 5203: } ! 5204: ! 5205: // %1111_010101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5206: // %1111_010101_001yyy .......... --4 PTESTW (Ay) ! 5207: // %1111_010101_101yyy .......... --4 PTESTR (Ay) ! 5208: OP_DEF(ptest) ! 5209: { ! 5210: if (mpu_type != m680x0MPUType::M68040) { ! 5211: op_cprestore(); ! 5212: return; ! 5213: } ! 5214: OP_FUNC(unimpl); ! 5215: } ! 5216: ! 5217: // %1111_011000_000yyy .......... --4 MOVE16 (Ay)+,xxx.L ! 5218: // %1111_011000_001yyy .......... --4 MOVE16 xxx.L,(Ay)+ ! 5219: // %1111_011000_010yyy .......... --4 MOVE16 (Ay),xxx.L ! 5220: // %1111_011000_011yyy .......... --4 MOVE16 xxx.L,(Ay) ! 5221: // %1111_011000_100yyy .......... --4 MOVE16 (Ay)+,(An)+ ! 5222: OP_DEF(move16) ! 5223: { ! 5224: if (mpu_type != m680x0MPUType::M68040) { ! 5225: op_illegal(); ! 5226: return; ! 5227: } ! 5228: OP_FUNC(unimpl); ! 5229: } ! 5230: ! 5231: // %1111_011100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5232: // %1111_100100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5233: // %1111_101100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5234: // %1111_110100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5235: // %1111_111100_mmmrrr ..m.-rxw.. 23- cpSAVE ! 5236: OP_DEF(cpsave) ! 5237: { ! 5238: // 020/030 では、(第1ワードが?) 有効な命令パターンの場合 ! 5239: // まず特権チェックを行う。 ! 5240: // cpSAVE の場合先に CIR で問い合わせて、その後 EA を評価すると書いて ! 5241: // あるように読める (68020 本 p.104) ので、コプロセッサがいない場合は ! 5242: // EA は評価しなさそう。 ! 5243: // -(An) はコプロセッサがいなければ変化しないような気がする。 ! 5244: // EA のパターンが無効なら F ライン例外になる。 ! 5245: // cpID=6,7 はユーザ用とあるが cpSAVE は影響を受けるかどうか。 ! 5246: // 040 ではコプロセッサプロトコル自体ないので全部 F ライン例外になる? ! 5247: // ! 5248: // ただし、Human68k モードではその特権判定よりも先んじて不当命令に ! 5249: // ならなければいけない。 ! 5250: // Human68k モードでは F ライン命令は例外を起こすのではなく、命令内部で ! 5251: // 直接ホストのコールバックを実行しているため、ゲスト側の特権違反ハンドラ ! 5252: // に来たものを F ライン例外へ回すというような処理は出来ないため。 ! 5253: if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) { ! 5254: switch (ir & 077) { ! 5255: case 020 ... 027: // m:(An) ! 5256: case 040 ... 047: // -:-(An) ! 5257: case 050 ... 057: // r:d16(An) ! 5258: case 060 ... 067: // x:d8(An,IX) ! 5259: case 070 ... 071: // w:Abs ! 5260: SUPERVISOR_OP; ! 5261: // コプロセッサがいないので EA をフェッチせず終了のはず。 ! 5262: break; ! 5263: default: ! 5264: break; ! 5265: } ! 5266: } ! 5267: op_illegal(); ! 5268: } ! 5269: ! 5270: // %1111_011101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5271: // %1111_100101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5272: // %1111_101101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5273: // %1111_110101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5274: // %1111_111101_mmmrrr ..m+.rxwp. 23- cpRESTORE ! 5275: OP_DEF(cprestore) ! 5276: { ! 5277: // すぐ上の cpsave 内のコメント参照。 ! 5278: // cpRESTORE の場合先に1ロングワード読んでみて、その後コプロセッサに ! 5279: // 通信するので、コプロセッサがいなくても読み込みは発生する。 ! 5280: // See XEiJ/misc/flinebuserror.x ! 5281: if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) { ! 5282: switch (ir & 077) { ! 5283: case 020 ... 027: // m:(An) ! 5284: case 030 ... 037: // +:(An)+ ! 5285: case 050 ... 057: // r:d16(An) ! 5286: case 060 ... 067: // x:d8(An,IX) ! 5287: case 070 ... 071: // w:Abs ! 5288: case 072 ... 073: // p:d8(PC,IX) ! 5289: { ! 5290: SUPERVISOR_OP; ! 5291: uint32 ea = cea_fpu(4); ! 5292: read_4(ea); ! 5293: break; ! 5294: } ! 5295: default: ! 5296: break; ! 5297: } ! 5298: } ! 5299: op_illegal(); ! 5300: } ! 5301: ! 5302: // illegal (or not-assigned) instructions ! 5303: OP_DEF(illegal) ! 5304: { ! 5305: // ILLEGAL 命令と F ライン命令と不当命令パターンがすべてここに来る。 ! 5306: // catch 内からも呼ばれるので、ここで C++ の例外をスローしてはいけない。 ! 5307: ! 5308: CYCLE2(18, 20); ! 5309: ! 5310: if ((ir & 0xf000) == 0xf000) { ! 5311: // F系列命令 ! 5312: ! 5313: if (fline_callback) { ! 5314: if (fline_callback(this, fline_arg)) { ! 5315: return; ! 5316: } ! 5317: } ! 5318: Exception(M68K::EXCEP_FLINE); ! 5319: } else { ! 5320: // 不当命令 ! 5321: Exception(M68K::EXCEP_ILLEGAL); ! 5322: } ! 5323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.