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