[comp.os.minix] PC-AT-386 debugger source 7 of 7

brucee@runx.ips.oz (Bruce Evans) (11/26/88)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 7)."
# Contents:  kernel/db/unasm.c
# Wrapped by sys@besplex on Sat Nov 26 06:00:33 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kernel/db/unasm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/db/unasm.c'\"
else
echo shar: Extracting \"'kernel/db/unasm.c'\" \(24851 characters\)
sed "s/^X//" >'kernel/db/unasm.c' <<'END_OF_FILE'
X/* unasm.c */
X
X#define Ib() outget8()
X#define Iw() outget16()
X
Xtypedef int su8_pt;
Xtypedef int su16_t;
X
X#include "const.h"
X#include "type.h"
X#include "var.h"
X#include "/usr/include/a.out.h"		/* full pathname to get right one! */
X
X#define LINDIRECT '['
X#define RINDIRECT ']'
X
X#define BASE_MASK 0x07
X#define INDEX_MASK 0x38
X#define INDEX_SHIFT 3
X#define MOD_MASK 0xC0       /* mod reg r/m  is  mmrrr/// */
X# define REG_MOD 0xC0
X# define MEM0_MOD 0x00
X# define MEM1_MOD 0x40
X# define MEM2_MOD 0x80
X#define REG_MASK 0x38
X#define REG_SHIFT 3
X#define RM_MASK 0x07
X#define SREG_MASK 0x38
X#define SREG_SHIFT 3
X#define SS_MASK 0xC0
X#define SS_SHIFT 6
X
X#define SIGNBIT 0x02        /* opcode bits xxxxxxsw for immediates */
X#define WORDBIT 0x01
X#define TOREGBIT 0x02       /* opcode bit for non-immediates */
X
X#define MAX_SIGNED_CHAR 0x7F  /* will assume 2's complement */
X#define MAX_UNSIGNED_CHAR 0xFF
X
XFORWARD void i_00_to_3f();
XFORWARD void i_40_to_5f();
XFORWARD void i_60_to_6f();
XFORWARD void i_70_to_7f();
XFORWARD void i_80();
XFORWARD void i_88();
XFORWARD void i_90();
XFORWARD void i_98();
XFORWARD void i_a0();;
XFORWARD void i_a8();
XFORWARD void i_b0();
XFORWARD void i_b8();
XFORWARD void i_c0();
XFORWARD void i_c8();;
XFORWARD void i_d0();
XFORWARD void i_d8();;
XFORWARD void i_e0();
XFORWARD void i_e8();
XFORWARD void i_f0();
XFORWARD void i_f8();
X
XPRIVATE pfv_t optable[] =
X{
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_00_to_3f,
X	i_40_to_5f,
X	i_40_to_5f,
X	i_40_to_5f,
X	i_40_to_5f,
X	i_60_to_6f,
X	i_60_to_6f,
X	i_70_to_7f,
X	i_70_to_7f,
X	i_80,
X	i_88,
X	i_90,
X	i_98,
X	i_a0,
X	i_a8,
X	i_b0,
X	i_b8,
X	i_c0,
X	i_c8,
X	i_d0,
X	i_d8,
X	i_e0,
X	i_e8,
X	i_f0,
X	i_f8
X};
X
XPRIVATE char bttab[] = "bt\t";
XPRIVATE char btctab[] = "btc\t";
XPRIVATE char btrtab[] = "btr\t";
XPRIVATE char btstab[] = "bts\t";
XPRIVATE char calltab[] = "call\t";
XPRIVATE char dectab[] = "dec\t";
XPRIVATE char empty[] = "";
X
XPRIVATE char f2xm1[] = "f2xm1";
XPRIVATE char fabs[] = "fabs";
XPRIVATE char fadd[] = "fadd";
XPRIVATE char faddp[] = "faddp";
XPRIVATE char fbld[] = "fbld";
XPRIVATE char fbstp[] = "fbstp";
XPRIVATE char fchs[] = "fchs";
XPRIVATE char fclex[] = "fclex";
XPRIVATE char fcom[] = "fcom";
XPRIVATE char fcomp[] = "fcomp";
XPRIVATE char fdecstp[] = "fdecstp";
XPRIVATE char fdisi[] = "fdisi";
XPRIVATE char fdiv[] = "fdiv";
XPRIVATE char fdivp[] = "fdivp";
XPRIVATE char fdivr[] = "fdivr";
XPRIVATE char fdivrp[] = "fdivrp";
XPRIVATE char feni[] = "feni";
XPRIVATE char ffree[] = "ffree";
XPRIVATE char fiadd[] = "fiadd";
XPRIVATE char ficom[] = "ficom";
XPRIVATE char ficomp[] = "ficomp";
XPRIVATE char fidiv[] = "fidiv";
XPRIVATE char fidivr[] = "fidivr";
XPRIVATE char fild[] = "fild";
XPRIVATE char fimul[] = "fimul";
XPRIVATE char fincstp[] = "fincstp";
XPRIVATE char finit[] = "finit";
XPRIVATE char fist[] = "fist";
XPRIVATE char fistp[] = "fistp";
XPRIVATE char fisub[] = "fisub";
XPRIVATE char fisubr[] = "fisubr";
XPRIVATE char fld[] = "fld";
XPRIVATE char fld1[] = "fld1";
XPRIVATE char fldcw[] = "fldcw";
XPRIVATE char fldenv[] = "fldenv";
XPRIVATE char fldl2e[] = "fldl2e";
XPRIVATE char fldl2t[] = "fldl2t";
XPRIVATE char fldlg2[] = "fldlg2";
XPRIVATE char fldln2[] = "fldln2";
XPRIVATE char fldpi[] = "fldpi";
XPRIVATE char fldz[] = "fldz";
XPRIVATE char fmul[] = "fmul";
XPRIVATE char fmulp[] = "fmulp";
XPRIVATE char fnop[] = "fnop";
XPRIVATE char fpatan[] = "fpatan";
XPRIVATE char fprem[] = "fprem";
XPRIVATE char fptan[] = "fptan";
XPRIVATE char frndint[] = "frndint";
XPRIVATE char frstor[] = "frstor";
XPRIVATE char fsave[] = "fsave";
XPRIVATE char fscale[] = "fscale";
XPRIVATE char fsqrt[] = "fsqrt";
XPRIVATE char fst[] = "fst";
XPRIVATE char fstcw[] = "fstcw";
XPRIVATE char fstenv[] = "fstenv";
XPRIVATE char fstp[] = "fstp";
XPRIVATE char fstsw[] = "fstsw";
XPRIVATE char fsub[] = "fsub";
XPRIVATE char fsubp[] = "fsubp";
XPRIVATE char fsubr[] = "fsubr";
XPRIVATE char fsubrp[] = "fsubrp";
XPRIVATE char ftst[] = "ftst";
XPRIVATE char fxam[] = "fxam";
XPRIVATE char fxch[] = "fxch";
XPRIVATE char fxtract[] = "fxtract";
XPRIVATE char fyl2x[] = "fyl2x";
XPRIVATE char fyl2xp1[] = "fyl2xp1";
X
XPRIVATE char fishy[] = "???";
XPRIVATE char fishytab[] = "???\t";
XPRIVATE char imultab[] = "imul\t";
XPRIVATE char intab[] = "in\t";
XPRIVATE char inctab[] = "inc\t";
XPRIVATE char jmptab[] = "jmp\t";
XPRIVATE char movtab[] = "mov\t";
XPRIVATE char movsxtab[] = "movsx\t";
XPRIVATE char movzxtab[] = "movzx\t";
XPRIVATE char pushtab[] = "push\t";
XPRIVATE char s_outtab[] = "out\t";
XPRIVATE char shldtab[] = "shld\t";
XPRIVATE char shrdtab[] = "shrd\t";
XPRIVATE char testtab[] = "test\t";
XPRIVATE char xchgtab[] = "xchg\t";
X
XPRIVATE char *genreg[] =
X{
X	"al",	"cl",	"dl",	"bl",
X	"ah",	"ch",	"dh",	"bh",
X	"ax",	"cx",	"dx",	"bx",
X	"sp",	"bp",	"si",	"di",
X	"eax",	"ecx",	"edx",	"ebx",
X	"esp",	"ebp",	"esi",	"edi"
X};
XPRIVATE char *segreg[] =
X{
X	"es",	"cs",	"ss",	"ds",
X	"fs",	"gs",	"?s",	"?s",
X};
XPRIVATE char *indreg[] =
X{
X	"bx+si",	"bx+di",	"bp+si",	"bp+di",
X	"si",	"di",	"bp",	"bx",
X};
X
XPRIVATE char *str_00_to_3f[] =
X{
X	/* index by (opcode >> 3) & 7 */
X	"add",	"or",	"adc",	"sbb",
X	"and",	"sub",	"xor",	"cmp"
X};
XPRIVATE char *sstr_00_to_3f[] =
X{
X	/* index ((opc>>2) & 0xE) + (opc & 7) - 6 */
X	"push\tes",	"pop\tes",	"push\tcs",	"pop\tcs",
X	"push\tss",	"pop\tss",	"push\tds",	"pop\tds",
X	"es:",	"daa",	"cs:",	"das",
X	"ss:",	"aaa",	"ds:",	"aas"
X};
XPRIVATE char *sstr_0f[] =
X{
X	"push\tfs",	"pop\tfs",	fishy,	bttab,
X	shldtab,	shldtab,	fishy,	fishy,
X	"push\tgs",	"pop\tgs",	fishy,	btstab,
X	shrdtab,	shrdtab,	fishy,	imultab,
X	fishy,	fishy,	"lss\t",	btrtab,
X	"lfs\t",	"lgs\t",	movzxtab,	movzxtab,
X	fishy,	fishy,	empty,	btctab,
X	"bsf\t",	"bsr\t",	movsxtab,	movsxtab
X};
XPRIVATE char *ssstr_0f[] =
X{
X	"sldt\t",	"str\t",	"lldt\t",	"ltr\t",
X	"verr\t",	"verw\t", fishy, fishy,
X	"sgdt\t",	"sidt\t",	"lgdt\t",	"lidt\t",
X	"smsw\t",	fishy, "lmsw\t", fishy,
X	fishy,	fishy, fishy,	fishy,
X	bttab,	btstab,	btrtab,	btctab
X};
XPRIVATE char *str_40_to_5f[] =
X{
X	/* index by (opcode >> 3) & 3 */
X	inctab,	dectab,	pushtab,	"pop\t"
X};
XPRIVATE char *str_60_to_6f[] =
X{
X	"pusha",	"popa",	"bound\t",	"arpl\t",
X	"fs:",	"gs:",	"os:",	"as:",
X	pushtab,	imultab,	pushtab,	imultab,
X	"insb",	"insw",	"outsb",	"outsw"
X};
XPRIVATE char *str_flags[] =
X{
X	/* opcodes 0x70 to 0x7F, and 0x0F80 to 0x0F9F */
X	"o",	"no",	"b",	"nb",
X	"z",	"nz",	"be",	"a",
X	"s",	"ns",	"pe",	"po",
X	"l",	"ge",	"le",	"g"
X};
XPRIVATE char *str_98[] =
X{
X	"cbw",	"cwd",	calltab,	"wait",
X	"pushf",	"popf",	"sahf",	"lahf"
X};
XPRIVATE char *str_a0[] =
X{
X	movtab,	movtab,	movtab,	movtab,
X	"movsb",	"movsw",	"cmpsb",	"cmpsw"
X};
XPRIVATE char *str_a8[] =
X{
X	testtab,	testtab,	"stosb",	"stosw",
X	"lodsb",	"lodsw",	"scasb",	"scasw"
X};
XPRIVATE char *str_c0[] = 
X{
X	empty,	empty,	"ret\t",	"ret",
X	"les\t",	"lds\t",	movtab,	movtab
X};
XPRIVATE char *str_c8[] =
X{
X	"enter\t",	"leave",	"retf\t",	"retf",
X	"int\t3",	"int\t",	"into",	"iret"
X};
XPRIVATE char *str_d0[] =
X{
X	"aam",	"aad",	"db\td6",	"xlat"
X};
XPRIVATE char *sstr_d0[] =
X{
X	"rol",	"ror",	"rcl",	"rcr",
X	"shl",	"shr",	fishy,	"sar"
X};
XPRIVATE char *str_d8[] =
X{
X	fadd,	fmul,	fcom,	fcomp,
X	fsub,	fsubr,	fdiv,	fdivr,
X	fld,	NULL,	fst,	fstp,
X	fldenv,	fldcw,	fstenv,	fstcw,
X	fiadd,	fimul,	ficom,	ficomp,
X	fisub,	fisubr,	fidiv,	fidivr,
X	fild,	NULL,	fist,	fistp,
X	NULL,	fld,	NULL,	fstp,
X	fadd,	fmul,	fcom,	fcomp,
X	fsub,	fsubr,	fdiv,	fdivr,
X	fld,	NULL,	fst,	fstp,
X	frstor,	NULL,	fsave,	fstsw,
X	fiadd,	fimul,	ficom,	ficomp,
X	fisub,	fisubr,	fidiv,	fidivr,
X	fild,	NULL,	fist,	fistp,
X	fbld,	fild,	fbstp,	fistp
X};
XPRIVATE char *str1_d8[] =
X{
X	fadd,	fmul,	fcom,	fcomp,
X	fsub,	fsubr,	fdiv,	fdivr,
X	fld,	fxch,	empty,	fstp,
X	empty,	empty,	empty,	empty,
X	NULL,	NULL,	NULL,	NULL,
X	NULL,	NULL,	NULL,	NULL,
X	NULL,	NULL,	NULL,	NULL,
X	empty,	NULL,	NULL,	NULL,
X	fadd,	fmul,	fcom,	fcomp,
X	fsubr,	fsub,	fdivr,	fdiv,
X	ffree,	fxch,	fst,	fstp,
X	NULL,	NULL,	NULL,	NULL,
X	faddp,	fmulp,	fcomp,	empty,
X	fsubrp,	fsubp,	fdivrp,	fdivp,
X	ffree,	fxch,	fst,	fstp,
X	NULL,	NULL,	NULL,	NULL,
X};
XPRIVATE char *sstr1_d8[] =
X{
X	fnop,	NULL,	NULL,	NULL,
X	NULL,	NULL,	NULL,	NULL,
X};
XPRIVATE char *sstr2_d8[] =
X{
X	fchs,	fabs,	empty,	empty,
X	ftst,	fxam,	empty,	empty,
X	fld1,	fldl2t,	fldl2e,	fldpi,
X	fldlg2,	fldln2,	fldz,	empty,
X	f2xm1,	fyl2x,	fptan,	fpatan,
X	fxtract,	empty,	fdecstp,	fincstp,
X	fprem,	fyl2xp1,	fsqrt,	empty,
X	frndint,	fscale,	empty,	empty,
X};
XPRIVATE char *sstr3_d8[] =
X{
X	feni,	fdisi,	fclex,	finit,
X	NULL,	NULL,	NULL,	NULL,
X};
XPRIVATE char *str_e0[] =
X{
X	"loopnz\t",	"loopz\t",	"loop\t",	"jcxz\t",
X	intab,	intab,	s_outtab,	s_outtab
X};
XPRIVATE char *str_e8[] =
X{
X	calltab,	jmptab,	jmptab,	jmptab,
X	intab,	intab,	s_outtab,	s_outtab
X};
XPRIVATE char *str_f0[] =
X{
X	"lock\t",	"db\tf1",	"repnz\t",	"repz\t",
X	"hlt",	"cmc",
X	/* other 2 from sstr_f0 */
X};
XPRIVATE char *sstr_f0[] =
X{
X	testtab,	fishy,	"not\t",	"neg\t",
X	"mul\t",	imultab,	"div\t",	"idiv\t"
X};
XPRIVATE char *str_f8[] =
X{
X	"clc",	"stc",	"cli",	"sti",
X	"cld",	"std",
X	/* other 2 from sstr_f8 */
X};
XPRIVATE char *sstr_f8[] =
X{
X	inctab,	dectab,	calltab,	"call\tfar ",
X	jmptab,	"jmp\tfar ",	pushtab, fishytab
X};
X
XPRIVATE int data_seg;          /* data segment (munged name for asld) */
XPRIVATE count_t hasize;        /* half address size in bits */
XPRIVATE count_t hdefsize;
XPRIVATE count_t hosize;        /* half operand size in bits */
X                               /* for easy index into reg tables */
XPRIVATE opcode_pt modregrm;
XPRIVATE offset_t offtable[2];
XPRIVATE offset_t *offptr;
XPRIVATE offset_t *off1ptr;
X
XPRIVATE su8_pt get8s()
X{
X	u8_pt got;
X
X	if ( (got = get8()) > MAX_SIGNED_CHAR )
X		got -= (MAX_UNSIGNED_CHAR + 1);
X	return got;
X}
X
XPRIVATE offset_t getasize()
X{
X	if ( hasize == 16 )
X		return get32();
X	return get16();
X}
X
XPRIVATE void getmodregrm()
X{
X	modregrm = get8();
X}
X
XPRIVATE void i_00_to_3f( opc )
Xopcode_pt opc;
X{
X	opcode_pt sub;
X
X	if ( opc == 15 )
X		pagef();
X	else if ( (sub = opc & 7) >= 6 )
X	{
X		outustr( (sstr_00_to_3f - 6)[((opc >> 2) & 0xE) + sub] );
X		if ( !(opc & 1) )
X			data_seg = opc;	
X	}
X	else
X	{
X		oututstr( str_00_to_3f[(opc >> 3) & 7] );
X		if ( sub == 4 )
X		{
X			outustr( genreg[0] );
X			outcomma();
X			Ib();
X		}
X		else if ( sub == 5 )
X		{
X			outax();
X			outcomma();
X			Iv();
X		}
X		else
X			outad( sub );
X	}
X}
X
XPRIVATE void i_40_to_5f( opc )
Xopcode_pt opc;
X{
X	outustr( str_40_to_5f[(opc >> 3) & 3] );
X	outustr( genreg[hosize + (opc & 7)] );
X}
X
XPRIVATE void i_60_to_6f( opc )
Xopcode_pt opc;
X{
X	/* for 386, some for 286 */
X
X	outustr( (str_60_to_6f - 0x60)[opc] );
X	switch( opc )
X	{
X	case 0x62: GvMa(); break;
X	case 0x63: EwRw(); break;
X	case 0x64:
X	case 0x65: data_seg = opc; break;
X	case 0x66: hosize = (16 + 8) - hdefsize; break;
X	case 0x67: hasize = (16 + 8) - hdefsize; break;
X	case 0x68: outword();Iv(); break;
X	case 0x6A: outword(); outimmed( SIGNBIT | WORDBIT ); break;
X	case 0x69:
X		/* IMUL /r iw-id like MOV iw */
X	case 0x6B:
X		/* IMUL /r ib like MOV ib but target is w not b */
X		getmodregrm();
X		outbwptr( opc );  /* like C6, C7 but this differs */
X		outea( opc );
X		outcomma();
X		if ( opc == 0x69 )
X			/* also differs from C6, C7 */
X			Iv();
X		else
X			outimmed( SIGNBIT | WORDBIT );
X		if ( modregrm & REG_MASK )
X			/* not completely decoded (like DEBUG) */
X			outfishy();
X		break;
X	}
X}
X
XPRIVATE void i_70_to_7f( opc )
Xopcode_pt opc;
X{
X	outustr( "j" );
X	oututstr( (str_flags - 0x70)[opc] );
X	Jb();
X}
X
XPRIVATE void i_80( opc )
Xopcode_pt opc;
X{
X	opcode_pt sub;
X
X	if ( opc >= 4 )
X	{
X		outustr( opc >=6 ? xchgtab : testtab );
X		outad( opc );
X	}
X	else
X	{
X		getmodregrm();
X		oututstr( str_00_to_3f[sub = (modregrm & REG_MASK) >> REG_SHIFT] );
X		outbwptr( opc );
X		outea( opc );
X		outcomma();
X		outimmed( opc );
X		if ( opc & SIGNBIT && (sub == 1 || sub == 4 || sub == 6) )
X			/*
X				and, or and xor are technically illegal with sign extension
X				but make sense and are produced by MASM!
X			*/
X			outfishy();
X	}
X}
X
XPRIVATE void i_88( opc )
Xopcode_pt opc;
X{
X	if ( opc < 4 )
X	{
X		outustr( movtab );
X		outad( opc );
X	}
X	else if ( opc == 5 )
X	{
X		oututstr( "lea" );
X		GvM();
X	}
X	else if ( opc == 7 )
X	{
X		oututstr( "pop" );
X		getmodregrm();
X		outwptr();
X		Ev();
X		if ( modregrm & REG_MASK )
X			outfishy();
X	}
X	else
X	{
X		getmodregrm();
X		outustr( movtab );
X		if ( !(opc & TOREGBIT) )
X		{
X			Ev();
X			outcomma();
X		}
X		outustr( segreg[(modregrm & SREG_MASK) >> SREG_SHIFT] );
X		if ( opc & TOREGBIT )
X		{
X			outcomma();
X			Ev();
X		}
X	}
X}
X
XPRIVATE void i_90( opc )
Xopcode_pt opc;
X{
X	if ( opc == 0 )
X		outustr("nop");
X	else
X	{
X		outustr( xchgtab );
X		outax();
X		outcomma();
X		outustr( genreg[hosize + opc] );
X	}
X}
X
XPRIVATE void i_98( opc )
Xopcode_pt opc;
X{
X	outustr( str_98[opc] );
X	if ( opc == 2 )
X		outsegpc();
X}
X
XPRIVATE void i_a0( opc )
Xopcode_pt opc;
X{
X	outustr( str_a0[opc] );
X	if ( opc < 4 )
X	{
X		/* fake mod == MEM0_MOD, reg = 0 (ax) and rm == 6 or 5 ([d32] or [d16]) */
X		if ( hasize == 16 )
X			modregrm = 5;
X		else
X			modregrm = 6;
X		outad1( opc ^ TOREGBIT );
X	}
X}
X
XPRIVATE void i_a8( opc )
Xopcode_pt opc;
X{
X	outustr( str_a8[opc] );
X	if ( opc < 2 )
X	{
X		outalorx( opc );
X		outcomma();
X		outimmed( opc );
X	}
X}
X
XPRIVATE void i_b0( opc )
Xopcode_pt opc;
X{
X	outustr( movtab );
X	outustr( genreg[opc] );
X	outcomma();
X	Ib();
X}
X
XPRIVATE void i_b8( opc )
Xopcode_pt opc;
X{
X	outustr( movtab );
X	outustr( genreg[hosize + opc] );
X	outcomma();
X	Iv();
X}
X
XPRIVATE void i_c0( opc )
Xopcode_pt opc;
X{
X	outustr( str_c0[opc] );
X	if ( opc >= 6 )
X	{
X		getmodregrm();
X		outbwptr( opc );
X		outea( opc );
X		outcomma();
X		outimmed( opc & WORDBIT );
X		if ( modregrm & REG_MASK )
X			/* not completely decoded (like DEBUG) */
X			outfishy();
X	}
X	else if ( opc >= 4 )
X		GvMp();
X	else if ( opc == 2 )
X		Iv();
X	else if ( opc < 2 )
X		shift( opc );
X}
X
XPRIVATE void i_c8( opc )
Xopcode_pt opc;
X{
X	outustr( str_c8[opc] );
X	if ( opc == 0 )
X	{
X		Iw();
X		outcomma();
X		Ib();
X	}
X	if ( opc == 2 )
X		Iv();
X	else if ( opc == 5 )
X		Ib();
X}
X
XPRIVATE void i_d0( opc )
Xopcode_pt opc;
X{
X	opcode_pt aabyte;
X
X	if ( opc < 4 )
X		shift( opc | 0xD0 );
X	else
X	{
X		outustr( (str_d0 - 4)[opc] );
X		if ( opc < 6 && (aabyte = get8()) != 0xA )
X		{
X			outtab();
X			outh8( aabyte );
X			outfishy();
X		}
X	}
X}
X
XPRIVATE void i_d8( opc )
Xopcode_pt opc;
X{
X	opcode_pt esc;
X	char *str;
X	opcode_pt sub;
X
X	getmodregrm();
X	sub = (modregrm & REG_MASK) >> REG_SHIFT;
X	esc = (opc << 3) | sub;
X	if ( (str = ((modregrm & MOD_MASK) == REG_MOD ? str1_d8 : str_d8)[esc])
X		 == NULL )
X	{
Xescape:
X		oututstr( "esc" );
X		outh8( esc );
X		outcomma();
X		outea( opc );
X		return;
X	}
X	outustr( str );
X	if ( (modregrm & MOD_MASK) == REG_MOD )
X	{
X		if ( opc == 0 )
X		{
X			if ( sub == 2 || sub == 3 )
X				outtab();
X			else
X				outustr( "\tst," );
X			outf1();
X		}
X		else if ( opc == 1 )
X		{
X			if ( *str == 0 )
X			{
X				if ( sub == 2 )
X				{
X					str = sstr1_d8[modregrm & 7];
X					if ( str == NULL )
X						goto escape;
X				}
X				else
X					str = sstr2_d8[modregrm & 0x1F];
X				outustr( str );
X			}
X			else
X			{
X				outtab();
X				outf1();
X			}
X		}
X		else if ( opc < 4 )
X		{
X			if ( *str == 0 )
X			{
X				str = sstr3_d8[modregrm & 7];
X				if ( str == NULL )
X					goto escape;
X				outustr( str );
X			}
X			else
X				outea( opc );
X		}
X		else if ( !(opc & 1) )
X		{
X			if ( *str == 0 )
X			{
X				/* fcompp only */
X				if ( (modregrm & RM_MASK) != 1 )
X					goto escape;
X				outustr( "fcompp\tst(1)" );
X			}
X			else
X			{
X				outtab();
X				outf1();
X				if ( sub != 2 && sub != 3 )
X					outustr( ",st" );
X			}
X		}
X		else
X		{
X			if ( sub < 4 )
X			{
X				outtab();
X				outf1();
X			}
X			else
X				outea( opc );
X		}
X	}
X	else
X	{
X		outtab();
X		if ( (esc & 0xC) == 0xC )
X		{
X			if ( esc & 0x10 )
X			{
X				if ( esc == 0x3D || esc == 0x3F )
X				{
X					outustr( "q" );
X					outwptr();
X				}
X				else
X				{
X					outustr( "t" );
X					outbptr();
X				}
X			}
X			/* else environment stuff */
X		}
X		else
X		{
X			if ( opc < 4 )
X				outustr( "d" );
X			else if ( opc < 6 )
X				outustr( "q" );
X			outwptr();
X		}
X		outea( opc );
X	}
X}
X
XPRIVATE void i_e0( opc )
Xopcode_pt opc;
X{
X	outustr( str_e0[opc] );
X	if ( opc < 4 )
X		Jb();
X	else if ( opc < 6 )
X	{
X		outalorx( opc );
X		outcomma();
X		Ib();
X	}
X	else
X	{
X		Ib();
X		outcomma();
X		outalorx( opc );
X	}
X}
X
XPRIVATE void i_e8( opc )
Xopcode_pt opc;
X{
X	outustr( str_e8[opc] );
X	if ( opc < 2 )
X		Jv();
X	else if ( opc == 2 )
X		outsegpc();
X	else if ( opc == 3 )
X		Jb();
X	else
X	{
X		if ( opc & TOREGBIT )
X		{
X			outustr( genreg[10] );
X			outcomma();
X			outalorx( opc );
X		}
X		else
X		{
X			outalorx( opc );
X			outcomma();
X			outustr( genreg[10] );
X		}
X	}
X}
X
XPRIVATE void i_f0( opc )
Xopcode_pt opc;
X{
X	opcode_pt sub;
X
X	if ( opc < 6 )
X		outustr( str_f0[opc] );
X	else
X	{
X		getmodregrm();
X		sub = (modregrm & REG_MASK) >> REG_SHIFT;
X		outustr( sstr_f0[sub] );
X		outbwptr( opc );
X		outea( opc );
X		if ( sub == 0 )
X		{
X			outcomma();
X			outimmed( opc & WORDBIT );
X		}
X	}
X}
X
XPRIVATE void i_f8( opc )
Xopcode_pt opc;
X{
X	opcode_pt sub;
X
X	if ( opc < 6 )
X		outustr( str_f8[opc] );
X	else
X	{
X		getmodregrm();
X		sub = (modregrm & REG_MASK) >> REG_SHIFT;
X		if ( opc == 6 && sub >= 2 )
X			outustr( fishytab );
X		else
X			outustr( sstr_f8[sub] );
X		outbwptr( opc );
X		outea( opc );
X	}
X}
X
XPRIVATE void outad( opc )
Xopcode_pt opc;
X{
X	getmodregrm();
X	outad1( opc );
X}
X
XPRIVATE void outad1( opc )
Xopcode_pt opc;
X{
X	if ( !(opc & TOREGBIT) )
X	{
X		outea( opc );
X		outcomma();
X	}
X	if ( opc & WORDBIT )
X		Gv1();
X	else
X		outustr( genreg[(modregrm & REG_MASK) >> REG_SHIFT] );
X	if ( opc & TOREGBIT )
X	{
X		outcomma();
X		outea( opc );
X	}
X}
X
XPRIVATE void outasize( off )
Xoffset_t off;
X{
X	if ( hasize == 16 )
X		outh32( off );
X	else
X		outh16( (u16_t) off );
X}
X
XPRIVATE void outalorx( opc )
Xopcode_pt opc;
X{
X	if ( opc & WORDBIT )
X		outax();
X	else
X		outustr( genreg[0] );
X}
X
XPRIVATE void outax()
X{
X	outustr( genreg[hosize] );
X}
X
XPRIVATE void outbptr()
X{
X	outustr( "byte ptr " );
X}
X
XPRIVATE void outbwptr( opc )
Xopcode_pt opc;
X{
X	if ( (modregrm & MOD_MASK) != REG_MOD )
X	{
X		if ( opc & WORDBIT )
X			outwptr();
X		else
X			outbptr();
X	}
X}
X
XPRIVATE void outea( wordflags )
Xopcode_pt wordflags;
X{
X	reg_pt base;
X	reg_pt index;
X	opcode_pt mod;
X	reg_pt reg;
X	opcode_pt ss;
X	opcode_pt ssindexbase;
X
X	reg = modregrm & RM_MASK;
X	if ( (mod = modregrm & MOD_MASK) == REG_MOD )
X		outustr( genreg[hosize * (wordflags & WORDBIT) + reg] );
X	else
X	{
X		outbyte( LINDIRECT );
X		if ( hasize == 16 )
X		{
X			if ( reg == 4 )
X			{
X				base = (ssindexbase = get8()) & BASE_MASK;
X				if ( mod == MEM0_MOD && base == 5 )
X					outgetadr();
X				else
X					outustr( (genreg + 16)[base] );
X				ss = (ssindexbase & SS_MASK) >> SS_SHIFT;
X				if ( (index = (ssindexbase & INDEX_MASK) >> INDEX_SHIFT) != 4 )
X				{
X					outbyte( '+' );
X					outustr( (genreg + 16)[index] );
X					outstr( "\0\0\0*2\0*4\0*8\0" + (3 * ss) );
X				}
X			}
X			else if ( mod == MEM0_MOD && reg == 5 )
X				outgetadr();
X			else
X				outustr( (genreg + 16)[reg] );
X		}
X		else if ( mod == MEM0_MOD && reg == 6 )
X			outgetadr();
X		else
X			outustr( indreg[reg] );
X		if ( mod == MEM1_MOD )
X			/* fake sign extension to get +- */
X			outimmed( SIGNBIT | WORDBIT );
X		else if ( mod == MEM2_MOD )
X		{
X			outbyte( '+' );
X			outgetadr();
X		}
X		outbyte( RINDIRECT );
X		if ( hasize == 16 && reg == 4 && index == 4 && ss != 0 )
X			outfishy();
X	}
X}
X
XPRIVATE void outf1()
X{
X	outustr( "st(" );
X	outbyte( (int) ((modregrm & RM_MASK) + '0') );
X	outbyte( ')' );
X}
X
XPRIVATE void outfishy()
X{
X	outustr( "\t???" );
X}
X
XPRIVATE void outgetadr()
X{
X	offset_t off;
X	struct nlist *sp;
X
X	off = getasize();
X	if ( (sp = findsval( off, data_seg )) != NULL )
X	{
X		outsym( sp, off );
X		*offptr++ = off;
X	}
X	else
X		outasize( off );
X}
X
XPRIVATE void outimmed( signwordflag )
Xopcode_pt signwordflag;
X{
X	su8_pt byte;
X
X	if ( signwordflag & WORDBIT )
X	{
X		if ( signwordflag & SIGNBIT )
X		{
X			if ( (byte = get8s()) < 0 )
X			{
X				outbyte( '-' );
X				byte = -byte;
X			}
X			else
X				outbyte( '+' );
X			outh8( (u8_pt) byte );
X		}
X		else
X			Iv();
X	}
X	else
X		Ib();
X}
X
XPRIVATE void outpc( pc )
Xoffset_t pc;
X{
X	struct nlist *sp;
X
X	if ( hasize == 8 )
X		pc = (u16_t) pc;
X	if ( (sp = findsval( pc, CSEG )) != NULL )
X	{
X		outsym( sp, pc );
X		*offptr++ = pc;
X	}
X	else if ( hasize == 16 )
X		outh32( pc );
X	else
X		outh16( (u16_t) pc );
X}
X
XPRIVATE void outsegpc()
X{
X	segment_t oldseg;
X	offset_t pc;
X
X	pc = getasize();
X	oldseg = uptr.seg;
X	outh16( uptr.seg = get16() );  /* fake segment for lookup of pc */
X	outcolon();
X	outpc( pc );
X	uptr.seg = oldseg;
X}
X
XPRIVATE void oututstr( s )
Xchar *s;
X{
X	outustr( s );
X	outtab();
X}
X
XPRIVATE void outword()
X{
X	outustr( "dword " + ((16 - hosize) >> 3) );
X}
X
XPRIVATE void outwptr()
X{
X	outword();
X	outustr( "ptr " );
X}
X
XPRIVATE bool_pt pagef()
X{
X	opcode_pt opc;
X	opcode_pt reg;
X	bool_t regbad;
X
X	if ( (opc = get8()) <= 1 || opc == 0xBA )
X	{
X		if ( opc == 0xBA )
X			opc = 16;
X		else
X			opc *= 8;
X		getmodregrm();
X		outustr( ssstr_0f[opc += (modregrm & REG_MASK) >> REG_SHIFT] );
X		if ( opc < 6 || opc == 12 || opc == 14 )
X			Ew();
X		else if ( opc >= 8 && opc < 13 )
X			Ms();
X		else if ( opc >= 20 )
X		{
X			outbwptr( WORDBIT );
X			EvIb();
X		}
X	}
X	else if ( opc < 4 )
X	{
X		oututstr( "lar\0lsl" + 4 * (opc - 2) );
X		GvEw();
X	}
X	else if ( opc == 6 )
X		outustr( "clts" );
X	else if ( opc < 0x20 )
X		outstr( fishy );
X	else if ( opc < 0x27 && opc != 0x25 )
X	{
X		outustr( movtab );
X		getmodregrm();
X		reg = (modregrm & REG_MASK) >> REG_SHIFT;
X		hosize = 16;
X		if ( !(opc & TOREGBIT) )
X		{
X			Ev();				/* Rd() since hosize is 16 */
X			outcomma();
X		}
X		regbad = FALSE;
X		if ( opc & 1 )
X		{
X			outustr( "dr" );
X			if ( reg == 4 || reg == 5 )
X				regbad = TRUE;
X		}
X		else if ( opc < 0x24 )
X		{
X			outustr( "cr" );
X			if ( reg >= 4 || reg == 1 )
X				regbad = TRUE;
X		}
X		else
X		{
X			outustr( "tr" );
X			if ( reg < 6  )
X				regbad = TRUE;
X		}
X		outbyte( (int) (reg + '0') );
X		if ( opc & TOREGBIT )
X		{
X			outcomma();
X			Ev();
X		}
X		if ( regbad || (modregrm & MOD_MASK) != REG_MOD )
X			outfishy();
X	}
X	else if ( opc < 0x80 )
X		outstr( fishy );
X	else if ( opc < 0x90 )
X	{
X		outustr( "j" );
X		oututstr( (str_flags - 0x80)[opc] );
X		Jv();
X	}
X	else if ( opc < 0xA0 )
X	{
X		outustr( "set" );
X		oututstr( (str_flags - 0x90)[opc] );
X		getmodregrm();
X		outbwptr( 0 );
X		Eb();
X	}
X	else if ( opc < 0xC0 )
X	{
X		outustr( (sstr_0f - 0xA0)[opc] );
X		switch( opc )
X		{
X		case 0xA3: case 0xAB: case 0xB3: case 0xBB:
X			EvGv();
X			break;
X		case 0xA4: case 0xAC:
X			EvGv();
X			outcomma();
X			Ib();
X			break;
X		case 0xA5: case 0xAD:
X			EvGv();
X			outcomma();
X			CL();
X			break;
X		case 0xAF: case 0xBC: case 0xBD:
X			GvEv();
X			break;
X		case 0xB2: case 0xB4: case 0xB5:
X			GvMp();
X			break;
X		case 0xB6: case 0xBE:
X			Gv();
X			outcomma();
X			outbwptr( opc );
X			Eb();
X			break;
X		case 0xB7: case 0xBF:
X			Gv();
X			outcomma();
X			hosize = 8;  /* done in Ew(), but too late */
X			outbwptr( opc );
X			Ew();
X			break;
X		}
X	}
X	else
X		outstr( fishy );
X}
X
XPUBLIC bool_pt puti()
X{
X	static bool_t hadprefix;
X	opcode_pt opcode;
X
X	offptr = offtable;
X	opcode = get8();
X	if ( !hadprefix )
X	{
X		data_seg = DSEG;
X		hdefsize = 8;
X		if ( bits32 )
X			hdefsize = 16;
X		hosize =
X		hasize = hdefsize;
X	}
X	(*optable[opcode >> 3]) ( opcode < 0x80 ? opcode: opcode & 7 );
X	if ( offptr > offtable )
X	{
X		if ( stringtab() >= 31 )
X			out2space();
X		else
X			while ( stringtab() < 32 )
X				outtab();
X		outbyte( ';' );
X		for ( off1ptr = offtable; off1ptr < offptr; ++off1ptr )
X		{
X			outspace();
X			outh32( *off1ptr );
X		}
X		offptr = offtable;
X	}
X	if ( (opcode & 0xE7) == 0x26 ||
X	     opcode >= 0x64 && opcode < 0x68 ||
X	     opcode == 0xF0 || opcode == 0xF2 || opcode == 0xF3 )
X		/*
X			not finished instruction for 0x26, 0x2E, 0x36, 0x3E seg overrides
X			and 0x64, 0x65 386 seg overrides
X			and 0x66, 0x67 386 size prefixes
X			and 0xF0 lock, 0xF2 repne, 0xF3 rep
X		*/
X	{
X		hadprefix = TRUE;
X		return FALSE;
X	}
X	hadprefix = FALSE;
X	return TRUE;
X}
X
XPRIVATE void shift( opc )
Xopcode_pt opc;
X{
X	reg_pt reg;
X
X	getmodregrm();
X	reg = (modregrm & REG_MASK) >> REG_SHIFT;
X	oututstr( sstr_d0[reg] );
X	outbwptr( opc );
X	outea( opc );
X	outcomma();
X	if ( opc < 0xD0 )
X		Ib();
X	else if ( opc & 2 )
X		CL();
X	else
X		outbyte( '1' );
X}
X
XPRIVATE void checkmemory()
X{
X	if ( (modregrm & MOD_MASK) == REG_MOD )
X		outfishy();
X}
X
XPRIVATE void CL()
X{
X	outustr( genreg[1] );
X}
X
XPRIVATE void Eb()
X{
X	outea( 0 );
X}
X
XPRIVATE void Ev()
X{
X	outea( WORDBIT );
X}
X
XPRIVATE void EvGv()
X{
X	getmodregrm();
X	Ev();
X	outcomma();
X	Gv1();
X}
X
XPRIVATE void EvIb()
X{
X	Ev();
X	outcomma();
X	Ib();
X}
X
XPRIVATE void Ew()
X{
X	hosize = 8;
X	Ev();
X}
X
XPRIVATE void EwRw()
X{
X	hosize = 8;
X	EvGv();
X}
X
XPRIVATE void Gv()
X{
X	getmodregrm();
X	Gv1();
X}
X
XPRIVATE void Gv1()
X{
X	outustr( genreg[hosize + ((modregrm & REG_MASK) >> REG_SHIFT)] );
X}
X
XPRIVATE void GvEv()
X{
X	Gv();
X	outcomma();
X	Ev();
X}
X
XPRIVATE void GvEw()
X{
X	Gv();
X	outcomma();
X	Ew();
X}
X
XPRIVATE void GvM()
X{
X	GvEv();
X	checkmemory();
X}
X
XPRIVATE void GvMa()
X{
X	GvM();
X}
X
XPRIVATE void GvMp()
X{
X	GvM();
X}
X
XPRIVATE void Iv()
X{
X	if ( hosize == 16 )
X		outh32( get32() );
X	else
X		Iw();
X}
X
XPRIVATE void Jb()
X{
X	offset_t pcjump;
X
X	pcjump = get8s();
X	outpc( pcjump + uptr.off );
X}
X
XPRIVATE void Jv()
X{
X	offset_t pcjump;
X
X	if ( hasize == 16 )
X		pcjump = get32();
X	else
X		pcjump = (su16_t) get16();
X	outpc( pcjump + uptr.off );
X}
X
XPRIVATE void Ms()
X{
X	Ev();
X	checkmemory();
X}
END_OF_FILE
if test 24851 -ne `wc -c <'kernel/db/unasm.c'`; then
    echo shar: \"'kernel/db/unasm.c'\" unpacked with wrong size!
fi
# end of 'kernel/db/unasm.c'
fi
echo shar: End of archive 7 \(of 7\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

Bruce Evans
Internet: brucee@runx.ips.oz.au    UUCP: uunet!runx.ips.oz.au!brucee