summaryrefslogtreecommitdiff
path: root/dis88/dishand.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/dishand.c
parenta7aba15e8efffb1c5d3097656f1a93955a64f01f (diff)
parent42192453ea219b80d0bf9f41e51e36d3d4d0740b (diff)
downloaddev86-fe22c37817ce338fbbc90b239320248c270957fa.tar.gz
Import Dev86-0.0.4.tar.gzv0.0.4
Diffstat (limited to 'dis88/dishand.c')
-rw-r--r--dis88/dishand.c1049
1 files changed, 1049 insertions, 0 deletions
diff --git a/dis88/dishand.c b/dis88/dishand.c
new file mode 100644
index 0000000..5983972
--- /dev/null
+++ b/dis88/dishand.c
@@ -0,0 +1,1049 @@
+static char *sccsid =
+ "@(#) dishand.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 source code for most of the spe- *
+ * cialized handler routines of the disassembler program. *
+ * (The file disfp.c contains handler routines specific to *
+ * the 8087 numeric co-processor.) Each handler routine *
+ * interprets the opcode byte (and subsequent data bytes, *
+ * if any) of a particular family of opcodes, and is re- *
+ * sponsible for generating appropriate output. All of the *
+ * code in this file is highly MACHINE-SPECIFIC, and would *
+ * have to be rewritten for a different CPU. The handler *
+ * routines are accessed only via pointers in the optab[] *
+ * array, however, so machine dependencies are confined to *
+ * this file, its sister file "disfp.c", and the data file *
+ * "distabs.c". *
+ * *
+ * All of the code in this file is based on the assumption *
+ * of sixteen-bit integers. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "dis.h" /* Disassembler declarations */
+
+int segflg; /* Segment-override flag */
+
+unsigned char objbuf[OBJMAX]; /* Buffer for object code */
+
+int objptr; /* Index into objbuf[] */
+
+unsigned long PC; /* Current program counter */
+
+ /* * * * * * MISCELLANEOUS SUPPORTING ROUTINES * * * * * */
+
+
+void
+objini(j) /* Object code init routine */
+
+ register int j;
+
+{
+ if ((segflg == 1) || (segflg == 2))
+ segflg *= 3;
+ else
+ segflg = 0;
+ objptr = 0;
+ objbuf[objptr++] = (unsigned char)(j);
+}
+
+
+void
+objout() /* Object-code output routine */
+
+{
+ register int k;
+
+ if ( ! objflg )
+ return;
+ else
+ {
+ printf("\t|");
+ if (symptr >= 0)
+ printf(" %05.5lx:",(PC + 1L - (long)(objptr)));
+ for (k = 0; k < objptr; ++k)
+ printf(" %02.2x",objbuf[k]);
+ putchar('\n');
+ }
+}
+
+
+void
+badseq(j,k) /* Invalid-sequence routine */
+
+ register int j, k;
+
+{
+ printf("\t.byte\t0x%02.2x\t\t| invalid code sequence\n",j);
+ printf("\t.byte\t0x%02.2x\n",k);
+}
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This routine is the first of several opcode-specific *
+ * handlers, each of which is dedicated to a particular *
+ * opcode family. A pointer to a handler routine is con- *
+ * tained in the second field of each optab[] entry. The *
+ * dfhand() routine is the default handler, invoked when *
+ * no other handler is appropriate (generally, when an in- *
+ * valid opcode is encountered). *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+dfhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF dfhand() * * * * * * * * * */
+
+ segflg = 0;
+
+ printf("\t.byte\t0x%02.2x",j);
+
+ if (optab[j].min || optab[j].max)
+ putchar('\n');
+ else
+ printf("\t\t| unimplemented opcode\n");
+
+}/* * * * * * * * * * * END OF dfhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the single-byte handler, invoked whenever a *
+ * one-byte opcode is encountered. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+sbhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF sbhand() * * * * * * * * * */
+
+ objini(j);
+
+ if (j == 0x2e) /* seg cs */
+ segflg = 1;
+
+ if ((j == 0x26) /* seg es */
+ || (j == 0x36) /* seg ss */
+ || (j == 0x3e)) /* seg ds */
+ segflg = 2;
+
+ printf("%s\n",optab[j].text);
+
+ objout();
+
+}/* * * * * * * * * * * END OF sbhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for most of the processor's regular *
+ * arithmetic operations. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+aohand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF aohand() * * * * * * * * * */
+
+ register int k;
+ int m, n;
+ char b[80];
+
+ objini(j);
+
+ switch (j & 7)
+ {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ printf("%s\t",optab[j].text);
+ FETCH(k);
+ printf("%s\n",mtrans(j,k,TR_STD));
+ break;
+ case 4 :
+ FETCH(k);
+ printf("%s\tal,*0x%02.2x\n",optab[j].text,k);
+ break;
+ case 5 :
+ FETCH(m);
+ FETCH(n);
+ k = (n << 8) | m;
+ if (lookext((long)(k),(PC - 1),b))
+ printf("%s\tax,#%s\n",optab[j].text,b);
+ else
+ printf("%s\tax,#0x%04.4x\n",optab[j].text,k);
+ break;
+ default :
+ dfhand(j);
+ break;
+ }
+
+ objout();
+
+}/* * * * * * * * * * * END OF aohand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for opcodes which perform short *
+ * (eight-bit) relative jumps. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+sjhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF sjhand() * * * * * * * * * */
+
+ register int k;
+ int m;
+
+ objini(j);
+
+ FETCH(m);
+
+ if (m & 0x80)
+ k = 0xff00;
+ else
+ k = 0;
+
+ k |= m;
+
+ printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text,
+ lookup((PC + k + 1L),N_TEXT,LOOK_REL,-1L),
+ (PC + k + 1L));
+
+ objout();
+
+}/* * * * * * * * * * * END OF sjhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for a loosely-knit family of op- *
+ * codes which perform arithmetic and logical operations, *
+ * and which take immediate data. The routine's logic is *
+ * rather complex, so, in an effort to avoid additional *
+ * complexity, the search for external references in the *
+ * relocation table has been dispensed with. Eager hackers *
+ * can try their hand at coding such a search. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+imhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF imhand() * * * * * * * * * */
+
+ unsigned long pc;
+ register int k;
+ int offset, oflag, immed, iflag, mod, opi, w, rm;
+ int m, n;
+ static char a[100], b[30];
+
+ objini(j);
+
+ FETCH(k);
+
+ pc = PC + 1;
+
+ offset = 0;
+ mod = (k & 0xc0) >> 6;
+ opi = (k & 0x38) >> 3;
+ w = j & 1;
+ rm = k & 7;
+
+ if ((j & 2)
+ && ((opi == 1)
+ || (opi == 4)
+ || (opi == 6)))
+ {
+ badseq(j,k);
+ return;
+ }
+
+ strcpy(a,OPFAM[opi]);
+
+ if ( ! w )
+ strcat(a,"b");
+
+ if ((oflag = mod) > 2)
+ oflag = 0;
+
+ if ((mod == 0) && (rm == 6))
+ {
+ FETCH(m);
+ FETCH(n);
+ offset = (n << 8) | m;
+ }
+ else if (oflag)
+ if (oflag == 2)
+ {
+ FETCH(m);
+ FETCH(n);
+ offset = (n << 8) | m;
+ }
+ else
+ {
+ FETCH(m);
+ if (m & 0x80)
+ n = 0xff00;
+ else
+ n = 0;
+ offset = n | m;
+ }
+
+ switch (j & 3)
+ {
+ case 0 :
+ case 2 :
+ FETCH(immed);
+ iflag = 0;
+ break;
+ case 1 :
+ FETCH(m);
+ FETCH(n);
+ immed = (n << 8) | m;
+ iflag = 1;
+ break;
+ case 3 :
+ FETCH(immed);
+ if (immed & 0x80)
+ immed &= 0xff00;
+ iflag = 0;
+ break;
+ }
+
+ strcat(a,"\t");
+
+ switch (mod)
+ {
+ case 0 :
+ if (rm == 6)
+ 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;
+ }
+
+ strcat(a,",");
+ if (iflag)
+ strcat(a,"#");
+ else
+ strcat(a,"*");
+ sprintf(b,"%d",immed);
+ strcat(a,b);
+
+ printf("%s\n",a);
+
+ objout();
+
+}/* * * * * * * * * * * END OF imhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for various "mov"-type opcodes *
+ * which use the mod, reg, and r/m fields of the second *
+ * code byte in a standard, straightforward way. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mvhand(j)
+
+ int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mvhand() * * * * * * * * * */
+
+ register int k, m = j;
+
+ objini(j);
+
+ FETCH(k);
+
+ if ((m == 0x84) || (m == 0x85) /* Kind of kludgey */
+ || (m == 0xc4) || (m == 0xc5)
+ || (m == 0x8d))
+ if (m & 0x40)
+ m |= 0x03;
+ else
+ m |= 0x02;
+
+ printf("%s\t%s\n",optab[j].text,mtrans(m,k,TR_STD));
+
+ objout();
+
+}/* * * * * * * * * * * END OF mvhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for segment-register "mov" opcodes. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mshand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mshand() * * * * * * * * * */
+
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ if (k & 0x20)
+ {
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s\t%s\n",optab[j].text,mtrans(j,k,TR_SEG));
+
+ objout();
+
+}/* * * * * * * * * * * END OF mshand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for pops, other than single-byte *
+ * pops. (The 8088 allows popping into any register, or *
+ * directly into memory, accessed either immediately or *
+ * through a register and an index.) *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+pohand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF pohand() * * * * * * * * * */
+
+ char *a;
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ if (k & 0x38)
+ {
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s\t",optab[j].text);
+
+ a = mtrans((j & 0xfd),k,TR_STD);
+
+ mtrunc(a);
+
+ printf("%s\n",a);
+
+ objout();
+
+}/* * * * * * * * * * * END OF pohand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler routine for intersegment calls and *
+ * jumps. Its output is never symbolic, because the host *
+ * linker does not allow symbolic intersegment address *
+ * references except by means of symbolic constants, and *
+ * any such constants in the symbol table, even if they *
+ * are of the appropriate value, may be misleading. In *
+ * compiled code, intersegment references should not be *
+ * encountered, and even in assembled code, they should *
+ * occur infrequently. If and when they do occur, however, *
+ * they will be disassembled in absolute form. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+cihand(j)
+
+ int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF cihand() * * * * * * * * * */
+
+ register int m, n;
+
+ objini(j);
+
+ printf("%s\t",optab[j].text);
+
+ FETCH(m);
+ FETCH(n);
+
+ printf("#0x%04.4x,",((n << 8) | m));
+
+ FETCH(m);
+ FETCH(n);
+
+ printf("#0x%04.4x\n",((n << 8) | m));
+
+ objout();
+
+}/* * * * * * * * * * * END OF cihand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for "mov" opcodes with immediate *
+ * data. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mihand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mihand() * * * * * * * * * */
+
+ register int k;
+ int m, n;
+ char b[80];
+
+ objini(j);
+
+ printf("%s",optab[j].text);
+
+ if (j & 8)
+ {
+ FETCH(m);
+ FETCH(n);
+ k = ((n << 8) | m);
+ if (lookext((long)(k),(PC - 1),b))
+ printf("#%s\n",b);
+ else
+ printf("#%d\n",k);
+ }
+ else
+ {
+ FETCH(m);
+ printf("*%d\n",m);
+ }
+
+ objout();
+
+}/* * * * * * * * * * * END OF mihand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for a family of quick-move opcodes. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mqhand(j)
+
+ int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mqhand() * * * * * * * * * */
+
+ unsigned long pc;
+ register int m, n;
+
+ objini(j);
+
+ pc = PC + 1;
+
+ FETCH(m);
+ FETCH(n);
+
+ m = (n << 8) | m;
+
+ printf("%s\t",optab[j].text);
+
+ if (j & 2)
+ printf("%s,%s\n",
+ lookup((long)(m),N_DATA,LOOK_ABS,pc),
+ REGS[(j & 1) << 3]);
+ else
+ printf("%s,%s\n",
+ REGS[(j & 1) << 3],
+ lookup((long)(m),N_DATA,LOOK_ABS,pc));
+
+ objout();
+
+}/* * * * * * * * * * * END OF mqhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for a family of quick-test opcodes. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+tqhand(j)
+
+ int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF tqhand() * * * * * * * * * */
+
+ register int m, n;
+ int k;
+ char b[80];
+
+ objini(j);
+
+ printf("%s\t%s,",optab[j].text,REGS[(j & 1) << 3]);
+
+ FETCH(m);
+
+ if (j & 1)
+ {
+ FETCH(n);
+ k = ((n << 8) | m);
+ if (lookext((long)(k),(PC - 1),b))
+ printf("#%s\n",b);
+ else
+ printf("#%d\n",k);
+ }
+ else
+ {
+ if (m & 80)
+ m |= 0xff00;
+ printf("*%d\n",m);
+ }
+
+ objout();
+
+}/* * * * * * * * * * * END OF tqhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for multiple-byte "return" opcodes. *
+ * The 8088 allows returns to take an optional 16-bit ar- *
+ * gument, which reflects the amount to be added to SP *
+ * after the pop of the return address. The idea is to *
+ * facilitate the use of local parameters on the stack. *
+ * After some rumination, it was decided to disassemble *
+ * any such arguments as absolute quantities, rather than *
+ * rummaging through the symbol table for possible corre- *
+ * sponding constants. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+rehand(j)
+
+ int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF rehand() * * * * * * * * * */
+
+ register int m, n;
+
+ objini(j);
+
+ FETCH(m);
+ FETCH(n);
+
+ m = (n << 8) | m;
+
+ printf("%s\t#0x%04.4x\n",optab[j].text,m);
+
+ objout();
+
+}/* * * * * * * * * * * END OF rehand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for "mov" opcodes involving memory *
+ * and immediate data. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mmhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mmhand() * * * * * * * * * */
+
+ char *a;
+ register int k;
+ char b[80];
+
+ objini(j);
+
+ FETCH(k);
+
+ if (k & 0x38)
+ {
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s",optab[j].text);
+
+ if ( ! (j & 1) )
+ putchar('b');
+
+ a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
+
+ mtrunc(a);
+
+ printf("\t%s,",a);
+
+ if (j & 1)
+ {
+ FETCH(j);
+ FETCH(k);
+ k = (k << 8) | j;
+ if (lookext((long)(k),(PC - 1),b))
+ printf("#%s\n",b);
+ else
+ printf("#%d\n",k);
+ }
+ else
+ {
+ FETCH(k);
+ printf("*%d\n",k);
+ }
+
+ objout();
+
+}/* * * * * * * * * * * END OF mmhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for the 8088 family of shift and *
+ * rotate instructions. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+srhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF srhand() * * * * * * * * * */
+
+ char *a;
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ if ((k & 0x38) == 0x30)
+ {
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s",OPFAM[((k & 0x38) >> 3) + 16]);
+
+ if ( ! (j & 1) )
+ putchar('b');
+
+ a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
+
+ mtrunc(a);
+
+ printf("\t%s",a);
+
+ if (j & 2)
+ printf(",cl\n");
+ else
+ printf(",*1\n");
+
+ objout();
+
+}/* * * * * * * * * * * END OF srhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for the ASCII-adjust opcodes. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+aahand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF aahand() * * * * * * * * * */
+
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ if (k != 0x0a)
+ {
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s\n",optab[j].text);
+
+ objout();
+
+}/* * * * * * * * * * * END OF aahand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for port I/O opcodes which specify *
+ * the port address as an immediate operand. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+iohand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF iohand() * * * * * * * * * */
+
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ printf("%s\t0x%02.2x\n",optab[j].text,k);
+
+ objout();
+
+}/* * * * * * * * * * * END OF iohand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for opcodes which perform long *
+ * (sixteen-bit) relative jumps and calls. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+ljhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF ljhand() * * * * * * * * * */
+
+ register int k;
+ int m, n;
+
+ objini(j);
+
+ FETCH(m);
+ FETCH(n);
+
+ k = (n << 8) | m;
+
+ printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text,
+ lookup((PC + k + 1L),N_TEXT,LOOK_LNG,(PC - 1L)),
+ (PC + k + 1L));
+
+ objout();
+
+}/* * * * * * * * * * * END OF ljhand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for a pair of oddball opcodes (0xf6 *
+ * and 0xf7) which perform miscellaneous arithmetic opera- *
+ * tions not dealt with elsewhere. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mahand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mahand() * * * * * * * * * */
+
+ char *a;
+ register int k;
+ char b[80];
+
+ objini(j);
+
+ FETCH(k);
+
+ a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
+
+ mtrunc(a);
+
+ switch (((k = objbuf[1]) & 0x38) >> 3)
+ {
+ case 0 :
+ printf("\ttest");
+ break;
+ case 1 :
+ badseq(j,k);
+ return;
+ case 2 :
+ printf("\tnot");
+ break;
+ case 3 :
+ printf("\tneg");
+ break;
+ case 4 :
+ printf("\tmul");
+ break;
+ case 5 :
+ printf("\timul");
+ break;
+ case 6 :
+ printf("\tdiv");
+ break;
+ case 7 :
+ printf("\tidiv");
+ break;
+ }
+
+ if ( ! (j & 1) )
+ putchar('b');
+
+ printf("\t%s",a);
+
+ if (k & 0x38)
+ putchar('\n');
+ else
+ if (j & 1)
+ {
+ FETCH(j);
+ FETCH(k);
+ k = (k << 8) | j;
+ if (lookext((long)(k),(PC - 1),b))
+ printf(",#%s\n",b);
+ else
+ printf(",#%d\n",k);
+ }
+ else
+ {
+ FETCH(k);
+ printf(",*%d\n",k);
+ }
+
+ objout();
+
+}/* * * * * * * * * * * END OF mahand() * * * * * * * * * * */
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This is the handler for miscellaneous jump, call, push, *
+ * and increment/decrement opcodes (0xfe and 0xff) which *
+ * are not dealt with elsewhere. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+void
+mjhand(j)
+
+ register int j; /* Pointer to optab[] entry */
+
+{/* * * * * * * * * * START OF mjhand() * * * * * * * * * */
+
+ char *a;
+ register int k;
+
+ objini(j);
+
+ FETCH(k);
+
+ a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
+
+ mtrunc(a);
+
+ switch (((k = objbuf[1]) & 0x38) >> 3)
+ {
+ case 0 :
+ printf("\tinc");
+ if ( ! (j & 1) )
+ putchar('b');
+ putchar('\t');
+ break;
+ case 1 :
+ printf("\tdec");
+ if ( ! (j & 1) )
+ putchar('b');
+ putchar('\t');
+ break;
+ case 2 :
+ if (j & 1)
+ printf("\tcall\t@");
+ else
+ goto BAD;
+ break;
+ case 3 :
+ if (j & 1)
+ printf("\tcalli\t@");
+ else
+ goto BAD;
+ break;
+ case 4 :
+ if (j & 1)
+ printf("\tjmp\t@");
+ else
+ goto BAD;
+ break;
+ case 5 :
+ if (j & 1)
+ printf("\tjmpi\t@");
+ else
+ goto BAD;
+ break;
+ case 6 :
+ if (j & 1)
+ printf("\tpush\t");
+ else
+ goto BAD;
+ break;
+ case 7 :
+ BAD :
+ badseq(j,k);
+ return;
+ }
+
+ printf("%s\n",a);
+
+ objout();
+
+}/* * * * * * * * * * * END OF mjhand() * * * * * * * * * * */
+
+