|
|
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.