home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / emulator / unix / z80pack / z80sim / disas.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-09  |  20.4 KB  |  897 lines

  1. /*
  2.  * Z80 disassembler for    Z80-CPU    simulator
  3.  *
  4.  * Copyright (C) 1989-92 by Udo Munk
  5.  *
  6.  * This module of the Z80-CPU simulator must not be modified by a user,
  7.  * see license agreement!
  8.  *
  9.  * History:
  10.  * 06-DEC-89 Development on TARGON/35 with AT&T Unix System V.3
  11.  * 07-APR-92 forget to implement Op-Codes LD A,R and LD R,A, added
  12.  * 25-JUN-92 comments in english
  13.  */
  14.  
  15. #include <stdio.h>
  16.  
  17. /*
  18.  *    Forward    declarations
  19.  */
  20. int opout(), nout(), iout(), rout(), nnout(), inout(), cbop(), edop(), ddfd();
  21.  
  22. /*
  23.  *    Op-code    tables
  24.  */
  25. struct opt {
  26.     int (*fun) ();
  27.     char *text;
  28. };
  29.  
  30. static struct opt optab[256] = {
  31.     { opout,  "NOP"            },    /* 0x00    */
  32.     { nnout,  "LD\tBC,"        },    /* 0x01    */
  33.     { opout,  "LD\t(BC),A"        },    /* 0x02    */
  34.     { opout,  "INC\tBC"        },    /* 0x03    */
  35.     { opout,  "INC\tB"        },    /* 0x04    */
  36.     { opout,  "DEC\tB"        },    /* 0x05    */
  37.     { nout,      "LD\tB,"        },    /* 0x06    */
  38.     { opout,  "RLCA"        },    /* 0x07    */
  39.     { opout,  "EX\tAF,AF'"        },    /* 0x08    */
  40.     { opout,  "ADD\tHL,BC"        },    /* 0x09    */
  41.     { opout,  "LD\tA,(BC)"        },    /* 0x0a    */
  42.     { opout,  "DEC\tBC"        },    /* 0x0b    */
  43.     { opout,  "INC\tC"        },    /* 0x0c    */
  44.     { opout,  "DEC\tC"        },    /* 0x0d    */
  45.     { nout,      "LD\tC,"        },    /* 0x0e    */
  46.     { opout,  "RRCA"        },    /* 0x0f    */
  47.     { rout,      "DJNZ\t"        },    /* 0x10    */
  48.     { nnout,  "LD\tDE,"        },    /* 0x11    */
  49.     { opout,  "LD\t(DE),A"        },    /* 0x12    */
  50.     { opout,  "INC\tDE"        },    /* 0x13    */
  51.     { opout,  "INC\tD"        },    /* 0x14    */
  52.     { opout,  "DEC\tD"        },    /* 0x15    */
  53.     { nout,      "LD\tD,"        },    /* 0x16    */
  54.     { opout,  "RLA"            },    /* 0x17    */
  55.     { rout,      "JR\t"        },    /* 0x18    */
  56.     { opout,  "ADD\tHL,DE"        },    /* 0x19    */
  57.     { opout,  "LD\tA,(DE)"        },    /* 0x1a    */
  58.     { opout,  "DEC\tDE"        },    /* 0x1b    */
  59.     { opout,  "INC\tE"        },    /* 0x1c    */
  60.     { opout,  "DEC\tE"        },    /* 0x1d    */
  61.     { nout,      "LD\tE,"        },    /* 0x1e    */
  62.     { opout,  "RRA"            },    /* 0x1f    */
  63.     { rout,      "JR\tNZ,"        },    /* 0x20    */
  64.     { nnout,  "LD\tHL,"        },    /* 0x21    */
  65.     { inout,  "LD\t(%04x),HL"    },    /* 0x22    */
  66.     { opout,  "INC\tHL"        },    /* 0x23    */
  67.     { opout,  "INC\tH"        },    /* 0x24    */
  68.     { opout,  "DEC\tH"        },    /* 0x25    */
  69.     { nout,      "LD\tH,"        },    /* 0x26    */
  70.     { opout,  "DAA"            },    /* 0x27    */
  71.     { rout,      "JR\tZ,"        },    /* 0x28    */
  72.     { opout,  "ADD\tHL,HL"        },    /* 0x29    */
  73.     { inout,  "LD\tHL,(%04x)"    },    /* 0x2a    */
  74.     { opout,  "DEC\tHL"        },    /* 0x2b    */
  75.     { opout,  "INC\tL"        },    /* 0x2c    */
  76.     { opout,  "DEC\tL"        },    /* 0x2d    */
  77.     { nout,      "LD\tL,"        },    /* 0x2e    */
  78.     { opout,  "CPL"            },    /* 0x2f    */
  79.     { rout,      "JR\tNC,"        },    /* 0x30    */
  80.     { nnout,  "LD\tSP,"        },    /* 0x31    */
  81.     { inout,  "LD\t(%04x),A"    },    /* 0x32    */
  82.     { opout,  "INC\tSP"        },    /* 0x33    */
  83.     { opout,  "INC\t(HL)"        },    /* 0x34    */
  84.     { opout,  "DEC\t(HL)"        },    /* 0x35    */
  85.     { nout,      "LD\t(HL),"        },    /* 0x36    */
  86.     { opout,  "SCF"            },    /* 0x37    */
  87.     { rout,      "JR\tC,"        },    /* 0x38    */
  88.     { opout,  "ADD\tHL,SP"        },    /* 0x39    */
  89.     { inout,  "LD\tA,(%04x)"    },    /* 0x3a    */
  90.     { opout,  "DEC\tSP"        },    /* 0x3b    */
  91.     { opout,  "INC\tA"        },    /* 0x3c    */
  92.     { opout,  "DEC\tA"        },    /* 0x3d    */
  93.     { nout,      "LD\tA,"        },    /* 0x3e    */
  94.     { opout,  "CCF"            },    /* 0x3f    */
  95.     { opout,  "LD\tB,B"        },    /* 0x40    */
  96.     { opout,  "LD\tB,C"        },    /* 0x41    */
  97.     { opout,  "LD\tB,D"        },    /* 0x42    */
  98.     { opout,  "LD\tB,E"        },    /* 0x43    */
  99.     { opout,  "LD\tB,H"        },    /* 0x44    */
  100.     { opout,  "LD\tB,L"        },    /* 0x45    */
  101.     { opout,  "LD\tB,(HL)"        },    /* 0x46    */
  102.     { opout,  "LD\tB,A"        },    /* 0x47    */
  103.     { opout,  "LD\tC,B"        },    /* 0x48    */
  104.     { opout,  "LD\tC,C"        },    /* 0x49    */
  105.     { opout,  "LD\tC,D"        },    /* 0x4a    */
  106.     { opout,  "LD\tC,E"        },    /* 0x4b    */
  107.     { opout,  "LD\tC,H"        },    /* 0x4c    */
  108.     { opout,  "LD\tC,L"        },    /* 0x4d    */
  109.     { opout,  "LD\tC,(HL)"        },    /* 0x4e    */
  110.     { opout,  "LD\tC,A"        },    /* 0x4f    */
  111.     { opout,  "LD\tD,B"        },    /* 0x50    */
  112.     { opout,  "LD\tD,C"        },    /* 0x51    */
  113.     { opout,  "LD\tD,D"        },    /* 0x52    */
  114.     { opout,  "LD\tD,E"        },    /* 0x53    */
  115.     { opout,  "LD\tD,H"        },    /* 0x54    */
  116.     { opout,  "LD\tD,L"        },    /* 0x55    */
  117.     { opout,  "LD\tD,(HL)"        },    /* 0x56    */
  118.     { opout,  "LD\tD,A"        },    /* 0x57    */
  119.     { opout,  "LD\tE,B"        },    /* 0x58    */
  120.     { opout,  "LD\tE,C"        },    /* 0x59    */
  121.     { opout,  "LD\tE,D"        },    /* 0x5a    */
  122.     { opout,  "LD\tE,E"        },    /* 0x5b    */
  123.     { opout,  "LD\tE,H"        },    /* 0x5c    */
  124.     { opout,  "LD\tE,L"        },    /* 0x5d    */
  125.     { opout,  "LD\tE,(HL)"        },    /* 0x5e    */
  126.     { opout,  "LD\tE,A"        },    /* 0x5f    */
  127.     { opout,  "LD\tH,B"        },    /* 0x60    */
  128.     { opout,  "LD\tH,C"        },    /* 0x61    */
  129.     { opout,  "LD\tH,D"        },    /* 0x62    */
  130.     { opout,  "LD\tH,E"        },    /* 0x63    */
  131.     { opout,  "LD\tH,H"        },    /* 0x64    */
  132.     { opout,  "LD\tH,L"        },    /* 0x65    */
  133.     { opout,  "LD\tH,(HL)"        },    /* 0x66    */
  134.     { opout,  "LD\tH,A"        },    /* 0x67    */
  135.     { opout,  "LD\tL,B"        },    /* 0x68    */
  136.     { opout,  "LD\tL,C"        },    /* 0x69    */
  137.     { opout,  "LD\tL,D"        },    /* 0x6a    */
  138.     { opout,  "LD\tL,E"        },    /* 0x6b    */
  139.     { opout,  "LD\tL,H"        },    /* 0x6c    */
  140.     { opout,  "LD\tL,L"        },    /* 0x6d    */
  141.     { opout,  "LD\tL,(HL)"        },    /* 0x6e    */
  142.     { opout,  "LD\tL,A"        },    /* 0x6f    */
  143.     { opout,  "LD\t(HL),B"        },    /* 0x70    */
  144.     { opout,  "LD\t(HL),C"        },    /* 0x71    */
  145.     { opout,  "LD\t(HL),D"        },    /* 0x72    */
  146.     { opout,  "LD\t(HL),E"        },    /* 0x73    */
  147.     { opout,  "LD\t(HL),H"        },    /* 0x74    */
  148.     { opout,  "LD\t(HL),L"        },    /* 0x75    */
  149.     { opout,  "HALT"        },    /* 0x76    */
  150.     { opout,  "LD\t(HL),A"        },    /* 0x77    */
  151.     { opout,  "LD\tA,B"        },    /* 0x78    */
  152.     { opout,  "LD\tA,C"        },    /* 0x79    */
  153.     { opout,  "LD\tA,D"        },    /* 0x7a    */
  154.     { opout,  "LD\tA,E"        },    /* 0x7b    */
  155.     { opout,  "LD\tA,H"        },    /* 0x7c    */
  156.     { opout,  "LD\tA,L"        },    /* 0x7d    */
  157.     { opout,  "LD\tA,(HL)"        },    /* 0x7e    */
  158.     { opout,  "LD\tA,A"        },    /* 0x7f    */
  159.     { opout,  "ADD\tA,B"        },    /* 0x80    */
  160.     { opout,  "ADD\tA,C"        },    /* 0x81    */
  161.     { opout,  "ADD\tA,D"        },    /* 0x82    */
  162.     { opout,  "ADD\tA,E"        },    /* 0x83    */
  163.     { opout,  "ADD\tA,H"        },    /* 0x84    */
  164.     { opout,  "ADD\tA,L"        },    /* 0x85    */
  165.     { opout,  "ADD\tA,(HL)"        },    /* 0x86    */
  166.     { opout,  "ADD\tA,A"        },    /* 0x87    */
  167.     { opout,  "ADC\tA,B"        },    /* 0x88    */
  168.     { opout,  "ADC\tA,C"        },    /* 0x89    */
  169.     { opout,  "ADC\tA,D"        },    /* 0x8a    */
  170.     { opout,  "ADC\tA,E"        },    /* 0x8b    */
  171.     { opout,  "ADC\tA,H"        },    /* 0x8c    */
  172.     { opout,  "ADC\tA,L"        },    /* 0x8d    */
  173.     { opout,  "ADC\tA,(HL)"        },    /* 0x8e    */
  174.     { opout,  "ADC\tA,A"        },    /* 0x8f    */
  175.     { opout,  "SUB\tB"        },    /* 0x90    */
  176.     { opout,  "SUB\tC"        },    /* 0x91    */
  177.     { opout,  "SUB\tD"        },    /* 0x92    */
  178.     { opout,  "SUB\tE"        },    /* 0x93    */
  179.     { opout,  "SUB\tH"        },    /* 0x94    */
  180.     { opout,  "SUB\tL"        },    /* 0x95    */
  181.     { opout,  "SUB\t(HL)"        },    /* 0x96    */
  182.     { opout,  "SUB\tA"        },    /* 0x97    */
  183.     { opout,  "SBC\tA,B"        },    /* 0x98    */
  184.     { opout,  "SBC\tA,C"        },    /* 0x99    */
  185.     { opout,  "SBC\tA,D"        },    /* 0x9a    */
  186.     { opout,  "SBC\tA,E"        },    /* 0x9b    */
  187.     { opout,  "SBC\tA,H"        },    /* 0x9c    */
  188.     { opout,  "SBC\tA,L"        },    /* 0x9d    */
  189.     { opout,  "SBC\tA,(HL)"        },    /* 0x9e    */
  190.     { opout,  "SBC\tA,A"        },    /* 0x9f    */
  191.     { opout,  "AND\tB"        },    /* 0xa0    */
  192.     { opout,  "AND\tC"        },    /* 0xa1    */
  193.     { opout,  "AND\tD"        },    /* 0xa2    */
  194.     { opout,  "AND\tE"        },    /* 0xa3    */
  195.     { opout,  "AND\tH"        },    /* 0xa4    */
  196.     { opout,  "AND\tL"        },    /* 0xa5    */
  197.     { opout,  "AND\t(HL)"        },    /* 0xa6    */
  198.     { opout,  "AND\tA"        },    /* 0xa7    */
  199.     { opout,  "XOR\tB"        },    /* 0xa8    */
  200.     { opout,  "XOR\tC"        },    /* 0xa9    */
  201.     { opout,  "XOR\tD"        },    /* 0xaa    */
  202.     { opout,  "XOR\tE"        },    /* 0xab    */
  203.     { opout,  "XOR\tH"        },    /* 0xac    */
  204.     { opout,  "XOR\tL"        },    /* 0xad    */
  205.     { opout,  "XOR\t(HL)"        },    /* 0xae    */
  206.     { opout,  "XOR\tA"        },    /* 0xaf    */
  207.     { opout,  "OR\tB"        },    /* 0xb0    */
  208.     { opout,  "OR\tC"        },    /* 0xb1    */
  209.     { opout,  "OR\tD"        },    /* 0xb2    */
  210.     { opout,  "OR\tE"        },    /* 0xb3    */
  211.     { opout,  "OR\tH"        },    /* 0xb4    */
  212.     { opout,  "OR\tL"        },    /* 0xb5    */
  213.     { opout,  "OR\t(HL)"        },    /* 0xb6    */
  214.     { opout,  "OR\tA"        },    /* 0xb7    */
  215.     { opout,  "CP\tB"        },    /* 0xb8    */
  216.     { opout,  "CP\tC"        },    /* 0xb9    */
  217.     { opout,  "CP\tD"        },    /* 0xba    */
  218.     { opout,  "CP\tE"        },    /* 0xbb    */
  219.     { opout,  "CP\tH"        },    /* 0xbc    */
  220.     { opout,  "CP\tL"        },    /* 0xbd    */
  221.     { opout,  "CP\t(HL)"        },    /* 0xbe    */
  222.     { opout,  "CP\tA"        },    /* 0xbf    */
  223.     { opout,  "RET\tNZ"        },    /* 0xc0    */
  224.     { opout,  "POP\tBC"        },    /* 0xc1    */
  225.     { nnout,  "JP\tNZ,"        },    /* 0xc2    */
  226.     { nnout,  "JP\t"        },    /* 0xc3    */
  227.     { nnout,  "CALL\tNZ,"        },    /* 0xc4    */
  228.     { opout,  "PUSH\tBC"        },    /* 0xc5    */
  229.     { nout,      "ADD\tA,"        },    /* 0xc6    */
  230.     { opout,  "RST\t0"        },    /* 0xc7    */
  231.     { opout,  "RET\tZ"        },    /* 0xc8    */
  232.     { opout,  "RET"            },    /* 0xc9    */
  233.     { nnout,  "JP\tZ,"        },    /* 0xca    */
  234.     { cbop,      ""            },    /* 0xcb    */
  235.     { nnout,  "CALL\tZ,"        },    /* 0xcc    */
  236.     { nnout,  "CALL\t"        },    /* 0xcd    */
  237.     { nout,      "ADC\tA,"        },    /* 0xce    */
  238.     { opout,  "RST\t8"        },    /* 0xcf    */
  239.     { opout,  "RET\tNC"        },    /* 0xd0    */
  240.     { opout,  "POP\tDE"        },    /* 0xd1    */
  241.     { nnout,  "JP\tNC,"        },    /* 0xd2    */
  242.     { iout,      "OUT\t(%02x),A"    },    /* 0xd3    */
  243.     { nnout,  "CALL\tNC,"        },    /* 0xd4    */
  244.     { opout,  "PUSH\tDE"        },    /* 0xd5    */
  245.     { nout,      "SUB\t"        },    /* 0xd6    */
  246.     { opout,  "RST\t10"        },    /* 0xd7    */
  247.     { opout,  "RET\tC"        },    /* 0xd8    */
  248.     { opout,  "EXX"            },    /* 0xd9    */
  249.     { nnout,  "JP\tC,"        },    /* 0xda    */
  250.     { iout,      "IN\tA,(%02x)"    },    /* 0xdb    */
  251.     { nnout,  "CALL\tC,"        },    /* 0xdc    */
  252.     { ddfd,      ""            },    /* 0xdd    */
  253.     { nout,      "SBC\tA,"        },    /* 0xde    */
  254.     { opout,  "RST\t18"        },    /* 0xdf    */
  255.     { opout,  "RET\tPO"        },    /* 0xe0    */
  256.     { opout,  "POP\tHL"        },    /* 0xe1    */
  257.     { nnout,  "JP\tPO,"        },    /* 0xe2    */
  258.     { opout,  "EX\t(SP),HL"        },    /* 0xe3    */
  259.     { nnout,  "CALL\tPO,"        },    /* 0xe4    */
  260.     { opout,  "PUSH\tHL"        },    /* 0xe5    */
  261.     { nout,      "AND\t"        },    /* 0xe6    */
  262.     { opout,  "RST\t20"        },    /* 0xe7    */
  263.     { opout,  "RET\tPE"        },    /* 0xe8    */
  264.     { opout,  "JP\t(HL)"        },    /* 0xe9    */
  265.     { nnout,  "JP\tPE,"        },    /* 0xea    */
  266.     { opout,  "EX\tDE,HL"        },    /* 0xeb    */
  267.     { nnout,  "CALL\tPE,"        },    /* 0xec    */
  268.     { edop,      ""            },    /* 0xed    */
  269.     { nout,      "XOR\t"        },    /* 0xee    */
  270.     { opout,  "RST\t28"        },    /* 0xef    */
  271.     { opout,  "RET\tP"        },    /* 0xf0    */
  272.     { opout,  "POP\tAF"        },    /* 0xf1    */
  273.     { nnout,  "JP\tP,"        },    /* 0xf2    */
  274.     { opout,  "DI"            },    /* 0xf3    */
  275.     { nnout,  "CALL\tP,"        },    /* 0xf4    */
  276.     { opout,  "PUSH\tAF"        },    /* 0xf5    */
  277.     { nout,      "OR\t"        },    /* 0xf6    */
  278.     { opout,  "RST\t30"        },    /* 0xf7    */
  279.     { opout,  "RET\tM"        },    /* 0xf8    */
  280.     { opout,  "LD\tSP,HL"        },    /* 0xf9    */
  281.     { nnout,  "JP\tM,"        },    /* 0xfa    */
  282.     { opout,  "EI"            },    /* 0xfb    */
  283.     { nnout,  "CALL\tM,"        },    /* 0xfc    */
  284.     { ddfd,      ""            },    /* 0xfd    */
  285.     { nout,      "CP\t"        },    /* 0xfe    */
  286.     { opout,  "RST\t38"        }    /* 0xff    */
  287. };
  288.  
  289. static int addr;
  290. static char *unkown = "???";
  291. static char *reg[] = { "B", "C", "D", "E", "H",    "L", "(HL)", "A" };
  292. static char *regix = "IX";
  293. static char *regiy = "IY";
  294.  
  295. /*
  296.  *    The function disass() is the only global function of
  297.  *    this module. The first argument is a pointer to a
  298.  *    unsigned char pointer, which points to the op-code
  299.  *    to disassemble. The output of the disassembly goes
  300.  *    to stdout, terminated by a newline. After the
  301.  *    disassembly the pointer to the op-code will be
  302.  *    increased by the size of the op-code, so that
  303.  *    disass() can be called again.
  304.  *    The secound argument is the (Z80) address of the
  305.  *    op-code to disassemble. It is used to calculate the
  306.  *    destination address of relative jumps.
  307.  */
  308. disass(p, adr)
  309. register unsigned char **p;
  310. int adr;
  311. {
  312.     register int len;
  313.  
  314.     addr = adr;
  315.     len = (*optab[**p].fun)    (optab[**p].text, p);
  316.     *p += len;
  317. }
  318.  
  319. /*
  320.  *    disassemble 1 byte op-codes
  321.  */
  322. static opout(s,    p)
  323. register char *s, **p;
  324. {
  325.     puts(s);
  326.     return(1);
  327. }
  328.  
  329. /*
  330.  *    disassemble 2 byte op-codes of type "Op n"
  331.  */
  332. static nout(s, p)
  333. register char *s;
  334. unsigned char **p;
  335. {
  336.     printf("%s%02x\n", s, *(*p + 1));
  337.     return(2);
  338. }
  339.  
  340. /*
  341.  *    disassemble 2 byte op-codes with indirect addressing
  342.  */
  343. static iout(s, p)
  344. register char *s;
  345. unsigned char **p;
  346. {
  347.     printf(s, *(*p + 1));
  348.     putchar('\n');
  349.     return(2);
  350. }
  351.  
  352. /*
  353.  *    disassemble 2 byte op-codes with relative addressing
  354.  */
  355. static rout(s, p)
  356. register char *s;
  357. char **p;
  358. {
  359.     printf("%s%04x\n", s, addr + *(*p + 1) + 2);
  360.     return(2);
  361. }
  362.  
  363. /*
  364.  *    disassemble 3 byte op-codes of type "Op nn"
  365.  */
  366. static nnout(s,    p)
  367. register char *s;
  368. unsigned char **p;
  369. {
  370.     register int i;
  371.  
  372.     i = *(*p + 1) +    (*(*p +    2) << 8);
  373.     printf("%s%04x\n", s, i);
  374.     return(3);
  375. }
  376.  
  377. /*
  378.  *    disassemble 3 byte op-codes with indirect addressing
  379.  */
  380. static inout(s,    p)
  381. register char *s;
  382. unsigned char **p;
  383. {
  384.     register int i;
  385.  
  386.     i = *(*p + 1) +    (*(*p +    2) << 8);
  387.     printf(s, i);
  388.     putchar('\n');
  389.     return(3);
  390. }
  391.  
  392. /*
  393.  *    disassemble multi byte op-codes with prefix 0xcb
  394.  */
  395. static cbop(s, p)
  396. register char *s;
  397. unsigned char **p;
  398. {
  399.     register int b2;
  400.  
  401.     b2 = *(*p + 1);
  402.     if (b2 >= 0x00 && b2 <=    0x07) {
  403.         printf("RLC\t");
  404.         printf("%s\n", reg[b2 &    7]);
  405.         return(2);
  406.     }
  407.     if (b2 >= 0x08 && b2 <=    0x0f) {
  408.         printf("RRC\t");
  409.         printf("%s\n", reg[b2 &    7]);
  410.         return(2);
  411.     }
  412.     if (b2 >= 0x10 && b2 <=    0x17) {
  413.         printf("RL\t");
  414.         printf("%s\n", reg[b2 &    7]);
  415.         return(2);
  416.     }
  417.     if (b2 >= 0x18 && b2 <=    0x1f) {
  418.         printf("RR\t");
  419.         printf("%s\n", reg[b2 &    7]);
  420.         return(2);
  421.     }
  422.     if (b2 >= 0x20 && b2 <=    0x27) {
  423.         printf("SLA\t");
  424.         printf("%s\n", reg[b2 &    7]);
  425.         return(2);
  426.     }
  427.     if (b2 >= 0x28 && b2 <=    0x2f) {
  428.         printf("SRA\t");
  429.         printf("%s\n", reg[b2 &    7]);
  430.         return(2);
  431.     }
  432.     if (b2 >= 0x38 && b2 <=    0x3f) {
  433.         printf("SRL\t");
  434.         printf("%s\n", reg[b2 &    7]);
  435.         return(2);
  436.     }
  437.     if (b2 >= 0x40 && b2 <=    0x7f) {
  438.         printf("BIT\t");
  439.         printf("%c,", ((b2 >> 3) & 7) +    '0');
  440.         printf("%s\n", reg[b2 &    7]);
  441.         return(2);
  442.     }
  443.     if (b2 >= 0x80 && b2 <=    0xbf) {
  444.         printf("RES\t");
  445.         printf("%c,", ((b2 >> 3) & 7) +    '0');
  446.         printf("%s\n", reg[b2 &    7]);
  447.         return(2);
  448.     }
  449.     if (b2 >= 0xc0)    {
  450.         printf("SET\t");
  451.         printf("%c,", ((b2 >> 3) & 7) +    '0');
  452.         printf("%s\n", reg[b2 &    7]);
  453.         return(2);
  454.     }
  455.     puts(unkown);
  456.     return(2);
  457. }
  458.  
  459. /*
  460.  *    disassemble multi byte op-codes with prefix 0xed
  461.  */
  462. static edop(s, p)
  463. register char *s;
  464. unsigned char **p;
  465. {
  466.     register int b2, i;
  467.     int len    = 2;
  468.  
  469.     b2 = *(*p + 1);
  470.     switch (b2) {
  471.     case 0x40:
  472.         puts("IN\tB,(C)");
  473.         break;
  474.     case 0x41:
  475.         puts("OUT\t(C),B");
  476.         break;
  477.     case 0x42:
  478.         puts("SBC\tHL,BC");
  479.         break;
  480.     case 0x43:
  481.         i = *(*p + 2) +    (*(*p +    3) << 8);
  482.         printf("LD\t(%04x),BC\n", i);
  483.         len = 4;
  484.         break;
  485.     case 0x44:
  486.         puts("NEG");
  487.         break;
  488.     case 0x45:
  489.         puts("RETN");
  490.         break;
  491.     case 0x46:
  492.         puts("IM\t0");
  493.         break;
  494.     case 0x47:
  495.         puts("LD\tI,A");
  496.         break;
  497.     case 0x48:
  498.         puts("IN\tC,(C)");
  499.         break;
  500.     case 0x49:
  501.         puts("OUT\t(C),C");
  502.         break;
  503.     case 0x4a:
  504.         puts("ADC\tHL,BC");
  505.         break;
  506.     case 0x4b:
  507.         i = *(*p + 2) +    (*(*p +    3) << 8);
  508.         printf("LD\tBC,(%04x)\n", i);
  509.         len = 4;
  510.         break;
  511.     case 0x4d:
  512.         puts("RETI");
  513.         break;
  514.     case 0x4f:
  515.         puts("LD\tR,A");
  516.         break;
  517.     case 0x50:
  518.         puts("IN\tD,(C)");
  519.         break;
  520.     case 0x51:
  521.         puts("OUT\t(C),D");
  522.         break;
  523.     case 0x52:
  524.         puts("SBC\tHL,DE");
  525.         break;
  526.     case 0x53:
  527.         i = *(*p + 2) +    (*(*p +    3) << 8);
  528.         printf("LD\t(%04x),DE\n", i);
  529.         len = 4;
  530.         break;
  531.     case 0x56:
  532.         puts("IM\t1");
  533.         break;
  534.     case 0x57:
  535.         puts("LD\tA,I");
  536.         break;
  537.     case 0x58:
  538.         puts("IN\tE,(C)");
  539.         break;
  540.     case 0x59:
  541.         puts("OUT\t(C),E");
  542.         break;
  543.     case 0x5a:
  544.         puts("ADC\tHL,DE");
  545.         break;
  546.     case 0x5b:
  547.         i = *(*p + 2) +    (*(*p +    3) << 8);
  548.         printf("LD\tDE,(%04x)\n", i);
  549.         len = 4;
  550.         break;
  551.     case 0x5e:
  552.         puts("IM\t2");
  553.         break;
  554.     case 0x5f:
  555.         puts("LD\tA,R");
  556.         break;
  557.     case 0x60:
  558.         puts("IN\tH,(C)");
  559.         break;
  560.     case 0x61:
  561.         puts("OUT\t(C),H");
  562.         break;
  563.     case 0x62:
  564.         puts("SBC\tHL,HL");
  565.         break;
  566.     case 0x67:
  567.         puts("RRD");
  568.         break;
  569.     case 0x68:
  570.         puts("IN\tL,(C)");
  571.         break;
  572.     case 0x69:
  573.         puts("OUT\t(C),L");
  574.         break;
  575.     case 0x6a:
  576.         puts("ADC\tHL,HL");
  577.         break;
  578.     case 0x6f:
  579.         puts("RLD");
  580.         break;
  581.     case 0x72:
  582.         puts("SBC\tHL,SP");
  583.         break;
  584.     case 0x73:
  585.         i = *(*p + 2) +    (*(*p +    3) << 8);
  586.         printf("LD\t(%04x),SP\n", i);
  587.         len = 4;
  588.         break;
  589.     case 0x78:
  590.         puts("IN\tA,(C)");
  591.         break;
  592.     case 0x79:
  593.         puts("OUT\t(C),A");
  594.         break;
  595.     case 0x7a:
  596.         puts("ADC\tHL,SP");
  597.         break;
  598.     case 0x7b:
  599.         i = *(*p + 2) +    (*(*p +    3) << 8);
  600.         printf("LD\tSP,(%04x)\n", i);
  601.         len = 4;
  602.         break;
  603.     case 0xa0:
  604.         puts("LDI");
  605.         break;
  606.     case 0xa1:
  607.         puts("CPI");
  608.         break;
  609.     case 0xa2:
  610.         puts("INI");
  611.         break;
  612.     case 0xa3:
  613.         puts("OUTI");
  614.         break;
  615.     case 0xa8:
  616.         puts("LDD");
  617.         break;
  618.     case 0xa9:
  619.         puts("CPD");
  620.         break;
  621.     case 0xaa:
  622.         puts("IND");
  623.         break;
  624.     case 0xab:
  625.         puts("OUTD");
  626.         break;
  627.     case 0xb0:
  628.         puts("LDIR");
  629.         break;
  630.     case 0xb1:
  631.         puts("CPIR");
  632.         break;
  633.     case 0xb2:
  634.         puts("INIR");
  635.         break;
  636.     case 0xb3:
  637.         puts("OTIR");
  638.         break;
  639.     case 0xb8:
  640.         puts("LDDR");
  641.         break;
  642.     case 0xb9:
  643.         puts("CPDR");
  644.         break;
  645.     case 0xba:
  646.         puts("INDR");
  647.         break;
  648.     case 0xbb:
  649.         puts("OTDR");
  650.         break;
  651.     default:
  652.         puts(unkown);
  653.     }
  654.     return(len);
  655. }
  656.  
  657. /*
  658.  *    disassemble multi byte op-codes with prefix 0xdd and 0xfd
  659.  */
  660. static ddfd(s, p)
  661. register char *s;
  662. unsigned char **p;
  663. {
  664.     register int b2;
  665.     register char *ireg;
  666.     int len    = 3;
  667.  
  668.     if (**p    == 0xdd)
  669.         ireg = regix;
  670.     else
  671.         ireg = regiy;
  672.     b2 = *(*p + 1);
  673.     if (b2 >= 0x70 && b2 <=    0x77) {
  674.         printf("LD\t(%s+%02x),%s\n", ireg, *(*p    + 2), reg[b2 & 7]);
  675.         return(3);
  676.     }
  677.     switch (b2) {
  678.     case 0x09:
  679.         printf("ADD\t%s,BC\n", ireg);
  680.         len = 2;
  681.         break;
  682.     case 0x19:
  683.         printf("ADD\t%s,DE\n", ireg);
  684.         len = 2;
  685.         break;
  686.     case 0x21:
  687.         printf("LD\t%s,%04x\n",    ireg, *(*p + 2)    + (*(*p    + 3) <<    8));
  688.         len = 4;
  689.         break;
  690.     case 0x22:
  691.         printf("LD\t(%04x),%s\n", *(*p + 2) + (*(*p + 3) << 8),    ireg);
  692.         len = 4;
  693.         break;
  694.     case 0x23:
  695.         printf("INC\t%s\n", ireg);
  696.         len = 2;
  697.         break;
  698.     case 0x29:
  699.         if (**p    == 0xdd)
  700.             printf("ADD\tIX,IX\n");
  701.         else
  702.             printf("ADD\tIY,IY\n");
  703.         len = 2;
  704.         break;
  705.     case 0x2a:
  706.         printf("LD\t%s,(%04x)\n", ireg,    *(*p + 2) + (*(*p + 3) << 8));
  707.         len = 4;
  708.         break;
  709.     case 0x2b:
  710.         printf("DEC\t%s\n", ireg);
  711.         len = 2;
  712.         break;
  713.     case 0x34:
  714.         printf("INC\t(%s+%02x)\n", ireg, *(*p +    2));
  715.         break;
  716.     case 0x35:
  717.         printf("DEC\t(%s+%02x)\n", ireg, *(*p +    2));
  718.         break;
  719.     case 0x36:
  720.         printf("LD\t(%s+%02x),%02x\n", ireg, *(*p + 2),    *(*p + 3));
  721.         len = 4;
  722.         break;
  723.     case 0x39:
  724.         printf("ADD\t%s,SP\n", ireg);
  725.         len = 2;
  726.         break;
  727.     case 0x46:
  728.         printf("LD\tB,(%s+%02x)\n", ireg, *(*p + 2));
  729.         break;
  730.     case 0x4e:
  731.         printf("LD\tC,(%s+%02x)\n", ireg, *(*p + 2));
  732.         break;
  733.     case 0x56:
  734.         printf("LD\tD,(%s+%02x)\n", ireg, *(*p + 2));
  735.         break;
  736.     case 0x5e:
  737.         printf("LD\tE,(%s+%02x)\n", ireg, *(*p + 2));
  738.         break;
  739.     case 0x66:
  740.         printf("LD\tH,(%s+%02x)\n", ireg, *(*p + 2));
  741.         break;
  742.     case 0x6e:
  743.         printf("LD\tL,(%s+%02x)\n", ireg, *(*p + 2));
  744.         break;
  745.     case 0x7e:
  746.         printf("LD\tA,(%s+%02x)\n", ireg, *(*p + 2));
  747.         break;
  748.     case 0x86:
  749.         printf("ADD\tA,(%s+%02x)\n", ireg, *(*p    + 2));
  750.         break;
  751.     case 0x8e:
  752.         printf("ADC\tA,(%s+%02x)\n", ireg, *(*p    + 2));
  753.         break;
  754.     case 0x96:
  755.         printf("SUB\t(%s+%02x)\n", ireg, *(*p +    2));
  756.         break;
  757.     case 0x9e:
  758.         printf("SBC\tA,(%s+%02x)\n", ireg, *(*p    + 2));
  759.         break;
  760.     case 0xa6:
  761.         printf("AND\t(%s+%02x)\n", ireg, *(*p +    2));
  762.         break;
  763.     case 0xae:
  764.         printf("XOR\t(%s+%02x)\n", ireg, *(*p +    2));
  765.         break;
  766.     case 0xb6:
  767.         printf("OR\t(%s+%02x)\n", ireg,    *(*p + 2));
  768.         break;
  769.     case 0xbe:
  770.         printf("CP\t(%s+%02x)\n", ireg,    *(*p + 2));
  771.         break;
  772.     case 0xcb:
  773.         switch (*(*p + 3)) {
  774.         case 0x06:
  775.             printf("RLC\t(%s+%02x)\n", ireg, *(*p +    2));
  776.             break;
  777.         case 0x0e:
  778.             printf("RRC\t(%s+%02x)\n", ireg, *(*p +    2));
  779.             break;
  780.         case 0x16:
  781.             printf("RL\t(%s+%02x)\n", ireg,    *(*p + 2));
  782.             break;
  783.         case 0x1e:
  784.             printf("RR\t(%s+%02x)\n", ireg,    *(*p + 2));
  785.             break;
  786.         case 0x26:
  787.             printf("SLA\t(%s+%02x)\n", ireg, *(*p +    2));
  788.             break;
  789.         case 0x2e:
  790.             printf("SRA\t(%s+%02x)\n", ireg, *(*p +    2));
  791.             break;
  792.         case 0x3e:
  793.             printf("SRL\t(%s+%02x)\n", ireg, *(*p +    2));
  794.             break;
  795.         case 0x46:
  796.             printf("BIT\t0,(%s+%02x)\n", ireg, *(*p    + 2));
  797.             break;
  798.         case 0x4e:
  799.             printf("BIT\t1,(%s+%02x)\n", ireg, *(*p    + 2));
  800.             break;
  801.         case 0x56:
  802.             printf("BIT\t2,(%s+%02x)\n", ireg, *(*p    + 2));
  803.             break;
  804.         case 0x5e:
  805.             printf("BIT\t3,(%s+%02x)\n", ireg, *(*p    + 2));
  806.             break;
  807.         case 0x66:
  808.             printf("BIT\t4,(%s+%02x)\n", ireg, *(*p    + 2));
  809.             break;
  810.         case 0x6e:
  811.             printf("BIT\t5,(%s+%02x)\n", ireg, *(*p    + 2));
  812.             break;
  813.         case 0x76:
  814.             printf("BIT\t6,(%s+%02x)\n", ireg, *(*p    + 2));
  815.             break;
  816.         case 0x7e:
  817.             printf("BIT\t7,(%s+%02x)\n", ireg, *(*p    + 2));
  818.             break;
  819.         case 0x86:
  820.             printf("RES\t0,(%s+%02x)\n", ireg, *(*p    + 2));
  821.             break;
  822.         case 0x8e:
  823.             printf("RES\t1,(%s+%02x)\n", ireg, *(*p    + 2));
  824.             break;
  825.         case 0x96:
  826.             printf("RES\t2,(%s+%02x)\n", ireg, *(*p    + 2));
  827.             break;
  828.         case 0x9e:
  829.             printf("RES\t3,(%s+%02x)\n", ireg, *(*p    + 2));
  830.             break;
  831.         case 0xa6:
  832.             printf("RES\t4,(%s+%02x)\n", ireg, *(*p    + 2));
  833.             break;
  834.         case 0xae:
  835.             printf("RES\t5,(%s+%02x)\n", ireg, *(*p    + 2));
  836.             break;
  837.         case 0xb6:
  838.             printf("RES\t6,(%s+%02x)\n", ireg, *(*p    + 2));
  839.             break;
  840.         case 0xbe:
  841.             printf("RES\t7,(%s+%02x)\n", ireg, *(*p    + 2));
  842.             break;
  843.         case 0xc6:
  844.             printf("SET\t0,(%s+%02x)\n", ireg, *(*p    + 2));
  845.             break;
  846.         case 0xce:
  847.             printf("SET\t1,(%s+%02x)\n", ireg, *(*p    + 2));
  848.             break;
  849.         case 0xd6:
  850.             printf("SET\t2,(%s+%02x)\n", ireg, *(*p    + 2));
  851.             break;
  852.         case 0xde:
  853.             printf("SET\t3,(%s+%02x)\n", ireg, *(*p    + 2));
  854.             break;
  855.         case 0xe6:
  856.             printf("SET\t4,(%s+%02x)\n", ireg, *(*p    + 2));
  857.             break;
  858.         case 0xee:
  859.             printf("SET\t5,(%s+%02x)\n", ireg, *(*p    + 2));
  860.             break;
  861.         case 0xf6:
  862.             printf("SET\t6,(%s+%02x)\n", ireg, *(*p    + 2));
  863.             break;
  864.         case 0xfe:
  865.             printf("SET\t7,(%s+%02x)\n", ireg, *(*p    + 2));
  866.             break;
  867.         default:
  868.             puts(unkown);
  869.         }
  870.         len = 4;
  871.         break;
  872.     case 0xe1:
  873.         printf("POP\t%s\n", ireg);
  874.         len = 2;
  875.         break;
  876.     case 0xe3:
  877.         printf("EX\t(SP),%s\n",    ireg);
  878.         len = 2;
  879.         break;
  880.     case 0xe5:
  881.         printf("PUSH\t%s\n", ireg);
  882.         len = 2;
  883.         break;
  884.     case 0xe9:
  885.         printf("JP\t(%s)\n", ireg);
  886.         len = 2;
  887.         break;
  888.     case 0xf9:
  889.         printf("LD\tSP,%s\n", ireg);
  890.         len = 2;
  891.         break;
  892.     default:
  893.         puts(unkown);
  894.     }
  895.     return(len);
  896. }
  897.