summaryrefslogtreecommitdiff
path: root/dis88/distabs.c
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-03-24 17:45:55 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:29:43 +0200
commitfe22c37817ce338fbbc90b239320248c270957fa (patch)
treed9550410c4a20bdd382fcc58d2d3d7c5e04e5245 /dis88/distabs.c
parenta7aba15e8efffb1c5d3097656f1a93955a64f01f (diff)
parent42192453ea219b80d0bf9f41e51e36d3d4d0740b (diff)
downloaddev86-fe22c37817ce338fbbc90b239320248c270957fa.tar.gz
Import Dev86-0.0.4.tar.gzv0.0.4
Diffstat (limited to 'dis88/distabs.c')
-rw-r--r--dis88/distabs.c708
1 files changed, 708 insertions, 0 deletions
diff --git a/dis88/distabs.c b/dis88/distabs.c
new file mode 100644
index 0000000..283fe42
--- /dev/null
+++ b/dis88/distabs.c
@@ -0,0 +1,708 @@
+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() * * * * * * * * * * */
+
+