709 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			709 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 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[9];
 | ||
| 
 | ||
|    for (j = 0; j < 8; ++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[16];
 | ||
| 
 | ||
|    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[64];
 | ||
| 
 | ||
|    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() * * * * * * * * * * */
 | ||
| 
 | ||
| 
 | 
