static char *sccsid =
   "@(#) distabs.c, Ver. 2.1 created 00:00:00 87/09/01";

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  *  Copyright (C) 1987 G. M. Harding, all rights reserved  *
  *                                                         *
  * Permission to copy and  redistribute is hereby granted, *
  * provided full source code,  with all copyright notices, *
  * accompanies any redistribution.                         *
  *                                                         *
  * This file  contains  the  lookup  tables and other data *
  * structures for the Intel 8088 symbolic disassembler. It *
  * also contains a few global  routines  which  facilitate *
  * access to the tables,  for use primarily by the handler *
  * functions.                                              *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "dis.h"              /* Disassembler declarations  */

struct exec HDR;              /* Used to hold header info   */

struct nlist symtab[MAXSYM];  /* Array of symbol table info */

struct reloc relo[MAXSYM];    /* Array of relocation info   */

int symptr = -1,              /* Index into symtab[]        */
    relptr = -1;              /* Index into relo[]          */

char *REGS[] =                /* Table of register names    */
   {
   "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
   "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
   "es", "cs", "ss", "ds"
   };

char *REGS0[] =               /* Mode 0 register name table */
   {
   "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "", "bx"
   };

char *REGS1[] =               /* Mode 1 register name table */
   {
   "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "bp", "bx"
   };

int symrank[6][6] =           /* Symbol type/rank matrix    */
   {
              /* UND  ABS  TXT  DAT  BSS  COM */
   /* UND */      5,   4,   1,   2,   3,   0,
   /* ABS */      1,   5,   4,   3,   2,   0,
   /* TXT */      4,   1,   5,   3,   2,   0,
   /* DAT */      3,   1,   2,   5,   4,   0,
   /* BSS */      3,   1,   2,   4,   5,   0,
   /* COM */      2,   0,   1,   3,   4,   5
   };

 /* * * * * * * * * * * * OPCODE DATA * * * * * * * * * * * */

char ADD[]   = "\tadd",             /* Mnemonics by family  */
     OR[]    = "\tor",
     ADC[]   = "\tadc",
     SBB[]   = "\tsbb",
     AND[]   = "\tand",
     SUB[]   = "\tsub",
     XOR[]   = "\txor",
     CMP[]   = "\tcmp",
     NOT[]   = "\tnot",
     NEG[]   = "\tneg",
     MUL[]   = "\tmul",
     DIV[]   = "\tdiv",
     MOV[]   = "\tmov",
     ESC[]   = "\tesc",
     TEST[]  = "\ttest",
     AMBIG[] = "",
     ROL[]   = "\trol",
     ROR[]   = "\tror",
     RCL[]   = "\trcl",
     RCR[]   = "\trcr",
     SAL[]   = "\tsal",
     SHR[]   = "\tshr",
     SHL[]   = "\tshl",
     SAR[]   = "\tsar";

char *OPFAM[] =                     /* Family lookup table  */
   {
   ADD, OR, ADC, SBB, AND, SUB, XOR, CMP,
   NOT, NEG, MUL, DIV, MOV, ESC, TEST, AMBIG,
   ROL, ROR, RCL, RCR, SAL, SHR, SHL, SAR
   };

struct opcode optab[] =             /* Table of opcode data */
   {
   ADD,              aohand,  2,    4,             /* 0x00  */
   ADD,              aohand,  2,    4,             /* 0x01  */
   ADD,              aohand,  2,    4,             /* 0x02  */
   ADD,              aohand,  2,    4,             /* 0x03  */
   ADD,              aohand,  2,    2,             /* 0x04  */
   ADD,              aohand,  3,    3,             /* 0x05  */
   "\tpush\tes",     sbhand,  1,    1,             /* 0x06  */
   "\tpop\tes",      sbhand,  1,    1,             /* 0x07  */
   OR,               aohand,  2,    4,             /* 0x08  */
   OR,               aohand,  2,    4,             /* 0x09  */
   OR,               aohand,  2,    4,             /* 0x0a  */
   OR,               aohand,  2,    4,             /* 0x0b  */
   OR,               aohand,  2,    2,             /* 0x0c  */
   OR,               aohand,  3,    3,             /* 0x0d  */
   "\tpush\tcs",     sbhand,  1,    1,             /* 0x0e  */
   NULL,             dfhand,  0,    0,             /* 0x0f  */
   ADC,              aohand,  2,    4,             /* 0x10  */
   ADC,              aohand,  2,    4,             /* 0x11  */
   ADC,              aohand,  2,    4,             /* 0x12  */
   ADC,              aohand,  2,    4,             /* 0x13  */
   ADC,              aohand,  2,    2,             /* 0x14  */
   ADC,              aohand,  3,    3,             /* 0x15  */
   "\tpush\tss",     sbhand,  1,    1,             /* 0x16  */
   "\tpop\tss",      sbhand,  1,    1,             /* 0x17  */
   SBB,              aohand,  2,    4,             /* 0x18  */
   SBB,              aohand,  2,    4,             /* 0x19  */
   SBB,              aohand,  2,    4,             /* 0x1a  */
   SBB,              aohand,  2,    4,             /* 0x1b  */
   SBB,              aohand,  2,    2,             /* 0x1c  */
   SBB,              aohand,  3,    3,             /* 0x1d  */
   "\tpush\tds",     sbhand,  1,    1,             /* 0x1e  */
   "\tpop\tds",      sbhand,  1,    1,             /* 0x1f  */
   AND,              aohand,  2,    4,             /* 0x20  */
   AND,              aohand,  2,    4,             /* 0x21  */
   AND,              aohand,  2,    4,             /* 0x22  */
   AND,              aohand,  2,    4,             /* 0x23  */
   AND,              aohand,  2,    2,             /* 0x24  */
   AND,              aohand,  3,    3,             /* 0x25  */
   "\tseg\tes",      sbhand,  1,    1,             /* 0x26  */
   "\tdaa",          sbhand,  1,    1,             /* 0x27  */
   SUB,              aohand,  2,    4,             /* 0x28  */
   SUB,              aohand,  2,    4,             /* 0x29  */
   SUB,              aohand,  2,    4,             /* 0x2a  */
   SUB,              aohand,  2,    4,             /* 0x2b  */
   SUB,              aohand,  2,    2,             /* 0x2c  */
   SUB,              aohand,  3,    3,             /* 0x2d  */
   "\tseg\tcs",      sbhand,  1,    1,             /* 0x2e  */
   "\tdas",          sbhand,  1,    1,             /* 0x2f  */
   XOR,              aohand,  2,    4,             /* 0x30  */
   XOR,              aohand,  2,    4,             /* 0x31  */
   XOR,              aohand,  2,    4,             /* 0x32  */
   XOR,              aohand,  2,    4,             /* 0x33  */
   XOR,              aohand,  2,    2,             /* 0x34  */
   XOR,              aohand,  3,    3,             /* 0x35  */
   "\tseg\tss",      sbhand,  1,    1,             /* 0x36  */
   "\taaa",          sbhand,  1,    1,             /* 0x37  */
   CMP,              aohand,  2,    4,             /* 0x38  */
   CMP,              aohand,  2,    4,             /* 0x39  */
   CMP,              aohand,  2,    4,             /* 0x3a  */
   CMP,              aohand,  2,    4,             /* 0x3b  */
   CMP,              aohand,  2,    2,             /* 0x3c  */
   CMP,              aohand,  3,    3,             /* 0x3d  */
   "\tseg\tds",      sbhand,  1,    1,             /* 0x3e  */
   "\taas",          sbhand,  1,    1,             /* 0x3f  */
   "\tinc\tax",      sbhand,  1,    1,             /* 0x40  */
   "\tinc\tcx",      sbhand,  1,    1,             /* 0x41  */
   "\tinc\tdx",      sbhand,  1,    1,             /* 0x42  */
   "\tinc\tbx",      sbhand,  1,    1,             /* 0x43  */
   "\tinc\tsp",      sbhand,  1,    1,             /* 0x44  */
   "\tinc\tbp",      sbhand,  1,    1,             /* 0x45  */
   "\tinc\tsi",      sbhand,  1,    1,             /* 0x46  */
   "\tinc\tdi",      sbhand,  1,    1,             /* 0x47  */
   "\tdec\tax",      sbhand,  1,    1,             /* 0x48  */
   "\tdec\tcx",      sbhand,  1,    1,             /* 0x49  */
   "\tdec\tdx",      sbhand,  1,    1,             /* 0x4a  */
   "\tdec\tbx",      sbhand,  1,    1,             /* 0x4b  */
   "\tdec\tsp",      sbhand,  1,    1,             /* 0x4c  */
   "\tdec\tbp",      sbhand,  1,    1,             /* 0x4d  */
   "\tdec\tsi",      sbhand,  1,    1,             /* 0x4e  */
   "\tdec\tdi",      sbhand,  1,    1,             /* 0x4f  */
   "\tpush\tax",     sbhand,  1,    1,             /* 0x50  */
   "\tpush\tcx",     sbhand,  1,    1,             /* 0x51  */
   "\tpush\tdx",     sbhand,  1,    1,             /* 0x52  */
   "\tpush\tbx",     sbhand,  1,    1,             /* 0x53  */
   "\tpush\tsp",     sbhand,  1,    1,             /* 0x54  */
   "\tpush\tbp",     sbhand,  1,    1,             /* 0x55  */
   "\tpush\tsi",     sbhand,  1,    1,             /* 0x56  */
   "\tpush\tdi",     sbhand,  1,    1,             /* 0x57  */
   "\tpop\tax",      sbhand,  1,    1,             /* 0x58  */
   "\tpop\tcx",      sbhand,  1,    1,             /* 0x59  */
   "\tpop\tdx",      sbhand,  1,    1,             /* 0x5a  */
   "\tpop\tbx",      sbhand,  1,    1,             /* 0x5b  */
   "\tpop\tsp",      sbhand,  1,    1,             /* 0x5c  */
   "\tpop\tbp",      sbhand,  1,    1,             /* 0x5d  */
   "\tpop\tsi",      sbhand,  1,    1,             /* 0x5e  */
   "\tpop\tdi",      sbhand,  1,    1,             /* 0x5f  */
   NULL,             dfhand,  0,    0,             /* 0x60  */
   NULL,             dfhand,  0,    0,             /* 0x61  */
   NULL,             dfhand,  0,    0,             /* 0x62  */
   NULL,             dfhand,  0,    0,             /* 0x63  */
   NULL,             dfhand,  0,    0,             /* 0x64  */
   NULL,             dfhand,  0,    0,             /* 0x65  */
   NULL,             dfhand,  0,    0,             /* 0x66  */
   NULL,             dfhand,  0,    0,             /* 0x67  */
   NULL,             dfhand,  0,    0,             /* 0x68  */
   NULL,             dfhand,  0,    0,             /* 0x69  */
   NULL,             dfhand,  0,    0,             /* 0x6a  */
   NULL,             dfhand,  0,    0,             /* 0x6b  */
   NULL,             dfhand,  0,    0,             /* 0x6c  */
   NULL,             dfhand,  0,    0,             /* 0x6d  */
   NULL,             dfhand,  0,    0,             /* 0x6e  */
   NULL,             dfhand,  0,    0,             /* 0x6f  */
   "\tjo",           sjhand,  2,    2,             /* 0x70  */
   "\tjno",          sjhand,  2,    2,             /* 0x71  */
   "\tjc",           sjhand,  2,    2,             /* 0x72  */
   "\tjnc",          sjhand,  2,    2,             /* 0x73  */
   "\tjz",           sjhand,  2,    2,             /* 0x74  */
   "\tjnz",          sjhand,  2,    2,             /* 0x75  */
   "\tjna",          sjhand,  2,    2,             /* 0x76  */
   "\tja",           sjhand,  2,    2,             /* 0x77  */
   "\tjs",           sjhand,  2,    2,             /* 0x78  */
   "\tjns",          sjhand,  2,    2,             /* 0x79  */
   "\tjp",           sjhand,  2,    2,             /* 0x7a  */
   "\tjnp",          sjhand,  2,    2,             /* 0x7b  */
   "\tjl",           sjhand,  2,    2,             /* 0x7c  */
   "\tjnl",          sjhand,  2,    2,             /* 0x7d  */
   "\tjng",          sjhand,  2,    2,             /* 0x7e  */
   "\tjg",           sjhand,  2,    2,             /* 0x7f  */
   AMBIG,            imhand,  3,    5,             /* 0x80  */
   AMBIG,            imhand,  4,    6,             /* 0x81  */
   AMBIG,            imhand,  3,    5,             /* 0x82  */
   AMBIG,            imhand,  3,    5,             /* 0x83  */
   TEST,             mvhand,  2,    4,             /* 0x84  */
   TEST,             mvhand,  2,    4,             /* 0x85  */
   "\txchg",         mvhand,  2,    4,             /* 0x86  */
   "\txchg",         mvhand,  2,    4,             /* 0x87  */
   MOV,              mvhand,  2,    4,             /* 0x88  */
   MOV,              mvhand,  2,    4,             /* 0x89  */
   MOV,              mvhand,  2,    4,             /* 0x8a  */
   MOV,              mvhand,  2,    4,             /* 0x8b  */
   MOV,              mshand,  2,    4,             /* 0x8c  */
   "\tlea",          mvhand,  2,    4,             /* 0x8d  */
   MOV,              mshand,  2,    4,             /* 0x8e  */
   "\tpop",          pohand,  2,    4,             /* 0x8f  */
   "\tnop",          sbhand,  1,    1,             /* 0x90  */
   "\txchg\tax,cx",  sbhand,  1,    1,             /* 0x91  */
   "\txchg\tax,dx",  sbhand,  1,    1,             /* 0x92  */
   "\txchg\tax,bx",  sbhand,  1,    1,             /* 0x93  */
   "\txchg\tax,sp",  sbhand,  1,    1,             /* 0x94  */
   "\txchg\tax,bp",  sbhand,  1,    1,             /* 0x95  */
   "\txchg\tax,si",  sbhand,  1,    1,             /* 0x96  */
   "\txchg\tax,di",  sbhand,  1,    1,             /* 0x97  */
   "\tcbw",          sbhand,  1,    1,             /* 0x98  */
   "\tcwd",          sbhand,  1,    1,             /* 0x99  */
   "\tcalli",        cihand,  5,    5,             /* 0x9a  */
   "\twait",         sbhand,  1,    1,             /* 0x9b  */
   "\tpushf",        sbhand,  1,    1,             /* 0x9c  */
   "\tpopf",         sbhand,  1,    1,             /* 0x9d  */
   "\tsahf",         sbhand,  1,    1,             /* 0x9e  */
   "\tlahf",         sbhand,  1,    1,             /* 0x9f  */
   MOV,              mqhand,  3,    3,             /* 0xa0  */
   MOV,              mqhand,  3,    3,             /* 0xa1  */
   MOV,              mqhand,  3,    3,             /* 0xa2  */
   MOV,              mqhand,  3,    3,             /* 0xa3  */
   "\tmovb",         sbhand,  1,    1,             /* 0xa4  */
   "\tmovw",         sbhand,  1,    1,             /* 0xa5  */
   "\tcmpb",         sbhand,  1,    1,             /* 0xa6  */
   "\tcmpw",         sbhand,  1,    1,             /* 0xa7  */
   TEST,             tqhand,  2,    2,             /* 0xa8  */
   TEST,             tqhand,  3,    3,             /* 0xa9  */
   "\tstob",         sbhand,  1,    1,             /* 0xaa  */
   "\tstow",         sbhand,  1,    1,             /* 0xab  */
   "\tlodb",         sbhand,  1,    1,             /* 0xac  */
   "\tlodw",         sbhand,  1,    1,             /* 0xad  */
   "\tscab",         sbhand,  1,    1,             /* 0xae  */
   "\tscaw",         sbhand,  1,    1,             /* 0xaf  */
   "\tmov\tal,",     mihand,  2,    2,             /* 0xb0  */
   "\tmov\tcl,",     mihand,  2,    2,             /* 0xb1  */
   "\tmov\tdl,",     mihand,  2,    2,             /* 0xb2  */
   "\tmov\tbl,",     mihand,  2,    2,             /* 0xb3  */
   "\tmov\tah,",     mihand,  2,    2,             /* 0xb4  */
   "\tmov\tch,",     mihand,  2,    2,             /* 0xb5  */
   "\tmov\tdh,",     mihand,  2,    2,             /* 0xb6  */
   "\tmov\tbh,",     mihand,  2,    2,             /* 0xb7  */
   "\tmov\tax,",     mihand,  3,    3,             /* 0xb8  */
   "\tmov\tcx,",     mihand,  3,    3,             /* 0xb9  */
   "\tmov\tdx,",     mihand,  3,    3,             /* 0xba  */
   "\tmov\tbx,",     mihand,  3,    3,             /* 0xbb  */
   "\tmov\tsp,",     mihand,  3,    3,             /* 0xbc  */
   "\tmov\tbp,",     mihand,  3,    3,             /* 0xbd  */
   "\tmov\tsi,",     mihand,  3,    3,             /* 0xbe  */
   "\tmov\tdi,",     mihand,  3,    3,             /* 0xbf  */
   NULL,             dfhand,  0,    0,             /* 0xc0  */
   NULL,             dfhand,  0,    0,             /* 0xc1  */
   "\tret",          rehand,  3,    3,             /* 0xc2  */
   "\tret",          sbhand,  1,    1,             /* 0xc3  */
   "\tles",          mvhand,  2,    4,             /* 0xc4  */
   "\tlds",          mvhand,  2,    4,             /* 0xc5  */
   MOV,              mmhand,  3,    5,             /* 0xc6  */
   MOV,              mmhand,  4,    6,             /* 0xc7  */
   NULL,             dfhand,  0,    0,             /* 0xc8  */
   NULL,             dfhand,  0,    0,             /* 0xc9  */
   "\treti",         rehand,  3,    3,             /* 0xca  */
   "\treti",         sbhand,  1,    1,             /* 0xcb  */
   "\tint",          sbhand,  1,    1,             /* 0xcc  */
   "\tint",          inhand,  2,    2,             /* 0xcd  */
   "\tinto",         sbhand,  1,    1,             /* 0xce  */
   "\tiret",         sbhand,  1,    1,             /* 0xcf  */
   AMBIG,            srhand,  2,    4,             /* 0xd0  */
   AMBIG,            srhand,  2,    4,             /* 0xd1  */
   AMBIG,            srhand,  2,    4,             /* 0xd2  */
   AMBIG,            srhand,  2,    4,             /* 0xd3  */
   "\taam",          aahand,  2,    2,             /* 0xd4  */
   "\taad",          aahand,  2,    2,             /* 0xd5  */
   NULL,             dfhand,  0,    0,             /* 0xd6  */
   "\txlat",         sbhand,  1,    1,             /* 0xd7  */
   ESC,              eshand,  2,    2,             /* 0xd8  */
   ESC,              eshand,  2,    2,             /* 0xd9  */
   ESC,              eshand,  2,    2,             /* 0xda  */
   ESC,              eshand,  2,    2,             /* 0xdb  */
   ESC,              eshand,  2,    2,             /* 0xdc  */
   ESC,              eshand,  2,    2,             /* 0xdd  */
   ESC,              eshand,  2,    2,             /* 0xde  */
   ESC,              eshand,  2,    2,             /* 0xdf  */
   "\tloopne",       sjhand,  2,    2,             /* 0xe0  */
   "\tloope",        sjhand,  2,    2,             /* 0xe1  */
   "\tloop",         sjhand,  2,    2,             /* 0xe2  */
   "\tjcxz",         sjhand,  2,    2,             /* 0xe3  */
   "\tin",           iohand,  2,    2,             /* 0xe4  */
   "\tinw",          iohand,  2,    2,             /* 0xe5  */
   "\tout",          iohand,  2,    2,             /* 0xe6  */
   "\toutw",         iohand,  2,    2,             /* 0xe7  */
   "\tcall",         ljhand,  3,    3,             /* 0xe8  */
   "\tjmp",          ljhand,  3,    3,             /* 0xe9  */
   "\tjmpi",         cihand,  5,    5,             /* 0xea  */
   "\tj",            sjhand,  2,    2,             /* 0xeb  */
   "\tin",           sbhand,  1,    1,             /* 0xec  */
   "\tinw",          sbhand,  1,    1,             /* 0xed  */
   "\tout",          sbhand,  1,    1,             /* 0xee  */
   "\toutw",         sbhand,  1,    1,             /* 0xef  */
   "\tlock",         sbhand,  1,    1,             /* 0xf0  */
   NULL,             dfhand,  0,    0,             /* 0xf1  */
   "\trepnz",        sbhand,  1,    1,             /* 0xf2  */
   "\trepz",         sbhand,  1,    1,             /* 0xf3  */
   "\thlt",          sbhand,  1,    1,             /* 0xf4  */
   "\tcmc",          sbhand,  1,    1,             /* 0xf5  */
   AMBIG,            mahand,  2,    5,             /* 0xf6  */
   AMBIG,            mahand,  2,    6,             /* 0xf7  */
   "\tclc",          sbhand,  1,    1,             /* 0xf8  */
   "\tstc",          sbhand,  1,    1,             /* 0xf9  */
   "\tcli",          sbhand,  1,    1,             /* 0xfa  */
   "\tsti",          sbhand,  1,    1,             /* 0xfb  */
   "\tcld",          sbhand,  1,    1,             /* 0xfc  */
   "\tstd",          sbhand,  1,    1,             /* 0xfd  */
   AMBIG,            mjhand,  2,    4,             /* 0xfe  */
   AMBIG,            mjhand,  2,    4              /* 0xff  */
   };

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  * This simple routine  returns the name field of a symbol *
  * table entry as a printable string.                      *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

char *
getnam(k)

   register int k;

{/* * * * * * * * * *  START OF getnam()  * * * * * * * * * */

   register int j;
   static char a[sizeof(symtab->n_name)+1];

   for (j = 0; j < sizeof(symtab[k].n_name); ++j)
      if ( ! symtab[k].n_name[j] )
         break;
      else
         a[j] = symtab[k].n_name[j];

   a[j] = '\0';

   return (a);

}/* * * * * * * * * * * END OF getnam() * * * * * * * * * * */

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  * This function is  responsible  for mucking  through the *
  * relocation  table in  search of  externally  referenced *
  * symbols to be output as  operands.  It accepts two long *
  * arguments: the code-segment location at which an extern *
  * reference  is  expected,  and the offset value which is *
  * embedded  in the  object  code and used at link time to *
  * bias the external value.  In the most typical case, the *
  * function will be called by lookup(), which always makes *
  * a check for external names before  searching the symbol *
  * table proper.  However,  it may also be called directly *
  * by any function  (such as the  move-immediate  handler) *
  * which wants to make an independent check for externals. *
  * The caller is expected to supply, as the third argument *
  * to the function,  a pointer to a character buffer large *
  * enough to hold any possible  output  string.  Lookext() *
  * will fill this  buffer and return a logical  TRUE if it *
  * finds an extern reference;  otherwise, it will return a *
  * logical FALSE, leaving the buffer undisturbed.          *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int
lookext(off,loc,buf)

   long off, loc;
   char *buf;

{/* * * * * * * * * * START OF  lookext() * * * * * * * * * */

   register int k;
   char c[32];

   if ((loc != -1L) && (relptr >= 0))
      for (k = 0; k <= relptr; ++k)
         if ((relo[k].r_vaddr == loc)
          && (relo[k].r_symndx < S_BSS))
            {
            strcpy(buf,getnam(relo[k].r_symndx));
            if (off)
               {
               if (off < 0)
                  sprintf(c,"%ld",off);
               else
                  sprintf(c,"+%ld",off);
               strcat(buf,c);
               }
            return (1);
            }

   return (0);

}/* * * * * * * * * *  END OF  lookext()  * * * * * * * * * */

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  * This  function  finds an entry in the  symbol  table by *
  * value.  Its input is a (long) machine address,  and its *
  * output is a pointer to a string  containing  the corre- *
  * sponding symbolic name. The function first searches the *
  * relocation table for a possible external reference;  if *
  * none is found,  a linear  search of the symbol table is *
  * undertaken. If no matching symbol has been found at the *
  * end of these searches,  the function  returns a pointer *
  * to a string  containing the ASCII equivalent of the ad- *
  * dress which was to be located,  so that,  regardless of *
  * the success of the search,  the function's return value *
  * is suitable for use as a memory-reference operand.  The *
  * caller specifies the type of symbol to be found  (text, *
  * data, bss, undefined,  absolute, or common) by means of *
  * the function's  second  parameter.  The third parameter *
  * specifies  the  format to be used in the event of a nu- *
  * meric output:  zero for absolute format,  one for short *
  * relative  format,  two for long  relative  format.  The *
  * fourth  parameter is the address  which would appear in *
  * the relocation table for the reference in question,  or *
  * -1 if the relocation  table is not to be searched.  The *
  * function attempts to apply a certain amount of intelli- *
  * gence in its  selection  of symbols,  so it is possible *
  * that,  in the absence of a type match,  a symbol of the *
  * correct value but different type will be returned.      *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

char *
lookup(addr,type,kind,ext)

   long addr;              /* Machine address to be located */

   int type,               /* Type of symbol to be matched  */
       kind;               /* Addressing output mode to use */

   long ext;               /* Value for extern ref, if any  */

{/* * * * * * * * * *  START OF lookup()  * * * * * * * * * */

   register int j, k;
   static char b[80];

   struct
      {
      int   i;
      int   t;
      }
   best;

   if (lookext(addr,ext,b))
      return (b);

   if (segflg)
      if (segflg & 1)
         type = N_TEXT;
      else
         type = N_DATA;

   for (k = 0, best.i = -1; k <= symptr; ++k)
      if (symtab[k].n_value == addr)
         if ((j = symtab[k].n_sclass & N_SECT) == type)
            {
            best.t = j;
            best.i = k;
            break;
            }
         else if (segflg || (HDR.a_flags & A_SEP))
            continue;
         else if (best.i < 0)
            best.t = j, best.i = k;
         else if (symrank[type][j] > symrank[type][best.t])
            best.t = j, best.i = k;

   if (best.i >= 0)
      return (getnam(best.i));

   if (kind == LOOK_ABS)
      sprintf(b,"0x%05.5x",addr);
   else
      {
      long x = addr - (PC - kind);
      if (x < 0)
         sprintf(b,".%ld",x);
      else
         sprintf(b,".+%ld",x);
      }

   return (b);

}/* * * * * * * * * * * END OF lookup() * * * * * * * * * * */

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  * This function  translates an 8088  addressing mode byte *
  * to an equivalent assembler string,  returning a pointer *
  * thereto.  If necessary,  it performs  successive inputs *
  * of bytes from the object file in order to obtain offset *
  * data,  adjusting PC  accordingly.  (The addressing mode *
  * byte  appears in several  8088  opcodes;  it is used to *
  * specify source and destination operand locations.)  The *
  * third  argument to the function is zero if the standard *
  * registers are to be used,  or eight if the segment reg- *
  * isters are to be used; these constants are defined sym- *
  * bolically in dis.h.  NOTE:  The mtrans()  function must *
  * NEVER be called except  immediately  after fetching the *
  * mode byte.  If any additional  object bytes are fetched *
  * after  the fetch of the mode  byte,  mtrans()  will not *
  * produce correct output!                                 *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

char *
mtrans(c,m,type)

   register int c;            /* Primary instruction byte   */
   register int m;            /* Addressing mode byte       */

   int type;                  /* Type code: standard or seg */

{/* * * * * * * * * *  START OF mtrans()  * * * * * * * * * */

   unsigned long pc;
   int offset, oflag, dir, w, mod, reg, rm;
   static char a[100];
   static char b[30];

   offset = 0;
   dir = c & 2;
   w = c & 1;
   mod = (m & 0xc0) >> 6;
   reg = (m & 0x38) >> 3;
   rm = m & 7;
   pc = PC + 1;

   if (type)
      w = 1;

   if ((oflag = mod) > 2)
      oflag = 0;

   if (oflag)
      {
      int j, k;
      if (oflag == 2)
         {
         FETCH(j);
         FETCH(k);
         offset = (k << 8) | j;
         }
      else
         {
         FETCH(j);
         if (j & 0x80)
            k = 0xff00;
         else
            k = 0;
         offset = k | j;
         }
      }

   if (dir)
      {
      strcpy(a,REGS[type + ((w << 3) | reg)]);
      strcat(a,",");
      switch (mod)
         {
         case 0 :
            if (rm == 6)
               {
               int j, k;
               FETCH(j);
               FETCH(k);
               offset = (k << 8) | j;
               strcat(a,
                lookup((long)(offset),N_DATA,LOOK_ABS,pc));
               }
            else
               {
               sprintf(b,"(%s)",REGS0[rm]);
               strcat(a,b);
               }
            break;
         case 1 :
         case 2 :
            if (mod == 1)
               strcat(a,"*");
            else
               strcat(a,"#");
            sprintf(b,"%d(",offset);
            strcat(a,b);
            strcat(a,REGS1[rm]);
            strcat(a,")");
            break;
         case 3 :
            strcat(a,REGS[(w << 3) | rm]);
            break;
         }
      }
   else
      {
      switch (mod)
         {
         case 0 :
            if (rm == 6)
               {
               int j, k;
               FETCH(j);
               FETCH(k);
               offset = (k << 8) | j;
               strcpy(a,
                lookup((long)(offset),N_DATA,LOOK_ABS,pc));
               }
            else
               {
               sprintf(b,"(%s)",REGS0[rm]);
               strcpy(a,b);
               }
            break;
         case 1 :
         case 2 :
            if (mod == 1)
               strcpy(a,"*");
            else
               strcpy(a,"#");
            sprintf(b,"%d(",offset);
            strcat(a,b);
            strcat(a,REGS1[rm]);
            strcat(a,")");
            break;
         case 3 :
            strcpy(a,REGS[(w << 3) | rm]);
            break;
         }
      strcat(a,",");
      strcat(a,REGS[type + ((w << 3) | reg)]);
      }

   return (a);

}/* * * * * * * * * * * END OF mtrans() * * * * * * * * * * */

 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *                                                         *
  * This simple routine  truncates a string returned by the *
  * mtrans() function, removing its source operand. This is *
  * useful in handlers which ignore the "reg"  field of the *
  * mode byte.                                              *
  *                                                         *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void
mtrunc(a)

   register char *a;          /* Ptr. to string to truncate */

{/* * * * * * * * * *  START OF mtrunc()  * * * * * * * * * */

   register int k;

   for (k = strlen(a) - 1; k >= 0; --k)
      if (a[k] == ',')
         {
         a[k] = '\0';
         break;
         }

}/* * * * * * * * * * * END OF mtrunc() * * * * * * * * * * */


