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