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