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