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