Logo Search packages:      
Sourcecode: d52 version File versions  Download package

dz80pass2.c

/*
 * Z80 Disassembler
 * Copyright (C) 1990-2007 by Jeffery L. Post
 * j_post <AT> pacbell <DOT> net
 *
 * dz80pass2.c - Disassembly pass 2
 *
 * Version 3.4.1 - 2007/09/02
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *    GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include    <stdio.h>
#include    <stdlib.h>
#include    <ctype.h>
#include    <string.h>
#include    <time.h>

#include    "dz80.h"
#include    "common.h"
#include    "dz80pass1.h"
#include    "dz80pass2.h"
#include    "dz80table.h"
#include    "d80table.h"

//
//    Defined Constants
//
/* none */

//
//    Global variables
//
int               opcount;                      // bytes/opcode count

//
// Pass two of disassembly.
//
// Rescan data array and generate output file. Generate label if location
// flagged as referenced by some other opcode. If un-initialized data is
// encountered, ignore it but set skip flag so that an ORG statement can
// be generated when the next initialized data is found.
//

void pass2(void)
{
      char        c, *cptr;
      int         skip, year;
      int         i, l, q, temp;
      byte        j, k;
      int         pflag;
      time_t      tp;
      int         cyc, cyc2;  // for cycle counting

      k = 0;
      j = 0xff;
      skip = TRUE;
      dump = FALSE;
      byte_cnt = 0;
      asc_cnt = 0;
      newline = FALSE;

      printf("\nPass 2 0000");

      if ((fp = fopen(dst, "w")) == NULL) // open output source file
      {
            printf("\n* Can't open file %s *\n", dst);
            exit(FILE_ERROR);
      }

      fprintf(fp, ";\n;  DZ80 V%d.%d.%d ", VERSION, MAJORREV, MINORREV);      // output header

      switch (d8080)
      {
            case 1:
                  fprintf(fp, "8080");
                  break;

            case 2:
                  fprintf(fp, "8085");
                  break;

            default:
                  fprintf(fp, "Z80");
                  break;
      }

      fprintf(fp, " Disassembly of %s", src);

      time(&tp);                                                  // get current time
      date_time = localtime(&tp);               // convert to hr/min/day etc
      year = date_time->tm_year + 1900;

      fprintf(fp, "\n;  %d/%02d/%02d %02d:%02d", year,
            date_time->tm_mon + 1,
            date_time->tm_mday,
            date_time->tm_hour,
            date_time->tm_min);

//
//  Generate output file
//
      for (i=offset; i<himark; )
      {
            if (pgmflags[i] & PF_CMT)
            {
                  if (byte_cnt)                                   // dump any pending binary
                        dump_bytes(i);

                  if (asc_cnt)                                    // dump any accumulated ascii
                        dump_ascii(i);

                  output_comment(i);
            }

            if (pgmflags[i] & PF_PATCH)
            {
                  if (byte_cnt)                             // dump any pending binary
                        dump_bytes(i);

                  if (asc_cnt)                              // dump any accumulated ascii
                        dump_ascii(i);

                  output_patch(i);
            }

            l = i & 0xff;
            pflag = pgmflags[i];

            if (pflag & PF_NOINIT)              // ignore un-initialized data
            {
                  if (byte_cnt)                                   // if binary or ascii data in buffers...
                        dump_bytes(i);                            // output them now

                  if (asc_cnt)
                        dump_ascii(i);

                  if (dump)                                       // if we had to flush buffers...
                  {                                                           // do a newline, since we will
                        dump = FALSE;                             // be doing an org (or end)
                        fprintf(fp, "\n;");
                        newline = TRUE;
                  }

                  i++;                                                  // next program location
                  skip = TRUE;                                    // flag skip for ORG statement
                  j = -1;
            }
            else if (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII))
            {                                                                 // if not executable code
                  if (!(j & 0x80) && !skip)
                  {
                        j = -1;
                        fprintf(fp, "\n;");
                        newline = TRUE;
                  }

                  switch (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII))   // ignore irrelevant bits
                  {
                        case PF_ASCII:                            // if ascii text...
                              if (byte_cnt)                       // dump any pending binary
                                    dump_bytes(i);

                              if (skip)                           // insert ORG statement
                              {
                                    if (!newline)
                                          fprintf(fp, "\n;");

                                    fprintf(fp, "\n\t%s\t", orgstr);
                                    puthex(i);
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                                    skip = FALSE;                       // reset skip flag
                              }

                              if (is_ascii(pgmmem[i]))      // if it really is ascii...
                              {
                                    string[asc_cnt] = pgmmem[i];
                                    asc_cnt++;

                                    if (asc_cnt >= ASCLIMIT)
                                          dump_ascii(i + 1);
                              }
                              else                                            // else treat it as binary data
                              {
                                    pgmflags[i] |= PF_BYTE;

                                    if (asc_cnt)                        // dump any accumulated ascii
                                          dump_ascii(i);

                                    byte_data[byte_cnt] = pgmmem[i];    // add data to buffer
                                    byte_cnt++;
                              }
                              break;

                        case PF_WORD:                             // if word data...
                              if (byte_cnt)                       // dump any binary or ascii in buffers
                                    dump_bytes(i);

                              if (asc_cnt)
                                    dump_ascii(i);

                              if (skip)                           // insert ORG statement
                              {
                                    if (!newline)
                                          fprintf(fp, "\n;");

                                    fprintf(fp, "\n\t%s\t", orgstr);
                                    puthex(i);
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                                    skip = FALSE;                 // reset skip flag
                              }

                              chk_label(i);                                         // add label if referenced
                              q = ((int) pgmmem[i + 1]) << 8;     // get word value
                              temp = pgmmem[i] & 0xff;
                              q |= temp;
                              fprintf(fp, "%s\t", defwstr);

                              if (pgmflags[i] & PF_LABEL)
                                    cptr = find_entry(q, label_count, lab_val_index);     // see if label exists
                              else
                                    cptr = find_entry(q, symbol_count, sym_val_index);    // see if symbol exists

                              if (cptr == NULL)                               // if not, do hex value
                                    puthex(q);
                              else
                                    fprintf(fp, "%s", cptr);            // else output symbol

                              if (hexflag)                                          // add comment field
                              {
                                    fprintf(fp, "\t\t; %04x   %02x %02x      %c%c",
                                          i, pgmmem[i], pgmmem[i + 1],
                                          ascii(pgmmem[i]), ascii(pgmmem[i + 1]));

                              }

                              if (pgmflags[i] & PF_ICMT)
                                    output_icomment(i);

                              i++;

                              if (pgmflags[i + 2] != PF_ADRS && pgmflags[i + 2] != PF_WORD)
                              {
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                              }
                              break;

                        case PF_ADRS:                             // if address data...
                              if (byte_cnt)                       // output any pending binary or
                                    dump_bytes(i);                // ascii data from buffers

                              if (asc_cnt)
                                    dump_ascii(i);

                              if (skip)                           // insert ORG statement
                              {
                                    if (!newline)
                                          fprintf(fp, "\n;");

                                    fprintf(fp, "\n\t%s\t", orgstr);
                                    puthex(i);
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                                    skip = FALSE;                 // reset skip flag
                              }

                              chk_label(i);                             // add label if referenced
                              q = ((int) pgmmem[i + 1]) << 8;     // get address value
                              temp = pgmmem[i] & 0xff;
                              q |= temp;
                              fprintf(fp, "%s\t", defwstr);
                              cptr = find_entry(q, label_count, lab_val_index);     // see if label exists

                              if (cptr == NULL)                               // if not, output hex
                              {
                                    if (!pgmflags[i] & PF_LABEL)  // search symbol table only if not defined as label
                                          cptr = find_entry(q, symbol_count, sym_val_index);

                                    if (cptr == NULL)
                                    {
                                          if (!upperflag)
                                                fprintf(fp, "X%04x", q);
                                          else
                                                fprintf(fp, "X%04X", q);
                                    }
                                    else
                                          fprintf(fp, "%s", cptr);      // output symbol text
                              }
                              else
                                    fprintf(fp, "%s", cptr);            // else output label text

                              if (hexflag)                                          // do comment field
                              {
                                    fprintf(fp, "\t\t; %04x   %02x %02x      %c%c",
                                          i, pgmmem[i], pgmmem[i + 1],
                                          ascii(pgmmem[i]), ascii(pgmmem[i + 1]));
                              }

                              if (pgmflags[i] & PF_ICMT)
                                    output_icomment(i);

                              i++;

                              if (pgmflags[i + 2] != PF_ADRS)
                              {
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                              }
                              break;

                        default:                                        // default = binary data...
                              if (asc_cnt)                        // output any pending ascii data
                                    dump_ascii(i);

                              if (skip)                           // insert ORG statement
                              {
                                    if (!newline)
                                          fprintf(fp, "\n;");

                                    fprintf(fp, "\n\t%s\t", orgstr);
                                    puthex(i);
                                    fprintf(fp, "\n;");
                                    newline = TRUE;
                                    skip = FALSE;                 // reset skip flag
                              }

                              byte_data[byte_cnt] = pgmmem[i];    // add data to buffer
                              byte_cnt++;

                              if (byte_cnt >= BYTELIMIT)                // if end of buffer...
                                    dump_bytes(i + 1);                        // dump accumulated data
                  }

                  i++;                                                  // next program location

                  if (!(pgmflags[i] & PF_NOINIT) && (pgmflags[i] & PF_ASCII))
                  {                                                           // if next byte is flagged as
                        if (!is_ascii(pgmmem[i]))     // ascii, but is not...
                              pgmflags[i] |= PF_BYTE; // then flag it as binary
                  }
            }

//
//    If previous data was an unconditional transfer, AND current
//    location is not referenced by some other opcode, AND current
//    byte is 0 or 0FFH, then treat this byte as un-initialized data.
//
            else if ((j & 0x10) && (!(pflag & PF_REF)) &&
                  ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) &&
                  (!(pflag & PF_FORCE)))
            {
                  if (byte_cnt)                       // since we're going to skip some
                        dump_bytes(i);                // data, output any pending ascii

                  if (asc_cnt)                        // or binary data remaining in buffers
                        dump_ascii(i);

                  if (dump)                           // if ascii or binary output was done,
                  {                                               // stick in a newline
                        fprintf(fp, "\n;");
                        dump = FALSE;
                        newline = TRUE;
                  }

                  pgmflags[i] = PF_NOINIT;// flag as uninitialized data
                  i++;
                  skip = TRUE;
                  byte_cnt = 0;
            }

//
// If previous opcode was 0 or 0ffH, AND current location is not
//    referenced but is initialized, AND current opcode is 0 or 0ffH,
//    un-initialize it.
//
            else if (((k == 0) || (k == 0xff)) &&
                  (!(pflag & PF_REF)) &&
                  ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) &&
                  !(pflag & PF_NOINIT) &&
                  !(pflag & PF_FORCE))
            {
                  pgmflags[i] = PF_NOINIT;
                  i++;
                  skip = TRUE;
                  j = -1;
            }

            else                                            // IT'S EXECUTABLE CODE!
            {
                  pgmflags[i] &= ~PF_NOINIT;    // clear for label search in pass 3

                  if (byte_cnt)                             // if any ascii or binary data remains
                        dump_bytes(i);                      // in the buffers, output them now

                  if (asc_cnt)
                        dump_ascii(i);

                  if (dump)
                  {
                        fprintf(fp, "\n;");
                        dump = FALSE;
                        newline = TRUE;
                  }

                  byte_cnt = 0;

                  if (cycleflag)                            // cycle count summary
                        cycle_end(i);

                  if (skip)                                 // insert ORG statement
                  {
                        if (!newline)
                              fprintf(fp, "\n;");

                        fprintf(fp, "\n\t%s\t", orgstr);
                        puthex(i);
                        fprintf(fp, "\n;");
                        newline = TRUE;
                        skip = FALSE;                             // reset skip flag
                  }

                  chk_ref(i);                                     // add label if referenced
                  kcnt = 8;
                  opcount = 1;
                  k = pgmmem[i];                                  // get opcode

                  if (d8080)
                  {
                        j = opttbl80[k];                          // get options

                        if ((k == 0x20 || k == 0x30) && (d8080 != 2))   // sim/rim not in 8080
                        {
                              doopcode(defbstr);
                              fprintf(fp, "\t");
                              kcnt = (kcnt + 8) & 0x78;

                              q = (int) pgmmem[i] & 0xff;

                              if (pgmflags[i] & PF_NAME)
                                    cptr = find_entry(i, name_count, name_val_index);
                              else
                                    cptr = find_entry(q, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(pgmmem[i]);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);
                        }
                        else
                              doopcode(mnemtbl80[k].mnem);  // output mnemonic
                  }
                  else
                  {
                        j = opttbl[k];                            // get options
                        doopcode(mnemtbl[k].mnem);    // output mnemonic
                  }

//
// Generate operands
//
                  switch (j & ~OPT_XFER)
                  {
                        case OPT_NONE:                            // single byte - no options
                              break;

                        case OPT_PAR:                             // should only occur if 8080/8085 mnemonics
                              if (!d8080)
                              {
                                    fprintf(stderr, "\nZ80 PROCESSING ERROR!\n");
                                    fflush(stderr);
                              }

                              doopcode(defbstr);
                              fprintf(fp, "\t");
                              kcnt = (kcnt + 8) & 0x78;

                              q = (int) pgmmem[i] & 0xff;

                              if (pgmflags[i] & PF_NAME)
                                    cptr = find_entry(i, name_count, name_val_index);
                              else
                                    cptr = find_entry(q, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(pgmmem[i]);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              break;

                        case OPT_IMM2:                            // 2 byte immediate data
                              q = (int) pgmmem[i + 1] & 0xff;

                              if (pgmflags[i + 1] & PF_NAME)
                                    cptr = find_entry(i + 1, name_count, name_val_index);
                              else
                                    cptr = find_entry(q, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(pgmmem[i + 1]);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              splitcheck(i + 1);
                              break;

                        case OPT_PAR2:                            // 2 byte parenthesized address (in, out)
                              fprintf(fp, "(");
                              kcnt++;
                              q = (int) pgmmem[i + 1] & 0xff;

                              if (pgmflags[i + 1] & PF_NAME)
                                    cptr = find_entry(i + 1, name_count, name_val_index);
                              else
                                    cptr = find_entry(q, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(pgmmem[i + 1]);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              fprintf(fp, ")");
                              kcnt++;

                              if (!(k & 8))                       // if out (n),a
                              {
                                    if (!upperflag)
                                          fprintf(fp, ",a");
                                    else
                                          fprintf(fp, ",A");

                                    kcnt += 2;
                              }

                              splitcheck(i + 1);
                              break;

                        case OPT_DIR_IMM3:                              // 3 byte immediate data
                              q = (pgmmem[i + 2] << 8) | pgmmem[i + 1];
                              q &= WORD_MASK;

                              if (pgmflags[i + 1] & PF_NAME)
                              {
                                    pgmflags[i + 1] |= PF_2BYTE;
                                    cptr = find_entry(i + 1, name_count, name_val_index);
                              }
                              else if (pgmflags[i] & PF_SYMBOL)
                                    cptr = find_entry(q, symbol_count, sym_val_index);
                              else
                                    cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "X%04x", q);
                                    else
                                          kcnt += fprintf(fp, "X%04X", q);
                              }
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              splitcheck(i + 1);
                              splitcheck(i + 2);
                              break;

                        case OPT_PAR_IMM3:                              // 3 byte parenthesized address, immediate data
                              q = (pgmmem[i + 2] << 8) | pgmmem[i + 1];
                              q &= WORD_MASK;

                              if (pgmflags[i + 1] & PF_NAME)
                              {
                                    pgmflags[i + 1] |= PF_2BYTE;
                                    cptr = find_entry(i + 1, name_count, name_val_index);
                              }
                              else if (pgmflags[i] & PF_SYMBOL)
                                    cptr = find_entry(q, symbol_count, sym_val_index);
                              else
                                    cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "(X%04x", q);
                                    else
                                          kcnt += fprintf(fp, "(X%04X", q);
                              }
                              else
                                    kcnt += fprintf(fp, "(%s", cptr);

                              switch (k)
                              {
                                    case 0x22:
                                          if (!upperflag)
                                                kcnt += fprintf(fp, "),hl");
                                          else
                                                kcnt += fprintf(fp, "),HL");
                                          break;

                                    case 0x2a:
                                    case 0x3a:
                                          kcnt += fprintf(fp, ")");
                                          break;

                                    case 0x32:
                                          if (!upperflag)
                                                kcnt += fprintf(fp, "),a");
                                          else
                                                kcnt += fprintf(fp, "),A");
                                          break;
                              }
                              splitcheck(i + 1);
                              splitcheck(i + 2);
                              break;

                        case OPT_REL2:                            // 2 byte relative addressing
                              q = pgmmem[i + 1] & 0xff;
                              q = (q > 0x7f) ? q | 0xff00 : q;
                              q = i + 2 + q;
                              q &= WORD_MASK;
                              cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "X%04x", q);
                                    else
                                          kcnt += fprintf(fp, "X%04X", q);
                              }
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              splitcheck(i + 1);
                              break;

                        case OPT_SPEC:                            // special processing codes (dd, ed, fd)
                              opcount = 2;

                              switch (k)
                              {
                                    case 0xed:
                                          k = pgmmem[i + 1];            // get 2nd byte

                                          if (edcode[k])
                                          {
                                                c = (k < 0xa0) ? k - 0x40 : k - 0x64;
                                                doopcode(edtbl[(byte) c].mnem);

                                                switch (edcode[k])
                                                {
                                                      case OPT_ED_2:
                                                            break;

                                                      case OPT_ED_STORE:
                                                            q = (pgmmem[i + 3] << 8) | pgmmem[i + 2];
                                                            q &= WORD_MASK;

                                                            if (pgmflags[i + 2] & PF_NAME)
                                                            {
                                                                  pgmflags[i + 2] |= PF_2BYTE;
                                                                  cptr = find_entry(i + 2, name_count, name_val_index);
                                                            }
                                                            else if (pgmflags[i] & PF_SYMBOL)
                                                                  cptr = find_entry(q, symbol_count, sym_val_index);
                                                            else
                                                                  cptr = find_entry(q, label_count, lab_val_index);

                                                            if (cptr == NULL)
                                                            {
                                                                  if (!upperflag)
                                                                        kcnt += fprintf(fp, "(X%04x)", q);
                                                                  else
                                                                        kcnt += fprintf(fp, "(X%04X)", q);
                                                            }
                                                            else
                                                                  kcnt += fprintf(fp, "(%s)", cptr);

                                                            opcount = 4;
                                                            break;

                                                      case OPT_ED_LD_BC:
                                                            q = (pgmmem[i + 3] << 8) | pgmmem[i + 2];
                                                            q &= WORD_MASK;

                                                            if (pgmflags[i + 2] & PF_NAME)
                                                            {
                                                                  pgmflags[i + 2] |= PF_2BYTE;
                                                                  cptr = find_entry(i + 2, name_count, name_val_index);
                                                            }
                                                            else if (pgmflags[i] & PF_SYMBOL)
                                                                  cptr = find_entry(q, symbol_count, sym_val_index);
                                                            else
                                                                  cptr = find_entry(q, label_count, lab_val_index);

                                                            if (cptr == NULL)
                                                            {
                                                                  if (!upperflag)
                                                                        kcnt += fprintf(fp, "(X%04x)", q);
                                                                  else
                                                                        kcnt += fprintf(fp, "(X%04X)", q);
                                                            }
                                                            else
                                                                  kcnt += fprintf(fp, "(%s)", cptr);

                                                            if (!upperflag)
                                                                  kcnt += fprintf(fp, ",bc");
                                                            else
                                                                  kcnt += fprintf(fp, ",BC");

                                                            opcount = 4;
                                                            break;

                                                      case OPT_ED_LD_DE:
                                                            q = (pgmmem[i + 3] << 8) | pgmmem[i + 2];
                                                            q &= WORD_MASK;

                                                            if (pgmflags[i + 2] & PF_NAME)
                                                            {
                                                                  pgmflags[i + 2] |= PF_2BYTE;
                                                                  cptr = find_entry(i + 2, name_count, name_val_index);
                                                            }
                                                            else if (pgmflags[i] & PF_SYMBOL)
                                                                  cptr = find_entry(q, symbol_count, sym_val_index);
                                                            else
                                                                  cptr = find_entry(q, label_count, lab_val_index);

                                                            if (cptr == NULL)
                                                            {
                                                                  if (!upperflag)
                                                                        kcnt += fprintf(fp, "(X%04x)", q);
                                                                  else
                                                                        kcnt += fprintf(fp, "(X%04X)", q);
                                                            }
                                                            else
                                                                  kcnt += fprintf(fp, "(%s)", cptr);

                                                            if (!upperflag)
                                                                  kcnt += fprintf(fp, ",de");
                                                            else
                                                                  kcnt += fprintf(fp, ",DE");

                                                            opcount = 4;
                                                            break;

                                                      case OPT_ED_LD_SP:
                                                            q = (pgmmem[i + 3] << 8) | pgmmem[i + 2];
                                                            q &= WORD_MASK;

                                                            if (pgmflags[i + 2] & PF_NAME)
                                                            {
                                                                  pgmflags[i + 2] |= PF_2BYTE;
                                                                  cptr = find_entry(i + 2, name_count, name_val_index);
                                                            }
                                                            else if (pgmflags[i] & PF_SYMBOL)
                                                                  cptr = find_entry(q, symbol_count, sym_val_index);
                                                            else
                                                                  cptr = find_entry(q, label_count, lab_val_index);

                                                            if (cptr == NULL)
                                                            {
                                                                  if (!upperflag)
                                                                        kcnt += fprintf(fp, "(X%04x)", q);
                                                                  else
                                                                        kcnt += fprintf(fp, "(X%04X)", q);
                                                            }
                                                            else
                                                                  kcnt += fprintf(fp, "(%s)", cptr);

                                                            if (!upperflag)
                                                                  kcnt += fprintf(fp, ",sp");
                                                            else
                                                                  kcnt += fprintf(fp, ",SP");

                                                            opcount = 4;
                                                            break;

                                                      case OPT_ED_RET:        // retn or reti
                                                            j |= 0x80;
                                                            break;
                                                }
                                          }
                                          else
                                          {
                                                invalided(k);
                                                j |= 0x80;
                                          }
                                          break;

                                    case 0xdd:
                                          j |= doindex(i, 'x');
                                          break;

                                    case 0xfd:
                                          j |= doindex(i, 'y');
                                          break;
                              }
                              break;

                        case OPT_SPEC2:                           // cb special codes
                              c = pgmmem[i + 1] & 0xff;
                              temp = (int) (c >> 3) & 0x1f;

                              if (*cbtbl[temp].mnem == '\0')
                              {
                                    doopcode(defbstr);
                                    putc('\t', fp);
                                    kcnt = (kcnt + 8) & 0x78;
                                    puthex(0xcb);
                                    putc(',', fp);
                                    kcnt++;
                                    puthex(c);
                                    j |= 0x80;
                              }
                              else
                              {
                                    doopcode(cbtbl[temp].mnem);
                                    doopcode(regtbl[c & 7].mnem);
                              }
                              break;
                  }

                  if (cycleflag)                // do cycle counting and printout per instruction
                  {
                        while (kcnt < TSTOP)
                        {
                              fprintf(fp, "\t");
                              kcnt = (kcnt + 8) & 0x78;
                        }

// get cycles - here would come 8080 support, would we have the appropriate tables ready
                        cyc = cycles[pgmmem[i] & 0xff];
                        cyc2 = cycles2[pgmmem[i] & 0xff];

                        switch (pgmmem[i] & 0xff)
                        {
                              case 0xed:
                                    cyc = edcycles[pgmmem[i+1] & 0xff];
                                    cyc2 = edcycles2[pgmmem[i+1] & 0xff];
                                    break;

                              case 0xcb:
                                    cyc = cbcycles[pgmmem[i+1] & 0xff];
                                    cyc2 = cyc;
                                    break;

                              case 0xdd:
                                    if ((pgmmem[i+1] & 0xff) == 0xcb)
                                          cyc = ddcbcycles[pgmmem[i+3] & 0xff];
                                    else
                                          cyc = ddcycles[pgmmem[i+1] & 0xff];

                                    cyc2 = cyc;
                                    break;

                              case 0xfd:
                                    if ((pgmmem[i+1] & 0xff) == 0xcb)
                                          cyc = fdcbcycles[pgmmem[i+3] & 0xff];
                                    else
                                          cyc = fdcycles[pgmmem[i+1] & 0xff];

                                    cyc2 = cyc;
                                    break;
                        }

// would be for 8080 support d8080 ? i = i + (opttbl80[k] & OPT_SIZE) + opcount : i + (opttbl[k] & OPT_SIZE) + opcount,

                        cycle_in(i, i + (opttbl[k] & OPT_SIZE) + opcount, cyc, cyc2);
                  }

                  if (hexflag)                        // do comment field
                  {
                        while (kcnt < TSTOP)
                        {
                              fprintf(fp, "\t");
                              kcnt = (kcnt + 8) & 0x78;
                        }
                        
                        kcnt += fprintf(fp, "; %04x ", i);

                        if (d8080)
                              q = (opttbl80[k] & OPT_SIZE) + opcount;
                        else
                              q = (opttbl[k] & OPT_SIZE) + opcount;

                        for (c=0; c<q; c++)
                              kcnt += fprintf(fp, " %02x", pgmmem[i + c] & 0xff);

                        do
                        {
                              putc('\t', fp);
                              kcnt = (kcnt + 8) & 0x78;
                        } while (kcnt < ASTOP);

                        for (c=0; c<q; c++)
                              putc(ascii(pgmmem[i + c]), fp);
                  }

                  if (pgmflags[i] & PF_ICMT)
                        output_icomment(i);

                  newline = FALSE;

                  if (j & OPT_XFER)                   // if unconditional transfer
                  {
                        fprintf(fp, "\n;");           // or invalid opcode
                        newline = TRUE;
                  }

                  if (d8080)
                        i = i + (opttbl80[k] & OPT_SIZE) + opcount;     // update location counter
                  else
                        i = i + (opttbl[k] & OPT_SIZE) + opcount; // update location counter
            }

            if ((i & 0xff) < l)
                  printf("\rPass 2 %04x", i & 0xff00);
      }

      if (cycleflag)                                  // any remaining cycle count summary
            cycle_end(PMEMSIZE + 1);      // specifying a number above any possible
                                                                  // maximum address makes cycle_end to emit all
                                                                  // remaining sums (i would probably suffice, too (?))

      if (byte_cnt)                             // if any remaining ascii or binary,
            dump_bytes(i);                      // output it now

      if (asc_cnt)
            dump_ascii(i);

      printf("\rPass 2 - Source generation complete");
}                 // end of Pass 2

void invalided(byte k)
{
      doopcode(defbstr);
      putc('\t', fp);
      kcnt = (kcnt + 8) & 0x78;
      puthex(0xed);
      putc(',', fp);
      kcnt++;
      puthex(k & 0xff);
}

int doindex(int i, char index)
{
      byte              j, k;
      int               q, v;
      char              *cptr;

      j = pgmmem[i + 1] & 0xff;     // get second byte
      k = ddcode[j];                            // get flags
      q = 0;

      if (!k)
      {
            doopcode(defbstr);
            putc('\t', fp);
            kcnt = (kcnt + 8) & 0x78;
            index = (index == 'x') ? 0xdd : 0xfd;
            puthex(index & 0xff);
            putc(',', fp);
            kcnt++;
            puthex(j);
            opcount = 2;
            return (0x80);
      }

      if (upperflag)
            index = toupper(index);

      j = k >> 4;

      switch (k & 0xf)
      {
            case OPT_DD_2:
                  doopcode(dd1tbl[j].mnem);
                  q = 0;

                  switch (j)
                  {
                        case 0:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c,bc", index);
                              else
                                    kcnt += fprintf(fp, "I%c,BC", index);
                              break;

                        case 1:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c,de", index);
                              else
                                    kcnt += fprintf(fp, "I%c,DE", index);
                              break;

                        case 2:
                        case 4:
                        case 6:
                        case 8:
                        case 7:
                        case 10:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c", index);
                              else
                                    kcnt += fprintf(fp, "I%c", index);
                              break;

                        case 9:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c)", index);
                              else
                                    kcnt += fprintf(fp, "I%c)", index);
                              q = 0x80;
                              break;

                        case 3:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c,i%c", index, index);
                              else
                                    kcnt += fprintf(fp, "I%c,I%c", index, index);
                              break;

                        case 5:
                              if (!upperflag)
                                    kcnt += fprintf(fp, "i%c,sp", index);
                              else
                                    kcnt += fprintf(fp, "I%c,SP", index);
                              break;

                        default:
                              break;
                  }

                  opcount = 2;
                  return(q);

            case OPT_DD_LOAD:
                  switch (j)
                  {
                        case 0:
                              doopcode("inc (i");
                              kcnt += fprintf(fp, "%c+", index);
                              v = (int) pgmmem[i + 2] & 0xff;
                              cptr = find_entry(v, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(v);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              putc(')', fp);
                              kcnt++;
                              break;

                        case 1:
                              doopcode("dec (i");
                              kcnt += fprintf(fp, "%c+", index);
                              v = (int) pgmmem[i + 2] & 0xff;
                              cptr = find_entry(v, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(v);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              putc(')', fp);
                              kcnt++;
                              break;

                        case 2:
                              indxld1(i, 'b', index);
                              break;

                        case 3:
                              indxld1(i, 'c', index);
                              break;

                        case 4:
                              indxld1(i, 'd', index);
                              break;

                        case 5:
                              indxld1(i, 'e', index);
                              break;

                        case 6:
                              indxld1(i, 'h', index);
                              break;

                        case 7:
                              indxld1(i, 'l', index);
                              break;

                        case 8:
                              indxld2(i, 'b', index);
                              break;

                        case 9:
                              indxld2(i, 'c', index);
                              break;

                        case 10:
                              indxld2(i, 'd', index);
                              break;

                        case 11:
                              indxld2(i, 'e', index);
                              break;

                        case 12:
                              indxld2(i, 'h', index);
                              break;

                        case 13:
                              indxld2(i, 'l', index);
                              break;

                        case 14:
                              indxld2(i, 'a', index);
                              break;

                        case 15:
                              indxld1(i, 'a', index);
                              break;
                  }

                  opcount = 3;
                  return(0);

            case OPT_DD_DIR:
                  doopcode("ld ");
                  q = (pgmmem[i + 2] & 0xff) | ((pgmmem[i + 3] << 8) & 0xff00);

                  switch (j)
                  {
                        case 0:
                              if (pgmflags[i + 2] & PF_NAME)
                              {
                                    pgmflags[i + 2] |= PF_2BYTE;
                                    cptr = find_entry(i + 2, name_count, name_val_index);
                              }
                              else if (pgmflags[i] & PF_SYMBOL)
                                    cptr = find_entry(q, symbol_count, sym_val_index);
                              else
                                    cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "i%c,X%04x", index, q);
                                    else
                                          kcnt += fprintf(fp, "I%c,X%04X", index, q);
                              }
                              else
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "i%c,%s", index, cptr);
                                    else
                                          kcnt += fprintf(fp, "I%c,%s", index, cptr);
                              }
                              break;

                        case 1:
                              if (pgmflags[i + 2] & PF_NAME)
                              {
                                    pgmflags[i + 2] |= PF_2BYTE;
                                    cptr = find_entry(i + 2, name_count, name_val_index);
                              }
                              else if (pgmflags[i] & PF_SYMBOL)
                                    cptr = find_entry(q, symbol_count, sym_val_index);
                              else
                                    cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "(X%04x),i%c", q, index);
                                    else
                                          kcnt += fprintf(fp, "(X%04X),I%c", q, index);
                              }
                              else
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "(%s),i%c", cptr, index);
                                    else
                                          kcnt += fprintf(fp, "(%s),I%c", cptr, index);
                              }
                              break;

                        case 2:
                              if (pgmflags[i + 2] & PF_NAME)
                              {
                                    pgmflags[i + 2] |= PF_2BYTE;
                                    cptr = find_entry(i + 2, name_count, name_val_index);
                              }
                              else if (pgmflags[i] & PF_SYMBOL)
                                    cptr = find_entry(q, symbol_count, sym_val_index);
                              else
                                    cptr = find_entry(q, label_count, lab_val_index);

                              if (cptr == NULL)
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "i%c,(X%04x)", index, q);
                                    else
                                          kcnt += fprintf(fp, "I%c,(X%04X)", index, q);
                              }
                              else
                              {
                                    if (!upperflag)
                                          kcnt += fprintf(fp, "i%c,(%s)", index, cptr);
                                    else
                                          kcnt += fprintf(fp, "I%c,(%s)", index, cptr);
                              }
                              break;

                        case 3:           // this applies only to ld (ix+n),data and ld (iy+n),data
                              if (!upperflag)
                                    kcnt += fprintf(fp, "(i%c+", index);
                              else
                                    kcnt += fprintf(fp, "(I%c+", index);

                              v = (int) pgmmem[i + 2] & 0xff;
                              cptr = find_entry(v, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(v);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);

                              kcnt += fprintf(fp,"),");
                              v = (int) pgmmem[i + 3] & 0xff;

                              if (pgmflags[i + 2] & PF_NAME)
                                    cptr = find_entry(i + 2, name_count, name_val_index);
                              else if (pgmflags[i] & PF_LABEL)
                                    cptr = find_entry(q, label_count, lab_val_index);
                              else
                                    cptr = find_entry(v, symbol_count, sym_val_index);

                              if (cptr == NULL)
                                    puthex(v);
                              else
                                    kcnt += fprintf(fp, "%s", cptr);
                              break;
                  }

                  opcount = 4;
                  return(0);

            case OPT_DD_ARTH:
                  doopcode(dd2tbl[j].mnem);
                  kcnt += fprintf(fp, "%c+", index);
                  v = (int) pgmmem[i + 2] & 0xff;

                  if (pgmflags[i + 2] & PF_NAME)
                        cptr = find_entry(i + 2, name_count, name_val_index);
                  else if (pgmflags[i] & PF_LABEL)
                        cptr = find_entry(q, label_count, lab_val_index);
                  else
                        cptr = find_entry(v, symbol_count, sym_val_index);

                  if (cptr == NULL)
                        puthex(v);
                  else
                        kcnt += fprintf(fp, "%s", cptr);

                  putc(')', fp);
                  kcnt++;
                  opcount = 3;
                  return(0);

            case OPT_DD_CB:
                  j = pgmmem[i + 3];                                          // get cb ext byte

                  if (j == 0x36 || (j & 7) != 6)
                        return(0);

                  if (j < 0x40)
                  {
                        k = j >> 3;
                        doopcode(ddcbtbl[k].mnem);
                  }
                  else
                  {
                        k = (j >> 6) + 7;
                        doopcode(ddcbtbl[k].mnem);
                        putc(((j >> 3) & 7) | 0x30, fp);
                        putc(',', fp);
                        kcnt += 2;
                  }

                  if (!upperflag)
                        kcnt += fprintf(fp, "(i%c+", index);
                  else
                        kcnt += fprintf(fp, "(I%c+", index);

                  v = (int) pgmmem[i + 2] & 0xff;

                  if (pgmflags[i + 2] & PF_NAME)
                        cptr = find_entry(i + 2, name_count, name_val_index);
                  else if (pgmflags[i] & PF_LABEL)
                        cptr = find_entry(q, label_count, lab_val_index);
                  else
                        cptr = find_entry(v, symbol_count, sym_val_index);

                  if (cptr == NULL)
                        puthex(v);
                  else
                        kcnt += fprintf(fp, "%s", cptr);

                  putc(')', fp);
                  kcnt++;
                  opcount = 4;
                  return(0);
      }

      return(0);
}

void indxld1(int i, char reg, char idx)
{
      char              *cptr;
      int               v;

      doopcode("ld ");

      if (upperflag)
      {
            reg = toupper(reg);
            idx = toupper(idx);
      }

      if (upperflag)
            kcnt += fprintf(fp, "%c,(I%c+", reg, idx);
      else
            kcnt += fprintf(fp, "%c,(i%c+", reg, idx);

      v = (int) pgmmem[i + 2] & 0xff;

      if (pgmflags[i + 2] & PF_NAME)
            cptr = find_entry(i + 2, name_count, name_val_index);
      else if (pgmflags[i] & PF_LABEL)
            cptr = find_entry(v, label_count, lab_val_index);
      else
            cptr = find_entry(v, symbol_count, sym_val_index);

      if (cptr == NULL)
            puthex(v);
      else
            kcnt += fprintf(fp, "%s", cptr);

      putc(')', fp);
      kcnt++;
}

void indxld2(int i, char reg, char idx)
{
      char              *cptr;
      int               v;

      doopcode("ld ");

      if (upperflag)
      {
            reg = toupper(reg);
            idx = toupper(idx);
      }

      if (upperflag)
            kcnt += fprintf(fp, "(I%c+", idx);
      else
            kcnt += fprintf(fp, "(i%c+", idx);

      v = (int) pgmmem[i + 2] & 0xff;

      if (pgmflags[i + 2] & PF_NAME)
            cptr = find_entry(i + 2, name_count, name_val_index);
      else if (pgmflags[i] & PF_LABEL)
            cptr = find_entry(v, label_count, lab_val_index);
      else
            cptr = find_entry(v, symbol_count, sym_val_index);

      if (cptr == NULL)
            puthex(v);
      else
            kcnt += fprintf(fp, "%s", cptr);

      kcnt += fprintf(fp, "),%c", reg);
}

// end of dz80pass2.c


Generated by  Doxygen 1.6.0   Back to index