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