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