h02934
s 00416/00433/00081
d D 1.4 85/06/03 18:19:42 root 4 3
c changed to system 5 disassembler
e
s 00000/00100/00514
d D 1.3 85/02/13 00:27:20 dock 3 2
c moved a lot of unused code into stktrace.c
e
s 00039/00142/00575
d D 1.2 84/11/09 05:52:45 dock 2 1
c used common printf of monitor
e
s 00717/00000/00000
d D 1.1 84/11/01 22:37:14 dock 1 0
c date and time created 84/11/01 22:37:14 by dock
e
u
U
t
T
I 1
/*
D 4
 * disasm.c -- Disassembler for the debugger monitor
E 4
I 4
 * %M%: version %I% of %H%
 *
 * Disassembler for the debugger monitor
E 4
 * copyright (c) 1984  American Information Systems Corporation
D 4
 *  Dock Williams
 *  March, 1984
E 4
I 4
 *  Dock Williams   March, 1984
E 4
 */

D 4
# ifdef SCCS
static char *sccsid = "@(#)disasm.c	1.22 (NSC) 8/30/83";
# endif

E 4
#include "monitor.h"
#include "vctype.h"
#include "mondef.h"

D 4
/* externally defined read only data, see rodata.c */
extern INSTFORM format[];
extern char *fieldtab[];
extern char fieldtype[];
extern char indexm[];
E 4
I 4
extern OP1 ops1[];
extern OP2 ops2[];
extern OP3 ops3[];
extern char *preg[];	/* processor registers */
extern char *rnm[];	/* register for relative addressing modes */
extern char *sname[];	/* mmu registers */
extern short flen[2];	/* length parameters for f, l */
E 4

D 2

E 2

D 2
    static
nprint(num,radix)
unsigned int num,radix;
{
	unsigned int i,unum;
	char cout;
	unum = num;
	if ((i = num/radix) != 0) nprint(i,radix);
	num %= radix;
	if (num >= 10) {
	    cout = 'a' + (num - 10);
	    if (firsthex) OUTCHR('0');
	}
	else cout = num + '0';
	OUTCHR(cout);
	firsthex = FALSE;
}
E 2
D 4

D 2
    static
E 2
snprint(num)
int	num;
E 4
I 4
/*
 * disassemble an instruction
 * at address addr, return its length
 */
mdisasm(addr,print,map)
int addr, print;
E 4
{
D 2
	firsthex = TRUE;
	if ((num < 0) && ((curbase == 'd') || (num > -100))) {
		OUTCHR('-');
		num =  -num;
E 2
I 2
D 4
	switch(curbase) {
	case 'o':
		printf("%o",num);
E 4
I 4
	register int ins,tmp;

	tmp = mapping;		/* save old mapping */
	mapping = map;		/* use argument mapping */
	ins = mrdquad(addr,mapping);

	dot = addr;
	pflag = print;
	switch (ins & 7) {
	case 2:
		incp = 1;
		op1(ins);
E 4
		break;
D 4
	case 'd':
		printf("%d",num);
E 4
I 4
	case 6:
		incp = 3;
		op3(ins);
E 4
		break;
D 4
	case 'x':
E 4
	default:
D 4
		if ( (num < 0) && (num > -100) )
			printf("%d",num);
		else
			printf("%x",num);
E 4
I 4
		incp = 2;
		op2(ins);
E 4
		break;
E 2
	}
D 2
	nprint(num,curbase=='o'?8:(curbase=='d'?10:16));

E 2
D 4
}
E 4

D 2
/*
typeout(num,format)
int num;
char *format;
{
	int modf,off,symatch;
	char symfound[MAXSTRLEN];
	lasttypeout = num;	
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
	format++;
	if ((tempmodes.relative) && (num >= matchbase)) {
		if ((symatch) && (off <= matchequal)) {
			printf("%s",symfound);
			if (off) {
				OUTCHR('+');
				snprint(off);
			}
		} else snprint(num);
	} else snprint(num);
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
	format++;
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
E 2
D 4

D 2
}
*/
E 2

I 2
D 3

E 2
    static
E 3
typeout(num,format)
int num;
char *format;
{
D 2
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
E 2
I 2
	if ((*format != '*') && (*format != '\0')) OUTCHR(*format);
E 2
	format++;
	if (cflags & CF_SYMP) psym(num);
	else snprint(num);
D 2
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
E 2
I 2
	if ((*format != '*') && (*format != '\0')) OUTCHR(*format);
E 2
	format++;
D 2
	if ((*format != '*') && (*format != '\0')) printf("%c",*format);
E 2
I 2
	if ((*format != '*') && (*format != '\0')) OUTCHR(*format);
E 4
I 4
	mapping = tmp;		/* restore mapping */
	return(incp);
E 4
E 2
}

D 2
/*
autoi(addrat)
int addrat;
{
register struct exec *hpr = &ddtheader;
	if (tempmodes.outputmode == INSTRUCT) return(TRUE);
	if (tempmodes.outputmode != NUMERIC) return(FALSE);
	if (tempmodes.automat) {
		if ((((hpr->a_text_addr+hpr->a_mod) <= addrat) &&
		(addrat < (hpr->a_text_addr + hpr->a_text))) ||
		((hpr->a_mod_addr <= addrat) && (addrat <= hpr->a_mod_addr+12)))
		    return(TRUE);
	}
	return(FALSE);
}
*/
E 2
D 4

D 2
/*
display(address)
int address;
{
char	achar;
int	contentat, delta, instat, instlen;
	acontext = tempmodes.context;
	if ((address >= 0) && autoi(address)) {
		instat = address;
		if (disasm(instat,&instlen,TRUE)) {
			contentat = getmem(address);
			acontext = instlen;
			return(contentat);
		}
	}
	if (address < 0) {
		contentat = getreg(address);
	} else {
		contentat = getmem(address);
	}
	if (tempmodes.outputmode == ABSNUMERIC) {
		snprint(contentat);
	} else if (tempmodes.outputmode == STRING) {
		delta = 1;
		while (TRUE) {
			achar = getbyte(address+delta-1);
			if (achar == '\0') break;
			if ((achar >= ' ') && (achar <='~')) printf("%c",achar);
			else printf("/%x",achar);
			delta++;
		}
		acontext = delta;
		printf("\r\n");
	} else if (tempmodes.outputmode == CHARACTER) {
		acontext = 1;
		achar = contentat;
		if ((achar >= ' ') && (achar <= '~')) printf("%c",achar);
		else printf("/%x",achar);
	} else if (tempmodes.outputmode == FLOATING) {
		printf("%g",contentat);
	} else typeout(contentat,"  ");
	return(contentat);
}
*/
E 2

    static unsigned
ext(x,p,n)
unsigned x,p,n;
E 4
I 4
op1(a)
register int a;
E 4
{
D 4
	return((x >> (p+1-n)) & ~(~0 << n));
}
E 4
I 4
	register struct o1 *p;
E 4

I 2
D 4

E 2
    static unsigned
ins(x,y,n)
unsigned x,y,n;
{
	return((y << n) | (x & ~(~0 << n)));
E 4
I 4
	a &= 0xff;
	for (p=ops1; p->val != 0; p++) {
		if (p->val == a) {
			if (pflag) printf("%s\t", p->name);
			if (p->extra) {
				do_extra(p->extra);
			}
			return;
		}
	}
	if (pflag) OUTCHR('?');
E 4
}

I 2
D 4


E 2
    static unsigned
getfield(pattern,matchc,value)
char *pattern, matchc;
unsigned value;
E 4
I 4
op2(a)
register int a;
E 4
{
D 4
char *sp;
int firstbit,len;
	sp = (char *) index(pattern,matchc);
	if (sp == 0) return(-1);
	for (firstbit=len=0; *sp != '\0'; firstbit++)
		if (*sp++ == matchc) len++;
	return(ext(value,firstbit-1,len));
}
E 4
I 4
	register struct o2 *p;
	short cmp;
E 4

I 2
D 4

E 2
    static
getname(value,names,name)
int value;
char *names,*name;
{
int i;
	*name = '\0';
	if (value < 0) return;
	for (i=0; i < value; i++) {
		while (*names != '/') {
			if (*names == '\0') return;
			names++;
E 4
I 4
	a &= 0xffff;
	cmp = a>>2;
	for (p=ops2; p->mask != 0; p++) {
		if (p->val == (cmp & p->mask)) {
			if (pflag) printf(p->name);
			if (p->allow != 2) {
				if (pflag) OUTCHR("bw?d"[a&3]);
			}
			if (pflag) OUTCHR('\t');
			switch (p->type) {
			case 0:
				gen2(a>>11, (a>>6)&0x1f, a&3, a&3);
				break;
			case 1:
				quick((a>>7)&0xf);
				if (pflag) OUTCHR(',');
				gen1(a>>11, a&3);
				break;
			case 2:
				gen1(a>>11, a&3);
				break;
			case 3:
				if (pflag) printf("%s,", preg[(a>>7)&0xf]);
				gen1(a>>11, a&3);
				break;
			}
			if (p->extra) {
				if (pflag) OUTCHR(',');
				do_extra(p->extra);
			}
			return;
E 4
		}
D 4
		names++;
E 4
	}
D 4
	if ((*names == '/') || (*names == '\0')) return;
	do {
		*name++ = *names++;
	} while ((*names != '/') && (*names != '\0'));
	*name = '\0';
E 4
I 4
	if (pflag) printf("??");
E 4
}

I 2
D 4

E 2
    static unsigned
instget()
E 4
I 4
op3(a)
register int a;
E 4
{
D 4
	if (ibuf == 0) ibuf = inbuf;
	if ((ilen < 0) || (ilen >= IBUFFERSIZE)) {
		if (ilen < 0) ilen = 0;
		getmemb(istart+ilen,IBUFFERSIZE,ibuf);
		istart += ilen;
		ilen = 0;
	}
	return((0xff & (*(ibuf + ilen++))));
}
E 4
I 4
	register int itype, ftype;
	int i;
	short l1, l2;
	register struct o3 *p;
	short cmp;
E 4

I 2
D 4

E 2
    static
disp()
{
int i,r;
	r = instget();
	if ((r & 0x80) == 0) {
	  if (r & 0x40) {
		r = r | 0xffffff80;
	  } else r = r & 0x7f;
	} else if ((r & 0xc0) == 0x80) {
		r = instget() | (r << 8);
	        if (r & 0x2000) {
		    r = r | 0xffffc000;
	        } else r = r & 0x3fff;
	} else {
		for (i=0; i < 3; i++) {
		    r <<= 8;
		    r |= instget();
E 4
I 4
	a &= 0xffffff;
	cmp = a >> 3;
	for (p=ops3; p->mask != 0; p++) {
		if (p->val == (cmp & p->mask)) {
			if (pflag) printf(p->name);
			switch (p->typef) {
			case 0:
				itype = (a>>8)&3;
				l1 = l2 = itype;
				if (pflag) OUTCHR("bw?d"[itype]);
				break;
			case 1:
				ftype = (a>>8)&1;
				l1 = l2 = flen[ftype];
				if (pflag) OUTCHR("lf"[ftype]);
				break;
			case 2:
				itype = (a>>8)&3;
				ftype = (a>>10) & 1;
				l1 = flen[ftype];
				l2 = itype;
				if (pflag) {
					OUTCHR("lf"[ftype]);
					OUTCHR("bw?d"[itype]);
				}
				break;
			case 3:
				itype = (a>>8)&3;
				ftype = (a>>10) & 1;
				l1 = itype;
				l2 = flen[ftype];
				if (pflag) {
					OUTCHR("bw?d"[itype]);
					OUTCHR("lf"[ftype]);
				}
				break;
			case 4:
				l1 = l2 = 3;
				break;
			case 5:
				l1 = flen[0];
				l2 = flen[1];
				break;
			case 6:
				l1 = flen[1];
				l2 = flen[0];
				break;
			}
			if (pflag) OUTCHR('\t');
			if (p->regf == 0) {
				if (pflag) printf("r%d,", (a>>11) & 7);
			}
			if (p->f1 == 0 && p->f2 == 0) {
				gen2(a>>19, (a>>14)&0x1f, l1, l2);
			} else {
				i = (a>>14) & 0x1f;
				if (p->f2 == 3) {
					do_ss(i>>1);
					if (pflag) OUTCHR(',');
				}
				if (p->f1 == 0) {
					gen1(a>>19, l1);
					if (p->f2 != 3)
						if (pflag) OUTCHR(',');
				}
				if (p->f1 >= 4) {
					gen1(a>>19, p->f1 - 4);
					if (pflag) OUTCHR(',');
				}
				switch (p->f2) {
				case 0:
					gen1(i, l1);
					break;
				case 1:
					do_uwb(i>>2);
					break;
				case 2:
					do_xx(i>>1);
					break;
				case 3:
					break;
				default:
					gen1(i, p->f2 - 4);
					break;
				}
			}
			if (p->extra) {
				if (pflag) OUTCHR(',');
				do_extra(p->extra);
			}
			return;
E 4
		}
D 4
	        if (r & 0x20000000) {
		    r = r | 0xc0000000;
	        } else r = r & 0x3fffffff;
E 4
	}
D 4
	return(r);
E 4
I 4
	if (pflag) printf("??");
E 4
}

I 2
D 4

E 2
    static
reglist(value,f,i,l)
E 4
I 4
gen2(m1, m2, l1, l2)
register int m1,m2;
int l1,l2;
E 4
{
D 4
int	n = 0,t = FALSE;
	OUTCHR('[');
	while (f != l) {
		if (ext(value,f,1)) {
D 2
			if (t) printf(","); else t = TRUE;
E 2
I 2
			if (t) {
				OUTCHR(',');
			} else
				t = TRUE;
E 2
			printf("r%d",n);
		}
		n++;
		f += i;
E 4
I 4
	int idx1, idx2;

	if (m1 >= 0x1c) { /* scaled indexing */
		idx1 = egetchar();
E 4
	}
D 4
	OUTCHR(']');
	return(TRUE);
E 4
I 4
	if (m2 >= 0x1c) {
		idx2 = egetchar();
	}
	if (m1 >= 0x1c)
		sc_gen(idx1, m1&3);
	else
		sub_gen(m1, l1);
	if (pflag) OUTCHR(',');
	if (m2 >= 0x1c)
		sc_gen(idx2, m2&3);
	else
		sub_gen(m2, l2);
E 4
}
D 4

D 2
/*
findmod(pc)
{
	struct exec *hpr = &ddtheader;
	int modf,off,symatch;
	char symfound[MAXSTRLEN];
	int i;
	if (trustsyms)
	    symatch = lookbyval(pc,&off,&modf,symfound);
	else symatch = FALSE;
	if (symatch) {
		return(modf);
	} else if (pc < hpr->a_mod) return(0);
	else {
		i = hpr->a_mod_addr + (hpr->a_mod);
		do {
			i -= 16;
			if (getdouble(i+8) <= pc)
				return(i);
		} while (i >= hpr->a_mod_addr);
	}
	return(0);
	
}
*/
E 2

    static
findmod(pc)
E 4
I 4
gen1(mode, len)
E 4
{
I 4
	int idx;
E 4
I 2

D 4
#ifdef MODTAB
E 2
	register int i;

	for (i = 0x50; ((i < lastmod) && (i < 0x1000)); i+=16)
		if (getdouble(i+8) <= pc) return(i);
	return(0);
I 2
#else
	return(0x50);
#endif

E 4
I 4
	if (mode >= 0x1c) {	/* scaled indexing */
		idx = egetchar();
		sc_gen(idx, mode&3);
	} else
		sub_gen(mode, len);
E 4
E 2
}
D 4

I 2

E 2
    static
etype(d1,d2)
E 4
I 4
quick(x)
E 4
{
D 4
    printf("ext<");
    typeout(getdouble(getdouble(findmod(istart)+4)+(d1*4))+d2,"*>");
E 4
I 4
	if (pflag) {
		if (x <= 7) {
			printf("$%d", x);
		} else
			printf("$%d", x-16);
	}
E 4
}

D 4
    static
newsbtype(d1)
E 4
I 4
/* scaled indexing - index byte in idx, scale factor in slen */
sc_gen(idx, slen)
E 4
{
D 4
    if (opcxpd) {
	    d1 = getdouble(getdouble(findmod(istart))+d1);
	    typeout(getdouble((d1&0xffff)+8) + ext(d1,31,16),"**");
    } else {
	    typeout(getdouble(getdouble(findmod(istart))+d1),"*<");
	    printf("xsb>");
    }
}
E 4
I 4
	int mode, reg;
E 4

D 4
    static
mtype(d1,regn,regname)
char *regname;
{
	if (regn <= 1) {
		snprint(d1);
		printf("(%s)",regname);
E 4
I 4
	mode = idx>>3;
	reg = idx & 7;
	if (mode == 0x14) {	/* immediate */
		if (pflag) printf("BAD");
E 4
		return;
	}
D 4
	if (regn == 3) typeout(istart+d1,"*<");
	else
	typeout(getdouble(findmod(istart))+d1,"*<");
	printf("%s>",regname);
E 4
I 4
	sub_gen(mode, 0);
	if (pflag) printf("[r%d:%c]", reg, "bwdq"[slen]);
E 4
}

D 4
    static
mmtype(d1,d2,regn,regname)
char *regname;
E 4
I 4
/* generic, but not scaled - */
sub_gen(mode, len)
register int mode;
int len;
E 4
{
D 4
	snprint(d2);
	OUTCHR('(');
	mtype(d1,regn,regname);
	OUTCHR(')');
E 4
I 4
	register int d1, d2;

	if (mode <= 7) {	/* register */
		if (pflag) printf("%c%d", (len & 8) ? 'f' : 'r', mode);
		return;
	}
	if (mode <= 15) {	/* register relative */
		d1 = getdisp();
		if (pflag) printf("0x%x(r%d)", d1, mode&7);
		return;
	}
	if (mode <= 18) {	/* memory relative */
		d1 = getdisp();
		d2 = getdisp();
		if (pflag) printf("0x%x(0x%x(%s))", d2, d1, rnm[mode-16]);
		return;
	}
	if (mode >= 0x18) {	/* memory space */
		d1 = getdisp();
		if (pflag) printf("0x%x(%s)", d1, rnm[mode-0x18]);
		return;
	}
	switch (mode) {
	case 0x14:	/* immediate */
		putimm(len);
		return;
	case 0x15:	/* absolute */
		d1 = getdisp();
		if (pflag) printf("@0x%x",d1);
		return;
	case 0x16:	/* external */
		d1 = getdisp();
		d2 = getdisp();
		if (pflag) printf("ext(0x%x)0x%x", d1, d2);
		return;
	case 0x17:	/* top of stack */
		if (pflag) printf("tos");
		return;
	default:
		if (pflag) printf("??");
	}
E 4
}

D 4
    static
newsbmtype(d1,d2,regn,regname)
char *regname;
E 4
I 4
/* get a 1 to 4 byte signed displacement */
int
getdisp()
E 4
{
D 4
	if (d2 == 0) {
		newsbtype(d1);
	} else {
		snprint(d2);
		OUTCHR('(');
		newsbtype(d1);
		OUTCHR(')');
E 4
I 4
	register int a, b, c, d;

	a = egetchar();
	if ((a & 0x80) == 0) {
		if (a < 0x40)
			return(a);
		else
			return(a-0x80);
E 4
	}
I 4
	if ((a & 0xc0) == 0x80) {	/* short */
		b = egetchar();
		a = a<<8 | b;
		a &= 0x3fff;
		if (a < 0x2000)
			return(a);
		else
			return(a-0x4000);
	}
	/* long */
	b = egetchar(); c = egetchar(); d = egetchar();
	a = (a << 24) | (b << 16) | (c << 8) | d;
	a &= 0x3fffffff;
	if (a < 0x20000000)
		return(a);
	else
		return(a - 0x40000000);
E 4
}

D 4
    static
domode(mode,ibyte,printit)
E 4
I 4
/* print a 1 to 4 byte immediate */
/* or a 4 or 8 byte floating immediate */
int
putimm(len)
E 4
{
D 4
	int i,indexmode = 0,d1,d2;
	char fieldname[9];
	if (mode >= 0x1c) {
	    indexmode = mode;
	    mode = ibyte >> 3;
E 4
I 4
	register int a, x;
	register int i;
	int flo;

	flo = len & 8;
	len &= 7;
	x = 0;
	for (i=0; i<=len; i++) {
		a = egetchar();
		if (i <= 3)
			x = x<<8 | a;
	/* note that bytes are backwards in immediates! */
E 4
	}
D 4
	getname((8+(mode & 3)),fieldtab[6],fieldname);
	switch (mode) {
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
		if (printit) printf("r%d",mode & 7);
		break;
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
	case 14:
	case 15:
		d1 = disp();
		if (printit) {
		    snprint(d1);
		    printf("(r%d)",mode & 7);
E 4
I 4

#ifdef notdef
/*************** AIS - floating point not supported
	if (flo) {
		int f, e;
		double ldexp();
		double d;

		if (len == 3) {	/* float */
			f = (x & 0x7fffff) | 0x800000;
			e = ((x>>23) & 0xff) - 127;
			e -= 23;
		} else {
			f = (x & 0xfffff) | 0x100000;
			e = ((x>>20) & 0x7ff) - 1023;
			e -= 20;
E 4
		}
D 4
		break;
	case 16:
	case 17:
	case 18:
		d1 = disp();
		d2 = disp();
		if (printit) {
			if ((mode == 0x12) && (d1 < 0)) {
		    		newsbmtype(d1,d2,mode&3,fieldname);
			} else {
		    		mmtype(d1,d2,mode&3,fieldname);
			}
		}
		break;
	case 20:
		d1 = 0;
		for (i=1; i <= context; i++) d1 = instget() | (d1 << 8);
		switch (context) {
		case 1:
			if (d1 & 0x80) d1 |= 0xffffff00;
			break;
		case 2:
			if (d1 & 0x8000) d1 |= 0xffff0000;
			break;
		}
		if (printit) typeout(d1,"**");
		break;
	case 21:
		d1 = disp();
		if (printit) {
		    OUTCHR('@');
		    typeout(d1,"**");
		}
		break;
	case 22:
		d1 = disp();
		d2 = disp();
		if (printit) etype(d1,d2);
		break;
	case 23:
		if (printit) printf("tos");
		break;
	default:
		d1 = disp();
		if (printit) {
			if ((mode == 0x1a) && (d1 < 0)) {
				newsbtype(d1);
			} else {
				mtype(d1,mode&3,fieldname);
			}
		}
		break;
E 4
I 4
		d = ldexp((double)f, e);
		if (x < 0)
			d = -d;
		if (pflag) printf("$%-32.18F", d);
	} else {
*************************************************/
#endif notdef

	{
		if (len == 0 && (x & 0x80) != 0)
			x |= 0xffffff00;
		else if (len == 1 && (x & 0x8000) != 0)
			x |= 0xffff0000;
		if (pflag) printf("$0x%x",x);
E 4
	}
D 4
	if ((indexmode) && (printit))
		printf("[r%d:%c]",ibyte&7,indexm[indexmode&3]);
E 4
}

D 4
mdisasm(instat,instlen,printit,map)
int instat,*instlen,printit,map;
E 4
I 4
egetchar()
E 4
{
D 4
char *ip,*in,*fp;
char opname[9],firstchar;
int f,f2,ib1,ib2,i,j,opcode,len,displace,operand = FALSE,bytes = 0;
unsigned instrc, mask;
	mapping = map;		/* copy to global area */
	istart = instat;
	ilen = -1;
	for (i = 0; *(format[i].iproto) != '\0'; i++) {
		ip = format[i].iproto;
		in = format[i].inames;
		len = strlen(ip);
		while ((len / 8) > bytes) {
			instrc = ins(instrc,instget(),bytes << 3);
			bytes++;
		}
		mask = 1 << (len - 1);
		for (j = 0; j < len; j++) {
			if (instrc & mask) { if (*(ip+j) == '0') goto trynext; }
		 	else if (*(ip+j) == '1') goto trynext;
			mask >>= 1;
		}
		context = getfield(ip,'b',instrc) + 1;
		if (context == 3) {
			if (i == 14) {
				opcode = getfield(ip,'x',instrc);
				if (opcode == 2) context = 4;
				else goto trynext;
			} else goto trynext;
		} else if (context == 0) context = 4;
		opcode = getfield(ip,'x',instrc);
		if (opcode == -1) opcode = 0;
		getname(opcode,in,opname);
		if (opname[0] == '\0') goto trynext;
		if (displace = isupper(opname[0])) opname[0] |= 0x20;
	 	if (printit) printf("%s",opname);	
		firstchar = opname[0];
		if (printit) {
			if (i == 14) {
			    if ((opcode != 6) && (opcode >= 4))
D 2
				printf("%c",getfield(ip,'f',instrc) ? 'f' : 'l');
				
E 2
I 2
				OUTCHR(getfield(ip,'f',instrc) ? 'f' : 'l');
E 2
			} else if (i == 15)
D 2
				printf("%c",getfield(ip,'f',instrc) ? 'f' : 'l');
E 2
I 2
				OUTCHR(getfield(ip,'f',instrc) ? 'f' : 'l');
E 2
			fp = fieldtype;
			for (j=0; *fp != '\0'; j++) {
			    if (*fp == 'M') if (opcode <= 1) {
				fp++;
			    	continue;
			    }
			    f = getfield(ip,*fp++,instrc);
			    if (f >= 0) {
				if (j == 1) {
				    if (i == 5)
					if ((opcode == 0) || (opcode == 4) ||
					    (opcode == 12)) continue;
				    if ((i == 6) && (opcode == 9)) continue;
				    if (i == 10)
				    if ((opcode==4)||(opcode==5)) continue;
				    if (i == 14)
				    if ((opcode==1)||(opcode==6)||
					(opcode==2)||(opcode==3)) continue;
				}
				if ((opcode==1) && (j==5) && (i==12)) continue;
				getname(f,fieldtab[j],opname);
				if (j > 2) {
					if (operand) { OUTCHR(',');
					} else operand = TRUE;
				}
				printf("%s",opname);
				if (i == 10)
				    if ((opcode==6)||(opcode==7)) OUTCHR('d');
				if ((i == 14) && (opcode==0))
D 2
				printf("%c",getfield(ip,'f',instrc) ? 'f' : 'l');
E 2
I 2
				OUTCHR(getfield(ip,'f',instrc) ? 'f' : 'l');
E 2
			    }
E 4
I 4
	int a;
E 4

D 4
			    if (j == 2) OUTCHR('\t');
		    }
		}
		if (i == 1) {
			if ((opcode ==6) || (opcode ==8)) {
				f = instget();
				if (printit) operand = reglist(f,0,1,8);
			} else if ((opcode ==7) || (opcode ==9)) {
				f = instget();
				if (printit) operand = reglist(f,7,-1,-1);
E 4
I 4
	a = mrdbyte(dot+incp,mapping);
	incp++;
	return(a);
}

do_extra(x)
register int x;
{
	register int a, i, j;
	int some = 0;
	int disp;

	if (x & (1|8)) {	/* reglist */
		a = egetchar();
		if (pflag) OUTCHR('[');
		for (i=0; i<8; i++) {
			j = (x&1) ? 0x80>>i : 1<<i;
			if (a & j) {
				if (some)
					if (pflag) OUTCHR(',');
				if (pflag) printf("r%d", i);
				some++;
E 4
			}
		}
D 4
		if (i == 9)
			if ((opcode ==0) || (opcode == 1) || (opcode ==5))
				context = 1;
		if ((i == 5) && (opcode == 0)) opcxpd = TRUE;
		else opcxpd = FALSE;
		f = getfield(ip,'m',instrc);
		if (f >= 0x1c) ib1 = instget();
		f2 = getfield(ip,'2',instrc);
		if (f2 >= 0x1c) ib2 = instget();
		if (f >= 0) {
		    if ((operand) && (printit)) { OUTCHR(',');
		    } else operand = TRUE;
		    domode(f,ib1,printit);
E 4
I 4
		if (pflag) OUTCHR(']');
		some++;
	}
	if (x & (2|16)) {	/* disp */
		if (some) {
			if (pflag) OUTCHR(',');
		} else
			some++;
		disp = getdisp();
		if (x & 2)
		{
			if (pflag) printf("0x%x", disp);
		} else {
			if (pflag) printf("0x%x", dot + disp);
			/* AIS- if (pflag) psymoff(dot + disp, ISYM, ""); */
E 4
		}
D 4
		if (f2 >= 0) {
		    if ((operand) && (printit)) { OUTCHR(',');
		    } else operand = TRUE;
		    domode(f2,ib2,printit);
		}
		if (displace == TRUE) {
		    if (operand && printit) OUTCHR(',');
		    f = disp();
		    if (printit) {
			if (firstchar <= 'b') typeout(instat+f,"**");
			else if (firstchar == 'c') {
			    ib1 = getdouble(getdouble(findmod(instat)+4)+(f*4));
			    typeout(getdouble((ib1&0xffff)+8) +
				    ext(ib1,31,16),"**");
			}
			else snprint(f);
		    }
			
		}
		if (i == 10) 
			if ((opcode == 2) || (opcode == 3)) {
			    f = instget();
			    if (printit) 
			    printf(",%d,%d",(f >> 5),((f & 0x1f)+1));
			}
		*instlen = ilen + (istart - instat);
		return(TRUE);
		trynext: ;
E 4
	}
D 4
	return(FALSE);
E 4
I 4
	if (x & 4) {	/* short offset,len */
		if (some)
			if (pflag) OUTCHR(',');
		a = egetchar();
		if (pflag) printf("0x%x,0x%x", a>>5, (a&0x1f)+1);
	}
E 4
}

D 3
/*********************************************************
ibackup(addrat)
{
	int newaddr,modf,off,symatch;
	int instlen = 0;
	char symfound[MAXSTRLEN];
	if (autoi(addrat)) {
		newaddr = addrat - 1;
		symatch = lookbyval(newaddr,&off,&modf,symfound);
		if (symatch) {
		    newaddr -= off;
		    while ((newaddr + instlen) < addrat) {
			newaddr += instlen;
			if (disasm(newaddr,&instlen,FALSE)) {
			} else return(addrat);
		    }
		    return(newaddr);
		}
		
E 3
D 4

D 3
	} 
	return(addrat);
}

char *regstr(regnum)
int regnum;
{
char *preg = '\0';
	if (regnum >= 0) {
		printf("can't print this register- bug\r\n");
	} else {
		if (regnum > SPSR) {
			preg = reg2tab[0 - (regnum - SR0)].regname;
		} else if (regnum > SBPR0) {
			preg = reg3tab[0 - (regnum - SPSR)].regname;
		} else if (regnum >= SINTB) {
			preg = reg4tab[0 - (regnum - SBPR0)].regname;
		} else if (regnum == FSR) {
			preg = reg3tab[7].regname;
		} else if ((regnum >= F7) && (regnum <= F0)) {
			preg = reg2tab[11 + (F0 - regnum)].regname;
		} else {
		    printf("can't print this register- bug\r\n");
		}
	}
	return(preg);
}

tracestack(fpat,pcfrom,modin,doargs)
int fpat,pcfrom,modin;
{
	int pcreturn,fpnext,modf,off,symatch;
	int instreturn,args,arg,i = 0;
	char symfound[MAXSTRLEN];
	symatch = lookbyval(pcfrom,&off,&modf,symfound);
	if ((symatch == FALSE) || (modf != modin)) return;
	printf("%s",symfound);
	if (off) {
		OUTCHR('+');
		snprint(off);
	}
	OUTCHR('(');
	pcreturn = getdouble(fpat+4);
	if (doargs) {
		instreturn = getdouble(pcreturn);
		if ((instreturn & 0xffff) == 0xa57c) {
			args = 0 - ((instreturn >> 16) | 0xffffff00);
			while (args > 0) {
				arg = getdouble(fpat+12+i);
				typeout(arg,"***");
				i += 4;
				args -= 4;
				if (args > 0) OUTCHR(',');

			}
		}
	}
	printf(")\r\n");
	fpnext = getdouble(fpat);
	if (fpcheck(fpnext))
		tracestack(fpnext,pcreturn,(getdouble(fpat+8) & 0xffff),doargs);

}

skipinst()
{
int instlen, thepc;
	thepc = getreg(SPC);
	if (disasm(thepc,&instlen,FALSE)) {
		setreg(SPC,(thepc + instlen));
	} else {
		printf("\r\ncan not skip this instruction\r\n");
	}
	showspot();
}
******************************************************************/


E 3
/*
 * Return the ptr in sp at which the character c appears;
 * NULL if not found
 */

#define	NULL	0

    static
index(sp, c)
register char *sp, c;
E 4
I 4
do_ss(x)
E 4
{
D 4
	do {
		if (*sp == c)
			return((int)sp);
	} while (*sp++);
	return(NULL);
E 4
I 4
	if (pflag) printf(sname[x]);
E 4
}

D 4
    static
getmemb(addr,len,buf)
int addr, len;
char *buf;
E 4
I 4
do_uwb(x)
E 4
{
D 4
	register int i;
E 4
I 4
	prbits(x,"bwu");
}
E 4

D 4
	for(i=0;i<len;i++)
		buf[i] = mrdbyte((addr+i), mapping);
E 4
I 4
do_xx(x)
{
	prbits(x,"ifmc");
E 4
}

D 3
    static
E 3
D 4
getdouble(addr)
int addr;
E 4
I 4
prbits(x,str)
register int x;
register char *str;
E 4
{
D 4
	return(mrdquad(addr, mapping));
E 4
I 4
	register int i, some;

	some = 0;
	if (pflag) OUTCHR('[');
	for (i=0; i<4; i++) {
		if (x & (1<<i)) {
			if (some) {
				if (pflag) OUTCHR(',');
			} else
				some++;
			if (pflag) OUTCHR(str[i]);
		}
	}
	if (pflag) OUTCHR(']');
E 4
}

E 1
