C#でMSXの.BINファイルを逆アセンブルする

コンピュータ

MSXPENに触れてみて、昔、逆アセンブルという言葉に憧れていたことを思い出しました。

ソースコード

using System.Text.RegularExpressions;

public enum CodeType {
    SINGLE,
    SINGLE_E,
    SINGLE_NN,
    SINGLE_N,
    SINGLE_D,
    SINGLE_D_N,
    DOUBLE,
    DOUBLE_NN,
    DOUBLE_N,
    DOUBLE_D,
    DOUBLE_D_N,
    QUAD_IN_D,
}

public class Code {
    public CodeType Type {get;}
    public string Op {get;}
    public string Para {get;}
    public int Count {
        get {
            switch(Type) {
                case CodeType.SINGLE:
                    return 1;
                case CodeType.SINGLE_E:
                    return 2;
                case CodeType.SINGLE_NN:
                    return 3;
                case CodeType.SINGLE_N:
                    return 2;
                case CodeType.SINGLE_D:
                    return 2;
                case CodeType.SINGLE_D_N:
                    return 3;
                case CodeType.DOUBLE:
                    return 2;
                case CodeType.DOUBLE_NN:
                    return 4;
                case CodeType.DOUBLE_N:
                    return 3;
                case CodeType.DOUBLE_D:
                    return 3;
                case CodeType.DOUBLE_D_N:
                    return 4;
                case CodeType.QUAD_IN_D:
                    return 4;
                default:
                    return 0;
            }

        }
    }

    public Code(CodeType t, string op, string para)
    {
        Type = t;
        Op = op;
        Para = para;
    }
}

public class Program1
{
    static void Main()
    {
        var biosList = new List<string> {
            "0000H CHKRAM",
            "000CH RDSLT",
            "0010H CHRGTR",
            "0014H WRSLT",
            "0018H OUTDO",
            "001CH CALSLT",
            "0020H DCOMPR",
            "0024H ENASLT",
            "0028H GETYPR",
            "0030H CALLF",
            "0038H KEYINT",
            "003BH INITIO",
            "003EH INIFNK",
            "0041H DISSCR",
            "0044H ENASCR",
            "0047H WRTVDP",
            "004AH RDVRM",
            "004DH WRTVRM",
            "0050H SETRD",
            "0053H SETWRT",
            "0056H FILVRM",
            "0059H LDIRMV",
            "005CH LDIRVM",
            "005FH CHGMOD",
            "0062H CHGCLR",
            "0066H NMI",
            "0069H CLRSPR",
            "006CH INITXT",
            "006FH INIT32",
            "0072H INIGRP",
            "0075H INIMLT",
            "0078H SETTXT",
            "007BH SETT32",
            "007EH SETGRP",
            "0081H SETMLT",
            "0084H CALPAT",
            "0087H CALATR",
            "008AH GSPSIZ",
            "008DH GRPPRT",
            "0090H GICINI",
            "0093H WRTPSG",
            "0096H RDPSG",
            "0099H STRTMS",
            "009CH CHSNS",
            "009FH CHGET",
            "00A2H CHPUT",
            "00A5H LPTOUT",
            "00A8H LPTSTT",
            "00ABH CNVCHR",
            "00AEH PINLIN",
            "00B1H INLIN",
            "00B4H QINLIN",
            "00B7H BREAKX",
            "00C0H BEEP",
            "00C3H CLS",
            "00C6H POSIT",
            "00C9H FNKSB",
            "00CCH ERAFNK",
            "00CFH DSPFNK",
            "00D2H TOTEXT",
            "00D5H GTSTCK",
            "00D8H GTTRIG",
            "00DBH GTPAD",
            "00DEH GTPDL",
            "00E1H TAPION",
            "00E4H TAPIN",
            "00E7H TAPIOF",
            "00EAH TAPOON",
            "00EDH TAPOUT",
            "00F0H TAPOOF",
            "00F3H STMOTR",
            "0132H CHGCAP",
            "0135H CHGSND",
            "0138H RSLREG",
            "013BH WSLREG",
            "013EH RDVDP",
            "0141H SNSMAT",
            "0144H PHYDIO",
            "014AH ISFLIO",
            "014DH OUTDLP",
            "0156H KILBUF",
            "0159H CALBAS",
            "015CH SUBROM",
            "015FH EXTROM",
            "0168H EOL",
            "016BH BIGFIL",
            "016EH NSETRD",
            "0171H NSTWRT",
            "0174H NRDVRM",
            "0177H NWRVRM",
            "0180H CHGCPU",
            "0183H GETCPU",
            "0186H PCMPLY",
            "0189H PCMREC",
        };
        var mnemonicList = new List<string> {
            "00   NOP",
            "01   LD    BC,nn",
            "02   LD    (BC),A",
            "03   INC   BC",
            "04   INC   B",
            "05   DEC   B",
            "06   LD    B,n",
            "07   RLCA",
            "08   EX    AF,AF'",
            "09   ADD   HL,BC",
            "0A   LD    A,(BC)",
            "0B   DEC   BC",
            "0C   INC   C",
            "0D   DEC   C",
            "0E   LD    C,n",
            "0F   RRCA",
            "10   DJNZ  e",
            "11   LD    DE,nn",
            "12   LD    (DE),A",
            "13   INC   DE",
            "14   INC   D",
            "15   DEC   D",
            "16   LD    D,n",
            "17   RLA",
            "18   JR    e",
            "19   ADD   HL,DE",
            "1A   LD    A,(DE)",
            "1B   DEC   DE",
            "1C   INC   E",
            "1D   DEC   E",
            "1E   LD    E,n",
            "1F   RRA",
            "20   JR    NZ,e",
            "21   LD    HL,nn",
            "22   LD    (nn),HL",
            "23   INC   HL",
            "24   INC   H",
            "25   DEC   H",
            "26   LD    H,n",
            "27   DAA",
            "28   JR    Z,e",
            "29   ADD   HL,HL",
            "2A   LD    HL,(nn)",
            "2B   DEC   HL",
            "2C   INC   L",
            "2D   DEC   L",
            "2E   LD    L,n",
            "2F   CPL",
            "30   JR    NC,e",
            "31   LD    SP,nn",
            "32   LD    (nn),A",
            "33   INC   SP",
            "34   INC   (HL)",
            "35   DEC   (HL)",
            "36   LD    (HL),n",
            "37   SCF",
            "38   JR    C,e",
            "39   ADD   HL,SP",
            "3A   LD    A,(nn)",
            "3B   DEC   SP",
            "3C   INC   A",
            "3D   DEC   A",
            "3E   LD    A,n",
            "3F   CCF",
            "40   LD    B,B",
            "41   LD    B,C",
            "42   LD    B,D",
            "43   LD    B,E",
            "44   LD    B,H",
            "45   LD    B,L",
            "46   LD    B,(HL)",
            "47   LD    B,A",
            "48   LD    C,B",
            "49   LD    C,C",
            "4A   LD    C,D",
            "4B   LD    C,E",
            "4C   LD    C,H",
            "4D   LD    C,L",
            "4E   LD    C,(HL)",
            "4F   LD    C,A",
            "50   LD    D,B",
            "51   LD    D,C",
            "52   LD    D,D",
            "53   LD    D,E",
            "54   LD    D,H",
            "55   LD    D,L",
            "56   LD    D,(HL)",
            "57   LD    D,A",
            "58   LD    E,B",
            "59   LD    E,C",
            "5A   LD    E,D",
            "5B   LD    E,E",
            "5C   LD    E,H",
            "5D   LD    E,L",
            "5E   LD    E,(HL)",
            "5F   LD    E,A",
            "60   LD    H,B",
            "61   LD    H,C",
            "62   LD    H,D",
            "63   LD    H,E",
            "64   LD    H,H",
            "65   LD    H,L",
            "66   LD    H,(HL)",
            "67   LD    H,A",
            "68   LD    L,B",
            "69   LD    L,C",
            "6A   LD    L,D",
            "6B   LD    L,E",
            "6C   LD    L,H",
            "6D   LD    L,L",
            "6E   LD    L,(HL)",
            "6F   LD    L,A",
            "70   LD    (HL),B",
            "71   LD    (HL),C",
            "72   LD    (HL),D",
            "73   LD    (HL),E",
            "74   LD    (HL),H",
            "75   LD    (HL),L",
            "76   HALT",
            "77   LD    (HL),A",
            "78   LD    A,B",
            "79   LD    A,C",
            "7A   LD    A,D",
            "7B   LD    A,E",
            "7C   LD    A,H",
            "7D   LD    A,L",
            "7E   LD    A,(HL)",
            "7F   LD    A,A",
            "80   ADD   A,B",
            "81   ADD   A,C",
            "82   ADD   A,D",
            "83   ADD   A,E",
            "84   ADD   A,H",
            "85   ADD   A,L",
            "86   ADD   A,(HL)",
            "87   ADD   A,A",
            "88   ADC   A,B",
            "89   ADC   A,C",
            "8A   ADC   A,D",
            "8B   ADC   A,E",
            "8C   ADC   A,H",
            "8D   ADC   A,L",
            "8E   ADC   A,(HL)",
            "8F   ADC   A,A",
            "90   SUB   B",
            "91   SUB   C",
            "92   SUB   D",
            "93   SUB   E",
            "94   SUB   H",
            "95   SUB   L",
            "96   SUB   (HL)",
            "97   SUB   A",
            "98   SBC   A,B",
            "99   SBC   A,C",
            "9A   SBC   A,D",
            "9B   SBC   A,E",
            "9C   SBC   A,H",
            "9D   SBC   A,L",
            "9E   SBC   A,(HL)",
            "9F   SBC   A,A",
            "A0   AND   B",
            "A1   AND   C",
            "A2   AND   D",
            "A3   AND   E",
            "A4   AND   H",
            "A5   AND   L",
            "A6   AND   (HL)",
            "A7   AND   A",
            "A8   XOR   B",
            "A9   XOR   C",
            "AA   XOR   D",
            "AB   XOR   E",
            "AC   XOR   H",
            "AD   XOR   L",
            "AE   XOR   (HL)",
            "AF   XOR   A",
            "B0   OR    B",
            "B1   OR    C",
            "B2   OR    D",
            "B3   OR    E",
            "B4   OR    H",
            "B5   OR    L",
            "B6   OR    (HL)",
            "B7   OR    A",
            "B8   CP    B",
            "B9   CP    C",
            "BA   CP    D",
            "BB   CP    E",
            "BC   CP    H",
            "BD   CP    L",
            "BE   CP    (HL)",
            "BF   CP    A",
            "C0   RET   NZ",
            "C1   POP   BC",
            "C2   JP    NZ,nn",
            "C3   JP    nn",
            "C4   CALL  NZ,nn",
            "C5   PUSH  BC",
            "C6   ADD   A,n",
            "C7   RST   00H",
            "C8   RET   Z",
            "C9   RET",
            "CA   JP    Z,nn",
            "CB   xx",
            "CC   CALL  Z,nn",
            "CD   CALL  nn",
            "CE   ADC   A,n",
            "CF   RST   08H",
            "D0   RET   NC",
            "D1   POP   DE",
            "D2   JP    NC,nn",
            "D3   OUT   n,A",
            "D4   CALL  NC,nn",
            "D5   PUSH  DE",
            "D6   SUB   n",
            "D7   RST   10H",
            "D8   RET   C",
            "D9   EXX",
            "DA   JP    C,nn",
            "DB   IN    A,n",
            "DC   CALL  C,nn",
            "DD   xx",
            "DE   SBC   A,n",
            "DF   RST   18H",
            "E0   RET   PO",
            "E1   POP   HL",
            "E2   JP    PO,nn",
            "E3   EX    (SP),HL",
            "E4   CALL  PO,nn",
            "E5   PUSH  HL",
            "E6   AND   n",
            "E7   RST   20H",
            "E8   RET   PE",
            "E9   JP    (HL)",
            "EA   JP    PE,nn",
            "EB   EX    DE,HL",
            "EC   CALL  PE,NN",
            "ED   xx",
            "EE   XOR   n",
            "EF   RST   28H",
            "F0   RET   P",
            "F1   POP   AF",
            "F2   JP    P,nn",
            "F3   DI",
            "F4   CALL  P,nn",
            "F5   PUSH  AF",
            "F6   OR    n",
            "F7   RST   30H",
            "F8   RET   M",
            "F9   LD    SP,HL",
            "FA   JP    M,nn",
            "FB   EI",
            "FC   CALL  M,nn",
            "FD   xx",
            "FE   CP    n",
            "FF   RST   38H",
            "CB 00   RLC   B",
            "CB 01   RLC   C",
            "CB 02   RLC   D",
            "CB 03   RLC   E",
            "CB 04   RLC   H",
            "CB 05   RLC   L",
            "CB 06   RLC   (HL)",
            "CB 07   RLC   A",
            "CB 08   RRC   B",
            "CB 09   RRC   C",
            "CB 0A   RRC   D",
            "CB 0B   RRC   E",
            "CB 0C   RRC   H",
            "CB 0D   RRC   L",
            "CB 0E   RRC   (HL)",
            "CB 0F   RRC   A",
            "CB 10   RL    B",
            "CB 11   RL    C",
            "CB 12   RL    D",
            "CB 13   RL    E",
            "CB 14   RL    H",
            "CB 15   RL    L",
            "CB 16   RL    (HL)",
            "CB 17   RL    A",
            "CB 18   RR    B",
            "CB 19   RR    C",
            "CB 1A   RR    D",
            "CB 1B   RR    E",
            "CB 1C   RR    H",
            "CB 1D   RR    L",
            "CB 1E   RR    (HL)",
            "CB 1F   RR    A",
            "CB 20   SLA   B",
            "CB 21   SLA   C",
            "CB 22   SLA   D",
            "CB 23   SLA   E",
            "CB 24   SLA   H",
            "CB 25   SLA   L",
            "CB 26   SLA   (HL)",
            "CB 27   SLA   A",
            "CB 28   SRA   B",
            "CB 29   SRA   C",
            "CB 2A   SRA   D",
            "CB 2B   SRA   E",
            "CB 2C   SRA   H",
            "CB 2D   SRA   L",
            "CB 2E   SRA   (HL)",
            "CB 2F   SRA   A",
            "CB 30",
            "CB 31",
            "CB 32",
            "CB 33",
            "CB 34",
            "CB 35",
            "CB 36",
            "CB 37",
            "CB 38   SRL   B",
            "CB 39   SRL   C",
            "CB 3A   SRL   D",
            "CB 3B   SRL   E",
            "CB 3C   SRL   H",
            "CB 3D   SRL   L",
            "CB 3E   SRL   (HL)",
            "CB 3F   SRL   A",
            "CB 40   BIT   0,B",
            "CB 41   BIT   0,C",
            "CB 42   BIT   0,D",
            "CB 43   BIT   0,E",
            "CB 44   BIT   0,H",
            "CB 45   BIT   0,L",
            "CB 46   BIT   0,(HL)",
            "CB 47   BIT   0,A",
            "CB 48   BIT   1,B",
            "CB 49   BIT   1,C",
            "CB 4A   BIT   1,D",
            "CB 4B   BIT   1,E",
            "CB 4C   BIT   1,H",
            "CB 4D   BIT   1,L",
            "CB 4E   BIT   1,(HL)",
            "CB 4F   BIT   1,A",
            "CB 50   BIT   2,B",
            "CB 51   BIT   2,C",
            "CB 52   BIT   2,D",
            "CB 53   BIT   2,E",
            "CB 54   BIT   2,H",
            "CB 55   BIT   2,L",
            "CB 56   BIT   2,(HL)",
            "CB 57   BIT   2,A",
            "CB 58   BIT   3,B",
            "CB 59   BIT   3,C",
            "CB 5A   BIT   3,D",
            "CB 5B   BIT   3,E",
            "CB 5C   BIT   3,H",
            "CB 5D   BIT   3,L",
            "CB 5E   BIT   3,(HL)",
            "CB 5F   BIT   3,A",
            "CB 60   BIT   4,B",
            "CB 61   BIT   4,C",
            "CB 62   BIT   4,D",
            "CB 63   BIT   4,E",
            "CB 64   BIT   4,H",
            "CB 65   BIT   4,L",
            "CB 66   BIT   4,(HL)",
            "CB 67   BIT   4,A",
            "CB 68   BIT   5,B",
            "CB 69   BIT   5,C",
            "CB 6A   BIT   5,D",
            "CB 6B   BIT   5,E",
            "CB 6C   BIT   5,H",
            "CB 6D   BIT   5,L",
            "CB 6E   BIT   5,(HL)",
            "CB 6F   BIT   5,A",
            "CB 70   BIT   6,B",
            "CB 71   BIT   6,C",
            "CB 72   BIT   6,D",
            "CB 73   BIT   6,E",
            "CB 74   BIT   6,H",
            "CB 75   BIT   6,L",
            "CB 76   BIT   6,(HL)",
            "CB 77   BIT   6,A",
            "CB 78   BIT   7,B",
            "CB 79   BIT   7,C",
            "CB 7A   BIT   7,D",
            "CB 7B   BIT   7,E",
            "CB 7C   BIT   7,H",
            "CB 7D   BIT   7,L",
            "CB 7E   BIT   7,(HL)",
            "CB 7F   BIT   7,A",
            "CB 80   RES   0,B",
            "CB 81   RES   0,C",
            "CB 82   RES   0,D",
            "CB 83   RES   0,E",
            "CB 84   RES   0,H",
            "CB 85   RES   0,L",
            "CB 86   RES   0,(HL)",
            "CB 87   RES   0,A",
            "CB 88   RES   1,B",
            "CB 89   RES   1,C",
            "CB 8A   RES   1,D",
            "CB 8B   RES   1,E",
            "CB 8C   RES   1,H",
            "CB 8D   RES   1,L",
            "CB 8E   RES   1,(HL)",
            "CB 8F   RES   1,A",
            "CB 90   RES   2,B",
            "CB 91   RES   2,C",
            "CB 92   RES   2,D",
            "CB 93   RES   2,E",
            "CB 94   RES   2,H",
            "CB 95   RES   2,L",
            "CB 96   RES   2,(HL)",
            "CB 97   RES   2,A",
            "CB 98   RES   3,B",
            "CB 99   RES   3,C",
            "CB 9A   RES   3,D",
            "CB 9B   RES   3,E",
            "CB 9C   RES   3,H",
            "CB 9D   RES   3,L",
            "CB 9E   RES   3,(HL)",
            "CB 9F   RES   3,A",
            "CB A0   RES   4,B",
            "CB A1   RES   4,C",
            "CB A2   RES   4,D",
            "CB A3   RES   4,E",
            "CB A4   RES   4,H",
            "CB A5   RES   4,L",
            "CB A6   RES   4,(HL)",
            "CB A7   RES   4,A",
            "CB A8   RES   5,B",
            "CB A9   RES   5,C",
            "CB AA   RES   5,D",
            "CB AB   RES   5,E",
            "CB AC   RES   5,H",
            "CB AD   RES   5,L",
            "CB AE   RES   5,(HL)",
            "CB AF   RES   5,A",
            "CB B0   RES   6,B",
            "CB B1   RES   6,C",
            "CB B2   RES   6,D",
            "CB B3   RES   6,E",
            "CB B4   RES   6,H",
            "CB B5   RES   6,L",
            "CB B6   RES   6,(HL)",
            "CB B7   RES   6,A",
            "CB B8   RES   7,B",
            "CB B9   RES   7,C",
            "CB BA   RES   7,D",
            "CB BB   RES   7,E",
            "CB BC   RES   7,H",
            "CB BD   RES   7,L",
            "CB BE   RES   7,(HL)",
            "CB BF   RES   7,A",
            "CB C0   SET   0,B",
            "CB C1   SET   0,C",
            "CB C2   SET   0,D",
            "CB C3   SET   0,E",
            "CB C4   SET   0,H",
            "CB C5   SET   0,L",
            "CB C6   SET   0,(HL)",
            "CB C7   SET   0,A",
            "CB C8   SET   1,B",
            "CB C9   SET   1,C",
            "CB CA   SET   1,D",
            "CB CB   SET   1,E",
            "CB CC   SET   1,H",
            "CB CD   SET   1,L",
            "CB CE   SET   1,(HL)",
            "CB CF   SET   1,A",
            "CB D0   SET   2,B",
            "CB D1   SET   2,C",
            "CB D2   SET   2,D",
            "CB D3   SET   2,E",
            "CB D4   SET   2,H",
            "CB D5   SET   2,L",
            "CB D6   SET   2,(HL)",
            "CB D7   SET   2,A",
            "CB D8   SET   3,B",
            "CB D9   SET   3,C",
            "CB DA   SET   3,D",
            "CB DB   SET   3,E",
            "CB DC   SET   3,H",
            "CB DD   SET   3,L",
            "CB DE   SET   3,(HL)",
            "CB DF   SET   3,A",
            "CB E0   SET   4,B",
            "CB E1   SET   4,C",
            "CB E2   SET   4,D",
            "CB E3   SET   4,E",
            "CB E4   SET   4,H",
            "CB E5   SET   4,L",
            "CB E6   SET   4,(HL)",
            "CB E7   SET   4,A",
            "CB E8   SET   5,B",
            "CB E9   SET   5,C",
            "CB EA   SET   5,D",
            "CB EB   SET   5,E",
            "CB EC   SET   5,H",
            "CB ED   SET   5,L",
            "CB EE   SET   5,(HL)",
            "CB EF   SET   5,A",
            "CB F0   SET   6,B",
            "CB F1   SET   6,C",
            "CB F2   SET   6,D",
            "CB F3   SET   6,E",
            "CB F4   SET   6,H",
            "CB F5   SET   6,L",
            "CB F6   SET   6,(HL)",
            "CB F7   SET   6,A",
            "CB F8   SET   7,B",
            "CB F9   SET   7,C",
            "CB FA   SET   7,D",
            "CB FB   SET   7,E",
            "CB FC   SET   7,H",
            "CB FD   SET   7,L",
            "CB FE   SET   7,(HL)",
            "CB FF   SET   7,A",
            "DD 09        ADD   IX,BC",
            "DD 19        ADD   IX,DE",
            "DD 21        LD    IX,nn",
            "DD 22        LD    (nn),IX",
            "DD 23        INC   IX",
            "DD 29        ADD   IX,IX",
            "DD 2A        LD    IX,(nn)",
            "DD 2B        DEC   IX",
            "DD 34        INC   (IX+d)",
            "DD 35        DEC   (IX+D)",
            "DD 36        LD    (IX+d),n",
            "DD 39        ADD   IX,SP",
            "DD 46        LD    B,(IX+d)",
            "DD 4E        LD    C,(IX+d)",
            "DD 56        LD    D,(IX+d)",
            "DD 5E        LD    E,(IX+d)",
            "DD 66        LD    H,(IX+d)",
            "DD 6E        LD    L,(IX+d)",
            "DD 70        LD    (IX+d),B",
            "DD 71        LD    (IX+d),C",
            "DD 72        LD    (IX+d),D",
            "DD 73        LD    (IX+d),E",
            "DD 74        LD    (IX+d),H",
            "DD 75        LD    (IX+d),L",
            "DD 77        LD    (IX+d),A",
            "DD 7E        LD    A,(IX+d)",
            "DD 86        ADD   A,(IX+d)",
            "DD 8E        ADC   A,(IX+d)",
            "DD 96        SUB   A,(IX+d)",
            "DD 9E        SBC   A,(IX+d)",
            "DD A6        AND   (IX+d)",
            "DD AE        XOR   (IX+d)",
            "DD B6        OR    (IX+d)",
            "DD BE        CP    (IX+d)",
            "DD CB d 06   RLC   (IX+d)",
            "DD CB d 0E   RRC   (IX+d)",
            "DD CB d 16   RL    (IX+d)",
            "DD CB d 1E   RR    (IX+d)",
            "DD CB d 26   SLA   (IX+d)",
            "DD CB d 2E   SRA   (IX+d)",
            "DD CB d 3E   SRL   (IX+d)",
            "DD CB d 46   BIT   0,(IX+d)",
            "DD CB d 4E   BIT   1,(IX+d)",
            "DD CB d 56   BIT   2,(IX+d)",
            "DD CB d 5E   BIT   3,(IX+d)",
            "DD CB d 66   BIT   4,(IX+d)",
            "DD CB d 6E   BIT   5,(IX+d)",
            "DD CB d 76   BIT   6,(IX+d)",
            "DD CB d 7E   BIT   7,(IX+d)",
            "DD CB d 86   RES   0,(IX+d)",
            "DD CB d 8E   RES   1,(IX+d)",
            "DD CB d 96   RES   2,(IX+d)",
            "DD CB d 9E   RES   3,(IX+d)",
            "DD CB d A6   RES   4,(IX+d)",
            "DD CB d AE   RES   5,(IX+d)",
            "DD CB d B6   RES   6,(IX+d)",
            "DD CB d BE   RES   7,(IX+d)",
            "DD CB d C6   SET   0,(IX+d)",
            "DD CB d CE   SET   1,(IX+d)",
            "DD CB d D6   SET   2,(IX+d)",
            "DD CB d DE   SET   3,(IX+d)",
            "DD CB d E6   SET   4,(IX+d)",
            "DD CB d EE   SET   5,(IX+d)",
            "DD CB d F6   SET   6,(IX+d)",
            "DD CB d FE   SET   7,(IX+d)",
            "DD E1        POP   IX",
            "DD E3        EX    (SP),IX",
            "DD E5        PUSH   IX",
            "DD E9        JP    (IX)",
            "DD F9        LD    SP,IX",
            "ED 40   IN    B,(C)",
            "ED 41   OUT   (C),B",
            "ED 42   SBC   HL,BC",
            "ED 43   LD    (nn),BC",
            "ED 44   NEG",
            "ED 45   RETN",
            "ED 46   IM    0",
            "ED 47   LD    I,A",
            "ED 48   IN    C,(C)",
            "ED 49   OUT   (C),C",
            "ED 4A   ADC   HL,BC",
            "ED 4B   LD    BC,(nn)",
            "ED 4D   RETI",
            "ED 4F   LD    R,A",
            "ED 50   IN    D,(C)",
            "ED 51   OUT   (C),D",
            "ED 52   SBC   HL,DE",
            "ED 53   LD    (nn),DE",
            "ED 56   IM    1",
            "ED 57   LD    A,I",
            "ED 58   IN    E,(C)",
            "ED 59   OUT   (C),E",
            "ED 5A   ADC   HL,DE",
            "ED 5B   LD    DE,(nn)",
            "ED 5E   IM    2",
            "ED 5F   LD    A,R",
            "ED 60   IN    H,(C)",
            "ED 61   OUT   (C),H",
            "ED 62   SBC   HL,HL",
            "ED 67   RRD",
            "ED 68   IN    L,(C)",
            "ED 69   OUT   (C),L",
            "ED 6A   ADC   HL,HL",
            "ED 6F   RLD",
            "ED 72   SBC   HL,SP",
            "ED 73   LD    (nn),SP",
            "ED 78   IN    A,(C)",
            "ED 79   OUT   (c),A",
            "ED 7A   ADC   HL,SP",
            "ED 7B   LD    SP,(nn)",
            "ED A0   LDI",
            "ED A1   CPI",
            "ED A2   INI",
            "ED A3   OUTI",
            "ED A8   LDD",
            "ED A9   CPD",
            "ED AA   IND",
            "ED AB   OUTD",
            "ED B0   LDIR",
            "ED B1   CPIR",
            "ED B2   INIR",
            "ED B3   OTIR",
            "ED B8   LDDR",
            "ED B9   CPDR",
            "ED BA   INDR",
            "ED BB   OTDR",
            "FD 09        ADD   IY,BC",
            "FD 19        ADD   IY,DE",
            "FD 21        LD    IY,nn",
            "FD 22        LD    (nn),IY",
            "FD 23        INC   IY",
            "FD 29        ADD   IY,IY",
            "FD 2A        LD    IY,(nn)",
            "FD 2B        DEC   IY",
            "FD 34        INC   (IY+d)",
            "FD 35        DEC   (IY+D)",
            "FD 36        LD    (IY+d),n",
            "FD 39        ADD   IY,SP",
            "FD 46        LD    B,(IY+d)",
            "FD 4E        LD    C,(IY+d)",
            "FD 56        LD    D,(IY+d)",
            "FD 5E        LD    E,(IY+d)",
            "FD 66        LD    H,(IY+d)",
            "FD 6E        LD    L,(IY+d)",
            "FD 70        LD    (IY+d),B",
            "FD 71        LD    (IY+d),C",
            "FD 72        LD    (IY+d),D",
            "FD 73        LD    (IY+d),E",
            "FD 74        LD    (IY+d),H",
            "FD 75        LD    (IY+d),L",
            "FD 77        LD    (IY+d),A",
            "FD 7E        LD    A,(IY+d)",
            "FD 86        ADD   A,(IY+d)",
            "FD 8E        ADC   A,(IY+d)",
            "FD 96        SUB   A,(IY+d)",
            "FD 9E        SBC   A,(IY+d)",
            "FD A6        AND   (IY+d)",
            "FD AE        XOR   (IY+d)",
            "FD B6        OR    (IY+d)",
            "FD BE        CP    (IY+d)",
            "FD CB d 06   RLC   (IY+d)",
            "FD CB d 0E   RRC   (IY+d)",
            "FD CB d 16   RL    (IY+d)",
            "FD CB d 1E   RR    (IY+d)",
            "FD CB d 26   SLA   (IY+d)",
            "FD CB d 2E   SRA   (IY+d)",
            "FD CB d 3E   SRL   (IY+d)",
            "FD CB d 46   BIT   0,(IY+d)",
            "FD CB d 4E   BIT   1,(IY+d)",
            "FD CB d 56   BIT   2,(IY+d)",
            "FD CB d 5E   BIT   3,(IY+d)",
            "FD CB d 66   BIT   4,(IY+d)",
            "FD CB d 6E   BIT   5,(IY+d)",
            "FD CB d 76   BIT   6,(IY+d)",
            "FD CB d 7E   BIT   7,(IY+d)",
            "FD CB d 86   RES   0,(IY+d)",
            "FD CB d 8E   RES   1,(IY+d)",
            "FD CB d 96   RES   2,(IY+d)",
            "FD CB d 9E   RES   3,(IY+d)",
            "FD CB d A6   RES   4,(IY+d)",
            "FD CB d AE   RES   5,(IY+d)",
            "FD CB d B6   RES   6,(IY+d)",
            "FD CB d BE   RES   7,(IY+d)",
            "FD CB d C6   SET   0,(IY+d)",
            "FD CB d CE   SET   1,(IY+d)",
            "FD CB d D6   SET   2,(IY+d)",
            "FD CB d DE   SET   3,(IY+d)",
            "FD CB d E6   SET   4,(IY+d)",
            "FD CB d EE   SET   5,(IY+d)",
            "FD CB d F6   SET   6,(IY+d)",
            "FD CB d FE   SET   7,(IY+d)",
            "FD E1        POP   IY",
            "FD E3        EX    (SP),IY",
            "FD E5        PUSH  IY",
            "FD E9        JP    (IY)",
            "FD F9        LD    SP,IY"
        };

        Action<string> Sub = (string binPath) => {

            // アセンブラ命令の一覧辞書を作成
            var dic = new Dictionary<string, Code>();
            foreach(var line in mnemonicList) {
                var es = Regex.Split(line, @"\s+");
                int count = es.Count();

                switch(count) {
                    case 2:
                        if (es[0] == "CB") break;
                        if (es[1] == "xx") break;
                        // 00 NOP など 1バイト
                        dic.Add(es[0], new Code(CodeType.SINGLE, es[1], ""));
                        break;
                    case 3:
                        if (Regex.IsMatch(es[2], "nn")) {
                            dic.Add(es[0], new Code(CodeType.SINGLE_NN, es[1], es[2]));
                        } else if (Regex.IsMatch(es[2], "d") && Regex.IsMatch(es[3], "n")) {
                            dic.Add(es[0], new Code(CodeType.SINGLE_D_N, es[1], es[2]));
                        } else if (Regex.IsMatch(es[2], "d")) {
                            dic.Add(es[0], new Code(CodeType.SINGLE_D, es[1], es[2]));
                        } else if (Regex.IsMatch(es[2], "n")) {
                            dic.Add(es[0], new Code(CodeType.SINGLE_N, es[1], es[2]));
                        } else if (Regex.IsMatch(es[2], "e")) {
                            dic.Add(es[0], new Code(CodeType.SINGLE_E, es[1], es[2]));
                        } else {
                            if (es[0] == "ED") {
                                dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE, es[2], ""));
                            } else {
                                dic.Add(es[0], new Code(CodeType.SINGLE, es[1], es[2]));
                            }
                        }
                        break;
                    case 4:
                        if (Regex.IsMatch(es[3], "nn")) {
                            dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE_NN, es[2], es[3]));
                        } else if (Regex.IsMatch(es[3], "d") && Regex.IsMatch(es[3], "n")) {
                            dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE_D_N, es[2], es[3]));
                        } else if (Regex.IsMatch(es[3], "d")) {
                            dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE_D, es[2], es[3]));
                        } else if (Regex.IsMatch(es[3], "n")) {
                            dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE_N, es[2], es[3]));
                        } else {
                            dic.Add(es[0]+es[1], new Code(CodeType.DOUBLE, es[2], es[3]));
                        }
                        break;
                    case 6:
                            dic.Add(es[0]+es[1]+es[3], new Code(CodeType.DOUBLE, es[4], es[5]));
                        break;
                }
            }
            // bios一覧辞書を作成
            var biosDic = new Dictionary<string, string>();
            foreach(var line in biosList) {
                var es = Regex.Split(line, @"\s+");
                biosDic.Add(es[0], es[1]);
            }

            // .binファイルの読み込み
            int headerLen = 7;
            byte[] header = new byte[headerLen];
            byte[]? bins;
            int startAddress = 0;
            int endAddress = 0;
            int execAddress = 0;
            using (var fs = new FileStream(binPath, FileMode.Open))
            using (var bs = new BinaryReader(fs)) {
                int len = (int)fs.Length - headerLen;
                bins = new byte[len];

                bs.Read(header, 0, headerLen);
                bs.Read(bins, 0, len);
            }
            startAddress = header[2] * 256 + header[1];
            Console.WriteLine("開始番地:{0:X4}", startAddress);
            endAddress = header[4] * 256 + header[3];
            Console.WriteLine("終了番地:{0:X4}", endAddress);
            execAddress = header[6] * 256 + header[5];
            Console.WriteLine("実行番地:{0:X4}", execAddress);

            // ディスアセンブル
            string para = "";
            int n = 0;
            string nn = "";
            for(int i=0; i<bins.Length; i++) {
                var key = string.Format("{0:X2}", bins[i]);
                if (bins[i] == 0xCB || bins[i] == 0xDD || bins[i] == 0xED || bins[i] == 0xFD) {
                    // 2バイト
                    key = key + string.Format("{0:X2}", bins[i+1]);;
                }
                int a = startAddress + i;
                switch(dic[key].Type) {
                    case CodeType.SINGLE:
                        Console.WriteLine("{0:X4} {1}------ {2} {3} ", a, key, dic[key].Op, dic[key].Para);
                        break;
                    case CodeType.SINGLE_E:
                        n = bins[i+1];
                        if (n > 127) { n = n - 256; }
                        n = n + 2;
                        para = Regex.Replace(dic[key].Para, "e", String.Format("{0};[{1:X4}H]",n, a+n));
                        Console.WriteLine("{0:X4} {1}{2:X2}---- {3} {4} ", a, key, bins[i+1], dic[key].Op, para);
                        break;
                    case CodeType.SINGLE_N:
                        para = Regex.Replace(dic[key].Para, "n", String.Format("{0:X2}H", bins[i+1]));
                        if (bins[i+1] >= 0x21 && bins[i+1] <= 0x7e) {
                            para = para + "; '" + Convert.ToChar(bins[i+1]) + "'";
                        }
                        Console.WriteLine("{0:X4} {1}{2:X2}---- {3} {4} ", a, key, bins[i+1], dic[key].Op, para);
                        break;
                    case CodeType.SINGLE_D:
                        para = Regex.Replace(dic[key].Para, "d", String.Format("{0:X2}H", bins[i+1]));
                        Console.WriteLine("{0:X4} {1:X2}{2:X2}---- {3} {4} ", a, key, bins[i+1], dic[key].Op, para);
                        break;
                    case CodeType.SINGLE_D_N:
                        para = Regex.Replace(dic[key].Para, "d", String.Format("{0:X2}H", bins[i+2]));
                        para = Regex.Replace(dic[key].Para, "n", String.Format("{0:X2}H", bins[i+1]));
                        Console.WriteLine("{0:X4} {1}{2:X2}{3:X2}-- {3} {4} ", a, key, bins[i+1], bins[i+2], dic[key].Op, para);
                        break;
                    case CodeType.SINGLE_NN:
                        nn = String.Format("{0:X2}{1:X2}H", bins[i+2], bins[i+1]);
                        if (biosDic.ContainsKey(nn)) nn = nn + "; " + biosDic[nn];
                        para = Regex.Replace(dic[key].Para, "nn", nn);
                        Console.WriteLine("{0:X4} {1}{2:X2}{3:X2}-- {4} {5} ", a, key, bins[i+1], bins[i+2], dic[key].Op, para);
                        break;
                    case CodeType.DOUBLE:
                        Console.WriteLine("{0:X4} {1}---- {2} {3} ", a, key, dic[key].Op, dic[key].Para);
                        break;
                    case CodeType.DOUBLE_N:
                        para = Regex.Replace(dic[key].Para, "n", String.Format("{0:X2}H", bins[i+2]));
                        if (bins[i+2] >= 0x21 && bins[i+2] <= 0x7e) {
                            para = para + "; '" + Convert.ToChar(bins[i+2]) + "'";
                        }
                        Console.WriteLine("{0:X4} {1}{2:X2}---- {3} {4} ", a, key, bins[i+2], dic[key].Op, para);
                        break;
                    case CodeType.DOUBLE_D:
                        para = Regex.Replace(dic[key].Para, "d", String.Format("{0:X2}H", bins[i+2]));
                        Console.WriteLine("{0:X4} {1}{2:X2}---- {3} {4} ", a, key, bins[i+2], dic[key].Op, para);
                        break;
                    case CodeType.DOUBLE_D_N:
                        para = Regex.Replace(dic[key].Para, "d", String.Format("{0:X2}H", bins[i+3]));
                        para = Regex.Replace(dic[key].Para, "n", String.Format("{0:X2}H", bins[i+2]));
                        Console.WriteLine("{0:X4} {1}{2:X2}{3:X2} {4} {5} ", a, key, bins[i+2], bins[i+3], dic[key].Op, para);
                        break;
                    case CodeType.DOUBLE_NN:
                        nn = String.Format("{0:X2}{1:X2}H", bins[i+2], bins[i+1]);
                        if (biosDic.ContainsKey(nn)) nn = nn + "; " + biosDic[nn];
                        para = Regex.Replace(dic[key].Para, "nn", nn);
                        Console.WriteLine("{0:X4} {1}{2:X2}{3:X2} {4} {5} ", a, key, bins[i+2], bins[i+3], dic[key].Op, para);
                        break;
                    case CodeType.QUAD_IN_D:
                        para = Regex.Replace(dic[key].Para, "d", String.Format("{0:X2}H", bins[i+2]));
                        Console.WriteLine("{0:X4} {1:X2}{2:X2}{3:X2}{4:X2} {5} {6} ", a, bins[i], bins[i+1], bins[i+2], bins[i+3], dic[key].Op, para);
                        break;
                }
                i = i + (dic[key].Count-1);
            }
        };

        Sub("program.bin");
    }
}

実行例

開始番地:D000
終了番地:D005
実行番地:0000
D000 3E41---- LD A,41H; 'A' 
D002 CDA200-- CALL 00A2H; CHPUT 
D005 C9------ RET  

注意:MSX初心者が作ったプログラムです。バグがあるとは思いますが、そもそもマシン語に対する理解が間違っている可能性がありますので、あらかじめご了承ください。

コメント