home *** CD-ROM | disk | FTP | other *** search
/ messroms.de / 2007-01-13_www.messroms.de.zip / CGENIE / TOOLS / DZ80.ZIP / dis.c < prev    next >
C/C++ Source or Header  |  1999-12-07  |  52KB  |  2,420 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include "z80.h"
  6. #include "dis.h"
  7. #include "table.h"
  8.  
  9. #define COLUMN_OPCODE    32
  10. #define COLUMN_ARGUMENT 38
  11. #define COLUMN_COMMENT    56
  12.  
  13. MEMOPT    memopt[0x10000];    // memory flags and options
  14.  
  15. SYM    * symbols = NULL;
  16. COM    * comments = NULL;
  17. DIS    dis = {{0,}, };
  18. Z80    z80 = {{{0,},}, };
  19.  
  20. //****************************************************************************
  21. // print a value as 2 or 3 digit hexadecimal with trailing 'h'
  22. //******************************************************************----------
  23. char    * hexb(int val)
  24. {
  25.     static int hexb_indx=0;
  26.     static char hexb_buff[6*16];
  27.     char * dst = hexb_buff + 6 * (++hexb_indx & 15);
  28.     if (val > 0x9F)
  29.         sprintf(dst, "%03XH", val & 255);
  30.     else
  31.     if (val < 10)
  32.         sprintf(dst, "%d", val);
  33.     else
  34.         sprintf(dst, "%02XH", val);
  35.     return dst;
  36. }
  37.  
  38. //****************************************************************************
  39. // print a value as 4 or 5 digit hexadecimal with trailing 'h'
  40. //******************************************************************----------
  41. char    * hexw(int val)
  42. {
  43.     static int hexw_indx=0;
  44.     static char hexw_buff[8*16];
  45.     char *dst = hexw_buff + 8 * (++hexw_indx & 15);
  46.     if (val > 0x9FFF)
  47.         sprintf(dst, "%05XH", val & 65535);
  48.     else
  49.         sprintf(dst, "%04XH", val);
  50.     return dst;
  51. }
  52.  
  53. //****************************************************************************
  54. // convert hexadecimal digit sequence into a WORD
  55. //******************************************************************----------
  56. WORD hextoi(char * src)
  57. {
  58.     WORD rc = 0;
  59.     while (*src)
  60.     {
  61.         if ((*src >= '0') && (*src <= '9'))
  62.             rc = rc * 16 + *src - '0';
  63.         else
  64.         if ((*src >= 'A') && (*src <= 'F'))
  65.             rc = rc * 16 + *src - 'A' + 10;
  66.         else
  67.         if ((*src >= 'a') && (*src <= 'f'))
  68.             rc = rc * 16 + *src - 'a' + 10;
  69.         else
  70.             return rc;
  71.         src++;
  72.     }
  73.     return rc;
  74. }
  75.  
  76. //****************************************************************************
  77. // define an option for a memory location
  78. //******************************************************************----------
  79. void OPT_def(WORD addr, unsigned mode, unsigned size, unsigned opt)
  80. {
  81.     memopt[addr].mode = mode;
  82.     memopt[addr].size = size;
  83.     memopt[addr].opt  = opt;
  84. }
  85.  
  86.  
  87. //****************************************************************************
  88. // add a symbol to our table
  89. //******************************************************************----------
  90. void SYM_add(WORD addr, SYMTYPE type, char * name)
  91. {
  92. SYM    *sym, * sym0, * sym1;
  93.     for (sym0 = NULL, sym1 = symbols; (sym1); sym0 = sym1, sym1 = sym1->next)
  94.         if (addr <= sym1->addr)
  95.             break;
  96.     sym = (SYM *) malloc(sizeof(SYM) + strlen(name));
  97.  
  98.     if (!sym)
  99.         return;
  100.  
  101.     sym->next = sym1;
  102.     sym->type = type;
  103.     sym->addr = addr;
  104.     strcpy(sym->name, name);
  105.  
  106.     if (sym0)
  107.         sym0->next = sym;
  108.     else
  109.         symbols    = sym;
  110.  
  111.     memopt[addr].symbol = 1;
  112. }
  113.  
  114. //****************************************************************************
  115. // add a comment to our table
  116. //******************************************************************----------
  117. void COM_add(WORD addr, COMTYPE type, char * text)
  118. {
  119.     COM * com, * com0, * com1;
  120.  
  121.     for (com0 = NULL, com1 = comments; (com1); com0 = com1, com1 = com1->next)
  122.         if (addr <= com1->addr)
  123.             break;
  124.  
  125.     if( com1 &&                   // found an entry
  126.         com1->addr == addr &&      // address is equal ?
  127.         com1->type == type &&      // address is equal ?
  128.         strncmp(com1->text,text,strlen(text)) ) // and text not yet found ?
  129.     {
  130.         com = (COM *) realloc(com1, sizeof(COM) + strlen(com1->text) + 3 + strlen(text) + 1);
  131.  
  132.         if (!com)
  133.             return;
  134.  
  135.         strcat(com->text, "\n; ");
  136.         strcat(com->text, text);
  137.  
  138.         if (com0)
  139.             com0->next = com;
  140.         else
  141.             comments   = com;
  142.         return;
  143.     }
  144.  
  145.     com = (COM *) malloc(sizeof(COM) + strlen(text));
  146.  
  147.     if (!com)
  148.         return;
  149.  
  150.     com->next = com1;
  151.     com->type = type;
  152.     com->addr = addr;
  153.     strcpy(com->text, text);
  154.  
  155.     if (com0)
  156.         com0->next = com;
  157.     else
  158.         comments   = com;
  159.  
  160.     memopt[addr].comment = 1;
  161. }
  162.  
  163. //****************************************************************************
  164. // get a symbol name for the given address and of the given type
  165. //******************************************************************----------
  166. char    * SYM_get(WORD addr, SYMTYPE type)
  167. {
  168.     static char sym_buff[128];
  169.     SYM *sym;
  170.     if( memopt[addr].symbol )
  171.     {
  172.         for( sym = symbols; (sym); sym = sym->next )
  173.         {
  174.             if( addr != sym->addr )
  175.                 continue;
  176.             if( type == SYM_NONE || type == sym->type )
  177.                 return sym->name;
  178.         }
  179.     }
  180.     if( addr > 0 && memopt[addr-1].symbol )
  181.     {
  182.         for (sym = symbols; (sym); sym = sym->next)
  183.         {
  184.             if (addr != sym->addr+1)
  185.                 continue;
  186.             if( type == SYM_NONE || type == sym->type )
  187.             {
  188.                 sprintf(sym_buff, "%s+1", sym->name);
  189.                 return sym_buff;
  190.             }
  191.         }
  192.  
  193.         if( addr > 1 && memopt[addr-2].symbol )
  194.         {
  195.             for (sym = symbols; (sym); sym = sym->next)
  196.             {
  197.                 if (addr != sym->addr+2)
  198.                     continue;
  199.                 if( type == SYM_NONE || type == sym->type )
  200.                 {
  201.                     sprintf(sym_buff, "%s+2", sym->name);
  202.                     return sym_buff;
  203.                 }
  204.  
  205.             }
  206.             if( addr > 2 && memopt[addr-3].symbol )
  207.             {
  208.                 for( sym = symbols; (sym); sym = sym->next )
  209.                 {
  210.                     if( addr != sym->addr+3 )
  211.                         continue;
  212.                     if( type == SYM_NONE || type == sym->type )
  213.                     {
  214.                         sprintf(sym_buff, "%s+3", sym->name);
  215.                         return sym_buff;
  216.                     }
  217.  
  218.                 }
  219.             }
  220.                 }
  221.         }
  222.         return hexw(addr);
  223. }
  224.  
  225. //****************************************************************************
  226. // get a comment for the given address
  227. //******************************************************************----------
  228. char * COM_get(WORD addr, COMTYPE type)
  229. {
  230.     COM *com;
  231.     if( memopt[addr].comment )
  232.     {
  233.         for( com = comments; (com); com = com->next )
  234.         {
  235.             if( addr != com->addr )
  236.                 continue;
  237.             if( type == COM_NONE || type == com->type )
  238.                 return com->text;
  239.         }
  240.     }
  241.     return "";
  242. }
  243.  
  244. //****************************************************************************
  245. // read a symbol, flags and options definitions file
  246. //******************************************************************----------
  247. void DEF_file_read(char *filename)
  248. {
  249.     FILE *filp;
  250.     char *line;
  251.     char buff[64];
  252.     char *src;
  253.     WORD addr;
  254.     WORD offs;
  255.  
  256.     if (NULL == (line = alloca(1024)))
  257.         return;
  258.  
  259.     filp = fopen(filename, "r");
  260.  
  261.     if (!filp)
  262.         return;
  263.  
  264.     while (!feof(filp))
  265.     {
  266.         fgets(line, 1024, filp);
  267.         src = strtok(line, "\t \n\x1A");
  268.  
  269.         if (!src)
  270.             continue;
  271.  
  272.         addr = hextoi(src);
  273.         src = strtok(NULL, "\t \n\x1A");
  274.  
  275.         if (!src)
  276.             continue;
  277.  
  278.         switch (*src)
  279.         {
  280.             case '+':
  281.                 src = strtok(NULL, "\n\x1A");
  282.                 if (src)
  283.                     COM_add(addr, COM_APPEND, src);
  284.                 break;
  285.  
  286.             case ';':
  287.                 src = strtok(NULL, "\n\x1A");
  288.                 if (src)
  289.                     COM_add(addr, COM_BLOCK, src);
  290.                 break;
  291.  
  292.             case '=':
  293.                 src = strtok(NULL, "\n\x1A");
  294.                 if (src)
  295.                     SYM_add(addr, SYM_NONE, src);
  296.                 break;
  297.  
  298.             case 'c': case 'C':
  299.                 OPT_def(addr, MEM_CODE, 0, 0);
  300.                 src = strtok(NULL, "\t \n\x1A");
  301.                 if (src)
  302.                     SYM_add(addr, SYM_CODE, src);
  303.                 break;
  304.  
  305.             case 'b': case 'B':
  306.                 OPT_def(addr, MEM_DATA, 0, OPT_BYTES);
  307.                 memopt[addr].opt  = OPT_BYTES;
  308.                 src = strtok(NULL, "\t \n\x1A");
  309.                 if (src)
  310.                     SYM_add(addr, SYM_DATA, src);
  311.                 break;
  312.  
  313.  
  314.             case '7':
  315.                 OPT_def(addr, MEM_DATA, 0, OPT_7BIT);
  316.                 src = strtok(NULL, "\t \n\x1A");
  317.                 if (src)
  318.                     SYM_add(addr, SYM_DATA, src);
  319.                 break;
  320.  
  321.             case 'a': case 'A':
  322.                 OPT_def(addr, MEM_DATA, 0, OPT_ASCII);
  323.                 memopt[addr].opt  = OPT_ASCII;
  324.                 src = strtok(NULL, "\t \n\x1A");
  325.                 if (src)
  326.                     SYM_add(addr, SYM_DATA, src);
  327.                 break;
  328.  
  329.             case 'w': case 'W':
  330.                 OPT_def(addr, MEM_DATA, 1, OPT_WORDS);
  331.                 src = strtok(NULL, "\t \n\x1A");
  332.                 if (src)
  333.                     SYM_add(addr, SYM_DATA, src);
  334.                 break;
  335.  
  336.             case 'e': case 'E':
  337.                 OPT_def(addr, MEM_DATA, 1, OPT_ENTRY);
  338.                 src = strtok(NULL, "\t \n\x1A");
  339.                 if (src)
  340.                     SYM_add(addr, SYM_DATA, src);
  341.                 break;
  342.  
  343.             case 's': case 'S':
  344.                 OPT_def(addr, MEM_DATA, 2, OPT_FSNG);
  345.                 src = strtok(NULL, "\t \n\x1A");
  346.                 if (src)
  347.                     SYM_add(addr, SYM_DATA, src);
  348.                 break;
  349.  
  350.             case 'd': case 'D':
  351.                 OPT_def(addr, MEM_DATA, 3, OPT_FDBL);
  352.                 src = strtok(NULL, "\t \n\x1A");
  353.                 if (src)
  354.                     SYM_add(addr, SYM_DATA, src);
  355.                 break;
  356.  
  357.             case 'o': case 'O':
  358.                 offs = *(WORD*)&mem[addr];
  359.                 switch (src[1])
  360.                 {
  361.                     case 'c': case 'C':
  362.                         OPT_def(addr, MEM_DATA, 1, OPT_OC);
  363.                         memopt[addr].opt  = OPT_OC;
  364.                         if (memopt[offs].mode == MEM_UNKNOWN)
  365.                         {
  366.                             OPT_def(offs, MEM_CODE, 0, OPT_NONE);
  367.                             if (memopt[offs].comment == 0)
  368.                             {
  369.                                 sprintf(buff, "CODE xref [%04Xh]", addr);
  370.                                 COM_add(offs, COM_APPEND, buff);
  371.                             }
  372.                         }
  373.                         break;
  374.                     case '7':
  375.                         OPT_def(addr, MEM_DATA, 1, OPT_OD7);
  376.                         if (memopt[offs].mode == MEM_UNKNOWN)
  377.                         {
  378.                             OPT_def(offs, MEM_DATA, 0, OPT_7BIT);
  379.                             if (memopt[offs].comment == 0)
  380.                             {
  381.                                 sprintf(buff, "7BIT xref [%04Xh]", addr);
  382.                                 COM_add(offs, COM_APPEND, buff);
  383.                             }
  384.                         }
  385.                         break;
  386.                     case 'a': case 'A':
  387.                         OPT_def(addr, MEM_DATA, 1, OPT_ODA);
  388.                         if (memopt[offs].mode == MEM_UNKNOWN)
  389.                         {
  390.                             OPT_def(offs, MEM_DATA, 0, OPT_ASCII);
  391.                             if (memopt[offs].comment == 0)
  392.                             {
  393.                                 sprintf(buff, "ASCII xref [%04Xh]", addr);
  394.                                 COM_add(offs, COM_APPEND, buff);
  395.                             }
  396.                         }
  397.                         break;
  398.                     case 'b': case 'B':
  399.                         OPT_def(addr, MEM_DATA, 1, OPT_ODB);
  400.                         if (memopt[offs].mode == MEM_UNKNOWN)
  401.                         {
  402.                             OPT_def(offs, MEM_DATA, 0, OPT_BYTES);
  403.                             if (memopt[offs].comment == 0)
  404.                             {
  405.                                 sprintf(buff, "BYTES xref [%04Xh]", addr);
  406.                                 COM_add(offs, COM_APPEND, buff);
  407.                             }
  408.                         }
  409.                         break;
  410.                     case 'w': case 'W':
  411.                         OPT_def(addr, MEM_DATA, 1, OPT_ODW);
  412.                         if (memopt[offs].mode == MEM_UNKNOWN)
  413.                         {
  414.                             OPT_def(offs, MEM_DATA, 1, OPT_WORDS);
  415.                             if (memopt[offs].comment == 0)
  416.                             {
  417.                                 sprintf(buff, "WORDS xref [%04Xh]", addr);
  418.                                 COM_add(offs, COM_APPEND, buff);
  419.                             }
  420.                         }
  421.                         break;
  422.                     case 'e': case 'E':
  423.                         OPT_def(addr, MEM_DATA, 1, OPT_ODE);
  424.                         if (memopt[offs].mode == MEM_UNKNOWN)
  425.                         {
  426.                             OPT_def(offs, MEM_DATA, 1, OPT_ENTRY);
  427.                             if (memopt[offs].comment == 0)
  428.                             {
  429.                                 sprintf(buff, "ENTRY xref [%04Xh]", addr);
  430.                                 COM_add(offs, COM_APPEND, buff);
  431.                             }
  432.                         }
  433.                         break;
  434.                     default:
  435.                         OPT_def(addr, MEM_DATA, 1, OPT_ODB);
  436.                         if (memopt[offs].mode == MEM_UNKNOWN)
  437.                         {
  438.                             OPT_def(offs, MEM_DATA, 0, OPT_BYTES);
  439.                         }
  440.                         break;
  441.                 }
  442.                 src = strtok(NULL, "\t \n\x1A");
  443.                 if (src)
  444.                     SYM_add(addr, SYM_DATA, src);
  445.                 break;
  446.         }
  447.     }
  448.     fclose(filp);
  449. }
  450.  
  451. //****************************************************************************
  452. // pad the output buffer with blanks and output an opcode
  453. //******************************************************************----------
  454. int pad_opcode(char * fmt, ...)
  455. {
  456.     va_list arg;
  457.     int len;
  458.  
  459.     while( dis.dst < dis.buff + COLUMN_OPCODE )
  460.         *dis.dst++ = ' ';
  461.     va_start(arg, fmt);
  462.     len = vsprintf(dis.dst, fmt, arg);
  463.     va_end(arg);
  464.     return len;
  465. }
  466.  
  467. //****************************************************************************
  468. // pad the output buffer with blanks and output an argument
  469. //******************************************************************----------
  470. int pad_argument(char * fmt, ...)
  471. {
  472.     va_list arg;
  473.     int len;
  474.  
  475.     while( dis.dst < dis.buff + COLUMN_ARGUMENT )
  476.         *dis.dst++ = ' ';
  477.     va_start(arg, fmt);
  478.     len = vsprintf(dis.dst, fmt, arg);
  479.     va_end(arg);
  480.     return len;
  481. }
  482.  
  483. //****************************************************************************
  484. // pad the output buffer with blanks and output a comment
  485. //******************************************************************----------
  486. int pad_comment(char * fmt, ...)
  487. {
  488.     va_list arg;
  489.     int len;
  490.  
  491.     while (dis.dst < dis.buff + COLUMN_COMMENT)
  492.         *dis.dst++ = ' ';
  493.  
  494.     if (!dis.padcom)
  495.     {
  496.         dis.padcom = 1;
  497.         *dis.dst++ = ';';
  498.     }
  499.  
  500.     va_start(arg, fmt);
  501.     len = vsprintf(dis.dst, fmt, arg);
  502.     va_end(arg);
  503.     return len;
  504. }
  505.  
  506. //****************************************************************************
  507. // disassemble an destination operand from the given table entry
  508. //******************************************************************----------
  509. int dis_dst(TABLE * ptab, BOOL comma)
  510. {
  511.     int len = 0;
  512.  
  513.     switch (ptab->dst)
  514.     {
  515.         case _d0:
  516.             return 0;
  517.         case _dB:
  518.             len = pad_argument("B");
  519.             break;
  520.         case _dC:
  521.             len = pad_argument("C");
  522.             break;
  523.         case _dD:
  524.             len = pad_argument("D");
  525.             break;
  526.         case _dE:
  527.             len = pad_argument("E");
  528.             break;
  529.         case _dH:
  530.             len = pad_argument("H");
  531.             break;
  532.         case _dL:
  533.             len = pad_argument("L");
  534.             break;
  535.         case _dM:
  536.             dis.flag.dst_mem8 = 1;
  537.             dis.flag.dst_addr = 1;
  538.             dis.addr  = z80.hl.r16;
  539.             dis.mem8  = mem[dis.addr];
  540.             len = pad_argument("(HL)");
  541.             break;
  542.         case _dA:
  543.             len = pad_argument("A");
  544.             break;
  545.         case _dHIX:
  546.             len = pad_argument("HX");
  547.             break;
  548.         case _dLIX:
  549.             len = pad_argument("LX");
  550.             break;
  551.         case _dHIY:
  552.             len = pad_argument("HY");
  553.             break;
  554.         case _dLIY:
  555.             len = pad_argument("LY");
  556.             break;
  557.         case _dI:
  558.             len = pad_argument("I");
  559.             break;
  560.         case _dR:
  561.             len = pad_argument("R");
  562.             break;
  563.         case _dF:
  564.             len = pad_argument("F");
  565.             break;
  566.         case _dMBC:
  567.             dis.flag.dst_mem8 = 1;
  568.             dis.flag.dst_addr = 1;
  569.             dis.addr  = z80.bc.r16;
  570.             dis.mem8  = mem[dis.addr];
  571.             len = pad_argument("(BC)");
  572.             break;
  573.         case _dMDE:
  574.             dis.flag.dst_mem8 = 1;
  575.             dis.flag.dst_addr = 1;
  576.             dis.addr  = z80.de.r16;
  577.             dis.mem8  = mem[dis.addr];
  578.             len = pad_argument("(DE)");
  579.             break;
  580.         case _dMSP:
  581.             dis.flag.dst_mem16 = 1;
  582.             dis.flag.dst_addr  = 1;
  583.             dis.addr  = z80.sp.r16;
  584.             dis.mem16 = mem[dis.addr] + 256 * mem[dis.addr+1];
  585.             len = pad_argument("(SP)");
  586.             break;
  587.         case _dMIX:
  588.             if (!(dis.flag.has_ofs8))
  589.             {
  590.                 dis.flag.has_ofs8 = 1;
  591.                 dis.ofs8  = (OFS8) mem[dis.pc++];
  592.             }
  593.             dis.flag.dst_mem8 = 1;
  594.             dis.flag.dst_addr = 1;
  595.             dis.addr  = z80.ix.r16 + dis.ofs8;
  596.             dis.mem8  = mem[dis.addr];
  597.             if (dis.ofs8)
  598.                 len = pad_argument("(IX%+d)", dis.ofs8);
  599.             else
  600.                 len = pad_argument("(IX)");
  601.             break;
  602.         case _dMIY:
  603.             if (!dis.flag.has_ofs8)
  604.             {
  605.                 dis.flag.has_ofs8 = 1;
  606.                 dis.ofs8  = (OFS8) mem[dis.pc++];
  607.             }
  608.             dis.flag.dst_mem8 = 1;
  609.             dis.flag.dst_addr = 1;
  610.             dis.addr  = z80.iy.r16 + dis.ofs8;
  611.             dis.mem8  = mem[dis.addr];
  612.             if (dis.ofs8)
  613.                 len = pad_argument("(IY%+d)", dis.ofs8);
  614.             else
  615.                 len = pad_argument("(IY)");
  616.             break;
  617.         case _dIND8:
  618.             if (!(dis.flag.has_ind))
  619.             {
  620.                 dis.flag.has_ind = 1;
  621.                 dis.ind16  = mem[dis.pc++];
  622.                 dis.ind16 += mem[dis.pc++] << 8;
  623.             }
  624.             dis.flag.dst_mem8 = 1;
  625.             dis.addr  = dis.ind16;
  626.             dis.mem8  = mem[dis.addr];
  627.             len = pad_argument("(%s)", SYM_get(dis.ind16, SYM_NONE));
  628.             break;
  629.         case _dIMM8:
  630.             if (!(dis.flag.has_imm8))
  631.             {
  632.                 dis.flag.has_imm8 = 1;
  633.                 dis.imm8  = mem[dis.pc++];
  634.             }
  635.             len = pad_argument("%s", hexb(dis.imm8));
  636.             break;
  637.         case _dPORT8:
  638.             if (!(dis.flag.has_port))
  639.             {
  640.                 dis.flag.has_port = 1;
  641.                 dis.port  = mem[dis.pc++];
  642.             }
  643.             dis.flag.dst_port = 1;
  644.             len = pad_argument("(%s)", hexb(dis.port));
  645.             break;
  646.         case _dPORTC:
  647.             dis.flag.dst_port = 1;
  648.             dis.port  = z80.bc.r16;
  649.             len = pad_argument("(C)");
  650.             break;
  651.         case _dBC:
  652.             len = pad_argument("BC");
  653.             break;
  654.         case _dDE:
  655.             len = pad_argument("DE");
  656.             break;
  657.         case _dHL:
  658.             len = pad_argument("HL");
  659.             break;
  660.         case _dSP:
  661.             len = pad_argument("SP");
  662.             break;
  663.         case _dAF:
  664.             len = pad_argument("AF");
  665.             break;
  666.         case _dPC:
  667.             len = pad_argument("$");
  668.             break;
  669.         case _dIX:
  670.             len = pad_argument("IX");
  671.             break;
  672.         case _dIY:
  673.             len = pad_argument("IY");
  674.             break;
  675.         case _dPCHL:
  676.             dis.flag.dst_addr = 1;
  677.             dis.addr  = z80.hl.r16;
  678.             len = pad_argument("(HL)");
  679.             break;
  680.         case _dPCIX:
  681.             dis.flag.dst_addr = 1;
  682.             dis.addr  = z80.ix.r16;
  683.             len = pad_argument("(IX)");
  684.             break;
  685.         case _dPCIY:
  686.             dis.flag.dst_addr = 1;
  687.             dis.addr  = z80.iy.r16;
  688.             len = pad_argument("(IY)");
  689.             break;
  690.         case _dREG1:
  691.             len = pad_argument("BC,DE,HL");
  692.             break;
  693.         case _dREG2:
  694.             len = pad_argument("BC',DE',HL'");
  695.             break;
  696.         case _dAF2:
  697.             len = pad_argument("AF'");
  698.             break;
  699.         case _dIND16:
  700.             if (!(dis.flag.has_ind))
  701.             {
  702.                 dis.flag.has_ind = 1;
  703.                 dis.ind16  = mem[dis.pc++];
  704.                 dis.ind16 += mem[dis.pc++] << 8;
  705.             }
  706.             dis.flag.dst_mem16 = 1;
  707.             dis.addr  = dis.ind16;
  708.             dis.mem16 = mem[dis.addr] + 256 * mem[dis.addr + 1];
  709.             len = pad_argument("(%s)", SYM_get(dis.ind16, SYM_NONE));
  710.             break;
  711.         case _dIMPL:
  712.             dis.flag.dst_addr = 1;
  713.             dis.addr  = dis.cmd0 & 0x0038;
  714.             len = pad_argument("%s", hexb(dis.addr));
  715.             break;
  716.     }
  717.     if (comma)
  718.         len += sprintf(dis.dst + len, ",");
  719.     return len;
  720. }
  721.  
  722. //****************************************************************************
  723. // disassemble a source operand from the given table entry
  724. //******************************************************************----------
  725. int dis_src(TABLE * ptab)
  726. {
  727.     int len = 0;
  728.  
  729.     switch (ptab->src)
  730.     {
  731.         case _s0:
  732.             return 0;
  733.         case _sB:
  734.             len = pad_argument("B");
  735.             dis.val8 = z80.bc.r8[1];
  736.             break;
  737.  
  738.         case _sC:
  739.             len = pad_argument("C");
  740.             dis.val8 = z80.bc.r8[0];
  741.             break;
  742.  
  743.         case _sD:
  744.             len = pad_argument("D");
  745.             dis.val8 = z80.de.r8[1];
  746.             break;
  747.  
  748.         case _sE:
  749.             len = pad_argument("E");
  750.             dis.val8 = z80.de.r8[0];
  751.             break;
  752.  
  753.         case _sH:
  754.             len = pad_argument("H");
  755.             dis.val8 = z80.hl.r8[1];
  756.             break;
  757.  
  758.         case _sL:
  759.             len = pad_argument("L");
  760.             dis.val8 = z80.hl.r8[0];
  761.             break;
  762.  
  763.         case _sM:
  764.             dis.flag.src_mem8 = 1;
  765.             dis.flag.src_addr = 1;
  766.             dis.addr  = z80.hl.r16;
  767.             dis.mem8  = dis.val8 = mem[dis.addr];
  768.             len = pad_argument("(HL)");
  769.             break;
  770.  
  771.         case _sA:
  772.             len = pad_argument("A");
  773.             dis.val8 = z80.af.r8[1];
  774.             break;
  775.  
  776.         case _sHIX:
  777.             len = pad_argument("HX");
  778.             dis.val8 = z80.ix.r8[1];
  779.             break;
  780.  
  781.         case _sLIX:
  782.             len = pad_argument("LX");
  783.             dis.val8 = z80.ix.r8[0];
  784.             break;
  785.  
  786.         case _sHIY:
  787.             len = pad_argument("HY");
  788.             dis.val8 = z80.iy.r8[1];
  789.             break;
  790.  
  791.         case _sLIY:
  792.             len = pad_argument("LY");
  793.             dis.val8 = z80.iy.r8[0];
  794.             break;
  795.  
  796.         case _sI:
  797.             len = pad_argument("I");
  798.             dis.val8 = z80.ri.r8[0];
  799.             break;
  800.  
  801.         case _sR:
  802.             len = pad_argument("R");
  803.             dis.val8 = z80.ri.r8[1];
  804.             break;
  805.  
  806.         case _sF:
  807.             len = pad_argument("F");
  808.             dis.val8 = z80.af.r8[0];
  809.             break;
  810.  
  811.         case _sMBC:
  812.             dis.flag.src_mem8 = 1;
  813.             dis.flag.src_addr = 1;
  814.             dis.addr  = z80.bc.r16;
  815.             dis.mem8  = dis.val8 = mem[dis.addr];
  816.             len = pad_argument("(BC)");
  817.             break;
  818.  
  819.         case _sMDE:
  820.             dis.flag.src_mem8 = 1;
  821.             dis.flag.src_addr = 1;
  822.             dis.addr  = z80.de.r16;
  823.             dis.mem8  = dis.val8 = mem[dis.addr];
  824.             len = pad_argument("(DE)");
  825.             break;
  826.  
  827.         case _sMSP:
  828.             dis.flag.src_mem16 = 1;
  829.             dis.flag.src_addr  = 1;
  830.             dis.addr  = z80.sp.r16;
  831.             dis.mem16 = mem[dis.addr] + 256 * mem[dis.addr + 1];
  832.             len = pad_argument("(SP)");
  833.             break;
  834.  
  835.         case _sMIX:
  836.             if (!(dis.flag.has_ofs8))
  837.             {
  838.                 dis.flag.has_ofs8 = 1;
  839.                 dis.ofs8  = (OFS8) mem[dis.pc++];
  840.             }
  841.             dis.flag.src_mem8 = 1;
  842.             dis.flag.src_addr = 1;
  843.             dis.addr  = z80.ix.r16 + dis.ofs8;
  844.             dis.mem8  = dis.val8 = mem[dis.addr];
  845.             if (dis.ofs8)
  846.                 len = pad_argument("(IX%+d)", dis.ofs8);
  847.             else
  848.                 len = pad_argument("(IX)");
  849.             break;
  850.  
  851.         case _sMIY:
  852.             if (!(dis.flag.has_ofs8))
  853.             {
  854.                 dis.flag.has_ofs8 = 1;
  855.                 dis.ofs8  = (OFS8) mem[dis.pc++];
  856.             }
  857.             dis.flag.src_mem8 = 1;
  858.             dis.flag.src_addr = 1;
  859.             dis.addr  = z80.iy.r16 + dis.ofs8;
  860.             dis.mem8  = dis.val8 = mem[dis.addr];
  861.             if (dis.ofs8)
  862.                 len = pad_argument("(IY%+d)", dis.ofs8);
  863.             else
  864.                 len = pad_argument("(IY)");
  865.                         break;
  866.  
  867.         case _sIND8:
  868.             if (!(dis.flag.has_ind))
  869.             {
  870.                 dis.flag.has_ind = 1;
  871.                 dis.ind16  = mem[dis.pc++];
  872.                 dis.ind16 += mem[dis.pc++] << 8;
  873.             }
  874.             dis.flag.src_mem8 = 1;
  875.             dis.addr  = dis.ind16;
  876.             dis.mem8  = dis.val8 = mem[dis.addr];
  877.             len = pad_argument("(%s)", SYM_get(dis.ind16, SYM_NONE));
  878.             break;
  879.  
  880.         case _sIMM8:
  881.             if (!(dis.flag.has_imm8))
  882.             {
  883.                 dis.flag.has_imm8 = 1;
  884.                 dis.imm8  = mem[dis.pc++];
  885.             }
  886.             dis.val8 = dis.imm8;
  887.             len = pad_argument("%s", hexb(dis.imm8));
  888.             break;
  889.  
  890.         case _sIMM8A:
  891.             if (!(dis.flag.has_imm8))
  892.             {
  893.                 dis.flag.has_imm8 = 1;
  894.                 dis.imm8  = mem[dis.pc++];
  895.             }
  896.             dis.val8 = dis.imm8;
  897.             switch (dis.imm8)
  898.             {
  899.                 case 0 ... 31:
  900.                     len = pad_argument("%d", dis.imm8);
  901.                     break;
  902.                 case 32 ... 127:
  903.                     len = pad_argument("\"%c\"", dis.imm8);
  904.                     break;
  905.                 case 255:
  906.                     len = pad_argument("-1");
  907.                     break;
  908.                 default:
  909.                     len = pad_argument("%s", hexb(dis.imm8));
  910.                     break;
  911.             }
  912.             break;
  913.  
  914.         case _sPORT8:
  915.             if (!(dis.flag.has_port))
  916.             {
  917.                 dis.flag.has_port = 1;
  918.                 dis.port  = mem[dis.pc++];
  919.             }
  920.             dis.flag.src_port = 1;
  921.             dis.val8 = dis.port;
  922.             len = pad_argument("(%s)", hexb(dis.port));
  923.             break;
  924.  
  925.         case _sPORTC:
  926.             dis.flag.src_port = 1;
  927.             dis.port  = z80.bc.r16;
  928.             len = pad_argument("(C)");
  929.             break;
  930.  
  931.         case _sBC:
  932.             len = pad_argument("BC");
  933.             dis.val16 = z80.bc.r16;
  934.             break;
  935.  
  936.         case _sDE:
  937.             len = pad_argument("DE");
  938.             dis.val16 = z80.de.r16;
  939.             break;
  940.  
  941.         case _sHL:
  942.             len = pad_argument("HL");
  943.             dis.val16 = z80.hl.r16;
  944.             break;
  945.  
  946.         case _sSP:
  947.             len = pad_argument("SP");
  948.             dis.val16 = z80.sp.r16;
  949.             break;
  950.  
  951.         case _sAF:
  952.             len = pad_argument("AF");
  953.             dis.val16 = z80.af.r16;
  954.             break;
  955.  
  956.         case _sPC:
  957.             len = pad_argument("$");
  958.             break;
  959.  
  960.         case _sIX:
  961.             len = pad_argument("IX");
  962.             dis.val16 = z80.ix.r16;
  963.             break;
  964.  
  965.         case _sIY:
  966.             len = pad_argument("IY");
  967.             dis.val16 = z80.iy.r16;
  968.             break;
  969.  
  970.         case _sPCHL:
  971.             dis.flag.src_addr = 1;
  972.             dis.addr  = dis.val16 = z80.hl.r16;
  973.             len = pad_argument("(HL)");
  974.             break;
  975.  
  976.         case _sPCIX:
  977.             dis.flag.src_addr = 1;
  978.             dis.addr  = dis.val16 = z80.ix.r16;
  979.             len = pad_argument("(IX)");
  980.             break;
  981.  
  982.         case _sPCIY:
  983.             dis.flag.src_addr = 1;
  984.             dis.addr  = dis.val16 = z80.iy.r16;
  985.             len = pad_argument("(IY)");
  986.             break;
  987.  
  988.         case _sREL8:
  989.             if (!(dis.flag.has_rel8))
  990.             {
  991.                 dis.flag.has_rel8 = 1;
  992.                 dis.rel8  = (OFS8) mem[dis.pc++];
  993.             }
  994.             dis.flag.src_addr = 1;
  995.             dis.addr  = dis.pc + dis.rel8;
  996.             len = pad_argument("%s", SYM_get(dis.addr, SYM_CODE));
  997.             break;
  998.  
  999.         case _sREG1:
  1000.             len = pad_argument("BC,DE,HL");
  1001.             break;
  1002.  
  1003.         case _sREG2:
  1004.             len = pad_argument("BC',DE',HL'");
  1005.             break;
  1006.  
  1007.         case _sAF2:
  1008.             len = pad_argument("AF'");
  1009.             dis.val16 = z80.af2.r16;
  1010.             break;
  1011.  
  1012.         case _sIMM16:
  1013.             if (!(dis.flag.has_imm16))
  1014.             {
  1015.                 dis.flag.has_imm16 = 1;
  1016.                 dis.imm16  = mem[dis.pc++];
  1017.                 dis.imm16 += mem[dis.pc++] << 8;
  1018.             }
  1019.             dis.val16 = dis.imm16;
  1020.             len = pad_argument("%s", SYM_get(dis.imm16, SYM_NONE));
  1021.             break;
  1022.  
  1023.         case _sADR16:
  1024.             if (!(dis.flag.has_adr16))
  1025.             {
  1026.                 dis.flag.has_adr16 = 1;
  1027.                 dis.adr16  = mem[dis.pc++];
  1028.                 dis.adr16 += mem[dis.pc++] << 8;
  1029.             }
  1030.             dis.flag.jmp_addr = 1;
  1031.             dis.addr = dis.val16 = dis.adr16;
  1032.             len = pad_argument("%s", SYM_get(dis.adr16, SYM_NONE));
  1033.             break;
  1034.  
  1035.         case _sIND16:
  1036.             if (!(dis.flag.has_ind))
  1037.             {
  1038.                 dis.flag.has_ind = 1;
  1039.                 dis.ind16  = mem[dis.pc++];
  1040.                 dis.ind16 += mem[dis.pc++] << 8;
  1041.             }
  1042.             dis.flag.src_mem16 = 1;
  1043.             dis.addr  = dis.ind16;
  1044.             dis.mem16 = dis.val16 = mem[dis.addr] + 256 * mem[dis.addr + 1];
  1045.             len = pad_argument("(%s)", SYM_get(dis.ind16, SYM_NONE));
  1046.             break;
  1047.  
  1048.         case _sIMPL:
  1049.             dis.flag.jmp_addr = 1;
  1050.             dis.addr  = dis.cmd0 & 0x0038;
  1051.             len = pad_argument("%s", hexb(dis.addr));
  1052.             break;
  1053.     }
  1054.     return len;
  1055. }
  1056.  
  1057. //****************************************************************************
  1058. // disassemble a secondary destination from the given table entry
  1059. //******************************************************************----------
  1060. int dis_dst_2(TABLE * ptab)
  1061. {
  1062.     int len = 0;
  1063.     if (ptab->dst != ptab->src)    // DD CB and FD CB commands
  1064.     {
  1065.         len  = dis_dst(ptab, 0);
  1066.         len += pad_argument("=");
  1067.     }
  1068.     return len;
  1069. }
  1070.  
  1071. //****************************************************************************
  1072. // disassemble a bit number from the given table entry
  1073. //******************************************************************----------
  1074. int dis_bit(TABLE * ptab)
  1075. {
  1076.     int len = 0;
  1077.     switch (ptab->spec)
  1078.     {
  1079.         case _xBIT0:
  1080.             len = pad_argument("0");
  1081.             break;
  1082.         case _xBIT1:
  1083.             len = pad_argument("1");
  1084.             break;
  1085.         case _xBIT2:
  1086.             len = pad_argument("2");
  1087.             break;
  1088.         case _xBIT3:
  1089.             len = pad_argument("3");
  1090.             break;
  1091.         case _xBIT4:
  1092.             len = pad_argument("4");
  1093.             break;
  1094.         case _xBIT5:
  1095.             len = pad_argument("5");
  1096.             break;
  1097.         case _xBIT6:
  1098.             len = pad_argument("6");
  1099.             break;
  1100.         case _xBIT7:
  1101.             len = pad_argument("7");
  1102.             break;
  1103.         default:
  1104.             len = pad_argument("?");
  1105.             break;
  1106.     }
  1107.     len += sprintf(dis.dst + len, ",");
  1108.     return len;
  1109. }
  1110.  
  1111. //****************************************************************************
  1112. // disassemble a condition code from the given table entry
  1113. //******************************************************************----------
  1114. int dis_cond(TABLE * ptab, int comma)
  1115. {
  1116.     int len = 0;
  1117.     switch (ptab->cond)
  1118.     {
  1119.         case _c0:
  1120.             return len;
  1121.         case _cNZ:
  1122.             len = pad_argument("NZ");
  1123.             break;
  1124.         case _cZ:
  1125.             len = pad_argument("Z");
  1126.             break;
  1127.         case _cNC:
  1128.             len = pad_argument("NC");
  1129.             break;
  1130.         case _cC:
  1131.             len = pad_argument("C");
  1132.             break;
  1133.         case _cPO:
  1134.             len = pad_argument("PO");
  1135.             break;
  1136.         case _cPE:
  1137.             len = pad_argument("PE");
  1138.             break;
  1139.         case _cP:
  1140.             len = pad_argument("P");
  1141.             break;
  1142.         case _cM:
  1143.             len = pad_argument("M");
  1144.             break;
  1145.     }
  1146.     if (comma)
  1147.         len += sprintf(dis.dst + len, ",");
  1148.     return len;
  1149. }
  1150.  
  1151. //****************************************************************************
  1152. // disassemble one instruction from the given table entry
  1153. //******************************************************************----------
  1154. void dis_instr(TABLE * ptab)
  1155. {
  1156.     switch (ptab->oper)
  1157.     {
  1158.         case _t0:
  1159.             dis.dst += pad_opcode("???");
  1160.             break;
  1161.                         
  1162.         case _tADC:
  1163.             dis.dst += pad_opcode("ADC");
  1164.             dis.dst += dis_dst(ptab, 1);
  1165.             dis.dst += dis_src(ptab);
  1166.             if (ptab->dst == _dA)
  1167.                 dis.val8  += z80.af.r8[1] + z80.af.f.c;
  1168.             else
  1169.             if (ptab->dst == _dHL)
  1170.                 dis.val16 += z80.hl.r16 + z80.af.f.c;
  1171.             break;
  1172.             
  1173.         case _tADD:
  1174.             dis.dst += pad_opcode("ADD");
  1175.             dis.dst += dis_dst(ptab, 1);
  1176.             dis.dst += dis_src(ptab);
  1177.             if (ptab->dst == _dA)
  1178.                 dis.val8  += z80.af.r8[1];
  1179.             else
  1180.             if (ptab->dst == _dHL)
  1181.                 dis.val16 += z80.hl.r16;
  1182.             else
  1183.             if (ptab->dst == _dIX)
  1184.                 dis.val16 += z80.ix.r16;
  1185.             else
  1186.             if (ptab->dst == _dIY)
  1187.                 dis.val16 += z80.iy.r16;
  1188.             break;
  1189.                         
  1190.         case _tAND:
  1191.             dis.dst += pad_opcode("AND");
  1192.             dis.dst += dis_src(ptab);
  1193.             dis.val8 = (z80.af.r8[1] & dis.val8);
  1194.             break;
  1195.                         
  1196.         case _tBIT:
  1197.             dis.dst += pad_opcode("BIT");
  1198.             dis.dst += dis_bit(ptab);
  1199.             dis.dst += dis_dst_2(ptab);
  1200.             dis.dst += dis_src(ptab);
  1201.             break;
  1202.  
  1203.         case _tCALL:
  1204.             dis.dst += pad_opcode("CALL");
  1205.             dis.dst += dis_cond(ptab, 1);
  1206.             dis.dst += dis_src(ptab);
  1207.             break;
  1208.  
  1209.         case _tCCF:
  1210.             dis.dst += pad_opcode("CCF");
  1211.             z80.af.f.c = ~z80.af.f.c;
  1212.             break;
  1213.  
  1214.         case _tCP:
  1215.             dis.dst += pad_opcode("CP");
  1216.             dis.dst += dis_src(ptab);
  1217.             break;
  1218.  
  1219.         case _tCPD:
  1220.             dis.dst += pad_opcode("CPD");
  1221.             break;
  1222.  
  1223.         case _tCPDR:
  1224.             dis.dst += pad_opcode("CPDR");
  1225.             break;
  1226.  
  1227.         case _tCPI:
  1228.             dis.dst += pad_opcode("CPI");
  1229.             break;
  1230.  
  1231.         case _tCPIR:
  1232.             dis.dst += pad_opcode("CPIR");
  1233.             break;
  1234.  
  1235.         case _tCPL:
  1236.             dis.dst += pad_opcode("CPL");
  1237.             dis.val8 = ~z80.af.r8[1];
  1238.             break;
  1239.  
  1240.         case _tDAA:
  1241.             dis.dst += pad_opcode("DAA");
  1242.             break;
  1243.  
  1244.         case _tDEC:
  1245.             dis.dst += pad_opcode("DEC");
  1246.             dis.dst += dis_src(ptab);
  1247.             dis.val8  -= 1;
  1248.             dis.val16 -= 1;
  1249.             break;
  1250.  
  1251.         case _tDI:
  1252.             dis.dst += pad_opcode("DI");
  1253.             break;
  1254.  
  1255.         case _tDJNZ:
  1256.             dis.dst += pad_opcode("DJNZ");
  1257.             dis.dst += dis_src(ptab);
  1258.             z80.bc.r8[1] = 0;
  1259.             break;
  1260.  
  1261.         case _tEI:
  1262.             dis.dst += pad_opcode("EI");
  1263.             break;
  1264.  
  1265.         case _tEX:
  1266.             dis.dst += pad_opcode("EX");
  1267.             dis.dst += dis_dst(ptab, 1);
  1268.             dis.dst += dis_src(ptab);
  1269.             break;
  1270.  
  1271.         case _tEXX:
  1272.             dis.dst += pad_opcode("EXX");
  1273.             dis.val16 = z80.bc2.r16; z80.bc2.r16 = z80.bc.r16; z80.bc.r16 = dis.val16;
  1274.             dis.val16 = z80.de2.r16; z80.de2.r16 = z80.de.r16; z80.de.r16 = dis.val16;
  1275.             dis.val16 = z80.hl2.r16; z80.hl2.r16 = z80.hl.r16; z80.hl.r16 = dis.val16;
  1276.             break;
  1277.  
  1278.         case _tHALT:
  1279.             dis.dst += pad_opcode("HALT");
  1280.             break;
  1281.  
  1282.         case _tIM0:
  1283.             dis.dst += pad_opcode("IM");
  1284.             pad_argument("0");
  1285.             break;
  1286.             
  1287.         case _tIM1:
  1288.             dis.dst += pad_opcode("IM");
  1289.             pad_argument("1");
  1290.             break;
  1291.             
  1292.         case _tIM2:
  1293.             dis.dst += pad_opcode("IM");
  1294.             pad_argument("2");
  1295.             break;
  1296.             
  1297.         case _tIN:
  1298.             dis.dst += pad_opcode("IN");
  1299.             dis.dst += dis_dst(ptab, 1);
  1300.             dis.dst += dis_src(ptab);
  1301.             break;
  1302.  
  1303.         case _tINC:
  1304.             dis.dst += pad_opcode("INC");
  1305.             dis.dst += dis_src(ptab);
  1306.             dis.val8  += 1;
  1307.             dis.val16 += 1;
  1308.             break;
  1309.  
  1310.         case _tIND:
  1311.             dis.dst += pad_opcode("IND");
  1312.             break;
  1313.  
  1314.         case _tINDR:
  1315.             dis.dst += pad_opcode("INDR");
  1316.             break;
  1317.  
  1318.         case _tINI:
  1319.             dis.dst += pad_opcode("INI");
  1320.             break;
  1321.  
  1322.         case _tINIR:
  1323.             dis.dst += pad_opcode("INIR");
  1324.             break;
  1325.  
  1326.         case _tJP:
  1327.             dis.dst += pad_opcode("JP");
  1328.             dis.dst += dis_cond(ptab, 1);
  1329.             dis.dst += dis_src(ptab);
  1330.             dis.flag.end_mode = (ptab->cond == _c0) ? 1 : 0;
  1331.             break;
  1332.  
  1333.         case _tJR:
  1334.             dis.dst += pad_opcode("JR");
  1335.             dis.dst += dis_cond(ptab, 1);
  1336.             dis.dst += dis_src(ptab);
  1337.             dis.flag.end_mode = (ptab->cond == _c0) ? 1 : 0;
  1338.             break;
  1339.  
  1340.         case _tLD:
  1341.             dis.dst += pad_opcode("LD");
  1342.             dis.dst += dis_dst(ptab, 1);
  1343.             dis.dst += dis_src(ptab);
  1344.             break;
  1345.  
  1346.         case _tLDD:
  1347.             dis.dst += pad_opcode("LDD");
  1348.             z80.hl.r16 += 1;
  1349.             z80.de.r16 += 1;
  1350.             z80.bc.r16 -= 1;
  1351.             break;
  1352.  
  1353.         case _tLDDR:
  1354.             dis.dst += pad_opcode("LDDR");
  1355.             z80.hl.r16 -= z80.bc.r16;
  1356.             z80.de.r16 -= z80.bc.r16;
  1357.             z80.bc.r16  = 0;
  1358.             break;
  1359.  
  1360.         case _tLDI:
  1361.             dis.dst += pad_opcode("LDI");
  1362.             z80.hl.r16 += 1;
  1363.             z80.de.r16 += 1;
  1364.             z80.bc.r16 -= 1;
  1365.             break;
  1366.  
  1367.         case _tLDIR:
  1368.             dis.dst += pad_opcode("LDIR");
  1369.             z80.hl.r16 += z80.bc.r16;
  1370.             z80.de.r16 += z80.bc.r16;
  1371.             z80.bc.r16  = 0;
  1372.             break;
  1373.  
  1374.         case _tNEG:
  1375.             dis.dst += pad_opcode("NEG");
  1376.             dis.val8 = 0 - z80.af.r8[1];
  1377.             break;
  1378.  
  1379.         case _tNOP:
  1380.             dis.dst += pad_opcode("NOP");
  1381.             break;
  1382.  
  1383.         case _tOR:
  1384.             dis.dst += pad_opcode("OR");
  1385.             dis.dst += dis_src(ptab);
  1386.             dis.val8 |= z80.af.r8[1];
  1387.             break;
  1388.  
  1389.         case _tOTDR:
  1390.             dis.dst += pad_opcode("OTDR");
  1391.             break;
  1392.  
  1393.         case _tOTIR:
  1394.             dis.dst += pad_opcode("OTIR");
  1395.             break;
  1396.  
  1397.         case _tOUTD:
  1398.             dis.dst += pad_opcode("OUTD");
  1399.             break;
  1400.  
  1401.         case _tOUTI:
  1402.             dis.dst += pad_opcode("OUTI");
  1403.             break;
  1404.  
  1405.         case _tOUT:
  1406.             dis.dst += pad_opcode("OUT");
  1407.             dis.dst += dis_dst(ptab, 1);
  1408.             dis.dst += dis_src(ptab);
  1409.             break;
  1410.  
  1411.         case _tPOP:
  1412.             dis.dst += pad_opcode("POP");
  1413.             dis.dst += dis_dst(ptab, 0);
  1414.             break;
  1415.  
  1416.         case _tPUSH:
  1417.             dis.dst += pad_opcode("PUSH");
  1418.             dis.dst += dis_src(ptab);
  1419.             break;
  1420.  
  1421.         case _tRES:
  1422.             dis.dst += pad_opcode("RES");
  1423.             dis.dst += dis_bit(ptab);
  1424.             dis.dst += dis_dst_2(ptab);
  1425.             dis.dst += dis_src(ptab);
  1426.             switch (ptab->spec)
  1427.             {
  1428.                 case _x0:
  1429.                 case _xPC:                       break;
  1430.                 case _xBIT0: dis.val8 &= 0xFE; break;
  1431.                 case _xBIT1: dis.val8 &= 0xFD; break;
  1432.                 case _xBIT2: dis.val8 &= 0xFB; break;
  1433.                 case _xBIT3: dis.val8 &= 0xF7; break;
  1434.                 case _xBIT4: dis.val8 &= 0xEF; break;
  1435.                 case _xBIT5: dis.val8 &= 0xDF; break;
  1436.                 case _xBIT6: dis.val8 &= 0xBF; break;
  1437.                 case _xBIT7: dis.val8 &= 0x7F; break;
  1438.             }
  1439.             break;
  1440.  
  1441.         case _tRETN:
  1442.             dis.dst += pad_opcode("RETN");
  1443.             dis.flag.end_mode = 1;
  1444.             break;
  1445.  
  1446.         case _tRETI:
  1447.             dis.dst += pad_opcode("RETI");
  1448.             dis.flag.end_mode = 1;
  1449.             break;
  1450.  
  1451.         case _tRET:
  1452.             dis.dst += pad_opcode("RET");
  1453.             dis.dst += dis_cond(ptab, 0);
  1454.             dis.flag.end_mode = (ptab->cond == _c0) ? 1 : 0;
  1455.             break;
  1456.  
  1457.         case _tRL:
  1458.             dis.dst += pad_opcode("RL");
  1459.             dis.dst += dis_src(ptab);
  1460.             dis.val8 = (dis.val8 << 1) | (z80.af.f.c);
  1461.             break;
  1462.  
  1463.         case _tRLA:
  1464.             dis.dst += pad_opcode("RLA");
  1465.             dis.val8 = (z80.af.r8[1] << 1) | (z80.af.f.c);
  1466.             break;
  1467.  
  1468.         case _tRLC:
  1469.             dis.dst += pad_opcode("RLC");
  1470.             dis.dst += dis_dst_2(ptab);
  1471.             dis.dst += dis_src(ptab);
  1472.             dis.val8 = (dis.val8 << 1) | (dis.val8 >> 7);
  1473.             break;
  1474.  
  1475.         case _tRLCA:
  1476.             dis.dst += pad_opcode("RLCA");
  1477.             dis.val8 = (z80.af.r8[1] << 1) | (z80.af.r8[1] >> 7);
  1478.             break;
  1479.  
  1480.         case _tRLD:
  1481.             dis.dst += pad_opcode("RLD");
  1482.             dis.dst += dis_src(ptab);
  1483.             break;
  1484.  
  1485.         case _tRR:
  1486.             dis.dst += pad_opcode("RR");
  1487.             dis.dst += dis_dst_2(ptab);
  1488.             dis.dst += dis_src(ptab);
  1489.             dis.val8 = (dis.val8 >> 1) | (z80.af.f.c << 7);
  1490.             break;
  1491.  
  1492.         case _tRRA:
  1493.             dis.dst += pad_opcode("RRA");
  1494.             dis.val8 = (z80.af.r8[1] >> 1) | (z80.af.f.c << 7);
  1495.             break;
  1496.  
  1497.         case _tRRC:
  1498.             dis.dst += pad_opcode("RRC");
  1499.             dis.dst += dis_dst_2(ptab);
  1500.             dis.dst += dis_src(ptab);
  1501.             dis.val8 = (dis.val8 >> 1) | (dis.val8 << 7);
  1502.             break;
  1503.  
  1504.         case _tRRCA:
  1505.             dis.dst += pad_opcode("RRCA");
  1506.             dis.val8 = (z80.af.r8[1] >> 1) | (z80.af.r8[1] << 7);
  1507.             break;
  1508.  
  1509.         case _tRRD:
  1510.             dis.dst += pad_opcode("RRD");
  1511.             dis.dst += dis_src(ptab);
  1512.             break;
  1513.  
  1514.         case _tRST:
  1515.             dis.dst += pad_opcode("RST");
  1516.             dis.dst += dis_src(ptab);
  1517.             break;
  1518.  
  1519.         case _tSBC:
  1520.             dis.dst += pad_opcode("SBC");
  1521.             dis.dst += dis_dst(ptab, 1);
  1522.             dis.dst += dis_src(ptab);
  1523.             if (ptab->dst == _dA)
  1524.                 dis.val8  = (z80.af.r8[1] - dis.val8 - z80.af.f.c);
  1525.             else
  1526.             if (ptab->dst == _dHL)
  1527.                 dis.val16 = (z80.hl.r16 - dis.val16 - z80.af.f.c);
  1528.             break;
  1529.  
  1530.         case _tSCF:
  1531.             dis.dst += pad_opcode("SCF");
  1532.             z80.af.f.c = 1;
  1533.             break;
  1534.  
  1535.         case _tSET:
  1536.             dis.dst += pad_opcode("SET");
  1537.             dis.dst += dis_bit(ptab);
  1538.             dis.dst += dis_dst_2(ptab);
  1539.             dis.dst += dis_src(ptab);
  1540.             switch (ptab->spec)
  1541.             {
  1542.                 case _x0:
  1543.                 case _xPC:
  1544.                     break;
  1545.                 case _xBIT0: dis.val8 |= 0x01; break;
  1546.                 case _xBIT1: dis.val8 |= 0x02; break;
  1547.                 case _xBIT2: dis.val8 |= 0x04; break;
  1548.                 case _xBIT3: dis.val8 |= 0x08; break;
  1549.                 case _xBIT4: dis.val8 |= 0x10; break;
  1550.                 case _xBIT5: dis.val8 |= 0x20; break;
  1551.                 case _xBIT6: dis.val8 |= 0x40; break;
  1552.                 case _xBIT7: dis.val8 |= 0x80; break;
  1553.             }
  1554.             break;
  1555.  
  1556.         case _tSHL:
  1557.             dis.dst += pad_opcode("SHL");
  1558.             dis.dst += dis_dst_2(ptab);
  1559.             dis.dst += dis_src(ptab);
  1560.             dis.val8 = dis.val8 * 2;
  1561.             break;
  1562.  
  1563.         case _tSHR:
  1564.             dis.dst += pad_opcode("SHR");
  1565.             dis.dst += dis_dst_2(ptab);
  1566.             dis.dst += dis_src(ptab);
  1567.             dis.val8 = dis.val8 / 2;
  1568.             break;
  1569.  
  1570.         case _tSLI:
  1571.             dis.dst += pad_opcode("SLI");
  1572.             dis.dst += dis_dst_2(ptab);
  1573.             dis.dst += dis_src(ptab);
  1574.             dis.val8 = dis.val8 * 2 + 1;
  1575.             break;
  1576.  
  1577.         case _tSRL:
  1578.             dis.dst += pad_opcode("SRL");
  1579.             dis.dst += dis_dst_2(ptab);
  1580.             dis.dst += dis_src(ptab);
  1581.             dis.val8 = (dis.val8 & 0x80) + (dis.val8 / 2);
  1582.             break;
  1583.  
  1584.         case _tSUB:
  1585.             dis.dst += pad_opcode("SUB");
  1586.             dis.dst += dis_src(ptab);
  1587.             dis.val8 = (z80.af.r8[1] - dis.val8);
  1588.             break;
  1589.  
  1590.         case _tXOR:
  1591.             dis.dst += pad_opcode("XOR");
  1592.             dis.dst += dis_src(ptab);
  1593.             dis.val8 = (z80.af.r8[1] ^ dis.val8);
  1594.             break;
  1595.  
  1596.         case _tEXT:
  1597.             break;
  1598.     }
  1599. }
  1600.  
  1601. char * dis_code(WORD * addr)
  1602. {
  1603.     TABLE *ptab;
  1604.  
  1605.     dis.pc     = *addr;
  1606.     dis.cmd0  = mem[dis.pc++];
  1607.     dis.dst   = dis.buff + COLUMN_OPCODE;
  1608.  
  1609.     switch (dis.cmd0)
  1610.     {
  1611.         case 0xCB:
  1612.             dis.cmd1  = mem[dis.pc++];
  1613.             ptab      = dis_cb + dis.cmd1;
  1614.             dis.flag.has_cmd1 = 1;
  1615.             dis_instr(ptab);
  1616.             break;
  1617.  
  1618.         case 0xDD:
  1619.             dis.cmd1 = mem[dis.pc];
  1620.             ptab     = dis_dd + dis.cmd1;
  1621.             if (ptab->oper)
  1622.             {
  1623.                 dis.flag.has_cmd1 = 1;
  1624.                 dis.pc++;
  1625.                 if (ptab->oper == _tEXT)
  1626.                 {
  1627.                     dis.ofs8  = mem[dis.pc++];
  1628.                     dis.flag.has_ofs8 = 1;
  1629.                     dis.cmd3  = mem[dis.pc++];
  1630.                     dis.flag.has_cmd3 = 1;
  1631.                     ptab      = dis_ddcb + dis.cmd3;
  1632.                     dis_instr(ptab);
  1633.                     break;
  1634.                 }
  1635.                 dis_instr(ptab);
  1636.             }
  1637.             break;
  1638.  
  1639.         case 0xED:
  1640.             dis.cmd1 = mem[dis.pc];
  1641.             ptab     = dis_ed + dis.cmd1;
  1642.             if (ptab->oper)
  1643.             {
  1644.                 dis.flag.has_cmd1 = 1;
  1645.                 dis.pc++;
  1646.                 dis_instr(ptab);
  1647.             }
  1648.             break;
  1649.  
  1650.         case 0xFD:
  1651.             dis.cmd1 = mem[dis.pc];
  1652.             ptab     = dis_fd + dis.cmd1;
  1653.             if (ptab->oper)
  1654.             {
  1655.                 dis.flag.has_cmd1 = 1;
  1656.                 dis.pc++;
  1657.                 if (ptab->oper == _tEXT)
  1658.                 {
  1659.                     dis.ofs8  = mem[dis.pc++];
  1660.                     dis.flag.has_ofs8 = 1;
  1661.                     dis.cmd3  = mem[dis.pc++];
  1662.                     dis.flag.has_cmd3 = 1;
  1663.                     ptab      = dis_fdcb + dis.cmd3;
  1664.                     dis_instr(ptab);
  1665.                     break;
  1666.                 }
  1667.                 dis_instr(ptab);
  1668.             }
  1669.             break;
  1670.  
  1671.         default:
  1672.             ptab = dis_xx + dis.cmd0;
  1673.             dis_instr(ptab);
  1674.             break;
  1675.     }
  1676.  
  1677.     if (!ptab->oper)
  1678.         dis.dst += pad_opcode("???  %02X", dis.cmd0);
  1679.  
  1680.     *dis.dst   = '\0';
  1681.  
  1682.     if (dis.prtcom)
  1683.     {
  1684.         dis.prtcom = 0;
  1685.         dis.dst += pad_comment(" %s", COM_get(*addr, COM_APPEND));
  1686.     }
  1687.     else
  1688.     {
  1689.         if (dis.flag.has_rel8)
  1690.         {
  1691.             dis.dst += pad_comment(" $%+d", dis.rel8);
  1692.         }
  1693.  
  1694.         if (dis.flag.src_mem8)
  1695.         {
  1696.             dis.dst += pad_comment(" [%04X] {%02X}", dis.addr, dis.mem8);
  1697.             dis.flag.src_addr = 0;
  1698.         }
  1699.         else
  1700.         if (dis.flag.dst_mem8)
  1701.         {
  1702.             dis.dst += pad_comment(" [%04X] {%02X}", dis.addr, dis.mem8);
  1703.             dis.flag.dst_addr = 0;
  1704.         }
  1705.  
  1706.         if (dis.flag.src_mem16)
  1707.         {
  1708.             dis.dst += pad_comment(" [%04X] {%s}", dis.addr, SYM_get(dis.mem16, SYM_NONE));
  1709.             dis.flag.src_addr = 0;
  1710.         }
  1711.         else
  1712.         if (dis.flag.dst_mem16)
  1713.         {
  1714.             dis.dst += pad_comment(" [%04X] {%s}", dis.addr, SYM_get(dis.mem16, SYM_NONE));
  1715.             dis.flag.dst_addr = 0;
  1716.         }
  1717.  
  1718.         if (dis.flag.src_port)
  1719.         {
  1720.             dis.dst += pad_comment(" (%04X)", dis.port);
  1721.         }
  1722.  
  1723.         if (dis.flag.dst_port)
  1724.         {
  1725.             dis.dst += pad_comment(" (%04X)", dis.port);
  1726.         }
  1727.  
  1728.         if (dis.flag.src_addr)
  1729.         {
  1730.             dis.dst += pad_comment(" %04X", dis.addr);
  1731.         }
  1732.         else
  1733.         if (dis.flag.dst_addr)
  1734.         {
  1735.             dis.dst += pad_comment(" %04X", dis.addr);
  1736.         }
  1737.         else
  1738.         if (dis.flag.jmp_addr)
  1739.         {
  1740.             dis.dst += pad_comment(" %04X", dis.addr);
  1741.         }
  1742.     }
  1743.  
  1744.     sprintf(dis.buff, "%04X:%02X ", *addr, dis.cmd0);
  1745.  
  1746.     dis.dst = dis.buff + 8;
  1747.     *addr  += 1;
  1748.  
  1749.     if (dis.flag.has_cmd1)
  1750.     {
  1751.         dis.dst += sprintf(dis.dst, "%02X ", dis.cmd1);
  1752.         *addr    += 1;
  1753.     }
  1754.     if (dis.flag.has_port)
  1755.     {
  1756.         dis.dst += sprintf(dis.dst, "%02X ", dis.port);
  1757.         *addr    += 1;
  1758.     }
  1759.     if (dis.flag.has_imm8)
  1760.     {
  1761.         dis.dst += sprintf(dis.dst, "%02X ", dis.imm8);
  1762.         *addr    += 1;
  1763.     }
  1764.     if (dis.flag.has_ofs8)
  1765.     {
  1766.         dis.dst += sprintf(dis.dst, "%02X ", (BYTE)dis.ofs8);
  1767.         *addr    += 1;
  1768.     }
  1769.     if (dis.flag.has_rel8)
  1770.     {
  1771.         dis.dst += sprintf(dis.dst, "%02X ", (BYTE)dis.rel8);
  1772.         *addr    += 1;
  1773.     }
  1774.     if (dis.flag.has_imm16)
  1775.     {
  1776.         dis.dst += sprintf(dis.dst, "%04X ", dis.imm16);
  1777.         *addr    += 2;
  1778.     }
  1779.     if (dis.flag.has_adr16)
  1780.     {
  1781.         dis.dst += sprintf(dis.dst, "%04X ", dis.adr16);
  1782.         *addr    += 2;
  1783.     }
  1784.     if (dis.flag.has_ind)
  1785.     {
  1786.         dis.dst += sprintf(dis.dst, "%04X ", dis.ind16);
  1787.         *addr    += 2;
  1788.     }
  1789.     if (dis.flag.has_cmd3)
  1790.     {
  1791.         dis.dst += sprintf(dis.dst, "%02X ", dis.cmd3);
  1792.         *addr    += 1;
  1793.     }
  1794.  
  1795.     while (dis.dst < dis.buff + COLUMN_OPCODE)
  1796.         *dis.dst++ = ' ';
  1797.  
  1798.     switch (ptab->dst)
  1799.     {
  1800.         case _d0:
  1801.         case _dM:
  1802.         case _dMBC:
  1803.         case _dMDE:
  1804.         case _dMSP:
  1805.         case _dMIX:
  1806.         case _dMIY:
  1807.         case _dIMM8:
  1808.         case _dIND8:
  1809.         case _dPC:
  1810.         case _dREG1:
  1811.         case _dREG2:
  1812.         case _dIND16:
  1813.         case _dIMPL:
  1814.             break;
  1815.         case _dB:
  1816.             z80.bc.r8[1] = dis.val8;
  1817.             break;
  1818.         case _dC:
  1819.             z80.bc.r8[0] = dis.val8;
  1820.             break;
  1821.         case _dD:
  1822.             z80.de.r8[1] = dis.val8;
  1823.             break;
  1824.         case _dE:
  1825.             z80.de.r8[0] = dis.val8;
  1826.             break;
  1827.         case _dH:
  1828.             z80.hl.r8[1] = dis.val8;
  1829.             break;
  1830.         case _dL:
  1831.             z80.hl.r8[0] = dis.val8;
  1832.             break;
  1833.         case _dA:
  1834.             z80.af.r8[1] = dis.val8;
  1835.             break;
  1836.         case _dHIX:
  1837.             z80.ix.r8[1] = dis.val8;
  1838.             break;
  1839.         case _dLIX:
  1840.             z80.ix.r8[0] = dis.val8;
  1841.             break;
  1842.         case _dHIY:
  1843.             z80.iy.r8[1] = dis.val8;
  1844.             break;
  1845.         case _dLIY:
  1846.             z80.iy.r8[0] = dis.val8;
  1847.             break;
  1848.         case _dI:
  1849.             z80.ri.r8[0] = dis.val8;
  1850.             break;
  1851.         case _dR:
  1852.             z80.ri.r8[1] = dis.val8;
  1853.             break;
  1854.         case _dF:
  1855.             z80.af.r8[0] = dis.val8;
  1856.             break;
  1857.         case _dPORT8:
  1858.             break;
  1859.         case _dPORTC:
  1860.             break;
  1861.         case _dBC:
  1862.             z80.bc.r16 = dis.val16;
  1863.             break;
  1864.         case _dDE:
  1865.             z80.de.r16 = dis.val16;
  1866.             break;
  1867.         case _dHL:
  1868.             z80.hl.r16 = dis.val16;
  1869.             break;
  1870.         case _dSP:
  1871.             z80.sp.r16 = dis.val16;
  1872.             break;
  1873.         case _dAF:
  1874.             z80.af.r16 = dis.val16;
  1875.             break;
  1876.         case _dIX:
  1877.             z80.ix.r16 = dis.val16;
  1878.             break;
  1879.         case _dIY:
  1880.             z80.iy.r16 = dis.val16;
  1881.             break;
  1882.         case _dPCHL:
  1883.         case _dPCIX:
  1884.         case _dPCIY:
  1885.             z80.pc.r16 = dis.val16;
  1886.             break;
  1887.         case _dAF2:
  1888.             z80.af2.r16 = dis.val16;
  1889.             break;
  1890.     }
  1891.  
  1892.     if (dis.flag.end_mode)
  1893.         memset(&z80, 0, sizeof(z80));
  1894.  
  1895.     return dis.buff;
  1896. }
  1897.  
  1898. int    dis_bytes(void)
  1899. {
  1900.     int i;
  1901.  
  1902.     dis.dst += pad_opcode("DEFB");
  1903.     for (i = 0; i < 8; i++)
  1904.     {
  1905.         if (i > 0)
  1906.         {
  1907.             if (memopt[dis.pc].symbol)
  1908.                 break;
  1909.             if (memopt[dis.pc].comment)
  1910.                 break;
  1911.             if (NEWOPT(dis.pc))
  1912.                 break;
  1913.             dis.dst += pad_argument(",");
  1914.         }
  1915.         dis.val8 = mem[dis.pc++];
  1916.         dis.dst += pad_argument("%s", hexb(dis.val8));
  1917.     }
  1918.     return i;
  1919. }
  1920.  
  1921. int    dis_ascii(void)
  1922. {
  1923.     BYTE str = 0;
  1924.     BYTE old = 0;
  1925.     int i;
  1926.  
  1927.     dis.dst += pad_opcode("DEFM");
  1928.     for (i = 0; i < 8; i++)
  1929.     {
  1930.         if (i > 0)
  1931.         {
  1932.             if ((dis.val8 == 0x00) && (old != 0x00))
  1933.                 break;
  1934.             if (memopt[dis.pc].symbol)
  1935.                 break;
  1936.             if (memopt[dis.pc].comment)
  1937.                 break;
  1938.             if (NEWOPT(dis.pc))
  1939.                 break;
  1940.             if (!str)
  1941.                 dis.dst += pad_argument(",");
  1942.         }
  1943.         old = dis.val8;
  1944.         dis.val8 = mem[dis.pc++];
  1945.         switch (dis.val8)
  1946.         {
  1947.             case 0x00 ... 0x1F:
  1948.             case 0x22:
  1949.                 if (str)
  1950.                     dis.dst += pad_argument("\",");
  1951.                 dis.dst += pad_argument("%s", hexb(dis.val8));
  1952.                 str = 0;
  1953.                 break;
  1954.             default:
  1955.                 if (!str)
  1956.                     dis.dst += pad_argument("\"");
  1957.                 dis.dst += pad_argument("%c", dis.val8);
  1958.                 str = 1;
  1959.                 break;
  1960.         }
  1961.     }
  1962.     if (str)
  1963.         dis.dst += pad_argument("\"");
  1964.     return i;
  1965. }
  1966.  
  1967. int    dis_7bit(void)
  1968. {
  1969.     int first_bit8;
  1970.     BYTE str = 0;
  1971.     int i;
  1972.  
  1973.     dis.dst += pad_opcode("DEFM");
  1974.     first_bit8 = (mem[dis.pc] & 0x80) ? 1 : 0;
  1975.     for (i = 0; i < 8; i++)
  1976.     {
  1977.         if (i > 0)
  1978.         {
  1979.             if (mem[dis.pc] == 0x80)
  1980.             {
  1981.                 dis.flag.end_mode = 1;
  1982.                 break;
  1983.             }
  1984.  
  1985.             if (first_bit8 && (mem[dis.pc] & 0x80))
  1986.                 break;
  1987.             if (!first_bit8 && (dis.val8 & 0x80))
  1988.                 break;
  1989.             if (memopt[dis.pc].symbol)
  1990.                 break;
  1991.             if (memopt[dis.pc].comment)
  1992.                 break;
  1993.             if (NEWOPT(dis.pc))
  1994.                 break;
  1995.             if (!str)
  1996.                 dis.dst += pad_argument(",");
  1997.         }
  1998.         dis.val8 = mem[dis.pc++];
  1999.         switch (dis.val8)
  2000.         {
  2001.             case 0x00 ... 0x1F:
  2002.             case 0x22:
  2003.             case 0x80 ... 0x9F:
  2004.             case 0xA7:
  2005.                 if (str)
  2006.                     dis.dst += pad_argument("\",");
  2007.                 dis.dst += pad_argument("%s", hexb(dis.val8));
  2008.                 str = 0;
  2009.                 break;
  2010.             case 0xA0 ... 0xA6:
  2011.             case 0xA8 ... 0xFF:
  2012.                 if (str)
  2013.                     dis.dst += pad_argument("\",");
  2014.                 dis.dst += pad_argument("'%c'+80h", dis.val8 & 0x7F);
  2015.                 str = 0;
  2016.                 break;
  2017.             default:
  2018.                 if (!str)
  2019.                     dis.dst += pad_argument("\"");
  2020.                 dis.dst += pad_argument("%c", dis.val8);
  2021.                 str = 1;
  2022.                 break;
  2023.         }
  2024.     }
  2025.     if (str)
  2026.         dis.dst += pad_argument("\"");
  2027.     return i;
  2028. }
  2029.  
  2030. int    dis_words(void)
  2031. {
  2032.     int i;
  2033.     dis.dst += pad_opcode("DEFW");
  2034.     for (i = 0; i < 4; i++)
  2035.     {
  2036.         if (i > 0)
  2037.         {
  2038.             if (memopt[dis.pc].symbol)
  2039.                 break;
  2040.             if (memopt[dis.pc].comment)
  2041.                 break;
  2042.             if (NEWOPT(dis.pc))
  2043.                 break;
  2044.             dis.dst += pad_argument(",");
  2045.         }
  2046.         dis.val16  = mem[dis.pc++];
  2047.         dis.val16 += mem[dis.pc++] << 8;
  2048.         dis.dst += pad_argument("%s", hexw(dis.val16));
  2049.     }
  2050.     return i;
  2051. }
  2052.  
  2053. int    dis_entry(void)
  2054. {
  2055.     dis.dst += pad_opcode("DEFW");
  2056.     dis.val16  = mem[dis.pc++];
  2057.     dis.val16 += mem[dis.pc++] << 8;
  2058.     dis.dst += pad_argument("%s", SYM_get(dis.val16, SYM_NONE));
  2059.     return 1;
  2060. }
  2061.  
  2062. double frac2[56] = {
  2063.     0.5,
  2064.     0.25,
  2065.     0.125,
  2066.     0.0625,
  2067.     0.03125,
  2068.     0.015625,
  2069.     0.0078125,
  2070.     0.00390625,
  2071.     0.001953125,
  2072.     0.0009765625,
  2073.     0.00048828125,
  2074.     0.000244140625,
  2075.     0.0001220703125,
  2076.     0.00006103515625,
  2077.     0.000030517578125,
  2078.     0.0000152587890625,
  2079.     0.00000762939453125,
  2080.     0.000003814697265625,
  2081.     0.0000019073486328125,
  2082.     0.00000095367431640625,
  2083.     0.000000476837158203125,
  2084.     0.0000002384185791015625,
  2085.     0.00000011920928955078125,
  2086.     0.000000059604644775390625,
  2087.     0.0000000298023223876953125,
  2088.     0.00000001490116119384765625,
  2089.     0.000000007450580596923828125,
  2090.     0.0000000037252902984619140625,
  2091.     0.00000000186264514923095703125,
  2092.     0.000000000931322574615478515625,
  2093.     0.0000000004656612873077392578125,
  2094.     0.00000000023283064365386962890625,
  2095.     0.000000000116415321826934814453125,
  2096.     0.0000000000582076609134674072265625,
  2097.     0.00000000002910383045673370361328125,
  2098.     0.000000000014551915228366851806640625,
  2099.     0.0000000000072759576141834259033203125,
  2100.     0.00000000000363797880709171295166015625,
  2101.     0.000000000001818989403545856475830078125,
  2102.     0.0000000000009094947017729282379150390625,
  2103.     0.00000000000045474735088646411895751953125,
  2104.     0.000000000000227373675443232059478759765625,
  2105.     0.0000000000001136868377216160297393798828125,
  2106.     0.00000000000005684341886080801486968994140625,
  2107.     0.000000000000028421709430404007434844970703125,
  2108.     0.0000000000000142108547152020037174224853515625,
  2109.     0.00000000000000710542735760100185871124267578125,
  2110.     0.000000000000003552713678800500929355621337890625,
  2111.     0.0000000000000017763568394002504646778106689453125,
  2112.     0.00000000000000088817841970012523233890533447265625,
  2113.     0.000000000000000444089209850062616169452667236328125,
  2114.     0.0000000000000002220446049250313080847263336181640625,
  2115.     0.00000000000000011102230246251565404236316680908203125,
  2116.     0.000000000000000055511151231257827021181583404541015625,
  2117.     0.0000000000000000277555756156289135105907917022705078125,
  2118.     0.00000000000000001387778780781445675529539585113525390625,
  2119. };
  2120.  
  2121. int dis_float_single(void)
  2122. {
  2123.     BYTE b[4];
  2124.     int i;
  2125.     double    df;
  2126.  
  2127.     b[0] = mem[dis.pc++];
  2128.     b[1] = mem[dis.pc++];
  2129.     b[2] = mem[dis.pc++];
  2130.     b[3] = mem[dis.pc++];
  2131.     dis.fsng.man  = b[0];
  2132.     dis.fsng.man += b[1] << 8;
  2133.     dis.fsng.man += b[2] << 16;
  2134.     dis.fsng.exp  = b[3] - 128;
  2135.     dis.dst += pad_opcode("DEFB");
  2136.     dis.dst += pad_argument("%s,%s,%s,%s", hexb(b[0]), hexb(b[1]), hexb(b[2]), hexb(b[3]));
  2137.  
  2138.     if (dis.prtcom)
  2139.         return 1;
  2140.  
  2141.     df = frac2[0];
  2142.     for (i = 1; i < 24; i++)
  2143.         if (dis.fsng.man & (0x800000 >> i))
  2144.             df += frac2[i];
  2145.  
  2146.     if (dis.fsng.exp > 0)
  2147.         df *= 1 << dis.fsng.exp;
  2148.     else
  2149.         df /= 1 << -dis.fsng.exp;
  2150.  
  2151.     if (dis.fsng.man & 0x800000)
  2152.         df = -df;
  2153.  
  2154.     dis.dst += pad_comment(" %g", df);
  2155.  
  2156.     return 1;
  2157. }
  2158. int    dis_float_double(void)
  2159. {
  2160.     BYTE b[8];
  2161.     int i;
  2162.     double df;
  2163.  
  2164.     b[0] = mem[dis.pc++];
  2165.     b[1] = mem[dis.pc++];
  2166.     b[2] = mem[dis.pc++];
  2167.     b[3] = mem[dis.pc++];
  2168.     b[4] = mem[dis.pc++];
  2169.     b[5] = mem[dis.pc++];
  2170.     b[6] = mem[dis.pc++];
  2171.     b[7] = mem[dis.pc++];
  2172.     dis.fdbl.manl  = b[0];
  2173.     dis.fdbl.manl += b[1] << 8;
  2174.     dis.fdbl.manl += b[2] << 16;
  2175.     dis.fdbl.manl += b[3] << 24;
  2176.     dis.fdbl.manh  = b[4];
  2177.     dis.fdbl.manh += b[5] << 8;
  2178.     dis.fdbl.manh += b[6] << 16;
  2179.     dis.fdbl.exp   = b[7] - 128;
  2180.     dis.dst += pad_opcode("DEFB");
  2181.     dis.dst += pad_argument("%s,%s,%s,%s,%s,%s,%s,%s", hexb(b[0]), hexb(b[1]), hexb(b[2]), hexb(b[3]), hexb(b[4]), hexb(b[5]), hexb(b[6]), hexb(b[7]));
  2182.  
  2183.     if (dis.prtcom)
  2184.         return 1;
  2185.  
  2186.     df = frac2[0];
  2187.     for (i = 1; i < 32; i++)
  2188.         if (dis.fdbl.manl & (0x80000000 >> i))
  2189.             df += frac2[i];
  2190.     for (i = 0; i < 24; i++)
  2191.         if (dis.fdbl.manh & (0x800000 >> i))
  2192.             df += frac2[32+i];
  2193.     if (dis.fdbl.exp > 0)
  2194.         df *= 1 << dis.fdbl.exp;
  2195.     else
  2196.         df /= 1 << -dis.fdbl.exp;
  2197.  
  2198.     if (dis.fdbl.manh & 0x800000)
  2199.         df = -df;
  2200.  
  2201.     dis.dst += pad_comment(" %g", df);
  2202.     return 1;
  2203. }
  2204.  
  2205. char * dis_data(WORD * addr)
  2206. {
  2207.     char * phex;
  2208.     int cnt;
  2209.  
  2210.     dis.pc  = *addr;
  2211.  
  2212.     dis.dst = dis.buff + sprintf(dis.buff, "%04X:", dis.pc);
  2213.  
  2214.     phex    = dis.dst;
  2215.  
  2216.     switch (dis.curopt.opt)
  2217.     {
  2218.         case OPT_BYTES:
  2219.             cnt = dis_bytes();
  2220.             break;
  2221.  
  2222.         case OPT_ASCII:
  2223.             cnt = dis_ascii();
  2224.             break;
  2225.  
  2226.         case OPT_7BIT:
  2227.             cnt = dis_7bit();
  2228.             break;
  2229.  
  2230.         case OPT_WORDS:
  2231.             cnt = dis_words();
  2232.             break;
  2233.  
  2234.         case OPT_ENTRY:
  2235.             cnt = dis_entry();
  2236.             break;
  2237.  
  2238.         case OPT_FSNG:
  2239.             cnt = dis_float_single();
  2240.             break;
  2241.  
  2242.         case OPT_FDBL:
  2243.             cnt = dis_float_double();
  2244.             break;
  2245.  
  2246.         default:
  2247.             cnt = dis_bytes();
  2248.             break;
  2249.     }
  2250.  
  2251.     dis.pc  = *addr;
  2252.  
  2253.     while (cnt--)
  2254.     {
  2255.         switch (dis.curopt.size)
  2256.         {
  2257.             case 0:
  2258.                 dis.val8 = mem[dis.pc++];
  2259.                 phex += sprintf(phex, "%02X ", dis.val8);
  2260.                 break;
  2261.             case 1:
  2262.                 dis.val16  = mem[dis.pc++];
  2263.                 dis.val16 += mem[dis.pc++] << 8;
  2264.                 phex += sprintf(phex, "%04X ", dis.val16);
  2265.                 break;
  2266.             case 2:
  2267.                 dis.fsng.man  = mem[dis.pc++];
  2268.                 dis.fsng.man += mem[dis.pc++] << 8;
  2269.                 dis.fsng.man += mem[dis.pc++] << 16;
  2270.                 dis.fsng.exp  = mem[dis.pc++];
  2271.                 phex += sprintf(phex, "%06X %02X", dis.fsng.man, (unsigned) dis.fsng.exp);
  2272.                 break;
  2273.             case 3:
  2274.                 dis.fdbl.manl = mem[dis.pc++];
  2275.                 dis.fdbl.manl+= mem[dis.pc++] << 8;
  2276.                 dis.fdbl.manl+= mem[dis.pc++] << 16;
  2277.                 dis.fdbl.manl+= mem[dis.pc++] << 24;
  2278.                 dis.fdbl.manh = mem[dis.pc++];
  2279.                 dis.fdbl.manh+= mem[dis.pc++] << 8;
  2280.                 dis.fdbl.manh+= mem[dis.pc++] << 16;
  2281.                 dis.fdbl.exp  = mem[dis.pc++] - 128;
  2282.                 phex += sprintf(phex, "%06X%08X %02X ", dis.fdbl.manh, dis.fdbl.manl, (unsigned) dis.fdbl.exp);
  2283.                 break;
  2284.         }
  2285.     }
  2286.  
  2287.     *phex = ' ';
  2288.  
  2289.     if (dis.prtcom)
  2290.     {
  2291.         dis.prtcom = 0;
  2292.         dis.dst += pad_comment(" %s", COM_get(*addr, COM_APPEND));
  2293.     }
  2294.  
  2295.     *addr    = dis.pc;
  2296.  
  2297.     return dis.buff;
  2298. }
  2299.  
  2300. void disasm_init(WORD addr)
  2301. {
  2302.     memset(&z80, 0, sizeof(z80));
  2303.  
  2304.     dis.curopt = memopt[addr];
  2305.  
  2306.     if (dis.curopt.comment)
  2307.     {
  2308.         dis.curopt.comment = 0;
  2309.         dis.prtcom = 1;
  2310.     }
  2311.  
  2312.     if (dis.curopt.symbol)
  2313.     {
  2314.         dis.curopt.symbol  = 0;
  2315.         dis.prtsym = 1;
  2316.     }
  2317. }
  2318.  
  2319. char * disasm(WORD * addr, BOOL flg_dump)
  2320. {
  2321.     char * src;
  2322.     char * dst = "";
  2323.     WORD addr_cmd;
  2324.  
  2325.     addr_cmd = *addr;
  2326.  
  2327.     memset(&dis.flag, 0, sizeof(dis.flag));
  2328.     dis.padcom = 0;
  2329.  
  2330.     if (dis.prtcom)
  2331.     {
  2332.         dis.prtcom = 0;
  2333.         src = COM_get(*addr, COM_BLOCK);
  2334.         if (src && strlen(src))
  2335.         {
  2336.             dst = dis.buff;
  2337.             sprintf(dst, ";****** %s", COM_get(addr_cmd, COM_BLOCK));
  2338.             return dst;
  2339.         }
  2340.     }
  2341.  
  2342.     if (flg_dump)
  2343.     {
  2344.         if (dis.prtsym)
  2345.         {
  2346.             dis.prtsym = 0;
  2347.             dst = dis.buff;
  2348.             if (dis.curopt.mode == MEM_CODE)
  2349.                 sprintf(dst, "%s:", SYM_get(addr_cmd, SYM_NONE));
  2350.             else
  2351.                 sprintf(dst, "%-*sEQU  $", COLUMN_OPCODE, SYM_get(addr_cmd, SYM_NONE));
  2352.             return dst;
  2353.         }
  2354.     }
  2355.  
  2356.     switch (dis.curopt.mode)
  2357.     {
  2358.         case MEM_UNKNOWN:
  2359.             dst = dis_data(addr);
  2360.             break;
  2361.  
  2362.         case MEM_CODE:
  2363.             dst = dis_code(addr);
  2364.             break;
  2365.  
  2366.         case MEM_DATA:
  2367.             dst = dis_data(addr);
  2368.             break;
  2369.  
  2370.         case MEM_IO:
  2371.             dst = dis_data(addr);
  2372.             break;
  2373.     }
  2374.  
  2375.     if (!flg_dump)
  2376.     {
  2377.         if (dis.prtsym)
  2378.         {
  2379.             dis.prtsym = 0;
  2380.             dst[sprintf(dst, "%-*s ", COLUMN_OPCODE-2, SYM_get(addr_cmd, SYM_NONE))] = ' ';
  2381.         }
  2382.         else
  2383.         {
  2384.             dst[sprintf(dst, "%-*s", COLUMN_OPCODE-1, "")] = ' ';
  2385.         }
  2386.     }
  2387.  
  2388.     if (NEWOPT(*addr))
  2389.     {
  2390.         BYTE old_mode = dis.curopt.mode;
  2391.         BYTE old_opt  = dis.curopt.opt;
  2392.  
  2393.         dis.curopt = memopt[*addr];
  2394.  
  2395.         if (dis.curopt.mode == MEM_UNKNOWN)
  2396.         {
  2397.             dis.curopt.mode = old_mode;
  2398.             if (dis.curopt.opt  == OPT_NONE)
  2399.                 dis.curopt.opt    = old_opt;
  2400.         }
  2401.  
  2402.         if (dis.curopt.comment)
  2403.         {
  2404.             dis.curopt.comment = 0;
  2405.             dis.prtcom = 1;
  2406.         }
  2407.  
  2408.         if (dis.curopt.symbol)
  2409.         {
  2410.             dis.curopt.symbol  = 0;
  2411.             dis.prtsym = 1;
  2412.         }
  2413.     }
  2414.  
  2415.     if (dis.prtsym || dis.flag.end_mode)
  2416.         strcat(dst, "\n");
  2417.  
  2418.     return dst;
  2419. }
  2420.