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