|
|
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) {
1.1.1.3 ! root 2630: case 0x00: // TRAP #0
! 2631: CYCLE3(trap);
! 2632: // TRAP#0 例外 (NetBSD システムコール表示のため別処理)
! 2633: ExceptionTrap0();
! 2634: return;
! 2635:
! 2636: case 0x01 ... 0x0e:// TRAP #<vector>
1.1.1.2 root 2637: CYCLE3(trap);
1.1 root 2638: // TRAP#N 例外
2639: Exception(M68K::EXCEP_TRAP0 + n);
2640: return;
2641:
2642: case 0x0f: // TRAP #15
1.1.1.2 root 2643: CYCLE3(trap);
1.1 root 2644: // TRAP#15 例外 (IOCS コール表示のためこれだけ別処理)
2645: ExceptionTrap15();
2646: return;
2647:
2648: case 0x10:
2649: case 0x11:
2650: case 0x12:
2651: case 0x13:
2652: case 0x14:
2653: case 0x15:
2654: case 0x16:
2655: case 0x17: // LINK.W Ay,#<imm>
2656: {
1.1.1.2 root 2657: CYCLE3(link_w);
1.1 root 2658: // レジスタやスタックを変更する前にフェッチとセーブをしないと、
2659: // ページフォルトで再実行できなくなる
2660: int32 imm = (int32)(int16)fetch_2();
2661: ops_link(imm);
2662: return;
2663: }
2664:
2665: case 0x18:
2666: case 0x19:
2667: case 0x1a:
2668: case 0x1b:
2669: case 0x1c:
2670: case 0x1d:
2671: case 0x1e:
2672: case 0x1f: // UNLK Ay
1.1.1.2 root 2673: CYCLE3(unlk);
1.1 root 2674: // ページフォルトに備えて保存する
2675: save_reg_pi(7);
2676: reg.A[7] = RegAY;
2677: RegAY = pop_4();
2678: return;
2679:
2680: case 0x20:
2681: case 0x21:
2682: case 0x22:
2683: case 0x23:
2684: case 0x24:
2685: case 0x25:
2686: case 0x26:
2687: case 0x27: // MOVE.L Ay,USP
2688: SUPERVISOR_OP;
1.1.1.2 root 2689: CYCLE3(move_an_usp);
1.1 root 2690: reg.usp = RegAY;
2691: return;
2692:
2693: case 0x28:
2694: case 0x29:
2695: case 0x2a:
2696: case 0x2b:
2697: case 0x2c:
2698: case 0x2d:
2699: case 0x2e:
2700: case 0x2f: // MOVE.L USP,Ay
2701: SUPERVISOR_OP;
1.1.1.2 root 2702: CYCLE3(move_usp_an);
1.1 root 2703: RegAY = reg.usp;
2704: return;
2705:
2706: case 0x30: // RESET
1.1.1.2 root 2707: // CYCLE3() は int8 なので。
1.1 root 2708: CYCLE(518);
2709: ops_reset();
2710: return;
2711:
2712: case 0x31: // NOP
1.1.1.2 root 2713: CYCLE3(nop);
1.1 root 2714: // XXX ほんとは何かするらしいけど
2715: return;
2716:
2717: case 0x32: // STOP #<imm>
2718: SUPERVISOR_OP;
1.1.1.2 root 2719: CYCLE3(stop);
1.1 root 2720: ops_stop();
2721: return;
2722:
2723: case 0x33: // RTE
2724: SUPERVISOR_OP;
2725: ops_rte();
2726: return;
2727:
2728: case 0x34: // RTD #<imm>
2729: {
1.1.1.2 root 2730: CYCLE3(rtd);
1.1 root 2731: // ページフォルトに備えて保存する
2732: save_reg_pi(7);
2733: uint32 disp = fetch_2();
2734: Jump(pop_4());
2735: reg.A[7] += (int32)(int16)disp;
2736: return;
2737: }
2738:
2739: case 0x35: // RTS
1.1.1.2 root 2740: CYCLE3(rts);
1.1 root 2741: // ページフォルトに備えて保存する
2742: save_reg_pi(7);
2743: Jump(pop_4());
2744: return;
2745:
2746: case 0x36: // TRAPV
2747: if (CCR.IsV()) {
1.1.1.2 root 2748: CYCLE3(trapv_excep);
1.1 root 2749: Exception(M68K::EXCEP_TRAPV);
2750: } else {
1.1.1.2 root 2751: CYCLE3(trapv);
1.1 root 2752: }
2753: return;
2754:
2755: case 0x37: // RTR
1.1.1.2 root 2756: CYCLE3(rtr);
1.1 root 2757: // ページフォルトに備えて保存する
2758: save_reg_pi(7);
2759: CCR.Set(pop_2());
2760: Jump(pop_4());
2761: return;
2762:
2763: case 0x3a: // MOVEC.L Rc,Rn
2764: ops_movec_rc_rn();
2765: return;
2766:
2767: case 0x3b: // MOVEC.L Rn,Rc
2768: ops_movec_rn_rc();
2769: return;
2770:
2771: default:
2772: op_illegal();
2773: return;
2774: }
2775: }
2776:
2777: // %0100_111010_mmmrrr ..m..rxwp. 034 JSR <ea>
2778: OP_DEF(jsr)
2779: {
1.1.1.2 root 2780: CYCLE3(jsr);
1.1 root 2781: uint32 ea = cea_ctrl();
2782: uint32 return_addr = reg.pc;
2783:
2784: // ページフォルトに備えて保存する。
2785: save_reg_pd(7);
2786: push_4(return_addr);
2787: Jump(ea);
2788: }
2789:
2790: // %0100_111011_mmmrrr ..m..rxwp. 034 JMP <ea>
2791: OP_DEF(jmp)
2792: {
1.1.1.2 root 2793: CYCLE3(jmp);
1.1 root 2794: // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか
2795: uint32 ea = cea_ctrl();
2796: Jump(ea);
2797: }
2798:
2799: // %0101_qqq000_mmmrrr d.m+-rxw.. 034 ADDQ.B #qqq,<ea>
2800: OP_DEF(addq_b)
2801: {
2802: uint n = ir & 0x3f;
2803:
2804: uint32 src = RegIRX;
2805: src = (src == 0) ? 8 : src;
2806: if (n < 8) {
2807: // ADDQ.B #qqq,Dn
1.1.1.2 root 2808: CYCLE3(addq_rn);
1.1 root 2809: uint32 data = ACC.add_8(src, reg.D[n] & 0xff);
2810: reg.D[n] = (reg.D[n] & 0xffffff00) | data;
2811: } else {
2812: // ADDQ.B #qqq,<ea>
1.1.1.2 root 2813: CYCLE3(addq_ea);
1.1 root 2814: uint32 ea = cea_data_1();
2815: uint32 data = read_1(ea);
2816: data = ACC.add_8(src, data);
2817: write_1(ea, data);
2818: }
2819: }
2820:
2821: // %0101_qqq001_mmmrrr d.m+-rxw.. 034 ADDQ.W #qqq,<ea>
2822: // %0101_qqq001_001yyy .a........ 034 ADDQ.W #qqq,Ay (.Lと等価)
2823: OP_DEF(addq_w)
2824: {
2825: uint n = ir & 0x3f;
2826:
2827: uint32 src = RegIRX;
2828: src = (src == 0) ? 8 : src;
2829: if (n < 8) {
2830: // ADDQ.W #qqq,Dn
1.1.1.2 root 2831: CYCLE3(addq_rn);
1.1 root 2832: uint32 data = ACC.add_16(src, reg.D[n] & 0xffff);
2833: reg.D[n] = (reg.D[n] & 0xffff0000) | data;
2834: } else if (n < 16) {
2835: // ADDQ.W #qqq,An は ADDQ.L と等価
2836: // フラグは変化しない
1.1.1.2 root 2837: CYCLE3(addq_rn);
1.1 root 2838: reg.R[n] += src;
2839: } else {
2840: // ADDQ.W #qqq,<ea>
1.1.1.2 root 2841: CYCLE3(addq_ea);
1.1 root 2842: uint32 ea = cea_data_2();
2843: uint32 data = read_2(ea);
2844: data = ACC.add_16(src, data);
2845: write_2(ea, data);
2846: }
2847: }
2848:
2849: // %0101_qqq010_mmmrrr d.m+-rxw.. 034 ADDQ.L #qqq,<ea>
2850: // %0101_qqq010_001yyy .a........ 034 ADDQ.L #qqq,Ay
2851: OP_DEF(addq_l)
2852: {
2853: uint n = ir & 0x3f;
2854:
2855: uint32 src = RegIRX;
2856: src = (src == 0) ? 8 : src;
2857: if (n < 8) {
2858: // ADDQ.L #qqq,Dn
1.1.1.2 root 2859: CYCLE3(addq_rn);
1.1 root 2860: reg.D[n] = ACC.add_32(src, reg.D[n]);
2861: } else if (n < 16) {
2862: // ADDQ.L #qqq,An
2863: // フラグは変化しない
1.1.1.2 root 2864: CYCLE3(addq_rn);
1.1 root 2865: reg.R[n] += src;
2866: } else {
2867: // ADDQ.L #qqq,<ea>
1.1.1.2 root 2868: CYCLE3(addq_ea);
1.1 root 2869: uint32 ea = cea_data_4();
2870: uint32 data = read_4(ea);
2871: data = ACC.add_32(src, data);
2872: write_4(ea, data);
2873: }
2874: }
2875:
2876: // TRAPcc の共通部分。
2877: void
2878: MPU680x0Device::ops_trapcc(uint cond)
2879: {
2880: // 条件成立すれば例外。成立しなければ何もしない。
2881: // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。
2882: if (CCR.Cond(cond)) {
1.1.1.2 root 2883: CYCLE3(trapcc_excep);
1.1 root 2884: Exception(M68K::EXCEP_TRAPV);
2885: } else {
2886: // サイクルを消費するだけ
1.1.1.2 root 2887: CYCLE3(trapcc);
1.1 root 2888: }
2889: }
2890:
2891: // %0101_cccc11_mmmrrr d.m+-rxw.. 034 Scc.B <ea>
2892: // %0101_cccc11_001yyy .......... 034 DBcc.W Dy,<label>
2893: // %0101_cccc11_111010 .......... -34 TRAPcc.W #<imm>
2894: // %0101_cccc11_111011 .......... -34 TRAPcc.L #<imm>
2895: // %0101_cccc11_111100 .......... -34 TRAPcc
2896: // %0101_000111_001yyy .......... 034 DBRA.W Dy,<label>
2897: OP_DEF(scc)
2898: {
2899: uint n = ir & 0x3f;
2900: uint cond = (ir >> 8) & 0x0f;
2901:
2902: switch (n) {
2903: case 0b000000 ... 0b000111: // Scc.B Dn
1.1.1.2 root 2904: CYCLE3(scc_dn);
1.1 root 2905: if (CCR.Cond(cond)) {
2906: RegDY |= 0xff;
2907: } else {
2908: RegDY &= ~0xff;
2909: }
2910: return;
2911:
2912: case 0b001000 ... 0b001111: // DBcc.W Dy,<label>
2913: if (CCR.Cond(cond)) {
2914: // 真なら何もしない。disp を読み飛ばして次へ。
1.1.1.2 root 2915: CYCLE3(dbcc_nop);
1.1 root 2916: fetch_2();
2917: } else {
2918: // 偽の場合
2919:
2920: // Dy.W を減算して(下位ワードに)書き戻し、Dy.W が -1 だったら
2921: // ループ終了。だが最適化のため、減算前の Dy.W が 0 の時は
2922: // 下位ワードを 0xffff にしてループ終了、そうでなければ Dy.L を
2923: // 減算するだけでいいはず。
2924:
2925: uint16 data = RegDY;
2926: if (data == 0) {
2927: // ループ終了。disp を読み飛ばす
1.1.1.2 root 2928: CYCLE3(dbcc_done);
1.1 root 2929: RegDY |= 0x0000ffff;
2930: fetch_2();
2931: } else {
1.1.1.2 root 2932: CYCLE3(dbcc_jmp);
1.1 root 2933: RegDY--;
2934: uint32 origin = reg.pc;
2935: int32 disp = (int32)(int16)fetch_2();
2936: Jump(origin + disp);
2937: }
2938: }
2939: return;
2940:
2941: case 0b010000 ... 0b010111: // Scc.B <ea>
2942: case 0b011000 ... 0b011111: // Scc.B <ea>
2943: case 0b100000 ... 0b100111: // Scc.B <ea>
2944: case 0b101000 ... 0b101111: // Scc.B <ea>
2945: case 0b110000 ... 0b110111: // Scc.B <ea>
2946: case 0b111000: // Scc.B <ea>
2947: case 0b111001: // Scc.B <ea>
2948: {
1.1.1.2 root 2949: CYCLE3(scc_ea);
1.1 root 2950: // 条件成立可否に関わらず EA は取得しないといけない
2951: uint32 ea = cea_data_1();
2952: uint32 data;
2953: if (CCR.Cond(cond)) {
2954: data = 0xff;
2955: } else {
2956: data = 0;
2957: }
2958: write_1(ea, data);
2959: return;
2960: }
2961:
2962: case 0b111010: // TRAPcc.W #<imm>
2963: // オペランドなしTRAPccに比べてすべてのケースで2サイクル多い
1.1.1.2 root 2964: CYCLE3(trapcc_w_inc);
1.1 root 2965: fetch_2();
2966: ops_trapcc(cond);
2967: return;
2968:
2969: case 0b111011: // TRAPcc.L #<imm>
2970: // オペランドなしTRAPccに比べてすべてのケースで4サイクル多い
1.1.1.2 root 2971: CYCLE3(trapcc_l_inc);
1.1 root 2972: fetch_4();
2973: ops_trapcc(cond);
2974: return;
2975:
2976: case 0b111100: // TRAPcc
2977: ops_trapcc(cond);
2978: return;
2979:
2980: default:
1.1.1.3 ! root 2981: break;
1.1 root 2982: }
1.1.1.3 ! root 2983: OP_FUNC(illegal);
1.1 root 2984: }
2985:
2986: // %0101_qqq100_mmmrrr d.m+-rxw.. 034 SUBQ.B #qqq,<ea>
2987: OP_DEF(subq_b)
2988: {
2989: uint n = ir & 0x3f;
2990:
2991: uint32 src = RegIRX;
2992: src = (src == 0) ? 8 : src;
2993: if (n < 8) {
2994: // SUBQ.B #qqq,Dn
1.1.1.2 root 2995: CYCLE3(subq_rn);
1.1 root 2996: uint32 data = ACC.sub_8(src, reg.D[n] & 0xff);
2997: reg.D[n] = (reg.D[n] & 0xffffff00) | data;
2998: } else {
2999: // SUBQ.B #qqq,<ea>
1.1.1.2 root 3000: CYCLE3(subq_ea);
1.1 root 3001: uint32 ea = cea_data_1();
3002: uint32 data = read_1(ea);
3003: data = ACC.sub_8(src, data);
3004: write_1(ea, data);
3005: }
3006: }
3007:
3008: // %0101_qqq101_mmmrrr d.m+-rxw.. 034 SUBQ.W #qqq,<ea>
3009: // %0101_qqq101_001yyy .a........ 034 SUBQ.W #qqq,Ay (.Lと等価)
3010: OP_DEF(subq_w)
3011: {
3012: uint n = ir & 0x3f;
3013:
3014: uint32 src = RegIRX;
3015: src = (src == 0) ? 8 : src;
3016: if (n < 8) {
3017: // SUBQ.W #qqq,Dn
1.1.1.2 root 3018: CYCLE3(subq_rn);
1.1 root 3019: uint32 data = ACC.sub_16(src, reg.D[n] & 0xffff);
3020: reg.D[n] = (reg.D[n] & 0xffff0000) | data;
3021: } else if (n < 16) {
3022: // SUBQ.W #qqq,An は SUBQ.L と等価
3023: // フラグは変化しない
1.1.1.2 root 3024: CYCLE3(subq_rn);
1.1 root 3025: reg.R[n] -= src;
3026: } else {
3027: // SUBQ.W #qqq,<ea>
1.1.1.2 root 3028: CYCLE3(subq_ea);
1.1 root 3029: uint32 ea = cea_data_2();
3030: uint32 data = read_2(ea);
3031: data = ACC.sub_16(src, data);
3032: write_2(ea, data);
3033: }
3034: }
3035:
3036: // %0101_qqq110_mmmrrr d.m+-rxw.. 034 SUBQ.L #qqq,<ea>
3037: // %0101_qqq110_001yyy .a........ 034 SUBQ.L #qqq,Ay
3038: OP_DEF(subq_l)
3039: {
3040: uint n = ir & 0x3f;
3041:
3042: uint32 src = RegIRX;
3043: src = (src == 0) ? 8 : src;
3044: if (n < 8) {
3045: // SUBQ.L #qqq,Dn
1.1.1.2 root 3046: CYCLE3(subq_rn);
1.1 root 3047: reg.D[n] = ACC.sub_32(src, reg.D[n]);
3048: } else if (n < 16) {
3049: // SUBQ.L #qqq,An
3050: // フラグは変化しない
1.1.1.2 root 3051: CYCLE3(subq_rn);
1.1 root 3052: reg.R[n] -= src;
3053: } else {
3054: // SUBQ.L #qqq,<ea>
1.1.1.2 root 3055: CYCLE3(subq_ea);
1.1 root 3056: uint32 ea = cea_data_4();
3057: uint32 data = read_4(ea);
3058: data = ACC.sub_32(src, data);
3059: write_4(ea, data);
3060: }
3061: }
3062:
3063: inline void
3064: MPU680x0Device::ops_bra()
3065: {
1.1.1.2 root 3066: CYCLE3(bra);
1.1 root 3067:
3068: uint32 origin = reg.pc;
3069: int32 disp = (int32)(int8)(ir & 0xff);
3070: if (disp == -1) {
3071: // Bcc.L
3072: disp = (int32)fetch_4();
3073: } else if (disp == 0) {
3074: // Bcc.W
3075: disp = (int32)(int16)fetch_2();
3076: }
3077: Jump(origin + disp);
3078: }
3079:
3080: // %0110_0000nn_nnnnnn .......... 034 BRA.B <label>
3081: // %0110_000000_000000 .......... 034 BRA.W <label>
3082: // %0110_000011_111111 .......... -34 BRA.L <label>
3083: OP_DEF(bra)
3084: {
3085: ops_bra();
3086: }
3087:
3088: // %0110_0001nn_nnnnnn .......... 034 BSR.B <label>
3089: // %0110_000100_000000 .......... 034 BSR.W <label>
3090: // %0110_000111_111111 .......... -34 BSR.L <label>
3091: OP_DEF(bsr)
3092: {
1.1.1.2 root 3093: CYCLE3(bsr);
1.1 root 3094: uint32 origin = reg.pc;
3095: int32 disp = (int32)(int8)(ir & 0xff);
3096: if (disp == -1) {
3097: // BSR.L <label>
3098: disp = (int32)fetch_4();
3099: } else if (disp == 0) {
3100: // BSR.W <label>
3101: disp = (int32)(int16)fetch_2();
3102: }
3103:
3104: // ページフォルトに備えて保存する。
3105: save_reg_pd(7);
3106: push_4(reg.pc);
3107: Jump(origin + disp);
3108: }
3109:
3110: // %0110_ccccnn_nnnnnn .......... 034 Bcc.B <label>
3111: // %0110_cccc00_000000 .......... 034 Bcc.W <label>
3112: // %0110_cccc11_111111 .......... -34 Bcc.L <label>
3113: OP_DEF(bcc)
3114: {
3115: // ブランチするかどうかでサイクルが変わるので先に条件を調べる
3116: uint cond = (ir >> 8) & 0x0f;
3117: if (CCR.Cond(cond)) {
3118: // Bcc (taken)
3119: ops_bra();
3120: } else {
3121: int32 disp = (int32)(int8)(ir & 0xff);
3122: if (disp == -1) {
3123: // Bcc.L (not taken)
1.1.1.2 root 3124: CYCLE3(bcc_l_not);
1.1 root 3125: fetch_4();
3126: } else if (disp == 0) {
3127: // Bcc.W (not taken)
1.1.1.2 root 3128: CYCLE3(bcc_w_not);
1.1 root 3129: fetch_2();
3130: } else {
3131: // Bcc.B (not taken)
1.1.1.2 root 3132: CYCLE3(bcc_b_not);
1.1 root 3133: }
3134: }
3135: }
3136:
3137: // %0111_xxx0nn_nnnnnn .......... 034 MOVEQ.L #<imm>,Dx
3138: OP_DEF(moveq)
3139: {
1.1.1.2 root 3140: CYCLE3(moveq);
1.1 root 3141: RegDX = (int32)(int8)(ir & 0xff);
3142: ACC.move_32(RegDX);
3143: }
3144:
3145: // %1000_xxx000_mmmrrr d.m+-rxwpi 034 OR.B <ea>,Dx
3146: OP_DEF(or_b_ea_dn)
3147: {
3148: uint n = ir & 0x3f;
3149:
1.1.1.2 root 3150: CYCLE3(or_ea_dn);
1.1 root 3151: uint x = RegIRX;
3152: if (n < 8) {
3153: // OR.B Dn,Dx
3154: uint32 data = (reg.D[x] | reg.D[n]) & 0xff;
3155: ACC.move_8(data);
3156: reg.D[x] = (reg.D[x] & 0xffffff00) | data;
3157: } else {
3158: // OR.B <ea>,Dx
3159: uint32 src = fea_data_1();
3160: uint32 data = (reg.D[x] | src) & 0xff;
3161: ACC.move_8(data);
3162: reg.D[x] = (reg.D[x] & 0xffffff00) | data;
3163: }
3164: }
3165:
3166: // %1000_xxx001_mmmrrr d.m+-rxwpi 034 OR.W <ea>,Dx
3167: OP_DEF(or_w_ea_dn)
3168: {
3169: uint n = ir & 0x3f;
3170:
1.1.1.2 root 3171: CYCLE3(or_ea_dn);
1.1 root 3172: uint x = RegIRX;
3173: if (n < 8) {
3174: // OR.W Dn,Dx
3175: uint32 data = (reg.D[x] | reg.D[n]) & 0xffff;
3176: ACC.move_16(data);
3177: reg.D[x] = (reg.D[x] & 0xffff0000) | data;
3178: } else {
3179: // OR.W <ea>,Dx
3180: uint32 src = fea_data_2();
3181: uint32 data = (reg.D[x] | src) & 0xffff;
3182: ACC.move_16(data);
3183: reg.D[x] = (reg.D[x] & 0xffff0000) | data;
3184: }
3185: }
3186:
3187: // %1000_xxx010_mmmrrr d.m+-rxwpi 034 OR.L <ea>,Dx
3188: OP_DEF(or_l_ea_dn)
3189: {
3190: uint n = ir & 0x3f;
3191:
1.1.1.2 root 3192: CYCLE3(or_ea_dn);
1.1 root 3193: uint x = RegIRX;
3194: if (n < 8) {
3195: // OR.L Dn,Dx
3196: reg.D[x] |= reg.D[n];
3197: ACC.move_32(reg.D[x]);
3198: } else {
3199: // OR.L <ea>,Dx
3200: uint32 src = fea_data_4();
3201: uint32 data = reg.D[x] | src;
3202: ACC.move_32(data);
3203: reg.D[x] = data;
3204: }
3205: }
3206:
3207: // %1000_xxx011_mmmrrr d.m+-rxwpi 034 DIVU.W <ea>,Dx
3208: OP_DEF(divu_w)
3209: {
1.1.1.2 root 3210: CYCLE3(divu_w_max);
1.1 root 3211:
3212: uint16 src = fea_data_2();
3213: uint32 dst = RegDX;
3214:
3215: if (src == 0) {
3216: // ゼロ除算の場合、
3217: // X は変化しない
3218: // C は常にクリア
3219: // N,Z,V は未定義
3220: CCR.SetC(false);
3221: Exception(M68K::EXCEP_ZERODIV);
3222: return;
3223: }
3224:
3225: uint32 quo = dst / src;
3226: uint32 rem = dst % src;
3227: if (quo > 0xffff) {
3228: // オーバーフローの場合、
3229: // X は変化しない
3230: // N,Z は未定義
3231: // V はセット
3232: // C は常にクリア
3233: CCR.SetV(true);
3234: CCR.SetC(false);
3235: return;
3236: }
3237:
3238: // 正常の場合、
3239: // X は変化しない
3240: // V, C はクリア
3241: // N, Z は quo の結果。
3242: RegDX = (rem << 16) | quo;
3243: ACC.move_16(quo);
3244: }
3245:
3246: // %1000_xxx100_mmmrrr ..m+-rxw.. 034 OR.B Dx,<ea>
3247: // %1000_xxx100_000yyy .......... 034 SBCD.B Dy,Dx
3248: // %1000_xxx100_001yyy .......... 034 SBCD.B -(Ay),-(Ax)
3249: OP_DEF(or_b_dn_ea)
3250: {
3251: uint n = ir & 0x3f;
3252:
3253: if (n < 8) {
3254: // SBCD.B Dy,Dx
1.1.1.2 root 3255: CYCLE3(sbcd_dn);
1.1 root 3256: uint32 src = RegDY & 0xff;
3257: uint32 dst = RegDX & 0xff;
3258: dst = ACC.sbcd_8(src, dst);
3259: RegDX &= 0xffffff00;
3260: RegDX |= dst;
3261: } else if (n < 16) {
3262: // SBCD.B -(Ay),-(Ax)
1.1.1.2 root 3263: CYCLE3(sbcd_an);
1.1 root 3264: save_reg_pd_if(RegIRY);
3265: save_reg_pd_if(RegIRX);
3266: uint32 srcea = internal_ea_anpd_1(RegIRY);
3267: uint32 dstea = internal_ea_anpd_1(RegIRX);
3268: uint32 src = read_1(srcea);
3269: uint32 dst = read_1(dstea);
3270: dst = ACC.sbcd_8(src, dst);
3271: write_1(dstea, dst);
3272: } else {
3273: // OR.B Dx,<ea>
1.1.1.2 root 3274: CYCLE3(or_dn_ea);
1.1 root 3275: uint32 ea = cea_data_1();
3276: uint8 data = read_1(ea);
3277: data |= RegDX;
3278: ACC.move_8(data);
3279: write_1(ea, data);
3280: }
3281: }
3282:
3283: // %1000_xxx101_mmmrrr ..m+-rxw.. 034 OR.W Dx,<ea>
3284: // %1000_xxx101_000yyy .......... -34 PACK Dy,Dx,#<imm>
3285: // %1000_xxx101_001yyy .......... -34 PACK -(Ay),-(Ax),#<imm>
3286: OP_DEF(or_w_dn_ea)
3287: {
3288: uint n = ir & 0x3f;
3289:
3290: if (n < 8) {
3291: // PACK Dy,Dx,#<imm>
1.1.1.2 root 3292: CYCLE3(pack_dn);
1.1 root 3293: uint32 imm = fetch_2();
3294: uint32 src = RegDY + imm;
3295: RegDX = (RegDX & 0xffffff00) | ((src >> 4) & 0x00f0) | (src & 0x000f);
3296: } else if (n < 16) {
3297: // PACK -(Ay),-(Ax),#<imm>
1.1.1.2 root 3298: CYCLE3(pack_an);
1.1 root 3299: uint32 imm = fetch_2();
3300: save_reg_pd(RegIRY);
1.1.1.3 ! root 3301: uint32 srcea = internal_ea_anpd_2(RegIRY);
! 3302: uint32 src = read_2(srcea);
1.1 root 3303: src += imm;
3304: uint32 dst = ((src >> 4) & 0x00f0) | (src & 0x000f);
3305: save_reg_pd_if(RegIRX);
3306: uint32 dstea = internal_ea_anpd_1(RegIRX);
3307: write_1(dstea, dst);
3308: } else {
3309: // OR.W Dx,<ea>
1.1.1.2 root 3310: CYCLE3(or_dn_ea);
1.1 root 3311: uint32 ea = cea_data_2();
3312: uint16 data = read_2(ea);
3313: data |= RegDX;
3314: ACC.move_16(data);
3315: write_2(ea, data);
3316: }
3317: }
3318:
3319: // %1000_xxx110_mmmrrr ..m+-rxw.. 034 OR.L Dx,<ea>
3320: // %1000_xxx110_000yyy .......... -34 UNPK Dy,Dx,#<imm>
3321: // %1000_xxx110_001yyy .......... -34 UNPK -(Ay),-(Ax),#<imm>
3322: OP_DEF(or_l_dn_ea)
3323: {
3324: uint n = ir & 0x3f;
3325:
3326: if (n < 8) {
3327: // UNPK Dy,Dx,#<imm>
1.1.1.2 root 3328: CYCLE3(unpk_dn);
1.1 root 3329: uint32 imm = fetch_2();
3330: uint16 src = RegDY;
3331: src = ((src & 0x00f0) << 4) | (src & 0x000f);
3332: src += imm;
3333: RegDX = (RegDX & 0xffff0000) | src;
3334: } else if (n < 16) {
3335: // UNPK -(Ay),-(Ax),#<imm>
1.1.1.2 root 3336: CYCLE3(unpk_an);
1.1 root 3337: uint32 imm = fetch_2();
3338: save_reg_pd(RegIRY);
3339: uint32 srcea = internal_ea_anpd_1(RegIRY);
3340: uint16 src = read_1(srcea);
3341: src = ((src & 0x00f0) << 4) | (src & 0x000f);
3342: src += imm;
3343: save_reg_pd_if(RegIRX);
1.1.1.3 ! root 3344: uint32 dstea = internal_ea_anpd_2(RegIRX);
! 3345: write_2(dstea, src);
1.1 root 3346: } else {
3347: // OR.L Dx,<ea>
1.1.1.2 root 3348: CYCLE3(or_dn_ea);
1.1 root 3349: uint32 ea = cea_data_4();
3350: uint32 data = read_4(ea);
3351: data |= RegDX;
3352: ACC.move_32(data);
3353: write_4(ea, data);
3354: }
3355: }
3356:
3357: // %1000_xxx111_mmmrrr d.m+-rxwpi 034 DIVS.W <ea>,Dx
3358: OP_DEF(divs_w)
3359: {
1.1.1.2 root 3360: CYCLE3(divs_w_max);
1.1 root 3361:
3362: uint16 src = fea_data_2();
3363: uint32 dst = RegDX;
3364:
3365: if (src == 0) {
3366: // ゼロ除算の場合、
3367: // X は変化しない
3368: // C は常にクリア
3369: // N,Z,V は未定義
3370: CCR.SetC(false);
3371: Exception(M68K::EXCEP_ZERODIV);
3372: return;
3373: }
3374:
3375: // ホストでオーバーフローが起きるのはこのケースのみ
3376: if (dst == 0x80000000 && src == 0xffff) {
3377: // オーバーフローの場合、
3378: // X は変化しない
3379: // N,Z は未定義
3380: // V はセット
3381: // C は常にクリア
3382: CCR.SetV(true);
3383: CCR.SetC(false);
3384: return;
3385: }
3386:
3387: int32 squo = (int32)dst / (int32)(int16)src;
3388: int32 srem = (int32)dst % (int32)(int16)src;
3389: if ((int16)squo != squo) {
3390: // オーバーフローの場合
3391: CCR.SetV(true);
3392: CCR.SetC(false);
3393: return;
3394: }
3395: // 正常の場合、
3396: // X は変化しない
3397: // V, C はクリア
3398: // N, Z は quo の結果。
3399: uint32 quo = (uint32)squo & 0xffff;
3400: uint32 rem = (uint32)srem & 0xffff;
3401: RegDX = (rem << 16) | quo;
3402: ACC.move_16(quo);
3403: }
3404:
3405: // %1001_xxx000_mmmrrr dam+-rxwpi 034 SUB.B <ea>,Dx
3406: OP_DEF(sub_b_ea_dn)
3407: {
1.1.1.2 root 3408: CYCLE3(sub_ea_dn);
1.1 root 3409: uint32 src = fea_all_1();
3410: uint32 data = ACC.sub_8(src, RegDX & 0xff);
3411: RegDX = (RegDX & 0xffffff00) | data;
3412: }
3413:
3414: // %1001_xxx001_mmmrrr dam+-rxwpi 034 SUB.W <ea>,Dx
3415: OP_DEF(sub_w_ea_dn)
3416: {
1.1.1.2 root 3417: CYCLE3(sub_ea_dn);
1.1 root 3418: uint32 src = fea_all_2();
3419: uint32 data = ACC.sub_16(src, RegDX & 0xffff);
3420: RegDX = (RegDX & 0xffff0000) | data;
3421: }
3422:
3423: // %1001_xxx010_mmmrrr dam+-rxwpi 034 SUB.L <ea>,Dx
3424: OP_DEF(sub_l_ea_dn)
3425: {
1.1.1.2 root 3426: CYCLE3(sub_ea_dn);
1.1 root 3427: uint32 src = fea_all_4();
3428: RegDX = ACC.sub_32(src, RegDX);
3429: }
3430:
3431: // %1001_xxx011_mmmrrr dam+-rxwpi 034 SUBA.W <ea>,Ax
3432: OP_DEF(suba_w)
3433: {
1.1.1.2 root 3434: CYCLE3(suba_w);
1.1 root 3435: uint32 src = (int32)(int16)fea_all_2();
3436: RegAX -= src;
3437: }
3438:
3439: // %1001_xxx100_mmmrrr ..m+-rxw.. 034 SUB.B Dx,<ea>
3440: // %1001_xxx100_000yyy .......... 034 SUBX.B Dy,Dx
3441: // %1001_xxx100_001yyy .......... 034 SUBX.B -(Ay),-(Ax)
3442: OP_DEF(sub_b_dn_ea)
3443: {
3444: uint n = ir & 0x3f;
3445:
3446: if (n < 8) {
3447: // SUBX.B Dy,Dx
1.1.1.2 root 3448: CYCLE3(subx_dn);
1.1 root 3449: uint32 src = RegDY & 0xff;
3450: uint32 dst = RegDX & 0xff;
3451: dst = ACC.subx_8(src, dst);
3452: RegDX = (RegDX & 0xffffff00) | dst;
3453: } else if (n < 16) {
3454: // SUBX.B -(Ay),-(Ax)
1.1.1.2 root 3455: CYCLE3(subx_an);
1.1 root 3456: save_reg_pd_if(RegIRY);
3457: save_reg_pd_if(RegIRX);
3458: uint32 srcea = internal_ea_anpd_1(RegIRY);
3459: uint32 dstea = internal_ea_anpd_1(RegIRX);
3460: uint32 src = read_1(srcea);
3461: uint32 dst = read_1(dstea);
3462: dst = ACC.subx_8(src, dst);
3463: write_1(dstea, dst);
3464: } else {
3465: // SUB.B Dx,<ea>
1.1.1.2 root 3466: CYCLE3(sub_dn_ea);
1.1 root 3467: uint32 ea = cea_data_1();
3468: uint32 data = read_1(ea);
3469: data = ACC.sub_8(RegDX & 0xff, data);
3470: write_1(ea, data);
3471: }
3472: }
3473:
3474: // %1001_xxx101_mmmrrr ..m+-rxw.. 034 SUB.W Dx,<ea>
3475: // %1001_xxx101_000yyy .......... 034 SUBX.W Dy,Dx
3476: // %1001_xxx101_001yyy .......... 034 SUBX.W -(Ay),-(Ax)
3477: OP_DEF(sub_w_dn_ea)
3478: {
3479: uint n = ir & 0x3f;
3480:
3481: if (n < 8) {
3482: // SUBX.W Dy,Dx
1.1.1.2 root 3483: CYCLE3(subx_dn);
1.1 root 3484: uint32 src = RegDY & 0xffff;
3485: uint32 dst = RegDX & 0xffff;
3486: dst = ACC.subx_16(src, dst);
3487: RegDX = (RegDX & 0xffff0000) | dst;
3488: } else if (n < 16) {
3489: // SUBX.W -(Ay),-(Ax)
1.1.1.2 root 3490: CYCLE3(subx_an);
1.1 root 3491: save_reg_pd_if(RegIRY);
3492: save_reg_pd_if(RegIRX);
3493: uint32 srcea = internal_ea_anpd_2(RegIRY);
3494: uint32 dstea = internal_ea_anpd_2(RegIRX);
3495: uint32 src = read_2(srcea);
3496: uint32 dst = read_2(dstea);
3497: dst = ACC.subx_16(src, dst);
3498: write_2(dstea, dst);
3499: } else {
3500: // SUB.W Dx,<ea>
1.1.1.2 root 3501: CYCLE3(sub_dn_ea);
1.1 root 3502: uint32 ea = cea_data_2();
3503: uint32 data = read_2(ea);
3504: data = ACC.sub_16(RegDX & 0xffff, data);
3505: write_2(ea, data);
3506: }
3507: }
3508:
3509: // %1001_xxx110_mmmrrr ..m+-rxw.. 034 SUB.L Dx,<ea>
3510: // %1001_xxx110_000yyy .......... 034 SUBX.L Dy,Dx
3511: // %1001_xxx110_001yyy .......... 034 SUBX.L -(Ay),-(Ax)
3512: OP_DEF(sub_l_dn_ea)
3513: {
3514: uint n = ir & 0x3f;
3515:
3516: if (n < 8) {
3517: // SUBX.L Dy,Dx
1.1.1.2 root 3518: CYCLE3(subx_dn);
1.1 root 3519: uint32 src = RegDY;
3520: uint32 dst = RegDX;
3521: RegDX = ACC.subx_32(src, dst);
3522: } else if (n < 16) {
3523: // SUBX.L -(Ay),-(Ax)
1.1.1.2 root 3524: CYCLE3(subx_an);
1.1 root 3525: save_reg_pd_if(RegIRY);
3526: save_reg_pd_if(RegIRX);
3527: uint32 srcea = internal_ea_anpd_4(RegIRY);
3528: uint32 dstea = internal_ea_anpd_4(RegIRX);
3529: uint32 src = read_4(srcea);
3530: uint32 dst = read_4(dstea);
3531: dst = ACC.subx_32(src, dst);
3532: write_4(dstea, dst);
3533: } else {
3534: // SUB.L Dx,<ea>
1.1.1.2 root 3535: CYCLE3(sub_dn_ea);
1.1 root 3536: uint32 ea = cea_data_4();
3537: uint32 data = read_4(ea);
3538: data = ACC.sub_32(RegDX, data);
3539: write_4(ea, data);
3540: }
3541: }
3542:
3543: // %1001_xxx111_mmmrrr dam+-rxwpi 034 SUBA.L <ea>,Ax
3544: OP_DEF(suba_l)
3545: {
1.1.1.2 root 3546: CYCLE3(suba_l);
1.1 root 3547: uint32 src = fea_all_4();
3548: RegAX -= src;
3549: }
3550:
3551: // %1010_nnnnnn_nnnnnn .......... 034 A-Line
3552: OP_DEF(aline)
3553: {
1.1.1.2 root 3554: CYCLE3(aline);
1.1 root 3555: if (aline_callback) {
3556: if (aline_callback(this, aline_arg)) {
3557: return;
3558: }
3559: }
3560: // A系列命令例外
3561: Exception(M68K::EXCEP_ALINE);
3562: }
3563:
3564: // %1011_xxx000_mmmrrr d.m+-rxwpi 034 CMP.B <ea>,Dx
3565: OP_DEF(cmp_b)
3566: {
1.1.1.2 root 3567: CYCLE3(cmp);
1.1 root 3568: uint32 src = fea_all_1();
3569: uint32 dst = RegDX & 0xff;
3570: ACC.cmp_8(src, dst);
3571: }
3572:
3573: // %1011_xxx001_mmmrrr d.m+-rxwpi 034 CMP.W <ea>,Dx
3574: OP_DEF(cmp_w)
3575: {
1.1.1.2 root 3576: CYCLE3(cmp);
1.1 root 3577: uint32 src = fea_all_2();
3578: uint32 dst = RegDX & 0xffff;
3579: ACC.cmp_16(src, dst);
3580: }
3581:
3582: // %1011_xxx010_mmmrrr d.m+-rxwpi 034 CMP.L <ea>,Dx
3583: OP_DEF(cmp_l)
3584: {
1.1.1.2 root 3585: CYCLE3(cmp);
1.1 root 3586: uint32 src = fea_all_4();
3587: ACC.cmp_32(src, RegDX);
3588: }
3589:
3590: // %1011_xxx011_mmmrrr dam+-rxwpi 034 CMPA.W <ea>,Ax
3591: OP_DEF(cmpa_w)
3592: {
1.1.1.2 root 3593: CYCLE3(cmpa);
1.1 root 3594: uint32 src = (uint32)(int32)(int16)fea_all_2();
3595: ACC.cmp_32(src, RegAX);
3596: }
3597:
3598: // %1011_xxx100_mmmrrr d.m+-rxw.. 034 EOR.B Dx,<ea>
3599: // %1011_xxx100_001yyy .......... 034 CMPM.B (Ay)+,(Ax)+
3600: OP_DEF(eor_b)
3601: {
3602: uint n = ir & 0x3f;
3603:
3604: if (n < 8) {
3605: // EOR.B Dx,Dy
1.1.1.2 root 3606: CYCLE3(eor_dn_dn);
1.1 root 3607: uint32 data = (reg.D[n] ^ RegDX) & 0xff;
3608: reg.D[n] = (reg.D[n] & 0xffffff00) | data;
3609: ACC.move_8(data);
3610: } else if (n < 16) {
3611: // CMPM.B (Ay)+,(Ax)+
1.1.1.2 root 3612: CYCLE3(cmpm);
1.1 root 3613: save_reg_pi_if(RegIRY);
3614: save_reg_pi_if(RegIRX);
3615: uint32 srcea = internal_ea_anpi_1(RegIRY);
3616: uint32 dstea = internal_ea_anpi_1(RegIRX);
3617: uint32 src = read_1(srcea);
3618: uint32 dst = read_1(dstea);
3619: ACC.cmp_8(src, dst);
3620: } else {
3621: // EOR.B Dx,<ea>
1.1.1.2 root 3622: CYCLE3(eor_dn_ea);
1.1 root 3623: uint32 ea = cea_data_1();
3624: uint32 data = read_1(ea);
3625: data ^= (RegDX & 0xff);
3626: ACC.move_8(data);
1.1.1.3 ! root 3627: write_1(ea, data);
1.1 root 3628: }
3629: }
3630:
3631: // %1011_xxx101_mmmrrr d.m+-rxw.. 034 EOR.W Dx,<ea>
3632: // %1011_xxx101_001yyy .......... 034 CMPM.W (Ay)+,(Ax)+
3633: OP_DEF(eor_w)
3634: {
3635: uint n = ir & 0x3f;
3636:
3637: if (n < 8) {
3638: // EOR.W Dx,Dy
1.1.1.2 root 3639: CYCLE3(eor_dn_dn);
1.1 root 3640: uint32 data = (reg.D[n] ^ RegDX) & 0xffff;
3641: reg.D[n] = (reg.D[n] & 0xffff0000) | data;
3642: ACC.move_16(data);
3643: } else if (n < 16) {
3644: // CMPM.W (Ay)+,(Ax)+
1.1.1.2 root 3645: CYCLE3(cmpm);
1.1 root 3646: save_reg_pi_if(RegIRY);
3647: save_reg_pi_if(RegIRX);
3648: uint32 srcea = internal_ea_anpi_2(RegIRY);
3649: uint32 dstea = internal_ea_anpi_2(RegIRX);
3650: uint32 src = read_2(srcea);
3651: uint32 dst = read_2(dstea);
3652: ACC.cmp_16(src, dst);
3653: } else {
3654: // EOR.W Dx,<ea>
1.1.1.2 root 3655: CYCLE3(eor_dn_ea);
1.1 root 3656: uint32 ea = cea_data_2();
3657: uint32 data = read_2(ea);
3658: data ^= (RegDX & 0xffff);
3659: ACC.move_16(data);
1.1.1.3 ! root 3660: write_2(ea, data);
1.1 root 3661: }
3662: }
3663:
3664: // %1011_xxx110_mmmrrr d.m+-rxw.. 034 EOR.L Dx,<ea>
3665: // %1011_xxx110_001yyy .......... 034 CMPM.L (Ay)+,(Ax)+
3666: OP_DEF(eor_l)
3667: {
3668: uint n = ir & 0x3f;
3669:
3670: if (n < 8) {
3671: // EOR.L Dx,Dy
1.1.1.2 root 3672: CYCLE3(eor_dn_dn);
1.1 root 3673: reg.D[n] ^= RegDX;
3674: ACC.move_32(reg.D[n]);
3675: } else if (n < 16) {
3676: // CMPM.L (Ay)+,(Ax)+
1.1.1.2 root 3677: CYCLE3(cmpm);
1.1 root 3678: save_reg_pi_if(RegIRY);
3679: save_reg_pi_if(RegIRX);
3680: uint32 srcea = internal_ea_anpi_4(RegIRY);
3681: uint32 dstea = internal_ea_anpi_4(RegIRX);
3682: uint32 src = read_4(srcea);
3683: uint32 dst = read_4(dstea);
3684: ACC.cmp_32(src, dst);
3685: } else {
3686: // EOR.L Dx,<ea>
1.1.1.2 root 3687: CYCLE3(eor_dn_ea);
1.1 root 3688: uint32 ea = cea_data_4();
3689: uint32 data = read_4(ea);
3690: data ^= RegDX;
3691: ACC.move_32(data);
1.1.1.3 ! root 3692: write_4(ea, data);
1.1 root 3693: }
3694: }
3695:
3696: // %1011_xxx111_mmmrrr dam+-rxwpi 034 CMPA.L <ea>,Ax
3697: OP_DEF(cmpa_l)
3698: {
1.1.1.2 root 3699: CYCLE3(cmpa);
1.1 root 3700: uint32 src = fea_all_4();
3701: ACC.cmp_32(src, RegAX);
3702: }
3703:
3704: // %1100_xxx000_mmmrrr d.m+-rxwpi 034 AND.B <ea>,Dx
3705: OP_DEF(and_b_ea_dn)
3706: {
1.1.1.2 root 3707: CYCLE3(and_ea_dn);
1.1 root 3708: uint32 src = fea_data_1();
3709: uint32 dst = (RegDX & 0x000000ff) & src;
3710: ACC.move_8(dst);
3711: RegDX = (RegDX & 0xffffff00) | dst;
3712: }
3713:
3714: // %1100_xxx001_mmmrrr d.m+-rxwpi 034 AND.W <ea>,Dx
3715: OP_DEF(and_w_ea_dn)
3716: {
1.1.1.2 root 3717: CYCLE3(and_ea_dn);
1.1 root 3718: uint32 src = fea_data_2();
3719: uint32 dst = (RegDX & 0x0000ffff) & src;
3720: ACC.move_16(dst);
3721: RegDX = (RegDX & 0xffff0000) | dst;
3722: }
3723:
3724: // %1100_xxx010_mmmrrr d.m+-rxwpi 034 AND.L <ea>,Dx
3725: OP_DEF(and_l_ea_dn)
3726: {
1.1.1.2 root 3727: CYCLE3(and_ea_dn);
1.1 root 3728: uint32 src = fea_data_4();
3729: RegDX = RegDX & src;
3730: ACC.move_32(RegDX);
3731: }
3732:
3733: // %1100_xxx011_mmmrrr d.m+-rxwpi 034 MULU.W <ea>,Dx
3734: OP_DEF(mulu_w)
3735: {
1.1.1.2 root 3736: CYCLE3(mulu_w_max);
1.1 root 3737: uint32 src = fea_data_2();
3738: uint32 dst = RegDX & 0xffff;
3739: RegDX = ACC.mulu_16(src, dst);
3740: }
3741:
3742: // %1100_xxx100_mmmrrr ..m+-rxw.. 034 AND.B Dx,<ea>
3743: // %1100_xxx100_000yyy .......... 034 ABCD.B Dy,Dx
3744: // %1100_xxx100_001yyy .......... 034 ABCD.B -(Ay),-(Ax)
3745: OP_DEF(and_b_dn_ea)
3746: {
3747: uint n = ir & 0x3f;
3748:
3749: if (n < 8) {
3750: // ABCD.B Dy,Dx
1.1.1.2 root 3751: CYCLE3(abcd_dn);
1.1 root 3752: uint32 src = RegDY & 0xff;
3753: uint32 dst = RegDX & 0xff;
3754: dst = ACC.abcd_8(src, dst);
3755: RegDX &= 0xffffff00;
3756: RegDX |= dst;
3757: return;
3758: } else if (n < 16) {
3759: // ABCD.B -(Ay),-(Ax)
1.1.1.2 root 3760: CYCLE3(abcd_an);
1.1 root 3761: save_reg_pd_if(RegIRY);
3762: save_reg_pd_if(RegIRX);
3763: uint32 srcea = internal_ea_anpd_1(RegIRY);
3764: uint32 dstea = internal_ea_anpd_1(RegIRX);
3765: uint32 src = read_1(srcea);
3766: uint32 dst = read_1(dstea);
3767: dst = ACC.abcd_8(src, dst);
3768: write_1(dstea, dst);
3769: return;
3770: } else {
3771: // AND.B Dx,<ea>
1.1.1.2 root 3772: CYCLE3(and_ea_dn);
1.1 root 3773: uint32 ea = cea_data_1();
3774: uint32 dst = read_1(ea);
3775: dst &= RegDX & 0xff;
3776: ACC.move_8(dst);
3777: write_1(ea, dst);
3778: }
3779: }
3780:
3781: // %1100_xxx101_mmmrrr ..m+-rxw.. 034 AND.W Dx,<ea>
3782: // %1100_xxx101_000yyy .......... 034 EXG.L Dx,Dy
3783: // %1100_xxx101_001yyy .......... 034 EXG.L Ax,Ay
3784: OP_DEF(and_w_dn_ea)
3785: {
3786: uint n = ir & 0x3f;
3787:
3788: if (n < 8) {
3789: // EXG.L Dx,Dy
1.1.1.2 root 3790: CYCLE3(exg);
1.1 root 3791: uint x = RegIRX;
3792: uint y = n;
3793: uint32 tmp = reg.D[x];
3794: reg.D[x] = reg.D[y];
3795: reg.D[y] = tmp;
3796: return;
3797: } else if (n < 16) {
3798: // EXG.L Ax,Ay
3799: // ここでは x は 0..7 で A(x)、y は 8..15 で R(y)
1.1.1.2 root 3800: CYCLE3(exg);
1.1 root 3801: uint x = RegIRX;
3802: uint y = n;
3803: uint32 tmp = reg.A[x];
3804: reg.A[x] = reg.R[y];
3805: reg.R[y] = tmp;
3806: return;
3807: } else {
3808: // AND.W Dx,<ea>
1.1.1.2 root 3809: CYCLE3(and_dn_ea);
1.1 root 3810: uint32 ea = cea_data_2();
3811: uint32 dst = read_2(ea);
3812: dst &= RegDX & 0xffff;
3813: ACC.move_16(dst);
3814: write_2(ea, dst);
3815: }
3816: }
3817:
3818: // %1100_xxx110_mmmrrr ..m+-rxw.. 034 AND.L Dx,<ea>
3819: // %1100_xxx110_001yyy .......... 034 EXG.L Dx,Ay
3820: OP_DEF(and_l_dn_ea)
3821: {
3822: uint n = ir & 0x3f;
3823:
3824: if (n < 8) {
3825: op_illegal();
3826: return;
3827: } else if (n < 16) {
3828: // EXG.L Dx,Ay
3829: // ここでは x は 0..7 で D(x)、y は 8..15 で R(y)
1.1.1.2 root 3830: CYCLE3(exg);
1.1 root 3831: uint x = RegIRX;
3832: uint y = n;
3833: uint32 tmp = reg.D[x];
3834: reg.D[x] = reg.R[y];
3835: reg.R[y] = tmp;
3836: return;
3837: } else {
3838: // AND.L Dx,<ea>
1.1.1.2 root 3839: CYCLE3(and_dn_ea);
1.1 root 3840: uint32 ea = cea_data_4();
3841: uint32 dst = read_4(ea);
3842: dst &= RegDX;
3843: ACC.move_32(dst);
3844: write_4(ea, dst);
3845: }
3846: }
3847:
3848: // %1100_xxx111_mmmrrr d.m+-rxwpi 034 MULS.W <ea>,Dx
3849: OP_DEF(muls_w)
3850: {
1.1.1.2 root 3851: CYCLE3(muls_w_max);
1.1 root 3852: uint32 src = fea_data_2();
3853: uint32 dst = RegDX & 0xffff;
3854: RegDX = ACC.muls_16(src, dst);
3855: }
3856:
3857: // %1101_xxx000_mmmrrr dam+-rxwpi 034 ADD.B <ea>,Dx
3858: OP_DEF(add_b_ea_dn)
3859: {
1.1.1.2 root 3860: CYCLE3(add_ea_dn);
1.1 root 3861: uint32 src = fea_all_1();
3862: uint32 data = ACC.add_8(src, RegDX & 0xff);
3863: RegDX = (RegDX & 0xffffff00) | data;
3864: }
3865:
3866: // %1101_xxx001_mmmrrr dam+-rxwpi 034 ADD.W <ea>,Dx
3867: OP_DEF(add_w_ea_dn)
3868: {
1.1.1.2 root 3869: CYCLE3(add_ea_dn);
1.1 root 3870: uint32 src = fea_all_2();
3871: uint32 data = ACC.add_16(src, RegDX & 0xffff);
3872: RegDX = (RegDX & 0xffff0000) | data;
3873: }
3874:
3875: // %1101_xxx010_mmmrrr dam+-rxwpi 034 ADD.L <ea>,Dx
3876: OP_DEF(add_l_ea_dn)
3877: {
1.1.1.2 root 3878: CYCLE3(add_ea_dn);
1.1 root 3879: uint32 src = fea_all_4();
3880: RegDX = ACC.add_32(src, RegDX);
3881: }
3882:
3883: // %1101_xxx011_mmmrrr dam+-rxwpi 034 ADDA.W <ea>,Ax
3884: OP_DEF(adda_w)
3885: {
1.1.1.2 root 3886: CYCLE3(adda_w);
1.1 root 3887: uint32 src = (int32)(int16)fea_all_2();
3888: RegAX += src;
3889: }
3890:
3891: // %1101_xxx100_mmmrrr ..m+-rxw.. 034 ADD.B Dx,<ea>
3892: // %1101_xxx100_000yyy .......... 034 ADDX.B Dy,Dx
3893: // %1101_xxx100_001yyy .......... 034 ADDX.B -(Ay),-(Ax)
3894: OP_DEF(add_b_dn_ea)
3895: {
3896: uint n = ir & 0x3f;
3897:
3898: if (n < 8) {
3899: // ADDX.B Dy,Dx
1.1.1.2 root 3900: CYCLE3(addx_dn);
1.1 root 3901: uint32 src = RegDY & 0xff;
3902: uint32 dst = RegDX & 0xff;
3903: dst = ACC.addx_8(src, dst);
3904: RegDX = (RegDX & 0xffffff00) | dst;
3905: } else if (n < 16) {
3906: // ADDX.B -(Ay),-(Ax)
1.1.1.2 root 3907: CYCLE3(addx_an);
1.1 root 3908: save_reg_pd_if(RegIRY);
3909: save_reg_pd_if(RegIRX);
3910: uint32 srcea = internal_ea_anpd_1(RegIRY);
3911: uint32 dstea = internal_ea_anpd_1(RegIRX);
3912: uint32 src = read_1(srcea);
3913: uint32 dst = read_1(dstea);
3914: dst = ACC.addx_8(src, dst);
3915: write_1(dstea, dst);
3916: } else {
3917: // ADD.B Dx,<ea>
1.1.1.2 root 3918: CYCLE3(add_dn_ea);
1.1 root 3919: uint32 ea = cea_data_1();
3920: uint32 data = read_1(ea);
3921: data = ACC.add_8(RegDX & 0xff, data);
3922: write_1(ea, data);
3923: }
3924: }
3925:
3926: // %1101_xxx101_mmmrrr ..m+-rxw.. 034 ADD.W Dx,<ea>
3927: // %1101_xxx101_000yyy .......... 034 ADDX.W Dy,Dx
3928: // %1101_xxx101_001yyy .......... 034 ADDX.W -(Ay),-(Ax)
3929: OP_DEF(add_w_dn_ea)
3930: {
3931: uint n = ir & 0x3f;
3932:
3933: if (n < 8) {
3934: // ADDX.W Dy,Dx
1.1.1.2 root 3935: CYCLE3(addx_dn);
1.1 root 3936: uint32 src = RegDY & 0xffff;
3937: uint32 dst = RegDX & 0xffff;
3938: dst = ACC.addx_16(src, dst);
3939: RegDX = (RegDX & 0xffff0000) | dst;
3940: } else if (n < 16) {
3941: // ADDX.W -(Ay),-(Ax)
1.1.1.2 root 3942: CYCLE3(addx_an);
1.1 root 3943: save_reg_pd_if(RegIRY);
3944: save_reg_pd_if(RegIRX);
3945: uint32 srcea = internal_ea_anpd_2(RegIRY);
3946: uint32 dstea = internal_ea_anpd_2(RegIRX);
3947: uint32 src = read_2(srcea);
3948: uint32 dst = read_2(dstea);
3949: dst = ACC.addx_16(src, dst);
3950: write_2(dstea, dst);
3951: } else {
3952: // ADD.W Dx,<ea>
1.1.1.2 root 3953: CYCLE3(add_dn_ea);
1.1 root 3954: uint32 ea = cea_data_2();
3955: uint32 data = read_2(ea);
3956: data = ACC.add_16(RegDX & 0xffff, data);
3957: write_2(ea, data);
3958: }
3959: }
3960:
3961: // %1101_xxx110_mmmrrr ..m+-rxw.. 034 ADD.L Dx,<ea>
3962: // %1101_xxx110_000yyy .......... 034 ADDX.L Dy,Dx
3963: // %1101_xxx110_001yyy .......... 034 ADDX.L -(Ay),-(Ax)
3964: OP_DEF(add_l_dn_ea)
3965: {
3966: uint n = ir & 0x3f;
3967:
3968: if (n < 8) {
3969: // ADDX.L Dy,Dx
1.1.1.2 root 3970: CYCLE3(addx_dn);
1.1 root 3971: uint32 src = RegDY;
3972: uint32 dst = RegDX;
3973: RegDX = ACC.addx_32(src, dst);
3974: } else if (n < 16) {
3975: // ADDX.L -(Ay),-(Ax)
1.1.1.2 root 3976: CYCLE3(addx_an);
1.1 root 3977: save_reg_pd_if(RegIRY);
3978: save_reg_pd_if(RegIRX);
3979: uint32 srcea = internal_ea_anpd_4(RegIRY);
3980: uint32 dstea = internal_ea_anpd_4(RegIRX);
3981: uint32 src = read_4(srcea);
3982: uint32 dst = read_4(dstea);
3983: dst = ACC.addx_32(src, dst);
3984: write_4(dstea, dst);
3985: } else {
3986: // ADD.L Dx,<ea>
1.1.1.2 root 3987: CYCLE3(add_dn_ea);
1.1 root 3988: uint32 ea = cea_data_4();
3989: uint32 data = read_4(ea);
3990: data = ACC.add_32(RegDX, data);
3991: write_4(ea, data);
3992: }
3993: }
3994:
3995: // %1101_xxx111_mmmrrr dam+-rxwpi 034 ADDA.L <ea>,Ax
3996: OP_DEF(adda_l)
3997: {
1.1.1.2 root 3998: CYCLE3(adda_l);
1.1 root 3999: uint32 src = fea_all_4();
4000: RegAX += src;
4001: }
4002:
4003: // %1110_qqq000_000yyy .......... 034 ASR.B #qqq,Dy
4004: // %1110_qqq000_001yyy .......... 034 LSR.B #qqq,Dy
4005: // %1110_qqq000_010yyy .......... 034 ROXR.B #qqq,Dy
4006: // %1110_qqq000_011yyy .......... 034 ROR.B #qqq,Dy
4007: // %1110_xxx000_100yyy .......... 034 ASR.B Dx,Dy
4008: // %1110_xxx000_101yyy .......... 034 LSR.B Dx,Dy
4009: // %1110_xxx000_110yyy .......... 034 ROXR.B Dx,Dy
4010: // %1110_xxx000_111yyy .......... 034 ROR.B Dx,Dy
4011: OP_DEF(asr_b_imm)
4012: {
4013: int count;
4014: uint32 data;
4015: switch (eamode(ir)) {
4016: case 0: // ASR.B #qqq,Dy
1.1.1.2 root 4017: CYCLE3(asr_imm_dn);
1.1 root 4018: count = RegIRX;
4019: count = (count == 0) ? 8 : count;
4020: __assume(1 <= count && count <= 8);
4021: data = ACC.asr_8(RegDY & 0xff, count);
4022: RegDY = (RegDY & 0xffffff00) | data;
4023: return;
4024: case 1: // LSR.B #qqq,Dy
1.1.1.2 root 4025: CYCLE3(lsd_imm_dn);
1.1 root 4026: count = RegIRX;
4027: count = (count == 0) ? 8 : count;
4028: __assume(1 <= count && count <= 8);
4029: data = ACC.lsr_8(RegDY & 0xff, count);
4030: RegDY = (RegDY & 0xffffff00) | data;
4031: return;
4032: case 2: // ROXR.B #qqq,Dy
1.1.1.2 root 4033: CYCLE3(roxd_dn);
1.1 root 4034: count = RegIRX;
4035: count = (count == 0) ? 8 : count;
4036: __assume(1 <= count && count <= 8);
4037: data = ACC.roxr_8(RegDY & 0xff, count);
4038: RegDY = (RegDY & 0xffffff00) | data;
4039: return;
4040: case 3: // ROR.B #qqq,Dy
1.1.1.2 root 4041: CYCLE3(rod_imm_dn);
1.1 root 4042: count = RegIRX;
4043: count = (count == 0) ? 8 : count;
4044: __assume(1 <= count && count <= 8);
4045: data = ACC.ror_8(RegDY & 0xff, count);
4046: RegDY = (RegDY & 0xffffff00) | data;
4047: return;
4048: case 4: // ASR.B Dx,Dy
4049: count = RegDX & 63;
4050: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4051: if (count <= 8) {
4052: CYCLE3(asr_dn_dn_less);
4053: } else {
4054: CYCLE3(asr_dn_dn_over);
4055: }
1.1 root 4056: __assume(0 <= count && count < 64);
4057: data = ACC.asr_8(RegDY & 0xff, count);
4058: RegDY = (RegDY & 0xffffff00) | data;
4059: return;
4060: case 5: // LSR.B Dx,Dy
4061: count = RegDX & 63;
4062: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4063: if (count <= 8) {
4064: CYCLE3(lsd_dn_dn_less);
4065: } else {
4066: CYCLE3(lsd_dn_dn_over);
4067: }
1.1 root 4068: __assume(0 <= count && count < 64);
4069: data = ACC.lsr_8(RegDY & 0xff, count);
4070: RegDY = (RegDY & 0xffffff00) | data;
4071: return;
4072: case 6: // ROXR.B Dx,Dy
1.1.1.2 root 4073: CYCLE3(roxd_dn);
1.1 root 4074: count = RegDX & 63;
4075: __assume(0 <= count && count < 64);
4076: data = ACC.roxr_8(RegDY & 0xff, count);
4077: RegDY = (RegDY & 0xffffff00) | data;
4078: return;
4079: case 7: // ROR.B Dx,Dy
1.1.1.2 root 4080: CYCLE3(rod_dn_dn);
1.1 root 4081: count = RegDX & 63;
4082: __assume(0 <= count && count < 64);
4083: data = ACC.ror_8(RegDY & 0xff, count);
4084: RegDY = (RegDY & 0xffffff00) | data;
4085: return;
4086: }
4087: }
4088:
4089: // %1110_qqq001_000yyy .......... 034 ASR.W #qqq,Dy
4090: // %1110_qqq001_001yyy .......... 034 LSR.W #qqq,Dy
4091: // %1110_qqq001_010yyy .......... 034 ROXR.W #qqq,Dy
4092: // %1110_qqq001_011yyy .......... 034 ROR.W #qqq,Dy
4093: // %1110_xxx001_100yyy .......... 034 ASR.W Dx,Dy
4094: // %1110_xxx001_101yyy .......... 034 LSR.W Dx,Dy
4095: // %1110_xxx001_110yyy .......... 034 ROXR.W Dx,Dy
4096: // %1110_xxx001_111yyy .......... 034 ROR.W Dx,Dy
4097: OP_DEF(asr_w_imm)
4098: {
4099: int count;
4100: uint32 data;
4101: switch (eamode(ir)) {
4102: case 0: // ASR.W #qqq,Dy
1.1.1.2 root 4103: CYCLE3(asr_imm_dn);
1.1 root 4104: count = RegIRX;
4105: count = (count == 0) ? 8 : count;
4106: __assume(1 <= count && count <= 8);
4107: data = ACC.asr_16(RegDY & 0xffff, count);
4108: RegDY = (RegDY & 0xffff0000) | data;
4109: return;
4110: case 1: // LSR.W #qqq,Dy
1.1.1.2 root 4111: CYCLE3(lsd_imm_dn);
1.1 root 4112: count = RegIRX;
4113: count = (count == 0) ? 8 : count;
4114: __assume(1 <= count && count <= 8);
4115: data = ACC.lsr_16(RegDY & 0xffff, count);
4116: RegDY = (RegDY & 0xffff0000) | data;
4117: return;
4118: case 2: // ROXR.W #qqq,Dy
1.1.1.2 root 4119: CYCLE3(roxd_dn);
1.1 root 4120: count = RegIRX;
4121: count = (count == 0) ? 8 : count;
4122: __assume(1 <= count && count <= 8);
4123: data = ACC.roxr_16(RegDY & 0xffff, count);
4124: RegDY = (RegDY & 0xffff0000) | data;
4125: return;
4126: case 3: // ROR.W #qqq,Dy
1.1.1.2 root 4127: CYCLE3(rod_imm_dn);
1.1 root 4128: count = RegIRX;
4129: count = (count == 0) ? 8 : count;
4130: __assume(1 <= count && count <= 8);
4131: data = ACC.ror_16(RegDY & 0xffff, count);
4132: RegDY = (RegDY & 0xffff0000) | data;
4133: return;
4134: case 4: // ASR.W Dx,Dy
4135: count = RegDX & 63;
4136: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4137: if (count <= 16) {
4138: CYCLE3(asr_dn_dn_less);
4139: } else {
4140: CYCLE3(asr_dn_dn_over);
4141: }
1.1 root 4142: __assume(0 <= count && count < 64);
4143: data = ACC.asr_16(RegDY & 0xffff, count);
4144: RegDY = (RegDY & 0xffff0000) | data;
4145: return;
4146: case 5: // LSR.W Dx,Dy
4147: count = RegDX & 63;
4148: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4149: if (count <= 16) {
4150: CYCLE3(lsd_dn_dn_less);
4151: } else {
4152: CYCLE3(lsd_dn_dn_over);
4153: }
1.1 root 4154: __assume(0 <= count && count < 64);
4155: data = ACC.lsr_16(RegDY & 0xffff, count);
4156: RegDY = (RegDY & 0xffff0000) | data;
4157: return;
4158: case 6: // ROXR.W Dx,Dy
1.1.1.2 root 4159: CYCLE3(roxd_dn);
1.1 root 4160: count = RegDX & 63;
4161: __assume(0 <= count && count < 64);
4162: data = ACC.roxr_16(RegDY & 0xffff, count);
4163: RegDY = (RegDY & 0xffff0000) | data;
4164: return;
4165: case 7: // ROR.W Dx,Dy
1.1.1.2 root 4166: CYCLE3(rod_dn_dn);
1.1 root 4167: count = RegDX & 63;
4168: __assume(0 <= count && count < 64);
4169: data = ACC.ror_16(RegDY & 0xffff, count);
4170: RegDY = (RegDY & 0xffff0000) | data;
4171: return;
4172: }
4173: }
4174:
4175: // %1110_qqq010_000yyy .......... 034 ASR.L #qqq,Dy
4176: // %1110_qqq010_001yyy .......... 034 LSR.L #qqq,Dy
4177: // %1110_qqq010_010yyy .......... 034 ROXR.L #qqq,Dy
4178: // %1110_qqq010_011yyy .......... 034 ROR.L #qqq,Dy
4179: // %1110_xxx010_100yyy .......... 034 ASR.L Dx,Dy
4180: // %1110_xxx010_101yyy .......... 034 LSR.L Dx,Dy
4181: // %1110_xxx010_110yyy .......... 034 ROXR.L Dx,Dy
4182: // %1110_xxx010_111yyy .......... 034 ROR.L Dx,Dy
4183: OP_DEF(asr_l_imm)
4184: {
4185: int count;
4186: switch (eamode(ir)) {
4187: case 0: // ASR.L #qqq,Dy
1.1.1.2 root 4188: CYCLE3(asr_imm_dn);
1.1 root 4189: count = RegIRX;
4190: count = (count == 0) ? 8 : count;
4191: __assume(1 <= count && count <= 8);
4192: RegDY = ACC.asr_32(RegDY, count);
4193: return;
4194: case 1: // LSR.L #qqq,Dy
1.1.1.2 root 4195: CYCLE3(lsd_imm_dn);
1.1 root 4196: count = RegIRX;
4197: count = (count == 0) ? 8 : count;
4198: __assume(1 <= count && count <= 8);
4199: RegDY = ACC.lsr_32(RegDY, count);
4200: return;
4201: case 2: // ROXR.L #qqq,Dy
1.1.1.2 root 4202: CYCLE3(roxd_dn);
1.1 root 4203: count = RegIRX;
4204: count = (count == 0) ? 8 : count;
4205: __assume(1 <= count && count <= 8);
4206: RegDY = ACC.roxr_32(RegDY, count);
4207: return;
4208: case 3: // ROR.L #qqq,Dy
1.1.1.2 root 4209: CYCLE3(rod_imm_dn);
1.1 root 4210: count = RegIRX;
4211: count = (count == 0) ? 8 : count;
4212: __assume(1 <= count && count <= 8);
4213: RegDY = ACC.ror_32(RegDY, count);
4214: return;
4215: case 4: // ASR.L Dx,Dy
4216: count = RegDX & 63;
4217: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4218: if (count <= 32) {
4219: CYCLE3(asr_dn_dn_less);
4220: } else {
4221: CYCLE3(asr_dn_dn_over);
4222: }
1.1 root 4223: __assume(0 <= count && count < 64);
4224: RegDY = ACC.asr_32(RegDY, count);
4225: return;
4226: case 5: // LSR.L Dx,Dy
4227: count = RegDX & 63;
4228: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4229: if (count <= 32) {
4230: CYCLE3(lsd_dn_dn_less);
4231: } else {
4232: CYCLE3(lsd_dn_dn_over);
4233: }
1.1 root 4234: __assume(0 <= count && count < 64);
4235: RegDY = ACC.lsr_32(RegDY, count);
4236: return;
4237: case 6: // ROXR.L Dx,Dy
1.1.1.2 root 4238: CYCLE3(roxd_dn);
1.1 root 4239: count = RegDX & 63;
4240: __assume(0 <= count && count < 64);
4241: RegDY = ACC.roxr_32(RegDY, count);
4242: return;
4243: case 7: // ROR.L Dx,Dy
1.1.1.2 root 4244: CYCLE3(rod_dn_dn);
1.1 root 4245: count = RegDX & 63;
4246: __assume(0 <= count && count < 64);
4247: RegDY = ACC.ror_32(RegDY, count);
4248: return;
4249: }
4250: }
4251:
4252: // %1110_000011_mmmrrr ..m+-rxw.. 034 ASR.W <ea>
4253: OP_DEF(asr_w)
4254: {
1.1.1.2 root 4255: CYCLE3(asr_w);
1.1 root 4256: uint32 ea = cea_data_2();
4257: uint32 data = read_2(ea);
4258: data = ACC.asr_16(data, 1);
4259: write_2(ea, data);
4260: }
4261:
4262: // %1110_qqq100_000yyy .......... 034 ASL.B #qqq,Dy
4263: // %1110_qqq100_001yyy .......... 034 LSL.B #qqq,Dy
4264: // %1110_qqq100_010yyy .......... 034 ROXL.B #qqq,Dy
4265: // %1110_qqq100_011yyy .......... 034 ROL.B #qqq,Dy
4266: // %1110_xxx100_100yyy .......... 034 ASL.B Dx,Dy
4267: // %1110_xxx100_101yyy .......... 034 LSL.B Dx,Dy
4268: // %1110_xxx100_110yyy .......... 034 ROXL.B Dx,Dy
4269: // %1110_xxx100_111yyy .......... 034 ROL.B Dx,Dy
4270: OP_DEF(asl_b_imm)
4271: {
4272: int count;
4273: uint32 data;
4274: switch (eamode(ir)) {
4275: case 0: // ASL.B #qqq,Dy
1.1.1.2 root 4276: CYCLE3(asl_imm_dn);
1.1 root 4277: count = RegIRX;
4278: count = (count == 0) ? 8 : count;
4279: __assume(1 <= count && count <= 8);
4280: data = ACC.asl_8(RegDY & 0xff, count);
4281: RegDY = (RegDY & 0xffffff00) | data;
4282: return;
4283: case 1: // LSL.B #qqq,Dy
1.1.1.2 root 4284: CYCLE3(lsd_imm_dn);
1.1 root 4285: count = RegIRX;
4286: count = (count == 0) ? 8 : count;
4287: __assume(1 <= count && count <= 8);
4288: data = ACC.lsl_8(RegDY & 0xff, count);
4289: RegDY = (RegDY & 0xffffff00) | data;
4290: return;
4291: case 2: // ROXL.B #qqq,Dy
1.1.1.2 root 4292: CYCLE3(roxd_dn);
1.1 root 4293: count = RegIRX;
4294: count = (count == 0) ? 8 : count;
4295: __assume(1 <= count && count <= 8);
4296: data = ACC.roxl_8(RegDY & 0xff, count);
4297: RegDY = (RegDY & 0xffffff00) | data;
4298: return;
4299: case 3: // ROL.B #qqq,Dy
1.1.1.2 root 4300: CYCLE3(rod_imm_dn);
1.1 root 4301: count = RegIRX;
4302: count = (count == 0) ? 8 : count;
4303: __assume(1 <= count && count <= 8);
4304: data = ACC.rol_8(RegDY & 0xff, count);
4305: RegDY = (RegDY & 0xffffff00) | data;
4306: return;
4307: case 4: // ASL.B Dx,Dy
1.1.1.2 root 4308: CYCLE3(asl_dn_dn);
1.1 root 4309: count = RegDX & 63;
4310: __assume(0 <= count && count < 64);
4311: data = ACC.asl_8(RegDY & 0xff, count);
4312: RegDY = (RegDY & 0xffffff00) | data;
4313: return;
4314: case 5: // LSL.B Dx,Dy
4315: count = RegDX & 63;
4316: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4317: if (count <= 8) {
4318: CYCLE3(lsd_dn_dn_less);
4319: } else {
4320: CYCLE3(lsd_dn_dn_over);
4321: }
1.1 root 4322: __assume(0 <= count && count < 64);
4323: data = ACC.lsl_8(RegDY & 0xff, count);
4324: RegDY = (RegDY & 0xffffff00) | data;
4325: return;
4326: case 6: // ROXL.B Dx,Dy
1.1.1.2 root 4327: CYCLE3(roxd_dn);
1.1 root 4328: count = RegDX & 63;
4329: __assume(0 <= count && count < 64);
4330: data = ACC.roxl_8(RegDY & 0xff, count);
4331: RegDY = (RegDY & 0xffffff00) | data;
4332: return;
4333: case 7: // ROL.B Dx,Dy
1.1.1.2 root 4334: CYCLE3(rod_dn_dn);
1.1 root 4335: count = RegDX & 63;
4336: __assume(0 <= count && count < 64);
4337: data = ACC.rol_8(RegDY & 0xff, count);
4338: RegDY = (RegDY & 0xffffff00) | data;
4339: return;
4340: }
4341: }
4342:
4343: // %1110_qqq101_000yyy .......... 034 ASL.W #qqq,Dy
4344: // %1110_qqq101_001yyy .......... 034 LSL.W #qqq,Dy
4345: // %1110_qqq101_010yyy .......... 034 ROXL.W #qqq,Dy
4346: // %1110_qqq101_011yyy .......... 034 ROL.W #qqq,Dy
4347: // %1110_xxx101_100yyy .......... 034 ASL.W Dx,Dy
4348: // %1110_xxx101_101yyy .......... 034 LSL.W Dx,Dy
4349: // %1110_xxx101_110yyy .......... 034 ROXL.W Dx,Dy
4350: // %1110_xxx101_111yyy .......... 034 ROL.W Dx,Dy
4351: OP_DEF(asl_w_imm)
4352: {
4353: int count;
4354: uint32 data;
4355: switch (eamode(ir)) {
4356: case 0: // ASL.W #qqq,Dy
1.1.1.2 root 4357: CYCLE3(asl_imm_dn);
1.1 root 4358: count = RegIRX;
4359: count = (count == 0) ? 8 : count;
4360: __assume(1 <= count && count <= 8);
4361: data = ACC.asl_16(RegDY & 0xffff, count);
4362: RegDY = (RegDY & 0xffff0000) | data;
4363: return;
4364: case 1: // LSL.W #qqq,Dy
1.1.1.2 root 4365: CYCLE3(lsd_imm_dn);
1.1 root 4366: count = RegIRX;
4367: count = (count == 0) ? 8 : count;
4368: __assume(1 <= count && count <= 8);
4369: data = ACC.lsl_16(RegDY & 0xffff, count);
4370: RegDY = (RegDY & 0xffff0000) | data;
4371: return;
4372: case 2: // ROXL.W #qqq,Dy
1.1.1.2 root 4373: CYCLE3(roxd_dn);
1.1 root 4374: count = RegIRX;
4375: count = (count == 0) ? 8 : count;
4376: __assume(1 <= count && count <= 8);
4377: data = ACC.roxl_16(RegDY & 0xffff, count);
4378: RegDY = (RegDY & 0xffff0000) | data;
4379: return;
4380: case 3: // ROL.W #qqq,Dy
1.1.1.2 root 4381: CYCLE3(rod_imm_dn);
1.1 root 4382: count = RegIRX;
4383: count = (count == 0) ? 8 : count;
4384: __assume(1 <= count && count <= 8);
4385: data = ACC.rol_16(RegDY & 0xffff, count);
4386: RegDY = (RegDY & 0xffff0000) | data;
4387: return;
4388: case 4: // ASL.W Dx,Dy
1.1.1.2 root 4389: CYCLE3(asl_dn_dn);
1.1 root 4390: count = RegDX & 63;
4391: __assume(0 <= count && count < 64);
4392: data = ACC.asl_16(RegDY & 0xffff, count);
4393: RegDY = (RegDY & 0xffff0000) | data;
4394: return;
4395: case 5: // LSL.W Dx,Dy
4396: count = RegDX & 63;
4397: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4398: if (count <= 16) {
4399: CYCLE3(lsd_dn_dn_less);
4400: } else {
4401: CYCLE3(lsd_dn_dn_over);
4402: }
1.1 root 4403: __assume(0 <= count && count < 64);
4404: data = ACC.lsl_16(RegDY & 0xffff, count);
4405: RegDY = (RegDY & 0xffff0000) | data;
4406: return;
4407: case 6: // ROXL.W Dx,Dy
1.1.1.2 root 4408: CYCLE3(roxd_dn);
1.1 root 4409: count = RegDX & 63;
4410: __assume(0 <= count && count < 64);
4411: data = ACC.roxl_16(RegDY & 0xffff, count);
4412: RegDY = (RegDY & 0xffff0000) | data;
4413: return;
4414: case 7: // ROL.W Dx,Dy
1.1.1.2 root 4415: CYCLE3(rod_dn_dn);
1.1 root 4416: count = RegDX & 63;
4417: __assume(0 <= count && count < 64);
4418: data = ACC.rol_16(RegDY & 0xffff, count);
4419: RegDY = (RegDY & 0xffff0000) | data;
4420: return;
4421: }
4422: }
4423:
4424: // %1110_qqq110_000yyy .......... 034 ASL.L #qqq,Dy
4425: // %1110_qqq110_001yyy .......... 034 LSL.L #qqq,Dy
4426: // %1110_qqq110_010yyy .......... 034 ROXL.L #qqq,Dy
4427: // %1110_qqq110_011yyy .......... 034 ROL.L #qqq,Dy
4428: // %1110_xxx110_100yyy .......... 034 ASL.L Dx,Dy
4429: // %1110_xxx110_101yyy .......... 034 LSL.L Dx,Dy
4430: // %1110_xxx110_110yyy .......... 034 ROXL.L Dx,Dy
4431: // %1110_xxx110_111yyy .......... 034 ROL.L Dx,Dy
4432: OP_DEF(asl_l_imm)
4433: {
4434: int count;
4435: switch (eamode(ir)) {
4436: case 0: // ASL.L #qqq,Dy
1.1.1.2 root 4437: CYCLE3(asl_imm_dn);
1.1 root 4438: count = RegIRX;
4439: count = (count == 0) ? 8 : count;
4440: __assume(1 <= count && count <= 8);
4441: RegDY = ACC.asl_32(RegDY, count);
4442: return;
4443: case 1: // LSL.L #qqq,Dy
1.1.1.2 root 4444: CYCLE3(lsd_imm_dn);
1.1 root 4445: count = RegIRX;
4446: count = (count == 0) ? 8 : count;
4447: __assume(1 <= count && count <= 8);
4448: RegDY = ACC.lsl_32(RegDY, count);
4449: return;
4450: case 2: // ROXL.L #qqq,Dy
1.1.1.2 root 4451: CYCLE3(roxd_dn);
1.1 root 4452: count = RegIRX;
4453: count = (count == 0) ? 8 : count;
4454: __assume(1 <= count && count <= 8);
4455: RegDY = ACC.roxl_32(RegDY, count);
4456: return;
4457: case 3: // ROL.L #qqq,Dy
1.1.1.2 root 4458: CYCLE3(rod_imm_dn);
1.1 root 4459: count = RegIRX;
4460: count = (count == 0) ? 8 : count;
4461: __assume(1 <= count && count <= 8);
4462: RegDY = ACC.rol_32(RegDY, count);
4463: return;
4464: case 4: // ASL.L Dx,Dy
1.1.1.2 root 4465: CYCLE3(asl_dn_dn);
1.1 root 4466: count = RegDX & 63;
4467: __assume(0 <= count && count < 64);
4468: RegDY = ACC.asl_32(RegDY, count);
4469: return;
4470: case 5: // LSL.L Dx,Dy
4471: count = RegDX & 63;
4472: // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2 root 4473: if (count <= 32) {
4474: CYCLE3(lsd_dn_dn_less);
4475: } else {
4476: CYCLE3(lsd_dn_dn_over);
4477: }
1.1 root 4478: __assume(0 <= count && count < 64);
4479: RegDY = ACC.lsl_32(RegDY, count);
4480: return;
4481: case 6: // ROXL.L Dx,Dy
1.1.1.2 root 4482: CYCLE3(roxd_dn);
1.1 root 4483: count = RegDX & 63;
4484: __assume(0 <= count && count < 64);
4485: RegDY = ACC.roxl_32(RegDY, count);
4486: return;
4487: case 7: // ROL.L Dx,Dy
1.1.1.2 root 4488: CYCLE3(rod_dn_dn);
1.1 root 4489: count = RegDX & 63;
4490: __assume(0 <= count && count < 64);
4491: RegDY = ACC.rol_32(RegDY, count);
4492: return;
4493: }
4494: }
4495:
4496: // %1110_000111_mmmrrr ..m+-rxw.. 034 ASL.W <ea>
4497: OP_DEF(asl_w)
4498: {
1.1.1.2 root 4499: CYCLE3(asl_w);
1.1 root 4500: uint32 ea = cea_data_2();
4501: uint32 data = read_2(ea);
4502: data = ACC.asl_16(data, 1);
4503: write_2(ea, data);
4504: }
4505:
4506: // %1110_001011_mmmrrr ..m+-rxw.. 034 LSR.W <ea>
4507: OP_DEF(lsr_w)
4508: {
1.1.1.2 root 4509: CYCLE3(lsd_w);
1.1 root 4510: uint32 ea = cea_data_2();
4511: uint32 data = read_2(ea);
4512: data = ACC.lsr_16(data, 1);
4513: write_2(ea, data);
4514: }
4515:
4516: // %1110_001111_mmmrrr ..m+-rxw.. 034 LSL.W <ea>
4517: OP_DEF(lsl_w)
4518: {
1.1.1.2 root 4519: CYCLE3(lsd_w);
1.1 root 4520: uint32 ea = cea_data_2();
4521: uint32 data = read_2(ea);
4522: data = ACC.lsl_16(data, 1);
4523: write_2(ea, data);
4524: }
4525:
4526: // %1110_010011_mmmrrr ..m+-rxw.. 034 ROXR.W <ea>
4527: OP_DEF(roxr_w)
4528: {
1.1.1.2 root 4529: CYCLE3(roxd_w);
1.1 root 4530: uint32 ea = cea_data_2();
4531: uint32 data = read_2(ea);
4532: data = ACC.roxr_16(data, 1);
4533: write_2(ea, data);
4534: }
4535:
4536: // %1110_010111_mmmrrr ..m+-rxw.. 034 ROXL.W <ea>
4537: OP_DEF(roxl_w)
4538: {
1.1.1.2 root 4539: CYCLE3(roxd_w);
1.1 root 4540: uint32 ea = cea_data_2();
4541: uint32 data = read_2(ea);
4542: data = ACC.roxl_16(data, 1);
4543: write_2(ea, data);
4544: }
4545:
4546: // %1110_011011_mmmrrr ..m+-rxw.. 034 ROR.W <ea>
4547: OP_DEF(ror_w)
4548: {
1.1.1.2 root 4549: CYCLE3(rod_w);
1.1 root 4550: uint32 ea = cea_data_2();
4551: uint32 data = read_2(ea);
4552: data = ACC.ror_16(data, 1);
4553: write_2(ea, data);
4554: }
4555:
4556: // %1110_011111_mmmrrr ..m+-rxw.. 034 ROL.W <ea>
4557: OP_DEF(rol_w)
4558: {
1.1.1.2 root 4559: CYCLE3(rod_w);
1.1 root 4560: uint32 ea = cea_data_2();
4561: uint32 data = read_2(ea);
4562: data = ACC.rol_16(data, 1);
4563: write_2(ea, data);
4564: }
4565:
4566: // %1110_100011_mmmrrr d.m..rxwp. -34 BFTST <ea>{#o:#w}
4567: OP_DEF(bftst)
4568: {
4569: uint n = ir & 0x3f;
4570: ir2 = fetch_2();
4571:
4572: acc_bf bf(this);
4573: if (n < 8) {
4574: // BFTST Dn{#o:#w}
1.1.1.2 root 4575: CYCLE3(bftst_dn);
1.1 root 4576: bf.LoadReg(n);
4577: } else {
4578: // BFTST <ea>{#o:#w}
4579: uint32 ea = cea_ctrl();
1.1.1.2 root 4580: if (__predict_true(bf.LoadMem(ea))) {
4581: CYCLE3(bftst_ea_less);
4582: } else {
4583: CYCLE3(bftst_ea_over);
4584: }
1.1 root 4585: }
4586: ACC.move_32(bf.data);
4587: }
4588:
4589: // %1110_100111_mmmrrr d.m..rxwp. -34 BFEXTU <ea>{#o:#w},Dn
4590: OP_DEF(bfextu)
4591: {
4592: uint n = ir & 0x3f;
4593: ir2 = fetch_2();
4594: uint dn = ir2 >> 12;
4595:
4596: acc_bf bf(this);
4597: if (n < 8) {
4598: // BFEXTU Dn{#o:#w},Dn
1.1.1.2 root 4599: CYCLE3(bfext_dn);
1.1 root 4600: bf.LoadReg(n);
4601: } else {
4602: // BFEXTU <ea>{#o:#w},Dn
4603: uint32 ea = cea_ctrl();
1.1.1.2 root 4604: if (__predict_true(bf.LoadMem(ea))) {
4605: CYCLE3(bfext_ea_less);
4606: } else {
4607: CYCLE3(bfext_ea_over);
4608: }
1.1 root 4609: }
4610: // CCR は操作前のビットフィールドに対して
4611: ACC.move_32(bf.data);
4612: // 符号なしシフト
4613: reg.D[dn] = bf.data >> (32 - bf.width);
4614: }
4615:
4616: // %1110_101011_mmmrrr d.m..rxw.. -34 BFCHG <ea>{#o:#w}
4617: OP_DEF(bfchg)
4618: {
4619: uint n = ir & 0x3f;
4620: ir2 = fetch_2();
4621:
4622: acc_bf bf(this);
4623: if (n < 8) {
4624: // BFCHG Dn{#o:#w}
1.1.1.2 root 4625: CYCLE3(bfchg_dn);
1.1 root 4626: bf.LoadReg(n);
4627: } else if (n >= 0x3a) {
4628: // BFCHG <ea> に PC 相対(と #imm) はない
4629: op_illegal();
4630: } else {
4631: // BFCHG <ea>{#o:#w}
4632: uint32 ea = cea_ctrl();
1.1.1.2 root 4633: if (__predict_true(bf.LoadMem(ea))) {
4634: CYCLE3(bfchg_ea_less);
4635: } else {
4636: CYCLE3(bfchg_ea_over);
4637: }
1.1 root 4638: }
4639: // CCR は操作前のビットフィールドに対して
4640: ACC.move_32(bf.data);
4641: bf.data = ~bf.data;
4642: bf.Store(n);
4643: }
4644:
4645: // %1110_101111_mmmrrr d.m..rxwp. -34 BFEXTS <ea>{#o:#w},Dn
4646: OP_DEF(bfexts)
4647: {
4648: uint n = ir & 0x3f;
4649: ir2 = fetch_2();
4650: uint dn = ir2 >> 12;
4651:
4652: acc_bf bf(this);
4653: if (n < 8) {
4654: // BFEXTS Dn{#o:#w},Dn
1.1.1.2 root 4655: CYCLE3(bfext_dn);
1.1 root 4656: bf.LoadReg(n);
4657: } else {
4658: // BFEXTS <ea>{#o:#w},Dn
4659: uint32 ea = cea_ctrl();
1.1.1.2 root 4660: if (__predict_true(bf.LoadMem(ea))) {
4661: CYCLE3(bfext_ea_less);
4662: } else {
4663: CYCLE3(bfext_ea_over);
4664: }
1.1 root 4665: }
4666: // CCR は操作前のビットフィールドに対して
4667: ACC.move_32(bf.data);
4668: // 符号付きシフト
4669: // XXX 負数の右シフト
4670: reg.D[dn] = ((int32)bf.data) >> (32 - bf.width);
4671: }
4672:
4673: // %1110_110011_mmmrrr d.m..rxw.. -34 BFCLR <ea>{#o:#w}
4674: OP_DEF(bfclr)
4675: {
4676: uint n = ir & 0x3f;
4677: ir2 = fetch_2();
4678:
4679: acc_bf bf(this);
4680: if (n < 8) {
4681: // BFCLR Dn{#o:#w}
1.1.1.2 root 4682: CYCLE3(bfclr_dn);
1.1 root 4683: bf.LoadReg(n);
4684: } else if (n >= 0x3a) {
4685: // BFCLR <ea> に PC 相対(と #imm) はない
4686: op_illegal();
4687: } else {
4688: // BFCLR <ea>{#o:#w}
4689: uint32 ea = cea_ctrl();
1.1.1.2 root 4690: if (__predict_true(bf.LoadMem(ea))) {
4691: CYCLE3(bfclr_ea_less);
4692: } else {
4693: CYCLE3(bfclr_ea_over);
4694: }
1.1 root 4695: }
4696: // CCR は操作前のビットフィールドに対して
4697: ACC.move_32(bf.data);
4698: bf.data = 0;
4699: bf.Store(n);
4700: }
4701:
4702: // %1110_110111_mmmrrr d.m..rxwp. -34 BFFFO <ea>{#o:#w},Dn
4703: OP_DEF(bfffo)
4704: {
4705: uint n = ir & 0x3f;
4706: ir2 = fetch_2();
4707: uint dn = ir2 >> 12;
4708:
4709: acc_bf bf(this);
4710: if (n < 8) {
4711: // BFFFO Dn{#o:#w},Dn
1.1.1.2 root 4712: CYCLE3(bfffo_dn);
1.1 root 4713: bf.LoadReg(n);
4714: } else {
4715: // BFFFO <ea>{#o:#w},Dn
4716: uint32 ea = cea_ctrl();
1.1.1.2 root 4717: if (__predict_true(bf.LoadMem(ea))) {
4718: CYCLE3(bfffo_ea_less);
4719: } else {
4720: CYCLE3(bfffo_ea_over);
4721: }
1.1 root 4722: }
4723: // CCR は操作前のビットフィールドに対して
4724: ACC.move_32(bf.data);
4725: // 1 になっているビットを探す
4726: for (; (int)bf.width-- > 0 && (int32)bf.data >= 0; bf.data <<= 1) {
4727: bf.offset++;
4728: }
4729: reg.D[dn] = bf.offset;
4730: }
4731:
4732: // %1110_111011_mmmrrr d.m..rxw.. -34 BFSET <ea>{#o:#w}
4733: OP_DEF(bfset)
4734: {
4735: uint n = ir & 0x3f;
4736: ir2 = fetch_2();
4737:
4738: acc_bf bf(this);
4739: if (n < 8) {
4740: // BFSET Dn{#o:#w}
1.1.1.2 root 4741: CYCLE3(bfset_dn);
1.1 root 4742: bf.LoadReg(n);
4743: } else if (n >= 0x3a) {
4744: // BFSET <ea> に PC 相対(と #imm) はない
4745: op_illegal();
4746: } else {
4747: // BFSET <ea>{#o:#w}
4748: uint32 ea = cea_ctrl();
1.1.1.2 root 4749: if (__predict_true(bf.LoadMem(ea))) {
4750: CYCLE3(bfset_ea_less);
4751: } else {
4752: CYCLE3(bfset_ea_over);
4753: }
1.1 root 4754: }
4755: // CCR は操作前のビットフィールドに対して
4756: ACC.move_32(bf.data);
4757: bf.data = 0xffffffff;
4758: bf.Store(n);
4759: }
4760:
4761: // %1110_111111_mmmrrr d.m..rxw.. -34 BFINS Dn,<ea>{#o:#w}
4762: OP_DEF(bfins)
4763: {
4764: uint n = ir & 0x3f;
4765: ir2 = fetch_2();
4766: uint dn = ir2 >> 12;
4767:
4768: acc_bf bf(this);
4769: if (n < 8) {
4770: // BFINS Dm,Dn{#o:#w}
1.1.1.2 root 4771: CYCLE3(bfins_dn);
1.1 root 4772: bf.LoadReg(n);
4773: } else if (n >= 0x3a) {
4774: // BFINS Dn,<ea> に PC 相対(と #imm) はない
4775: op_illegal();
4776: } else {
4777: // BFINS Dn,<ea>{#o:#w}
4778: uint32 ea = cea_ctrl();
1.1.1.2 root 4779: if (__predict_true(bf.LoadMem(ea))) {
4780: CYCLE3(bfins_ea_less);
4781: } else {
4782: CYCLE3(bfins_ea_over);
4783: }
1.1 root 4784: }
4785: bf.data = reg.D[dn] << (32 - bf.width);
4786: // BFINS のみ CCR は操作後のビットフィールドに対して
4787: ACC.move_32(bf.data);
4788: bf.Store(n);
4789: }
4790:
1.1.1.3 ! root 4791: // %1111_000nnn_nnnnnn .......... -3- MMU30_OP
! 4792: OP_DEF(mmu30)
1.1 root 4793: {
4794: // CPU ごとの virtual 関数になっている。
4795: ops_mmu30();
4796: }
4797:
4798: // 68030 MMU 命令跡地は 68040 では全部 F ライン例外。
4799: void
4800: MPU68040Device::ops_mmu30()
4801: {
4802: op_illegal();
4803: }
4804:
4805: // 68030 MMU 命令。
4806: void
4807: MPU68030Device::ops_mmu30()
4808: {
4809: ir2 = fetch_2();
4810: switch ((ir2 >> 8) & 0xff) {
4811: case (0x0800 >> 8):
4812: case (0x0900 >> 8):
4813: case (0x0c00 >> 8):
4814: case (0x0d00 >> 8):
4815: // %000_01n00_000_00000 PMOVE.L <ea>,TTn
4816: // %000_01n01_000_00000 PMOVEFD.L <ea>,TTn
4817: {
1.1.1.2 root 4818: CYCLE3(pmove_ea_tt);
1.1 root 4819: uint32 ea = cea_copro();
4820: uint32 data = read_4(ea);
4821: uint n = (ir2 >> 10) & 1;
4822: SetTT(n, data);
1.1.1.3 ! root 4823: if ((ir2 & 0x0100) == 0) {
! 4824: atc.FlushAll();
! 4825: }
! 4826: return;
1.1 root 4827: }
4828: case (0x0a00 >> 8):
4829: case (0x0e00 >> 8):
4830: // %000_01n10_000_00000 PMOVE.L TTn,<ea>
4831: {
1.1.1.2 root 4832: CYCLE3(pmove_tt_ea);
1.1 root 4833: uint32 ea = cea_copro();
4834: uint n = (ir2 >> 10) & 1;
4835: write_4(ea, GetTT(n));
1.1.1.3 ! root 4836: return;
1.1 root 4837: }
4838: case (0x2000 >> 8):
4839: // %001_00000_000_00000 PLOADW SFC,<ea>
4840: // %001_00000_000_00001 PLOADW DFC,<ea>
4841: // %001_00000_000_01yyy PLOADW Dy,<ea>
4842: // %001_00000_000_10nnn PLOADW #<imm>,<ea>
4843: {
1.1.1.2 root 4844: CYCLE3(pload);
1.1 root 4845: putlog(0, "ploadw");
1.1.1.3 ! root 4846: ops_mmu30_pload();
! 4847: return;
1.1 root 4848: }
4849: case (0x2200 >> 8):
4850: // %001_00010_000_00000 PLOADR SFC,<ea>
4851: // %001_00010_000_00001 PLOADR DFC,<ea>
4852: // %001_00010_000_01yyy PLOADR Dy,<ea>
4853: // %001_00010_000_10nnn PLOADR #<imm>,<ea>
4854: {
1.1.1.2 root 4855: CYCLE3(pload);
1.1 root 4856: putlog(0, "ploadr");
1.1.1.3 ! root 4857: ops_mmu30_pload();
! 4858: return;
1.1 root 4859: }
4860: case (0x2400 >> 8):
4861: // %001_00100_000_00000 PFLUSHA
4862: {
1.1.1.2 root 4863: CYCLE3(pflusha);
1.1.1.3 ! root 4864: ops_mmu30_pflusha();
! 4865: return;
1.1 root 4866: }
4867: case (0x3000 >> 8):
4868: // %001_10000_nnn_00000 PFLUSH SFC,#<mask>
4869: // %001_10000_nnn_00001 PFLUSH DFC,#<mask>
4870: // %001_10000_nnn_01yyy PFLUSH Dy,#<mask>
4871: // %001_10000_nnn_10nnn PFLUSH #<imm>,#<mask>
4872: {
1.1.1.2 root 4873: CYCLE3(pflush);
1.1.1.3 ! root 4874: ops_mmu30_pflush();
! 4875: return;
1.1 root 4876: }
4877: case (0x3800 >> 8):
4878: // %001_11000_nnn_00000 PFLUSH SFC,#<mask>,<ea>
4879: // %001_11000_nnn_00001 PFLUSH DFC,#<mask>,<ea>
4880: // %001_11000_nnn_01yyy PFLUSH Dy,#<mask>,<ea>
4881: // %001_11000_nnn_10nnn PFLUSH #<imm>,#<mask>,<ea>
4882: {
1.1.1.2 root 4883: CYCLE3(pflush);
1.1.1.3 ! root 4884: ops_mmu30_pflush_ea();
! 4885: return;
1.1 root 4886: }
4887: case (0x4000 >> 8):
4888: case (0x4100 >> 8):
4889: // %010_00000_000_00000 PMOVE.L <ea>,TC
4890: // %010_00001_000_00000 PMOVEFD.L <ea>,TC
4891: {
1.1.1.2 root 4892: CYCLE3(pmove_ea_tc);
1.1 root 4893: uint32 ea = cea_copro();
4894: uint32 data = read_4(ea);
1.1.1.3 ! root 4895: if (SetTC(data)) {
! 4896: if ((ir2 & 0x0100) == 0) {
! 4897: atc.FlushAll();
! 4898: }
! 4899: } else {
1.1 root 4900: Exception(M68K::EXCEP_MMU_CONFIG);
4901: }
1.1.1.3 ! root 4902: return;
1.1 root 4903: }
4904: case (0x4200 >> 8):
4905: // %010_00010_000_00000 PMOVE.L TC,<ea>
4906: {
1.1.1.2 root 4907: CYCLE3(pmove_tc_ea);
1.1 root 4908: uint32 ea = cea_copro();
4909: write_4(ea, GetTC());
1.1.1.3 ! root 4910: return;
1.1 root 4911: }
4912: case (0x4800 >> 8):
4913: case (0x4900 >> 8):
4914: // %010_01000_000_00000 PMOVE.Q <ea>,SRP
4915: // %010_01001_000_00000 PMOVEFD.Q <ea>,SRP
4916: {
1.1.1.2 root 4917: CYCLE3(pmove_ea_xrp);
1.1 root 4918: uint32 ea = cea_copro();
4919: uint32 h = read_4(ea);
4920: uint32 l = read_4(ea + 4);
1.1.1.3 ! root 4921: if (SetSRP(h, l)) {
! 4922: if ((ir2 & 0x0100) == 0) {
! 4923: atc.FlushAll();
! 4924: }
! 4925: } else {
1.1 root 4926: Exception(M68K::EXCEP_MMU_CONFIG);
4927: }
1.1.1.3 ! root 4928: return;
1.1 root 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());
1.1.1.3 ! root 4937: return;
1.1 root 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);
1.1.1.3 ! root 4948: if (SetCRP(h, l)) {
! 4949: if ((ir2 & 0x0100) == 0) {
! 4950: atc.FlushAll();
! 4951: }
! 4952: } else {
1.1 root 4953: Exception(M68K::EXCEP_MMU_CONFIG);
4954: }
1.1.1.3 ! root 4955: return;
1.1 root 4956: }
4957: case (0x4e00 >> 8):
4958: // %010_01110_000_00000 PMOVE.Q CRP,<ea>
4959: {
1.1.1.2 root 4960: CYCLE3(pmove_xrp_ea);
1.1 root 4961: uint32 ea = cea_copro();
4962: write_4(ea, GetCRPh());
4963: write_4(ea + 4, GetCRPl());
1.1.1.3 ! root 4964: return;
1.1 root 4965: }
4966: case (0x6000 >> 8):
4967: // %011_00000_000_00000 PMOVE.W <ea>,MMUSR
4968: {
1.1.1.2 root 4969: CYCLE3(pmove_ea_mmusr);
1.1 root 4970: uint32 ea = cea_copro();
4971: uint16 data = read_2(ea);
4972: SetMMUSR(data);
1.1.1.3 ! root 4973: return;
1.1 root 4974: }
4975: case (0x6200 >> 8):
4976: // %011_00010_000_00000 PMOVE.W MMUSR,<ea>
4977: {
1.1.1.2 root 4978: CYCLE3(pmove_mmusr_ea);
1.1 root 4979: uint32 ea = cea_copro();
4980: write_2(ea, GetMMUSR());
1.1.1.3 ! root 4981: return;
1.1 root 4982: }
4983: case (0x8000 >> 8):
4984: case (0x8400 >> 8):
4985: case (0x8800 >> 8):
4986: case (0x8c00 >> 8):
4987: case (0x9000 >> 8):
4988: case (0x9400 >> 8):
4989: case (0x9800 >> 8):
4990: case (0x9c00 >> 8):
4991: // %100_nnn00_000_00000 PTESTW SFC,<ea>,#<level>
4992: // %100_nnn00_000_00001 PTESTW DFC,<ea>,#<level>
4993: // %100_nnn00_000_01yyy PTESTW Dy,<ea>,#<level>
4994: // %100_nnn00_000_10nnn PTESTW #<imm>,<ea>,#<level>
4995: {
1.1.1.3 ! root 4996: ops_mmu30_ptest();
! 4997: return;
1.1 root 4998: }
4999: case (0x8100 >> 8):
5000: case (0x8500 >> 8):
5001: case (0x8900 >> 8):
5002: case (0x8d00 >> 8):
5003: case (0x9100 >> 8):
5004: case (0x9500 >> 8):
5005: case (0x9900 >> 8):
5006: case (0x9d00 >> 8):
5007: // %100_nnn01_nnn_00000 PTESTW SFC,<ea>,#<level>,An
5008: // %100_nnn01_nnn_00001 PTESTW DFC,<ea>,#<level>,An
5009: // %100_nnn01_nnn_01yyy PTESTW Dy,<ea>,#<level>,An
5010: // %100_nnn01_nnn_10nnn PTESTW #<imm>,<ea>,#<level>,An
5011: {
1.1.1.3 ! root 5012: ops_mmu30_ptest();
! 5013: return;
1.1 root 5014: }
5015: case (0x8200 >> 8):
5016: case (0x8600 >> 8):
5017: case (0x8a00 >> 8):
5018: case (0x8e00 >> 8):
5019: case (0x9200 >> 8):
5020: case (0x9600 >> 8):
5021: case (0x9a00 >> 8):
5022: case (0x9e00 >> 8):
5023: // %100_nnn10_000_00000 PTESTR SFC,<ea>,#<level>
5024: // %100_nnn10_000_00001 PTESTR DFC,<ea>,#<level>
5025: // %100_nnn10_000_01yyy PTESTR Dy,<ea>,#<level>
5026: // %100_nnn10_000_10nnn PTESTR #<imm>,<ea>,#<level>
5027: {
1.1.1.3 ! root 5028: ops_mmu30_ptest();
! 5029: return;
1.1 root 5030: }
5031: case (0x8300 >> 8):
5032: case (0x8700 >> 8):
5033: case (0x8b00 >> 8):
5034: case (0x8f00 >> 8):
5035: case (0x9300 >> 8):
5036: case (0x9700 >> 8):
5037: case (0x9b00 >> 8):
5038: case (0x9f00 >> 8):
5039: // %100_nnn11_nnn_00000 PTESTR SFC,<ea>,#<level>,An
5040: // %100_nnn11_nnn_00001 PTESTR DFC,<ea>,#<level>,An
5041: // %100_nnn11_nnn_01yyy PTESTR Dy,<ea>,#<level>,An
5042: // %100_nnn11_nnn_10nnn PTESTR #<imm>,<ea>,#<level>,An
5043: {
1.1.1.3 ! root 5044: ops_mmu30_ptest();
! 5045: return;
1.1 root 5046: }
5047: default:
5048: break;
5049: }
1.1.1.3 ! root 5050: OP_FUNC(illegal);
1.1 root 5051: }
5052:
5053: // 現在の FPCR/FPSR を fe 構造体にコピー。
5054: //
5055: // fe.fe_{fpcr,fpsr} のほうはこの fpe 用の内部ワークなので破壊してよい。
5056: // 命令実行の結果、FPSR レジスタの値を更新する際は fpu_upd_fpsr() を
5057: // 呼ぶこと。これを使わず独自に更新する場合は fe.fe_fpframe->fpf_fpsr
5058: // (こっちがレジスタ値) と fe.fe_fpsr (FPE 用) を同時に更新すること。
5059: // FPCR のほうは FMOVE-to-FPCR 命令以外で変更されることはないはず。
5060: #define INIT_FE() do { \
5061: fe.fe_fpcr = RegFPCR; \
5062: fe.fe_fpsr = RegFPSR; \
5063: } while (0)
5064:
5065: // ステートを (NULL なら) IDLE に変える。
5066: // 6888x では非条件命令、条件命令どちらでも IDLE になる。
5067: // 68040 では非条件命令でだけ IDLE になる。
5068: // 非条件命令はここでは1ワード目の opclass が 1,2,3 の命令。
5069: #define SET_IDLE() do { \
5070: if (fpu_state == FPU_STATE_NULL) \
5071: fpu_state = FPU_STATE_IDLE; \
5072: } while (0)
5073:
5074: // %1111_001000_nnnnnn .......... -34 FPGEN
5075: OP_DEF(fpgen)
5076: {
5077: if (GetFPUType().IsNoFPU()) {
5078: op_illegal();
5079: return;
5080: }
5081:
5082: INIT_FE();
5083: SET_IDLE();
5084:
5085: ir2 = fetch_2();
5086: switch (ir2 >> 13) {
5087: case 0:
5088: fpu_op_fgen_reg();
5089: break;
5090: case 1:
5091: fpu_op_illg();
5092: break;
5093: case 2:
5094: fpu_op_fgen_mem();
5095: break;
5096: case 3:
5097: fpu_op_fmove_to_mem();
5098: break;
5099: case 4:
5100: fpu_op_fmovem_ea2ctl();
5101: break;
5102: case 5:
5103: fpu_op_fmovem_ctl2ea();
5104: break;
5105: case 6:
5106: fpu_op_fmovem_ea2reg();
5107: break;
5108: case 7:
5109: fpu_op_fmovem_reg2ea();
5110: break;
5111: }
5112: }
5113:
5114: // %1111_001001_mmmrrr d.m+-rxw.. -34 FScc.B <ea>
5115: // %1111_001001_001yyy .......... -34 FDBcc Dy,<label>
5116: // %1111_001001_111010 .......... -34 FTRAPcc.W #<imm>
5117: // %1111_001001_111011 .......... -34 FTRAPcc.L #<imm>
5118: // %1111_001001_111100 .......... -34 FTRAPcc
5119: OP_DEF(fxcc)
5120: {
5121: if (GetFPUType().IsNoFPU()) {
5122: op_illegal();
5123: return;
5124: }
5125:
5126: if ((ir & 077) >= 075) {
5127: op_illegal();
5128: return;
5129: }
5130:
5131: INIT_FE();
5132: if (GetFPUType().Is6888x()) {
5133: SET_IDLE();
5134: }
5135:
5136: // ここまで来ると共通で ir2 に cc が来る。
5137: ir2 = fetch_2();
5138: switch (ir & 077) {
5139: case 010 ... 017: // FDBcc
5140: fpu_op_fdbcc();
5141: break;
5142: case 000 ... 007: // FScc
5143: case 020 ... 027:
5144: case 030 ... 037:
5145: case 040 ... 047:
5146: case 050 ... 057:
5147: case 060 ... 067:
5148: case 070 ... 071:
5149: fpu_op_fscc();
5150: break;
5151: case 072: // FTRAPcc.W
5152: fpu_op_ftrapcc_w();
5153: break;
5154: case 073: // FTRAPcc.L
5155: fpu_op_ftrapcc_l();
5156: break;
5157: case 074: // FTRAPcc
5158: fpu_op_ftrapcc();
5159: break;
5160: default:
5161: __unreachable();
5162: }
5163: }
5164:
5165: // %1111_001010_nnnnnn .......... -34 FBcc.W <label>
5166: OP_DEF(fbcc_w)
5167: {
5168: if (GetFPUType().IsNoFPU()) {
5169: op_illegal();
5170: return;
5171: }
5172:
5173: INIT_FE();
5174: if (GetFPUType().Is6888x()) {
5175: SET_IDLE();
5176: }
5177:
5178: fpu_op_fbcc_w();
5179: }
5180:
5181: // %1111_001011_nnnnnn .......... -34 FBcc.L <label>
5182: OP_DEF(fbcc_l)
5183: {
5184: if (GetFPUType().IsNoFPU()) {
5185: op_illegal();
5186: return;
5187: }
5188:
5189: INIT_FE();
5190: if (GetFPUType().Is6888x()) {
5191: SET_IDLE();
5192: }
5193:
5194: fpu_op_fbcc_l();
5195: }
5196:
5197: // %1111_001100_mmmrrr ..m.-rxw.. -34 FSAVE <ea>
5198: OP_DEF(fsave)
5199: {
5200: if (GetFPUType().IsNoFPU()) {
5201: op_illegal();
5202: return;
5203: }
5204:
5205: SUPERVISOR_OP;
5206:
5207: fpu_op_fsave();
5208: }
5209:
5210: // %1111_001101_mmmrrr ..m+.rxw.. -34 FRESTORE <ea>
5211: OP_DEF(frestore)
5212: {
5213: if (GetFPUType().IsNoFPU()) {
5214: op_illegal();
5215: return;
5216: }
5217:
5218: SUPERVISOR_OP;
5219:
5220: fpu_op_frestore();
5221: }
5222:
5223: // %1111_0100nn_001yyy .......... --4 CINVL <caches>,(Ay)
5224: // %1111_0100nn_010yyy .......... --4 CINVP <caches>,(Ay)
5225: // %1111_0100nn_011000 .......... --4 CINVA <caches>
5226: // %1111_0100nn_101yyy .......... --4 CPUSHL <caches>,(Ay)
5227: // %1111_0100nn_110yyy .......... --4 CPUSHP <caches>,(Ay)
5228: // %1111_0100nn_111000 .......... --4 CPUSHA <caches>
5229: OP_DEF(cinv)
5230: {
5231: if (mpu_type != m680x0MPUType::M68040) {
5232: op_illegal();
5233: return;
5234: }
5235: // putlog(1, "cinv*/cpush* (NOT IMPLEMENTED)");
5236: }
5237:
5238: // %1111_010100_mmmrrr ..m.-rxw.. 23- cpSAVE
5239: // %1111_010100_000yyy .......... --4 PFLUSHN (Ay)
5240: // %1111_010100_001yyy .......... --4 PFLUSH (Ay)
5241: // %1111_010100_010000 .......... --4 PFLUSHAN
5242: // %1111_010100_011000 .......... --4 PFLUSHA
5243: OP_DEF(pflush)
5244: {
5245: // CPU ごとの virtual 関数になっている。
5246: ops_mmu40_pflush();
5247: }
5248:
5249: // 68030 では 68040 MMU 命令の位置は全部 cpSAVE。
5250: void
5251: MPU68030Device::ops_mmu40_pflush()
5252: {
5253: op_cpsave();
5254: }
5255:
5256: // 68040 MMU 命令。
5257: void
5258: MPU68040Device::ops_mmu40_pflush()
5259: {
5260: SUPERVISOR_OP;
5261:
5262: // DFC は 1,2,5,6 の場合のみ有効で、0,3,4,7 なら動作不定。
5263: // 68000PRM.pdf, p6-35。
5264: // ここでは FC2 だけで判定する。
5265:
5266: switch (ir & 077) {
5267: case 000 ... 007: // PFLUSHN (Ay)
5268: {
1.1.1.2 root 5269: CYCLE(11);
1.1 root 5270: busaddr addr = busaddr(RegAY) | reg.dfc;
1.1.1.3 ! root 5271: atc_inst->Flush(addr, true);
! 5272: atc_data->Flush(addr, true);
! 5273: return;
1.1 root 5274: }
5275:
5276: case 010 ... 017: // PFLUSH (Ay)
5277: {
1.1.1.2 root 5278: CYCLE(11);
1.1 root 5279: busaddr addr = busaddr(RegAY) | reg.dfc;
1.1.1.3 ! root 5280: atc_inst->Flush(addr, false);
! 5281: atc_data->Flush(addr, false);
! 5282: return;
1.1 root 5283: }
5284:
5285: case 020: // PFLUSHAN
5286: {
1.1.1.2 root 5287: CYCLE(27);
1.1 root 5288: bool s = reg.dfc.IsSuper();
1.1.1.3 ! root 5289: atc_inst->Flush(s, true);
! 5290: atc_data->Flush(s, true);
! 5291: return;
1.1 root 5292: }
5293:
5294: case 030: // PFLUSHA
5295: {
1.1.1.2 root 5296: CYCLE3(pflusha);
1.1 root 5297: bool s = reg.dfc.IsSuper();
1.1.1.3 ! root 5298: atc_inst->Flush(s, false);
! 5299: atc_data->Flush(s, false);
! 5300: return;
1.1 root 5301: }
5302:
5303: default:
1.1.1.3 ! root 5304: break;
1.1 root 5305: }
1.1.1.3 ! root 5306: op_illegal();
1.1 root 5307: }
5308:
5309: // %1111_010101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5310: // %1111_010101_001yyy .......... --4 PTESTW (Ay)
5311: // %1111_010101_101yyy .......... --4 PTESTR (Ay)
5312: OP_DEF(ptest)
5313: {
5314: if (mpu_type != m680x0MPUType::M68040) {
5315: op_cprestore();
5316: return;
5317: }
1.1.1.2 root 5318: //CYCLE(25);
1.1 root 5319: OP_FUNC(unimpl);
5320: }
5321:
5322: // %1111_011000_000yyy .......... --4 MOVE16 (Ay)+,xxx.L
5323: // %1111_011000_001yyy .......... --4 MOVE16 xxx.L,(Ay)+
5324: // %1111_011000_010yyy .......... --4 MOVE16 (Ay),xxx.L
5325: // %1111_011000_011yyy .......... --4 MOVE16 xxx.L,(Ay)
5326: // %1111_011000_100yyy .......... --4 MOVE16 (Ay)+,(An)+
5327: OP_DEF(move16)
5328: {
5329: if (mpu_type != m680x0MPUType::M68040) {
5330: op_illegal();
5331: return;
5332: }
5333: OP_FUNC(unimpl);
5334: }
5335:
5336: // %1111_011100_mmmrrr ..m.-rxw.. 23- cpSAVE
5337: // %1111_100100_mmmrrr ..m.-rxw.. 23- cpSAVE
5338: // %1111_101100_mmmrrr ..m.-rxw.. 23- cpSAVE
5339: // %1111_110100_mmmrrr ..m.-rxw.. 23- cpSAVE
5340: // %1111_111100_mmmrrr ..m.-rxw.. 23- cpSAVE
5341: OP_DEF(cpsave)
5342: {
5343: // 020/030 では、(第1ワードが?) 有効な命令パターンの場合
5344: // まず特権チェックを行う。
5345: // cpSAVE の場合先に CIR で問い合わせて、その後 EA を評価すると書いて
5346: // あるように読める (68020 本 p.104) ので、コプロセッサがいない場合は
5347: // EA は評価しなさそう。
5348: // -(An) はコプロセッサがいなければ変化しないような気がする。
5349: // EA のパターンが無効なら F ライン例外になる。
5350: // cpID=6,7 はユーザ用とあるが cpSAVE は影響を受けるかどうか。
5351: // 040 ではコプロセッサプロトコル自体ないので全部 F ライン例外になる?
5352: //
5353: // ただし、Human68k モードではその特権判定よりも先んじて不当命令に
5354: // ならなければいけない。
5355: // Human68k モードでは F ライン命令は例外を起こすのではなく、命令内部で
5356: // 直接ホストのコールバックを実行しているため、ゲスト側の特権違反ハンドラ
5357: // に来たものを F ライン例外へ回すというような処理は出来ないため。
5358: if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) {
5359: switch (ir & 077) {
5360: case 020 ... 027: // m:(An)
5361: case 040 ... 047: // -:-(An)
5362: case 050 ... 057: // r:d16(An)
5363: case 060 ... 067: // x:d8(An,IX)
5364: case 070 ... 071: // w:Abs
5365: SUPERVISOR_OP;
5366: // コプロセッサがいないので EA をフェッチせず終了のはず。
5367: break;
5368: default:
5369: break;
5370: }
5371: }
5372: op_illegal();
5373: }
5374:
5375: // %1111_011101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5376: // %1111_100101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5377: // %1111_101101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5378: // %1111_110101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5379: // %1111_111101_mmmrrr ..m+.rxwp. 23- cpRESTORE
5380: OP_DEF(cprestore)
5381: {
5382: // すぐ上の cpsave 内のコメント参照。
5383: // cpRESTORE の場合先に1ロングワード読んでみて、その後コプロセッサに
5384: // 通信するので、コプロセッサがいなくても読み込みは発生する。
5385: // See XEiJ/misc/flinebuserror.x
5386: if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) {
5387: switch (ir & 077) {
5388: case 020 ... 027: // m:(An)
5389: case 030 ... 037: // +:(An)+
5390: case 050 ... 057: // r:d16(An)
5391: case 060 ... 067: // x:d8(An,IX)
5392: case 070 ... 071: // w:Abs
5393: case 072 ... 073: // p:d8(PC,IX)
5394: {
5395: SUPERVISOR_OP;
5396: uint32 ea = cea_fpu(4);
5397: read_4(ea);
5398: break;
5399: }
5400: default:
5401: break;
5402: }
5403: }
5404: op_illegal();
5405: }
5406:
1.1.1.2 root 5407: // %1111_010110_001nnn .......... --6 PLPAW (An)
5408: // %1111_010111_001nnn .......... --6 PLPAR (An)
5409: OP_DEF(plpa)
5410: {
5411: op_illegal();
5412: }
5413:
5414: // %1111_100000_000000 .......... --6 LPSTOP
5415: OP_DEF(lpstop)
5416: {
5417: op_illegal();
5418: }
5419:
1.1 root 5420: // illegal (or not-assigned) instructions
5421: OP_DEF(illegal)
5422: {
5423: // ILLEGAL 命令と F ライン命令と不当命令パターンがすべてここに来る。
5424: // catch 内からも呼ばれるので、ここで C++ の例外をスローしてはいけない。
5425:
5426: if ((ir & 0xf000) == 0xf000) {
5427: // F系列命令
1.1.1.2 root 5428: CYCLE3(fline);
1.1 root 5429: if (fline_callback) {
5430: if (fline_callback(this, fline_arg)) {
5431: return;
5432: }
5433: }
1.1.1.2 root 5434: ExceptionFLine();
1.1 root 5435: } else {
5436: // 不当命令
1.1.1.2 root 5437: CYCLE3(illegal);
1.1 root 5438: Exception(M68K::EXCEP_ILLEGAL);
5439: }
5440: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.