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