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