|
|
1.1 root 1: #include "hd64180acc.h"
2:
3: #define ACC (*(hd64180acc*)®.f)
4:
5: // LDIR, INDR 等のリピート系命令の雛形。
6: // いずれも OP(name) を実行して BC == 0 になるまでこの PC を繰り返すもの。
7: // ジャンプする際には 2クロック追加で消費する。
8: // フラグも OP(name) が変更した以上にはここでは変更しない。
9: #define REPEAT_UNTIL(name) do { \
10: OP_FUNC(name); \
11: if (reg.GetBC() != 0) { \
12: reg.pc -= 2; \
13: CYCLE(2); \
14: } \
15: } while (0)
16:
17: uint32
18: MPU64180Device::Read16(uint32 addr)
19: {
20: uint32 data;
21:
22: data = Read8(addr);
23: data |= Read8(addr + 1) << 8;
24:
25: return data;
26: }
27:
28: void
29: MPU64180Device::Write16(uint32 addr, uint32 data)
30: {
31: Write8(addr, data & 0xff);
32: Write8(addr + 1, data >> 8);
33: }
34:
35: uint32
36: MPU64180Device::Fetch16()
37: {
38: uint32 data;
39:
40: data = Fetch8();
41: data |= Fetch8() << 8;
42:
43: return data;
44: }
45:
46: void
47: MPU64180Device::Push16(uint32 data)
48: {
49: reg.sp -= 2;
50: Write16(reg.sp, data);
51: }
52:
53: uint32
54: MPU64180Device::Pop16()
55: {
56: uint16 data = Read16(reg.sp);
57: reg.sp += 2;
58: return data;
59: }
60:
61: // HL (もしくは IX/IY) の値を取得する。
62: uint32
63: MPU64180Device::GetIHL() const
64: {
65: switch (ixiy) {
66: case USE_HL: return reg.GetHL(); break;
67: case USE_IX: return reg.ix; break;
68: case USE_IY: return reg.iy; break;
69: default:
70: PANIC("invalid ixiy = %d", (int)ixiy);
71: }
72: }
73:
74: // HL (もしくは IX/IY) に値を代入する。
75: void
76: MPU64180Device::SetIHL(uint32 data)
77: {
78: switch (ixiy) {
79: case USE_HL: reg.SetHL(data); break;
80: case USE_IX: reg.ix = data; break;
81: case USE_IY: reg.iy = data; break;
82: default:
83: PANIC("invalid ixiy = %d", (int)ixiy);
84: }
85: }
86:
87: // (HL) 用に HL のアドレスを取得する。
88: // IX/IY の時は (IX/IY + d) のアドレスを取得する。
89: uint32
90: MPU64180Device::LeaIHL()
91: {
92: uint32 addr = GetIHL();
93: if (ixiy != USE_HL) {
94: // DD と DD CB で +d をフェッチする順序が違う。
95: if ((int32)ixd < 0) {
96: ixd = Fetch8();
97: }
98: addr += (int32)(int8)ixd;
99: }
100: return addr;
101: }
102:
103: // ww (BC, DE, HL, SP) の値を取得する。
104: // ixiy なら HL の代わりに IX/IY の値を取得する。
105: uint32
106: MPU64180Device::GetWW(uint ww) const
107: {
108: switch (ww) {
109: case 0: return reg.GetBC();
110: case 1: return reg.GetDE();
111: case 2: return GetIHL();
112: case 3: return reg.sp;
113: default:
114: PANIC("invalid ww = %u", ww);
115: }
116: }
117:
118: // ww (BC, DE, HL, SP) に値を代入する。
119: // ixiy なら HL の代わりに IX/IY に値を取得する。
120: void
121: MPU64180Device::SetWW(uint ww, uint32 data)
122: {
123: switch (ww) {
124: case 0: reg.SetBC(data); break;
125: case 1: reg.SetDE(data); break;
126: case 2: SetIHL(data); break;
127: case 3: reg.sp = data; break;
128: default:
129: PANIC("invalid ww = %u", ww);
130: }
131: }
132:
133:
134: // ここから命令
135:
136: // 00000000: NOP
137: OP_DEF(nop)
138: {
139: CYCLE(3);
140: }
141:
142: // 00ww0001: LD ww,nn
143: // DD:00100001: LD IX,nn
144: OP_DEF(ld_ww_nn)
145: {
146: uint32 nn = Fetch16();
147: uint ww = (op >> 4) & 3;
148: SetWW(ww, nn);
149: CYCLE_IX(9, 12);
150: }
151:
152: // 00ww0010: LD (ww),A
153: OP_DEF(ld_wwin_a)
154: {
155: uint ww = op >> 4;
156: uint32 addr = GetWW(ww); // ww は BC, DE のみ
157: Write8(addr, reg.a);
158: CYCLE_IX(7, 15);
159: }
160:
161: // 00ww0011: INC ww
162: // DD:00100011: INC IX
163: OP_DEF(inc_ww)
164: {
165: uint ww = op >> 4;
166: uint32 data = GetWW(ww);
167: data++;
168: SetWW(ww, data);
169: CYCLE_IX(4, 7);
170: }
171:
172: // 00rrr100: INC r
173: OP_DEF(inc_r)
174: {
175: uint r = op >> 3;
176: reg.r[r] = ACC.inc_8(reg.r[r]);
177: CYCLE(4);
178: }
179:
180: // 00rrr101: DEC r
181: OP_DEF(dec_r)
182: {
183: uint r = op >> 3;
184: reg.r[r] = ACC.dec_8(reg.r[r]);
185: CYCLE(4);
186: }
187:
188: // 00rrr110: LD r,n
189: OP_DEF(ld_r_n)
190: {
191: uint r = op >> 3;
192: reg.r[r] = Fetch8();
193: CYCLE(6);
194: }
195:
196: // 00000111: RLCA
197: OP_DEF(rlca)
198: {
199: reg.a = ACC.rlc_8(reg.a);
200: CYCLE(3);
201: }
202:
203: // 00001000: EX AF,AF'
204: OP_DEF(ex_af_af)
205: {
206: uint8 tmpa = reg.a;
207: uint8 tmpf = reg.f.Get();
208: reg.a = reg.ex.a;
209: reg.f.Set(reg.ex.f.Get());
210: reg.ex.a = tmpa;
211: reg.ex.f.Set(tmpf);
212: CYCLE(4);
213: }
214:
215: // 00ww1001: ADD HL,ww
216: // DD:00ww1001: ADD IX,ww
217: OP_DEF(add_hl_ww)
218: {
219: uint ww = op >> 4;
220: uint32 src = GetWW(ww);
221: uint32 dst = GetIHL();
222: dst = ACC.add_16(dst, src);
223: SetIHL(dst);
224: CYCLE_IX(7, 10);
225: }
226:
227: // 00ww1010: LD A,(ww)
228: OP_DEF(ld_a_wwin)
229: {
230: uint ww = op >> 4;
231: uint32 addr = GetWW(ww); // ww は BC, DE のみ
232: reg.a = Read8(addr);
233: CYCLE(6);
234: }
235:
236: // 00ww1011: DEC ww
237: // DD:00101011: DEC IX
238: OP_DEF(dec_ww)
239: {
240: uint ww = op >> 4;
241: uint32 data = GetWW(ww);
242: data--;
243: SetWW(ww, data);
244: CYCLE_IX(4, 7);
245: }
246:
247: // 00001111: RRCA
248: OP_DEF(rrca)
249: {
250: reg.a = ACC.rrc_8(reg.a);
251: CYCLE(3);
252: }
253:
254: // 00010000: DJNZ n
255: OP_DEF(djnz)
256: {
257: int8 n = Fetch8();
258: reg.b--;
259: if (reg.b != 0) {
260: Jump(reg.pc + n);
261: CYCLE(9);
262: } else {
263: CYCLE(7);
264: }
265: }
266:
267: // 00010111: RLA
268: OP_DEF(rla)
269: {
270: reg.a = ACC.rl_8(reg.a);
271: CYCLE(3);
272: }
273:
274: // 00011000: JR n
275: OP_DEF(jr)
276: {
277: int8 n = Fetch8();
278: Jump(reg.pc + n);
279: CYCLE(8);
280: }
281:
282: // 00011111: RRA
283: OP_DEF(rra)
284: {
285: reg.a = ACC.rr_8(reg.a);
286: CYCLE(3);
287: }
288:
289: // 00100000: JR NZ,n
290: OP_DEF(jr_nz)
291: {
292: int8 n = Fetch8();
293: if (reg.f.IsZ() == false) {
294: Jump(reg.pc + n);
295: CYCLE(8);
296: } else {
297: CYCLE(6);
298: }
299: }
300:
301: // 00100010: LD (nn),HL
302: // DD:00100010: LD (nn),IX
303: OP_DEF(ld_nnin_hl)
304: {
305: uint32 nn = Fetch16();
306: Write16(nn, GetIHL());
307: CYCLE_IX(16, 19);
308: }
309:
310: // 00100111: DAA
311: OP_DEF(daa)
312: {
1.1.1.2 ! root 313: reg.a = ACC.daa_8(reg.a);
1.1 root 314: CYCLE(4);
315: }
316:
317: // 00101000: JR Z,n
318: OP_DEF(jr_z)
319: {
320: int8 n = Fetch8();
321: if (reg.f.IsZ()) {
322: Jump(reg.pc + n);
323: CYCLE(8);
324: } else {
325: CYCLE(6);
326: }
327: }
328:
329: // 00101010: LD HL,(nn)
330: // DD:00101010: LD IX,(nn)
331: OP_DEF(ld_hl_nnin)
332: {
333: uint32 nn = Fetch16();
334: uint32 src = Read16(nn);
335: SetIHL(src);
336: CYCLE_IX(15, 18);
337: }
338:
339: // 00101111: CPL
340: OP_DEF(cpl)
341: {
342: reg.a = ~reg.a;
343: reg.f.SetH(true);
344: reg.f.SetN(true);
345: CYCLE(3);
346: }
347:
348: // 00110000: JR NC,n
349: OP_DEF(jr_nc)
350: {
351: int8 n = Fetch8();
352: if (reg.f.IsC() == false) {
353: Jump(reg.pc + n);
354: CYCLE(8);
355: } else {
356: CYCLE(6);
357: }
358: }
359:
360: // 00110010: LD (nn),A
361: OP_DEF(ld_nnin_a)
362: {
363: uint32 addr = Fetch16();
364: Write8(addr, reg.a);
365: CYCLE(13);
366: }
367:
368: // 00110100: INC (HL)
369: // DD:00110100: INC (IX+d)
370: OP_DEF(inc_hlin)
371: {
372: uint32 addr = LeaIHL();
373: uint32 src = Read8(addr);
374: uint32 dst = ACC.inc_8(src);
375: Write8(addr, dst);
376: CYCLE_IX(10, 18);
377: }
378:
379: // 00110101: DEC (HL)
380: // DD:00110101: DEC (IX+d)
381: OP_DEF(dec_hlin)
382: {
383: uint32 addr = LeaIHL();
384: uint32 src = Read8(addr);
385: uint32 dst = ACC.dec_8(src);
386: Write8(addr, dst);
387: CYCLE_IX(10, 18);
388: }
389:
390: // 00110110: LD (HL),n
391: // DD:00110110: LD (IX+d),n
392: OP_DEF(ld_hlin_n)
393: {
394: uint32 addr = LeaIHL();
395: uint32 src = Fetch8();
396: Write8(addr, src);
397: CYCLE_IX(9, 15);
398: }
399:
400: // 00110111: SCF
401: OP_DEF(scf)
402: {
403: reg.f.SetC(true);
404: reg.f.SetH(false);
405: reg.f.SetN(false);
406: CYCLE(3);
407: }
408:
409: // 00111000: JR C,n
410: OP_DEF(jr_c)
411: {
412: int8 n = Fetch8();
413: if (reg.f.IsC()) {
414: Jump(reg.pc + n);
415: CYCLE(8);
416: } else {
417: CYCLE(6);
418: }
419: }
420:
421: // 00111010: LD A,(nn)
422: OP_DEF(ld_a_nnin)
423: {
424: uint32 nn = Fetch16();
425: reg.a = Read8(nn);
426: CYCLE(12);
427: }
428:
429: // 00111111: CCF
430: OP_DEF(ccf)
431: {
432: reg.f.SetC(!reg.f.IsC());
433: reg.f.SetH(false);
434: reg.f.SetN(false);
435: CYCLE(3);
436: }
437:
438: // 01rrrsss: LD r,s
439: OP_DEF(ld_r_s)
440: {
441: uint d = (op >> 3) & 7;
442: uint s = op & 7;
443: reg.r[d] = reg.r[s];
444: CYCLE(4);
445: }
446:
447: // 01rrr110: LD r,(HL)
448: // DD:01rrr110: LD r,(IX+d)
449: OP_DEF(ld_r_hlin)
450: {
451: uint d = (op >> 3) & 7;
452: uint16 addr = LeaIHL();
453: reg.r[d] = Read8(addr);
454: CYCLE_IX(6, 14);
455: }
456:
457: // 01110sss: LD (HL),s
458: // DD:01110sss: LD (IX+d),s
459: OP_DEF(ld_hlin_s)
460: {
461: uint s = op & 7;
462: uint32 addr = LeaIHL();
463: Write8(addr, reg.r[s]);
464: CYCLE_IX(7, 15);
465: }
466:
467: // 01110110: HALT
468: OP_DEF(halt)
469: {
470: opmode = OpMode::Halt;
471: putlog(1, "Halt");
472: CYCLE(3);
473: }
474:
475: // 10000rrr: ADD A,r
476: OP_DEF(add_a_r)
477: {
478: uint r = op & 7;
479: reg.a = ACC.add_8(reg.a, reg.r[r]);
480: CYCLE(4);
481: }
482:
483: // 10000110: ADD A,(HL)
484: // DD:10000110: ADD A,(IX+d)
485: OP_DEF(add_a_hlin)
486: {
487: uint32 addr = LeaIHL();
488: uint32 src = Read8(addr);
489: reg.a = ACC.add_8(reg.a, src);
490: CYCLE_IX(6, 14);
491: }
492:
493: // 10001rrr: ADC A,r
494: OP_DEF(adc_a_r)
495: {
496: uint r = op & 7;
497: reg.a = ACC.adc_8(reg.a, reg.r[r]);
498: CYCLE(4);
499: }
500:
501: // 10001110: ADC A,(HL)
502: // DD:10001110: ADC A,(IX+d)
503: OP_DEF(adc_a_hlin)
504: {
505: uint32 addr = LeaIHL();
506: uint32 src = Read8(addr);
507: reg.a = ACC.adc_8(reg.a, src);
508: CYCLE_IX(6, 14);
509: }
510:
511: // 10010rrr: SUB r
512: OP_DEF(sub_r)
513: {
514: uint r = op & 7;
515: reg.a = ACC.sub_8(reg.a, reg.r[r]);
516: CYCLE(4);
517: }
518:
519: // 10010110: SUB (HL)
520: // DD:10010110: SUB (IX+d)
521: OP_DEF(sub_hlin)
522: {
523: uint32 addr = LeaIHL();
524: uint32 src = Read8(addr);
525: reg.a = ACC.sub_8(reg.a, src);
526: CYCLE_IX(6, 14);
527: }
528:
529: // 10011rrr: SBC A,r
530: OP_DEF(sbc_a_r)
531: {
532: uint r = op & 7;
533: reg.a = ACC.sbc_8(reg.a, reg.r[r]);
534: CYCLE(4);
535: }
536:
537: // 10011110: SBC A,(HL)
538: // DD:10011110: SBC A,(IX+d)
539: OP_DEF(sbc_a_hlin)
540: {
541: uint32 addr = LeaIHL();
542: uint32 src = Read8(addr);
543: reg.a = ACC.sbc_8(reg.a, src);
544: CYCLE_IX(6, 14);
545: }
546:
547: // 10100rrr: AND r
548: OP_DEF(and_r)
549: {
550: uint r = op & 7;
551: reg.a = ACC.and_8(reg.a, reg.r[r]);
552: CYCLE(4);
553: }
554:
555: // 10100110: AND (HL)
556: // DD:10100110: AND (IX+d)
557: OP_DEF(and_hlin)
558: {
559: uint16 addr = LeaIHL();
560: uint32 src = Read8(addr);
561: reg.a = ACC.and_8(reg.a, src);
562: CYCLE_IX(6, 14);
563: }
564:
565: // 10101rrr: XOR r
566: OP_DEF(xor_r)
567: {
568: uint r = op & 7;
569: reg.a = ACC.xor_8(reg.a, reg.r[r]);
570: CYCLE(4);
571: }
572:
573: // 10101110: XOR (HL)
574: // DD:10101110: XOR (IX+d)
575: OP_DEF(xor_hlin)
576: {
577: uint16 addr = LeaIHL();
578: uint32 src = Read8(addr);
579: reg.a = ACC.xor_8(reg.a, src);
580: CYCLE_IX(6, 14);
581: }
582:
583: // 10110rrr: OR r
584: OP_DEF(or_r)
585: {
586: uint r = op & 7;
587: reg.a = ACC.or_8(reg.a, reg.r[r]);
588: CYCLE(4);
589: }
590:
591: // 10110110: OR (HL)
592: // DD:10110110: OR (IX+d)
593: OP_DEF(or_hlin)
594: {
595: uint16 addr = LeaIHL();
596: uint32 src = Read8(addr);
597: reg.a = ACC.or_8(reg.a, src);
598: CYCLE_IX(6, 14);
599: }
600:
601: // 10111rrr: CP r
602: OP_DEF(cp_r)
603: {
604: uint r = op & 7;
605: ACC.sub_8(reg.a, reg.r[r]);
606: CYCLE(4);
607: }
608:
609: // 10111110: CP (HL)
610: // DD:10111110: CP (IX+d)
611: OP_DEF(cp_hlin)
612: {
613: uint16 addr = LeaIHL();
614: uint32 src = Read8(addr);
615: ACC.sub_8(reg.a, src);
616: CYCLE_IX(6, 14);
617: }
618:
619: void
620: MPU64180Device::ops_ret()
621: {
622: uint16 addr = Pop16();
623: Jump(addr);
624: }
625:
626: // 11fff000: RET f
627: OP_DEF(ret_f)
628: {
629: uint fff = (op >> 3) & 7;
630: if (reg.f.IsCond(fff)) {
631: ops_ret();
632: CYCLE(10);
633: } else {
634: CYCLE(5);
635: }
636: }
637:
638: // 11zz0001: POP zz
639: // DD:11100001: POP IX
640: OP_DEF(pop_zz)
641: {
642: // ここでは zz のうち BC, DE, HL のみなので ww が使える
643: uint zz = (op >> 4) & 3;
644: uint16 data = Pop16();
645: SetWW(zz, data);
646: CYCLE_IX(9, 12);
647: }
648:
649: // 11fff010: JP f,nn
650: OP_DEF(jp_f_nn)
651: {
652: uint fff = (op >> 3) & 7;
653: uint16 addr = Fetch16();
654: if (reg.f.IsCond(fff)) {
655: Jump(addr);
656: CYCLE(9);
657: } else {
658: CYCLE(6);
659: }
660: }
661:
662: // 11000011: JP nn
663: OP_DEF(jp_nn)
664: {
665: uint32 addr = Fetch16();
666: Jump(addr);
667: CYCLE(9);
668: }
669:
670: // 11fff100: CALL f,nn
671: OP_DEF(call_f_nn)
672: {
673: uint fff = (op >> 3) & 7;
674: uint16 nn = Fetch16();
675: if (reg.f.IsCond(fff)) {
676: Push16(reg.pc);
677: Jump(nn);
678: CYCLE(16);
679: } else {
680: CYCLE(6);
681: }
682: }
683:
684: // 11zz0101: PUSH zz
685: // DD:11100101: PUSH IX
686: OP_DEF(push_zz)
687: {
688: // ここでは zz のうち BC, DE, HL のみなので ww が使える
689: uint zz = (op >> 4) & 3;
690: uint16 data = GetWW(zz);
691: Push16(data);
692: CYCLE_IX(11, 14);
693: }
694:
695: // 11000110: ADD A,n
696: OP_DEF(add_a_n)
697: {
698: uint32 n = Fetch8();
699: reg.a = ACC.add_8(reg.a, n);
700: CYCLE(6);
701: }
702:
703: // 11vvv111: RST v
704: OP_DEF(rst)
705: {
706: Push16(reg.pc);
707: uint v = op & 0x38;
708: Jump(v);
709: CYCLE(11);
710: }
711:
712: // 11001001: RET
713: OP_DEF(ret)
714: {
715: ops_ret();
716: CYCLE(9);
717: }
718:
719: // 11001011: op_CB
720: OP_DEF(cb)
721: {
722: // 2バイト目をフェッチ
723: op = Fetch8();
724: // で分岐
725: switch (op) {
726: #include "hd64180switch_cb.inc"
727: default:
728: op_illegal(2);
729: break;
730: }
731: }
732:
733: // 11001101: CALL nn
734: OP_DEF(call)
735: {
736: uint16 nn = Fetch16();
737: Push16(reg.pc);
738: Jump(nn);
739: CYCLE(16);
740: }
741:
742: // 11001110: ADC A,n
743: OP_DEF(adc_a_n)
744: {
745: uint32 n = Fetch8();
746: reg.a = ACC.adc_8(reg.a, n);
747: CYCLE(6);
748: }
749:
750: // 11010011: OUT (n),A
751: OP_DEF(out_n_a)
752: {
753: uint32 n = Fetch8();
754: // バスの上位には A が出る
755: uint32 addr = (reg.a << 8) | n;
756: WriteIO(addr, reg.a);
757: CYCLE(10);
758: }
759:
760: // 11010110: SUB n
761: OP_DEF(sub_n)
762: {
763: uint32 n = Fetch8();
764: reg.a = ACC.sub_8(reg.a, n);
765: CYCLE(6);
766: }
767:
768: // 11011001: EXX
769: OP_DEF(exx)
770: {
771: uint8 tmpb = reg.b;
772: uint8 tmpc = reg.c;
773: uint8 tmpd = reg.d;
774: uint8 tmpe = reg.e;
775: uint8 tmph = reg.h;
776: uint8 tmpl = reg.l;
777: reg.b = reg.ex.b;
778: reg.c = reg.ex.c;
779: reg.d = reg.ex.d;
780: reg.e = reg.ex.e;
781: reg.h = reg.ex.h;
782: reg.l = reg.ex.l;
783: reg.ex.b = tmpb;
784: reg.ex.c = tmpc;
785: reg.ex.d = tmpd;
786: reg.ex.e = tmpe;
787: reg.ex.h = tmph;
788: reg.ex.l = tmpl;
789: CYCLE(3);
790: }
791:
792: // 11011011: IN A,(n)
793: OP_DEF(in_a_n)
794: {
795: uint32 n = Fetch8();
796: // バスの上位には A が出る
797: uint32 addr = (reg.a << 8) | n;
798: reg.a = ReadIO(addr);
799: CYCLE(9);
800: }
801:
802: // DD/FD の共通部
803: void
804: MPU64180Device::ops_ddfd(ixiy_t xy)
805: {
806: ixiy = xy;
807:
808: // 2バイト目をフェッチ
809: op = Fetch8();
810: // で分岐
811: switch (op) {
812: #include "hd64180switch_dd.inc"
813: default:
814: op_illegal(2);
815: break;
816: }
817: }
818:
819: // 11011101: op_DD
820: OP_DEF(dd)
821: {
822: ops_ddfd(USE_IX);
823: }
824:
825: // 11011110: SBC A,n
826: OP_DEF(sbc_a_n)
827: {
828: uint32 n = Fetch8();
829: reg.a = ACC.sbc_8(reg.a, n);
830: CYCLE(6);
831: }
832:
833: // 11100011: EX (SP),HL
834: // DD:11100011: EX (SP),IX
835: OP_DEF(ex_sp_hl)
836: {
837: uint32 tmp = Read16(reg.sp);
838: Write16(reg.sp, GetIHL());
839: SetIHL(tmp);
840: CYCLE_IX(16, 19);
841: }
842:
843: // 11100110: AND n
844: OP_DEF(and_n)
845: {
846: uint32 src = Fetch8();
847: reg.a = ACC.and_8(reg.a, src);
848: CYCLE(6);
849: }
850:
851: // 11101001: JP (HL)
852: // DD:11101001: JP (IX)
853: OP_DEF(jp_hl)
854: {
855: Jump(GetIHL());
856: CYCLE_IX(3, 6);
857: }
858:
859: // 11101011: EX DE,HL
860: OP_DEF(ex_de_hl)
861: {
862: uint16 tmp = reg.GetDE();
863: reg.SetDE(reg.GetHL());
864: reg.SetHL(tmp);
865: CYCLE(3);
866: }
867:
868: // 11101101: op_ED
869: OP_DEF(ed)
870: {
871: op = Fetch8();
872:
873: switch (op) {
874: #include "hd64180switch_ed.inc"
875: default:
876: op_illegal(2);
877: break;
878: }
879: }
880:
881: // 11101110: XOR n
882: OP_DEF(xor_n)
883: {
884: uint32 src = Fetch8();
885: reg.a = ACC.xor_8(reg.a, src);
886: CYCLE(6);
887: }
888:
889: // 11110001: POP AF
890: OP_DEF(pop_af)
891: {
892: uint16 data = Pop16();
893: reg.a = data >> 8;
894: reg.f.Set(data & 0xff);
895: CYCLE(9);
896: }
897:
898: // 11110011: DI
899: OP_DEF(di)
900: {
901: ief1 = false;
902: ief2 = false;
903:
904: // DI 命令の直後は割り込みをサンプルしない。HD647180.pdf, p.205
905: intcheck = false;
906:
907: CYCLE(3);
908: }
909:
910: // 11110101: PUSH AF
911: OP_DEF(push_af)
912: {
913: uint16 data;
914: data = reg.a << 8;
915: data |= reg.f.Get();
916: Push16(data);
917: CYCLE(11);
918: }
919:
920: // 11110110: OR n
921: OP_DEF(or_n)
922: {
923: uint32 src = Fetch8();
924: reg.a = ACC.or_8(reg.a, src);
925: CYCLE(6);
926: }
927:
928: // 11111001: LD SP,HL
929: // DD:11111001: LD SP,IX
930: OP_DEF(ld_sp_hl)
931: {
932: reg.sp = GetIHL();
933: CYCLE_IX(4, 7);
934: }
935:
936: // 11111011: EI
937: OP_DEF(ei)
938: {
939: ief1 = true;
940: ief2 = true;
941:
942: // EI 命令の直後は割り込みをサンプルしない。HD647180.pdf, p.205
943: intcheck = false;
944:
945: CYCLE(3);
946: }
947:
948: // 11111101: op_FD
949: OP_DEF(fd)
950: {
951: ops_ddfd(USE_IY);
952: }
953:
954: // 11111110: CP n
955: OP_DEF(cp_n)
956: {
957: uint32 n = Fetch8();
958: ACC.sub_8(reg.a, n);
959: CYCLE(6);
960: }
961:
962: // CB:00000rrr: RLC r
963: OP_DEF(rlc_r)
964: {
965: uint r = op & 7;
966: reg.r[r] = ACC.in_8(ACC.rlc_8(reg.r[r]));
967: CYCLE(7);
968: }
969:
970: // CB:00000110: RLC (HL)
971: // DD_CB:00000110: RLC (IX+d)
972: OP_DEF(rlc_hlin)
973: {
974: uint32 addr = LeaIHL();
975: uint32 src = Read8(addr);
976: uint32 res = ACC.in_8(ACC.rlc_8(src));
977: Write8(addr, res);
978: CYCLE_IX(13, 19);
979: }
980:
981: // CB:00001rrr: RRC r
982: OP_DEF(rrc_r)
983: {
984: uint r = op & 7;
985: reg.r[r] = ACC.in_8(ACC.rrc_8(reg.r[r]));
986: CYCLE(7);
987: }
988:
989: // CB:00001110: RRC (HL)
990: // DD_CB:00001110: RRC (IX+d)
991: OP_DEF(rrc_hlin)
992: {
993: uint32 addr = LeaIHL();
994: uint32 src = Read8(addr);
995: uint32 res = ACC.in_8(ACC.rrc_8(src));
996: Write8(addr, res);
997: CYCLE_IX(13, 19);
998: }
999:
1000: // CB:00010rrr: RL r
1001: OP_DEF(rl_r)
1002: {
1003: uint r = op & 7;
1004: reg.r[r] = ACC.in_8(ACC.rl_8(reg.r[r]));
1005: CYCLE(7);
1006: }
1007:
1008: // CB:00010110: RL (HL)
1009: // DD_CB:00010110: RL (IX+d)
1010: OP_DEF(rl_hlin)
1011: {
1012: uint32 addr = LeaIHL();
1013: uint32 src = Read8(addr);
1014: uint32 res = ACC.in_8(ACC.rl_8(src));
1015: Write8(addr, res);
1016: CYCLE_IX(13, 19);
1017: }
1018:
1019: // CB:00011rrr: RR r
1020: OP_DEF(rr_r)
1021: {
1022: uint r = op & 7;
1023: reg.r[r] = ACC.in_8(ACC.rr_8(reg.r[r]));
1024: CYCLE(7);
1025: }
1026:
1027: // CB:00011110: RR (HL)
1028: // DD_CB:00011110: RR (IX+d)
1029: OP_DEF(rr_hlin)
1030: {
1031: uint32 addr = LeaIHL();
1032: uint32 src = Read8(addr);
1033: uint32 res = ACC.in_8(ACC.rr_8(src));
1034: Write8(addr, res);
1035: CYCLE_IX(13, 19);
1036: }
1037:
1038: // CB:00100rrr: SLA r
1039: OP_DEF(sla_r)
1040: {
1041: uint r = op & 7;
1042: reg.r[r] = ACC.in_8(ACC.sla_8(reg.r[r]));
1043: CYCLE(7);
1044: }
1045:
1046: // CB:00100110: SLA (HL)
1047: // DD_CB:00100110: SLA (IX+d)
1048: OP_DEF(sla_hlin)
1049: {
1050: uint32 addr = LeaIHL();
1051: uint32 src = Read8(addr);
1052: uint32 res = ACC.in_8(ACC.sla_8(src));
1053: Write8(addr, res);
1054: CYCLE_IX(13, 19);
1055: }
1056:
1057: // CB:00101rrr: SRA r
1058: OP_DEF(sra_r)
1059: {
1060: uint r = op & 7;
1061: reg.r[r] = ACC.in_8(ACC.sra_8(reg.r[r]));
1062: CYCLE(7);
1063: }
1064:
1065: // CB:00101110: SRA (HL)
1066: // DD_CB:00101110: SRA (IX+d)
1067: OP_DEF(sra_hlin)
1068: {
1069: uint32 addr = LeaIHL();
1070: uint32 src = Read8(addr);
1071: uint32 res = ACC.in_8(ACC.sra_8(src));
1072: Write8(addr, res);
1073: CYCLE_IX(13, 19);
1074: }
1075:
1076: // CB:00111rrr: SRL r
1077: OP_DEF(srl_r)
1078: {
1079: uint r = op & 7;
1080: reg.r[r] = ACC.in_8(ACC.srl_8(reg.r[r]));
1081: CYCLE(7);
1082: }
1083:
1084: // CB:00111110: SRL (HL)
1085: // DD_CB:00111110: SRL (IX+d)
1086: OP_DEF(srl_hlin)
1087: {
1088: uint32 addr = LeaIHL();
1089: uint32 src = Read8(addr);
1090: uint32 res = ACC.in_8(ACC.srl_8(src));
1091: Write8(addr, res);
1092: CYCLE_IX(13, 19);
1093: }
1094:
1095: // CB:01bbbrrr: BIT b,r
1096: OP_DEF(bit_r)
1097: {
1098: uint b = (op >> 3) & 7;
1099: uint r = op & 7;
1100: ACC.bit_8(b, reg.r[r]);
1101: CYCLE(6);
1102: }
1103:
1104: // CB:01bbb110: BIT b,(HL)
1105: // DD_CB:01bbb110: BIT b,(IX+d)
1106: OP_DEF(bit_hlin)
1107: {
1108: uint b = (op >> 3) & 7;
1109: uint32 addr = LeaIHL();
1110: uint32 data = Read8(addr);
1111: ACC.bit_8(b, data);
1112: CYCLE_IX(9, 15);
1113: }
1114:
1115: // CB:10bbbrrr: RES b,r
1116: OP_DEF(res_r)
1117: {
1118: uint b = (op >> 3) & 7;
1119: uint r = op & 7;
1120: reg.r[r] &= ~(1U << b);
1121: CYCLE(7);
1122: }
1123:
1124: // CB:10bbb110: RES b,(HL)
1125: // DD_CB:10bbb110: RES b,(IX+d)
1126: OP_DEF(res_hlin)
1127: {
1128: uint b = (op >> 3) & 7;
1129: uint32 addr = LeaIHL();
1130: uint32 data = Read8(addr);
1131: data &= ~(1U << b);
1132: Write8(addr, data);
1133: CYCLE_IX(13, 19);
1134: }
1135:
1136: // CB:11bbbrrr: SET b,r
1137: OP_DEF(set_r)
1138: {
1139: uint b = (op >> 3) & 7;
1140: uint r = op & 7;
1141: reg.r[r] |= 1U << b;
1142: CYCLE(7);
1143: }
1144:
1145: // CB:11bbb110: SET b,(HL)
1146: // DD_CB:11bbb110: SET b,(IX+d)
1147: OP_DEF(set_hlin)
1148: {
1149: uint b = (op >> 3) & 7;
1150: uint32 addr = LeaIHL();
1151: uint32 data = Read8(addr);
1152: data |= 1U << b;
1153: Write8(addr, data);
1154: CYCLE_IX(13, 19);
1155: }
1156:
1157: // ED:00rrr000: IN0 r,(n) (HD64*180 only)
1158: OP_DEF(in0_r_n)
1159: {
1160: uint32 n = Fetch8();
1161: uint32 src = ReadIO(n);
1162: uint r = op >> 3;
1163: reg.r[r] = ACC.in_8(src);
1164: CYCLE(12);
1165: }
1166:
1167: // ED:00rrr001: OUT0 (n),r (HD64*180 only)
1168: OP_DEF(out0_n_r)
1169: {
1170: uint32 n = Fetch8();
1171: uint32 r = op >> 3;
1172: WriteIO(n, reg.r[r]);
1173: CYCLE(13);
1174: }
1175:
1176: // ED:00rrr100: TST r (HD64*180 only)
1177: OP_DEF(tst_r)
1178: {
1179: uint r = op & 7;
1180: ACC.tst_8(reg.a, reg.r[r]);
1181: CYCLE(7);
1182: }
1183:
1184: // ED:00110000: IN0 F,(n) (HD64*180 only)
1185: OP_DEF(in0_f_n)
1186: {
1187: uint32 n = Fetch8();
1188: uint32 src = ReadIO(n);
1189: ACC.in_8(src);
1190: CYCLE(12);
1191: }
1192:
1193: // ED:00110100: TST (HL) (HD64*180 only)
1194: OP_DEF(tst_hlin)
1195: {
1196: uint16 addr = reg.GetHL();
1197: uint32 src = Read8(addr);
1198: ACC.tst_8(reg.a, src);
1199: CYCLE(10);
1200: }
1201:
1202: // ED:01rrr000: IN r,(C)
1203: OP_DEF(in_r_c)
1204: {
1205: uint r = (op >> 3) & 7;
1206: // バスの上位には B が出る
1207: uint32 addr = reg.GetBC();
1208: uint32 data = ReadIO(addr);
1209: reg.r[r] = ACC.in_8(data);
1210: CYCLE(9);
1211: }
1212:
1213: // ED:01rrr001: OUT (C),r
1214: OP_DEF(out_c_r)
1215: {
1216: uint r = (op >> 3) & 7;
1217: // バスの上位には B が出る
1218: uint32 addr = reg.GetBC();
1219: WriteIO(addr, reg.r[r]);
1220: CYCLE(10);
1221: }
1222:
1223: // ED:01ww0010: SBC HL,ww
1224: OP_DEF(sbc_hl_ww)
1225: {
1226: uint ww = (op >> 4) & 3;
1227: uint32 src = GetWW(ww);
1228: uint32 dst = reg.GetHL();
1229: dst = ACC.sbc_16(dst, src);
1230: reg.SetHL(dst);
1231: CYCLE(10);
1232: }
1233:
1234: // ED:01ww0011: LD (nn),ww
1235: OP_DEF(ld_nnin_ww)
1236: {
1237: uint ww = (op >> 4) & 3;
1238: uint32 src = GetWW(ww);
1239: uint32 nn = Fetch16();
1240: Write16(nn, src);
1241: CYCLE(19);
1242: }
1243:
1244: // ED:01000100: NEG
1245: OP_DEF(neg)
1246: {
1247: reg.a = ACC.sub_8(0, reg.a);
1248: CYCLE(6);
1249: }
1250:
1251: // ED:01000101: RETN
1252: OP_DEF(retn)
1253: {
1254: ief1 = ief2;
1255: Jump(Pop16());
1256: }
1257:
1258: // ED:01000110: IM 0
1259: OP_DEF(im_0)
1260: {
1261: int0mode = 0;
1262: putlog(1, "IM %d", int0mode);
1263: CYCLE(6);
1264: }
1265:
1266: // ED:01000111: LD I,A
1267: OP_DEF(ld_i_a)
1268: {
1269: reg_i = reg.a;
1270: CYCLE(6);
1271: }
1272:
1273: // ED:01ww1010: ADC HL,ww
1274: OP_DEF(adc_hl_ww)
1275: {
1276: uint ww = (op >> 4) & 3;
1277: uint32 src = GetWW(ww);
1278: uint32 dst = reg.GetHL();
1279: dst = ACC.adc_16(dst, src);
1280: reg.SetHL(dst);
1281: CYCLE(10);
1282: }
1283:
1284: // ED:01ww1011: LD ww,(nn)
1285: OP_DEF(ld_ww_nnin)
1286: {
1287: uint ww = (op >> 4) & 3;
1288: uint32 nn = Fetch16();
1289: uint32 src = Read16(nn);
1290: SetWW(ww, src);
1291: CYCLE(18);
1292: }
1293:
1294: // ED:01ww1100: MLT ww (HD64*180 only)
1295: OP_DEF(mlt)
1296: {
1297: uint ww = (op >> 4) & 3;
1298: uint32 src = GetWW(ww);
1299: uint32 dst = (src >> 8) * (src & 0xff);
1300: SetWW(ww, dst);
1301: // フラグ変化なし
1302: CYCLE(17);
1303: }
1304:
1305: // ED:01001101: RETI
1306: OP_DEF(reti)
1307: {
1308: ops_ret();
1309: CYCLE(12);
1310: }
1311:
1312: // ED:01001111: LD R,A
1313: OP_DEF(ld_r_a)
1314: {
1315: reg_r = reg.a;
1316: CYCLE(6);
1317: }
1318:
1319: // ED:01010110: IM 1
1320: OP_DEF(im_1)
1321: {
1322: int0mode = 1;
1323: putlog(1, "IM %d", int0mode);
1324: CYCLE(6);
1325: }
1326:
1327: // ED:01010111: LD A,I
1328: OP_DEF(ld_a_i)
1329: {
1330: reg.a = ACC.ld_ir8(reg_i);
1331:
1332: // IEF2 を P/V にコピー。P でも V でもないので一応 V にしておく。
1333: reg.f.SetV(GetIEF2());
1334:
1335: // HD64180 ではこの命令の終わりで割り込みをサンプルしない。
1336: intcheck = false;
1337:
1338: CYCLE(6);
1339: }
1340:
1341: // ED:01011110: IM 2
1342: OP_DEF(im_2)
1343: {
1344: int0mode = 2;
1345: putlog(1, "IM %d", int0mode);
1346: CYCLE(6);
1347: }
1348:
1349: // ED:01011111: LD A,R
1350: OP_DEF(ld_a_r)
1351: {
1352: reg.a = ACC.ld_ir8(GetR());
1353:
1354: // IEF2 を P/V にコピー。P でも V でもないので一応 V にしておく。
1355: reg.f.SetV(GetIEF2());
1356:
1357: // HD64180 ではこの命令の終わりで割り込みをサンプルしない。
1358: intcheck = false;
1359:
1360: CYCLE(6);
1361: }
1362:
1363: // ED:01100100: TST n (HD64*180 only)
1364: OP_DEF(tst_n)
1365: {
1366: uint32 src = Fetch8();
1367: ACC.and_8(reg.a, src);
1368: CYCLE(9);
1369: }
1370:
1371: // ED:01100111: RRD
1372: OP_DEF(rrd)
1373: {
1374: // +-----------+ +---+
1375: // | v | v
1376: // +-----+-----+ +-----+-----+
1377: // A | 7654 3210 | (HL) | 7654 3210 |
1378: // +-----+-----+ +-----+-----+
1379: // ^ |
1380: // +-------------------+
1381:
1382: uint32 hl = reg.GetHL();
1383: uint32 m = Read8(hl);
1384: uint32 a = (reg.a & 0xf0) | (m & 0x0f);
1385: uint32 b = (reg.a << 4) | (m >> 4);
1386: Write8(hl, b);
1387: reg.a = ACC.in_8(a);
1388: CYCLE(16);
1389: }
1390:
1391: // ED:01101111: RLD
1392: OP_DEF(rld)
1393: {
1394: // +-------------------+
1395: // | v
1396: // +-----+-----+ +-----+-----+
1397: // A | 7654 3210 | (HL) | 7654 3210 |
1398: // +-----+-----+ +-----+-----+
1399: // ^ | ^ |
1400: // +-----------+ +---+
1401:
1402: uint32 hl = reg.GetHL();
1403: uint32 m = Read8(hl);
1404: uint32 a = (reg.a & 0xf0) | (m >> 4);
1405: uint32 b = (m << 4) | (reg.a & 0x0f);
1406: Write8(hl, b);
1407: reg.a = ACC.in_8(a);
1408: CYCLE(16);
1409: }
1410:
1411: // ED:01110000: IN F,(C)
1412: OP_DEF(in_f_c)
1413: {
1414: // バスの上位には B が出る
1415: uint32 addr = reg.GetBC();
1416: uint32 data = ReadIO(addr);
1417: ACC.in_8(data);
1418: CYCLE(9);
1419: }
1420:
1421: // ED:01110100: TSTIO n (HD64*180 only)
1422: OP_DEF(tstio_n)
1423: {
1424: // バスの上位は 0 になる
1425: uint32 n = Fetch8();
1426: uint32 dst = ReadIO(reg.c);
1427: ACC.tst_8(dst, n);
1428: CYCLE(12);
1429: }
1430:
1431: // ED:01110110: SLP (HD64*180 only)
1432: OP_DEF(slp)
1433: {
1434: putlog(0, "SLP (NOT IMPLEMENTED)");
1435: EnterSleep();
1436: CYCLE(8);
1437: }
1438:
1439: // OTIM/OTDM の共通部分
1440: void
1441: MPU64180Device::ops_otim(int inc)
1442: {
1443: uint32 hl = reg.GetHL();
1444: uint32 src = Read8(hl);
1445: // バスの上位は 0 になる
1446: WriteIO(reg.c, src);
1447: reg.c += inc;
1448: hl += inc;
1449: reg.SetHL(hl);
1450: reg.b = ACC.outm_8(src, reg.b);
1451: CYCLE(14);
1452: }
1453:
1454: // ED:10000011: OTIM (HD64*180 only)
1455: OP_DEF(otim)
1456: {
1457: ops_otim(+1);
1458: }
1459:
1460: // ED:10001011: OTDM (HD64*180 only)
1461: OP_DEF(otdm)
1462: {
1463: ops_otim(-1);
1464: }
1465:
1466: // OTIMR/OTDMR の終了条件の共通部分。
1467: // 他のリピート系命令とはフラグ変化が異なる。
1468: void
1469: MPU64180Device::ops_otmr_until()
1470: {
1471: if (reg.b != 0) {
1472: reg.pc -= 2;
1473: CYCLE(2);
1474: } else {
1475: // 終了時はフラグ変化が違う。
1476: // S:0 Z:1 H:0 P/V:1 N:* C:0
1477: // このうち S, Z, H, N, C はセットされているままでよい。
1478: // パリティだけセット。
1479: reg.f.SetP(true);
1480: }
1481: }
1482:
1483: // ED:10010011: OTIMR (HD64*180 only)
1484: OP_DEF(otimr)
1485: {
1486: OP_FUNC(otim);
1487: ops_otmr_until();
1488: }
1489:
1490: // ED:10011011: OTDMR (HD64*180 only)
1491: OP_DEF(otdmr)
1492: {
1493: OP_FUNC(otdm);
1494: ops_otmr_until();
1495: }
1496:
1497: // LDI/LDD の共通部分
1498: void
1499: MPU64180Device::ops_ldi(int inc)
1500: {
1501: uint32 hl = reg.GetHL();
1502: uint32 de = reg.GetDE();
1503: uint32 bc = reg.GetBC();
1504:
1505: uint32 data = Read8(hl);
1506: Write8(de, data);
1507: hl += inc;
1508: de += inc;
1509: bc--;
1510: reg.SetHL(hl);
1511: reg.SetDE(de);
1512: reg.SetBC(bc);
1513:
1514: reg.f.SetV((bc != 0));
1515: reg.f.SetN(false);
1516: reg.f.SetH(false);
1517:
1518: CYCLE(12);
1519: }
1520:
1521: // ED:10100000: LDI
1522: OP_DEF(ldi)
1523: {
1524: ops_ldi(+1);
1525: }
1526:
1527: // CPI/CPD の共通部分
1528: void
1529: MPU64180Device::ops_cpi(int inc)
1530: {
1531: uint32 hl = reg.GetHL();
1532: uint32 bc = reg.GetBC();
1533:
1534: uint32 src = Read8(hl);
1535: ACC.sub_8(reg.a, src, true);
1536: hl += inc;
1537: bc--;
1538: reg.SetHL(hl);
1539: reg.SetBC(bc);
1540:
1541: reg.f.SetV(bc != 0);
1542:
1543: CYCLE(12);
1544: }
1545:
1546: // ED:10100001: CPI
1547: OP_DEF(cpi)
1548: {
1549: ops_cpi(+1);
1550: }
1551:
1552: // INI/IND の共通部分
1553: void
1554: MPU64180Device::ops_ini(int inc)
1555: {
1556: uint32 hl = reg.GetHL();
1557: // バスの上位には B が出る
1558: uint32 addr = reg.GetBC();
1559: uint32 data = ReadIO(addr);
1560: Write8(hl, data);
1561: hl += inc;
1562: reg.b--;
1563: reg.SetHL(hl);
1564: // XXX S,H,P/V,C は本当は不定
1565: reg.f.SetZ(reg.b == 0);
1566: reg.f.SetN((int8)data < 0);
1567: CYCLE(12);
1568: }
1569:
1570: // ED:10100010: INI
1571: OP_DEF(ini)
1572: {
1573: ops_ini(+1);
1574: }
1575:
1576: // OUTI/OUTD の共通部分
1577: void
1578: MPU64180Device::ops_outi(int inc)
1579: {
1580: uint32 hl = reg.GetHL();
1581: // バスの上位には B が出る
1582: uint32 addr = reg.GetBC();
1583: uint32 data = Read8(hl);
1584: WriteIO(addr, data);
1585: hl += inc;
1586: reg.b--;
1587: reg.SetHL(hl);
1588: // XXX S,H,P/V,C は本当は不定
1589: reg.f.SetZ(reg.b == 0);
1590: reg.f.SetN((int8)data < 0);
1591: CYCLE(12);
1592: }
1593:
1594: // ED:10100011: OUTI
1595: OP_DEF(outi)
1596: {
1597: ops_outi(+1);
1598: }
1599:
1600: // ED:10101000: LDD
1601: OP_DEF(ldd)
1602: {
1603: ops_ldi(-1);
1604: }
1605:
1606: // ED:10101001: CPD
1607: OP_DEF(cpd)
1608: {
1609: ops_cpi(-1);
1610: }
1611:
1612: // ED:10101010: IND
1613: OP_DEF(ind)
1614: {
1615: ops_ini(-1);
1616: }
1617:
1618: // ED:10101011: OUTD
1619: OP_DEF(outd)
1620: {
1621: ops_outi(-1);
1622: }
1623:
1624: // ED:10110000: LDIR
1625: OP_DEF(ldir)
1626: {
1627: REPEAT_UNTIL(ldi);
1628: }
1629:
1630: // ED:10110001: CPIR
1631: OP_DEF(cpir)
1632: {
1633: REPEAT_UNTIL(cpi);
1634: }
1635:
1636: // ED:10110010: INIR
1637: OP_DEF(inir)
1638: {
1639: REPEAT_UNTIL(ini);
1640: }
1641:
1642: // ED:10110011: OTIR
1643: OP_DEF(otir)
1644: {
1645: REPEAT_UNTIL(outi);
1646: }
1647:
1648: // ED:10111000: LDDR
1649: OP_DEF(lddr)
1650: {
1651: REPEAT_UNTIL(ldd);
1652: }
1653:
1654: // ED:10111001: CPDR
1655: OP_DEF(cpdr)
1656: {
1657: REPEAT_UNTIL(cpd);
1658: }
1659:
1660: // ED:10111010: INDR
1661: OP_DEF(indr)
1662: {
1663: REPEAT_UNTIL(ind);
1664: }
1665:
1666: // ED:10111011: OTDR
1667: OP_DEF(otdr)
1668: {
1669: REPEAT_UNTIL(outd);
1670: }
1671:
1672: // ED:11rrr001: MULUB A,r (R800 only)
1673: OP_DEF(mulub_a_r)
1674: {
1675: op_illegal(2);
1676: }
1677:
1678: // ED:11000011: MULUB HL,BC (R800 only)
1679: OP_DEF(mulub_hl_bc)
1680: {
1681: op_illegal(2);
1682: }
1683:
1684: // ED:11110011: MULUB HL,SP (R800 only)
1685: OP_DEF(mulub_hl_sp)
1686: {
1687: op_illegal(2);
1688: }
1689:
1690: // ED:11111111: SYSCALL (HD64*180 only)
1691: OP_DEF(syscall)
1692: {
1693: // MSX-DOS エミュレーションのような何か。
1694: // 通常の DOSCALL と同様、コール番号は C レジスタに入っている。
1695:
1696: if (gMainApp.msxdos_mode) {
1697: // MSX-DOS エミュレーションなら DOS コールを処理する
1698: assert(syscall_callback != NULL);
1699: syscall_callback(syscall_arg);
1700: CYCLE(3);
1701: } else {
1702: // 通常時は他の ED 系列と同じく不当命令例外。
1703: op_illegal(2);
1704: }
1705: }
1706:
1707: // DD:00rrr100: INC ixr (Z80/R800)
1708: OP_DEF(inc_ixr)
1709: {
1710: op_illegal(2);
1711: }
1712:
1713: // DD:00rrr101: DEC ixr (Z80/R800)
1714: OP_DEF(dec_ixr)
1715: {
1716: op_illegal(2);
1717: }
1718:
1719: // DD:01rrrsss: LD r,ixs (Z80/R800)
1720: OP_DEF(ld_r_ixs)
1721: {
1722: op_illegal(2);
1723: }
1724:
1725: // DD:10000rrr: ADD A,ixr (Z80/R800)
1726: OP_DEF(add_a_ixr)
1727: {
1728: op_illegal(2);
1729: }
1730:
1731: // DD:10001rrr: ADC A,ixr (Z80/R800)
1732: OP_DEF(adc_a_ixr)
1733: {
1734: op_illegal(2);
1735: }
1736:
1737: // DD:10010rrr: SUB ixr (Z80/R800)
1738: OP_DEF(sub_ixr)
1739: {
1740: op_illegal(2);
1741: }
1742:
1743: // DD:10011rrr: SBC A,ixr (Z80/R800)
1744: OP_DEF(sbc_a_ixr)
1745: {
1746: op_illegal(2);
1747: }
1748:
1749: // DD:10100rrr: AND ixr (Z80/R800)
1750: OP_DEF(and_ixr)
1751: {
1752: op_illegal(2);
1753: }
1754:
1755: // DD:10101rrr: XOR ixr (Z80/R800)
1756: OP_DEF(xor_ixr)
1757: {
1758: op_illegal(2);
1759: }
1760:
1761: // DD:10110rrr: OR ixr (Z80/R800)
1762: OP_DEF(or_ixr)
1763: {
1764: op_illegal(2);
1765: }
1766:
1767: // DD:10111rrr: CP ixr (Z80/R800)
1768: OP_DEF(cp_ixr)
1769: {
1770: op_illegal(2);
1771: }
1772:
1773: // DD:11001011: op_DD_CB
1774: OP_DEF(dd_cb)
1775: {
1776: // DD CB の場合は 3バイト目が d で、4バイト目が命令語。
1777: ixd = Fetch8();
1778:
1779: // 4バイト目をフェッチ
1780: op = Fetch8();
1781:
1782: // で分岐
1783: switch (op) {
1784: #include "hd64180switch_dd_cb.inc"
1785: default:
1786: op_illegal(3);
1787: break;
1788: }
1789: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.