[net.sources] 8048/8085 disassembler

pgf@mtung.UUCP (02/13/87)

b

	Well, the requests reached critical mass...  here's my interactive
	disassembler.  It may be buggy, it may not be pretty, it may not
	even be portable, but it's free...  (no makefile, no manpage...)


#-------------cut here (and at the bottom) ----------
# The rest of this file is a shell script which will extract:
# dis.c opc48 opc85
echo extracting - dis.c
cat >dis.c <<'mtung-Fri_Jan_30_11-00-48_EST_1987-'

/* 
    8085/8048 disassembler	Paul Fox, 1982 or so... */
    This disassembler is offered as is, no warranty expressed or implied.
    It is now in the public domain-- think of me as you use it.  :-)

    The code is not beautiful, nor was it ever intended to be.  It 
    does do the job.  I'm not cleaning it up before sending it out 
    because I don't feel like testing it again.  
    
    The idea is that you start with an Intel hex format file, and just 
    dive in and disassemble.  The targets of jumps and calls are 
    automatically turned into symbols of the form "LxNNNN" where NNNN 
    is the hex value of the symbol.  Note that it takes at least two 
    disassemmbly passes to get all the symbols printed as labels, 
    since labels appearing before their reference won't be in the 
    table yet on the first pass.  As you figure out what the code 
    does, you add symbol names and values to the symbol table, and 
    change the names of the "LxNNNN" ones to more meaningful values.  
    Symbols beginning with "DB" and "DE" cause a switch to data dump 
    and opcode dump formats, respectively.  Useful when you discover 
    where all the data was stored in the original code.  

    I'm not sure the 8085 code has been used since I added the 8748 stuff.

*/
#define DIS48	/* define DIS48 or DIS85 for 8048 or 8085 disassembler */

#include <stdio.h>
#define SYMLEN 9
#define NMEMLEN 10
#define SYMTABSIZE 800
#define MEMSIZE 0x2000  /* max size of disassembled program */
#define BYTE 0xff

struct symbol_struct {
    int value;
    char name[SYMLEN];
} symbol[SYMTABSIZE];

struct symbol_struct *sym;

struct opc {
    char nmem[NMEMLEN];
    int operands;
} opcode[] = {

#ifdef DIS48
# include "opc48"
#else
# include "opc85"
#endif

};


int first, last, lastsym;
char byte[MEMSIZE];

main()
{
    char strng1[20], strng2[20], listfile[20];
    char error, filing, opcoding;
    int lowbyte, highbyte, cmnd, addr, const, ans;
    FILE *list_fd;
    struct symbol_struct *getsym();

    error = filing = 0;
    opcoding = 1;
    list_fd = stdout;
    lastsym = -1;

    load_hexfile();
    printf("\n Type 'h' for help...");
    while (cmnd = get_command())
    {
	switch (cmnd)
	{
	    case 'h':
		printf("The available commands are:\n");
		printf("	l - load symbol table\n");
		printf("	s - save symbol table\n");
		printf("	d - disassemble\n");
		printf("	o - toggle disassembly output between stdout and a listfile\n");
		printf("	b - toggle between opcodes and '.byte 0xXX' output\n");
		printf("	r - set range of addresses for disassembly\n");
		printf("	h - this message\n");
		printf("	q - quit\n");
		printf("	v - run vi on a file (useful for editing symbol table)\n");
		break;
	    case 'l':
		load_symtab();
		printf(" %d symbols loaded.\n", lastsym);
		error = 0;
		break;

	    case 'r':
		get_range();
		break;

	    case 'o':
		if (filing) 
		{
		    printf(" Listfile closed.\n");
		    fclose(list_fd);
		}
		filing = !filing;
		if (filing)
		{
		    list_fd = NULL;
		    while (list_fd == NULL)
		    {
			printf("List file name: ");
			scanf(" %s ", listfile);
			list_fd = fopen(listfile, "w");
		    }
		    printf("Listfile %s opened.",listfile);
		}
		else
		    list_fd = stdout;
		break;

	    case 'b':
		if (opcoding)
		{
		    printf("Will now default to data bytes...\n");
		    opcoding = 0;
		}
		else
		{
		    printf("Will now default to opcode nmemonics...\n");
		    opcoding = 1;
		}
		break;

	    case 'd':
		for (addr = first; addr <= last && !error ; addr++)
		{
		    fprintf(list_fd, "\n");
		    sym = getsym(addr);
		    if (sym == NULL || sym->name[0] == '0')
		    {
			fprintf(list_fd, "\t");
		    }
		    else
		    {
			if (sym->name[0] == 'D' && sym->name[1] == 'B')
			    opcoding = 0;
			else if (sym->name[0] == 'D' && sym->name[1] == 'E')
			    opcoding = 1;
			fprintf(list_fd,"%s:\t",sym->name);
		    }
		    if (opcoding)
		    {
			fprintf(list_fd, "%s", opcode[byte[addr] & BYTE].nmem);
			switch( opcode[byte[addr] & BYTE].operands )
			{
			    case 0:
				break;

			    case 1:
#ifdef DIS48
				if ((byte[addr] & 0x0f) == 0x04)
				{	/* then its a "call" or direct "jmp" */
				    highbyte = (byte[addr] & 0xe0) << 3;
				    lowbyte = byte[++addr] & BYTE;
				    const = highbyte + lowbyte;
				    if (sym = getsym(const))
					fprintf(list_fd, "	%s", sym->name);
				    else
				    {
					fprintf(list_fd, "	0x%x", const);
					error = !putsym(const);
				    }
				}
				else if ((byte[addr] & 0x0f) == 0x06 ||
					(byte[addr] & 0x1f) == 0x12)
				{	/* it's a page relative jump */
				    highbyte = (addr & ~0xff); /* this page */
				    lowbyte = byte[++addr] & BYTE;
				    const = highbyte + lowbyte;
				    if (sym = getsym(const))
					fprintf(list_fd, "	%s", sym->name);
				    else
				    {
					fprintf(list_fd, "	0x%x", const);
					error = !putsym(const);
				    }
				    
				}
				else
				{
				    fprintf(list_fd, " 0x%x", 
						byte[ ++addr] & BYTE);
				}
#else
 				fprintf(list_fd, " 0x%x", byte[ ++addr] & BYTE);
#endif
				break;
			    
#ifdef DIS85
			    case 2:
				lowbyte = byte[++addr] & BYTE;
				highbyte = byte[++addr] & BYTE;
				const = highbyte * 256 + lowbyte;
				if (sym = getsym(const))
				    fprintf(list_fd, " %s", sym->name);
				else
				{
				    fprintf(list_fd, " 0x%x", const);
				    error = !putsym(const);
				}
				break;
#endif

			    default:
				fprintf(stderr,"Opcode table error!\n");
			}
		    }
		    else
		    {
			fprintf(list_fd,".byte 0x%x",byte[addr] & BYTE);
		    }
		}
		fprintf(list_fd,"\n");
		break;

	    case 's':
		save_symtab();
		printf(" %d symbols saved.\n", lastsym);
		break;

	    case 'v':
		printf("File to edit (with vi): ");
		scanf( "%s", strng1);
		strcpy(strng2,"vi ");
		strcat(strng2,strng1);
		system(strng2);
		break;

	    case 'q':
		printf("Are you sure you want to quit? ");
		ans = getchar();
		if ( ans == 'y' ) 
		    return;
		break;

	}
	fflush(stdout);
    }
}


load_hexfile()
{
    char hexfile[20];
    FILE *hex_fd;
    int line;		/* Current input line number */
    int bytes;		/* Number of bytes to be read on a line */
    int sum;		/* Checksum of bytes on a line */
    int addr;		/* Address for input data to be loaded into */
    int value;		/* Value of data to be loaded */
    int mode;		/* Mode = 1 means start address is given */
    int i;		/* Scratch variables */
    char c;		/* Character scratch variables */

    hex_fd = NULL;
    while (hex_fd == NULL)
    {
	printf(" Hex file for disassembly: ");
	scanf("%s", hexfile);
	hex_fd = fopen( hexfile, "r" );
	if (hex_fd == NULL)
	    printf("	file %s not found...\n",hexfile);
    }

/* Mike's code. */

    printf("Reading from file %s\n",hexfile);

				/* 
				 * Read data from file.  Find number of bytes
				 * to read from a line, read them, and xor
				 * to get the checksum.  Continue until a
				 * line with a 0 byte count is read.  If the
				 * mode on the last line is 1, read the
				 * start address and put it into the PC.
				 */
    line = 0;
    bytes = 1;
    while (bytes > 0)
    {
	line++;			
	if (fscanf(hex_fd,":%2x%4x%2x",&bytes,&addr,&mode) <= 0) 
	{
	    printf("Improper program format in line %d\n",line);
	    fclose(hex_fd);
	    if (line == 1) first = addr;
	    return;
	}
	if (addr >= (MEMSIZE - bytes))
	{
	    printf("Address %x outside allocated memory.\n", addr);
	    return;
	}
	if (line == 1) first = addr;
	sum = bytes + ((addr/256) & BYTE) + (addr & BYTE) + mode;
	for (i = addr; i < addr + bytes; i++)
	{
	    if (fscanf(hex_fd,"%2x",&value) <= 0)
	    {
		printf("Improper program format in line %d at byte %d\n",line,
							i - addr);
		fclose(hex_fd);
		return;
	    }
	    sum += value;
	    byte[i] = value;
	    last = i;
	}
	if (fscanf(hex_fd,"%2x",&value) <= 0)
	{
	    printf("Improper program format in line %d at byte %d\n",line,
							      i - addr);
	    fclose(hex_fd);
	    return;
	}
	sum += value;
	if (sum & BYTE) 
	{
	    printf("Checksum error in line %d\n",line);
	    fclose(hex_fd);
	    return;
	}
	c = getc(hex_fd);
	while (c != '\n') c = getc(hex_fd);
    }
}

get_command()
{
    char c;
    do {
	putchar('-');
	c = getchar();
    } while (c== '\n');
    while (getchar() != '\n') ;
    return(c);
}

load_symtab()
{
    char symfile[20], symname[20];
    int rtncode, intval;
    FILE *sym_fd;

    sym_fd = NULL;
    while (sym_fd == NULL)
    {
	printf(" Symbol table from file: ");
	scanf("%s", symfile);
	sym_fd = fopen( symfile, "r" );
    }

    lastsym = -1;
    while (( rtncode = fscanf(sym_fd, "0x%x %s\n", &intval, symname)) > 0 )
    {
	lastsym++;
	symbol[lastsym].value = intval;
	strcpy(symbol[lastsym].name, symname);
    }
    if (rtncode != EOF)
	printf("!!! Error reading symbol table from %s", symfile);
    fclose(sym_fd);
}

save_symtab()
{
    char symfile[20];
    int i;
    FILE *sym_fd;

    sym_fd = NULL;
    while (sym_fd == NULL)
    {
	printf(" Symbol table to file: ");
	scanf("%s", symfile);
	sym_fd = fopen( symfile, "w" );
    }
    
    i = 0;
    while ( i <= lastsym)
    {
	fprintf( sym_fd, "0x%x\t%s\n", symbol[i].value, symbol[i].name);
	i++ ;
    }
    fclose(sym_fd);
}

get_range()
{
    printf(" Enter start address (hex): ");
    scanf("%x", &first);
    printf(" Enter finish address (hex): ");
    scanf("%x", &last);
}

struct symbol_struct
*getsym(val)
    int val;
{
    int low, high, mid;

    low = 0;
    high = lastsym;

    while (low <= high)
    {
	mid = (low + high)/2;
	if (val > symbol[mid].value )
	    low = mid + 1;
	else if (val < symbol[mid].value )
	    high = mid - 1;
	else return( &symbol[mid] );
    }

    return(NULL);
}

putsym(val)
    int val;
{
    int i, j;


    for (j = 0; j <= lastsym; j++)
	if( symbol[j].value > val)
	    break;


    if ( ++lastsym == SYMTABSIZE-1 )
    {
	printf("!!! Too many symbols !!!");
	return(0);
    }

    for (i = lastsym; i >= j; i--)
	symbol[i+1] = symbol[i];
    symbol[i+1].value = val;
    sprintf(symbol[i+1].name, "Lx%x", val);
    return(1);
}


mtung-Fri_Jan_30_11-00-48_EST_1987-
echo extracting - opc48
cat >opc48 <<'mtung-Fri_Jan_30_11-00-48_EST_1987-'
"nop",		0,
"xxx",		0,
"outl	bus,a",	0,
"add	a, ",	1,
"jmp",		1,
"en	i",	0,
"xxx",		0,
"dec	a",	0,
"ins	a,bus",	0,
"in	a,p1",	0,
"in	a,p2",	0,
"xxx",		0,
"movd	a,p4",	0,
"movd	a,p5",	0,
"movd	a,p6",	0,
"movd	a,p7",	0,
"inc	@r0",	0,
"inc	@r1",	0,
"jb0",		1,
"addc	a, ",	1,
"call",		1,
"dis	i",	0,
"jtf",		1,
"inc	a",	0,
"inc	r0",	0,
"inc	r1",	0,
"inc	r2",	0,
"inc	r3",	0,
"inc	r4",	0,
"inc	r5",	0,
"inc	r6",	0,
"inc	r7",	0,
"xch	@r0",	0,
"xch	@r1",	0,
"xxx",		0,
"mov	a, ",	1,
"jmp",		1,
"en	tcnti",	0,
"jnt0",		1,
"clr	a",	0,
"xch	a,r0",	0,
"xch	a,r1",	0,
"xch	a,r2",	0,
"xch	a,r3",	0,
"xch	a,r4",	0,
"xch	a,r5",	0,
"xch	a,r6",	0,
"xch	a,r7",	0,
"xchd	a,@r0",	0,
"xchd	a,@r1",	0,
"jb1",		1,
"xxx",		0,
"call",		1,
"dis	tcnti",	0,
"jt0",		1,
"cpl	a",	0,
"xxx",		0,
"outl	p1,a",	0,
"outl	p2,a",	0,
"xxx",		0,
"movd	p4,a",	0,
"movd	p5,a",	0,
"movd	p6,a",	0,
"movd	p7,a",	0,
"orl	a,@r0",	0,
"orl	a,@r1",	0,
"mov	a,t",	0,
"orl	a, ",	1,
"jmp",		1,
"strt	cnt",	0,
"jnt1",		1,
"swap	a",	0,
"orl	a,r0",	0,
"orl	a,r1",	0,
"orl	a,r2",	0,
"orl	a,r3",	0,
"orl	a,r4",	0,
"orl	a,r5",	0,
"orl	a,r6",	0,
"orl	a,r7",	0,
"anl	a,@r0",	0,
"anl	a,@r1",	0,
"jb2",		1,
"anl	a, ",	1,
"call",		1,
"strt	t",	0,
"jt1",		1,
"da	a",	0,
"anl	a,r0",	0,
"anl	a,r1",	0,
"anl	a,r2",	0,
"anl	a,r3",	0,
"anl	a,r4",	0,
"anl	a,r5",	0,
"anl	a,r6",	0,
"anl	a,r7",	0,
"add	a,@r0",	0,
"add	a,@r1",	0,
"mov	t,a",	0,
"xxx",		0,
"jmp",		1,
"stop	tcnt",	0,
"xxx",		0,
"rrc	a",	0,
"add	a,r0",	0,
"add	a,r1",	0,
"add	a,r2",	0,
"add	a,r3",	0,
"add	a,r4",	0,
"add	a,r5",	0,
"add	a,r6",	0,
"add	a,r7",	0,
"addc	a,@r0",	0,
"addc	a,@r1",	0,
"jb3",		1,
"xxx",		0,
"call",		1,
"ent0	clk",	0,
"jf1",		1,
"rr	a",	0,
"addc	a,r0",	0,
"addc	a,r1",	0,
"addc	a,r2",	0,
"addc	a,r3",	0,
"addc	a,r4",	0,
"addc	a,r5",	0,
"addc	a,r6",	0,
"addc	a,r7",	0,
"movx	a,@r0",	0,
"movx	a,@r1",	0,
"xxx",		0,
"ret",		0,
"jmp",		1,
"clr	f0",	0,
"jni",		1,
"xxx",		0,
"orl	bus, ",	1,
"orl	p1, ",	1,
"orl	p2, ",	1,
"xxx",		0,
"orld	p4,a",	0,
"orld	p5,a",	0,
"orld	p6,a",	0,
"orld	p7,a",	0,
"movx	a,@r0",	0,
"movx	a,@r1",	0,
"jb4",		1,
"retr",		0,
"call",		1,
"cpl	f0",	0,
"jnz",		1,
"clr	c",	0,
"anl	bus, ",	1,
"anl	p1, ",	1,
"anl	p2, ",	1,
"xxx",		0,
"anld	p4,a",	0,
"anld	p5,a",	0,
"anld	p6,a",	0,
"anld	p7,a",	0,
"mov	@r0,a",	0,
"mov	@r1,a",	0,
"xxx",		0,
"movp	a,@a",	0,
"jmp",		1,
"clr	f1",	0,
"xxx",		0,
"cpl	c",	0,
"mov	r0,a",	0,
"mov	r1,a",	0,
"mov	r2,a",	0,
"mov	r3,a",	0,
"mov	r4,a",	0,
"mov	r5,a",	0,
"mov	r6,a",	0,
"mov	r7,a",	0,
"mov	@r0, ",	1,
"mov	@r1, ",	1,
"jb5",		1,
"jmpp	@a",	0,
"call",		1,
"cpl	f1",	0,
"jf0",		1,
"xxx",		0,
"mov	r0, ",	1,
"mov	r1, ",	1,
"mov	r2, ",	1,
"mov	r3, ",	1,
"mov	r4, ",	1,
"mov	r5, ",	1,
"mov	r6, ",	1,
"mov	r7, ",	1,
"xxx",		0,
"xxx",		0,
"xxx",		0,
"xxx",		0,
"jmp",		1,
"sel	rb0",	0,
"jz",		1,
"mov	a,psw",	0,
"dec	r0",	0,
"dec	r1",	0,
"dec	r2",	0,
"dec	r3",	0,
"dec	r4",	0,
"dec	r5",	0,
"dec	r6",	0,
"dec	r7",	0,
"xrl	a,@r0",	0,
"xrl	a,@r1",	0,
"jb6",		1,
"xrl	a, ",	1,
"call",		1,
"sel	rb1",	0,
"xxx",		0,
"mov	psw,a",	0,
"xrl	a,r0",	0,
"xrl	a,r1",	0,
"xrl	a,r2",	0,
"xrl	a,r3",	0,
"xrl	a,r4",	0,
"xrl	a,r5",	0,
"xrl	a,r6",	0,
"xrl	a,r7",	0,
"xxx",		0,
"xxx",		0,
"xxx",		0,
"movp3	a,@a",	0,
"jmp",		1,
"sel	mb0",	0,
"jnc",		1,
"rl	a",	0,
"djnz	r0, ",	1,
"djnz	r1, ",	1,
"djnz	r2, ",	1,
"djnz	r3, ",	1,
"djnz	r4, ",	1,
"djnz	r5, ",	1,
"djnz	r6, ",	1,
"djnz	r7, ",	1,
"mov	a,@r0",	0,
"mov	a,@r1",	0,
"jb7",		1,
"xxx",		0,
"call",		1,
"sel	mb1",	0,
"jc",		1,
"rlc	a",	0,
"mov	r0, ",	1,
"mov	r1, ",	1,
"mov	r2, ",	1,
"mov	r3, ",	1,
"mov	r4, ",	1,
"mov	r5, ",	1,
"mov	r6, ",	1,
"mov	r7, ",	1,
mtung-Fri_Jan_30_11-00-48_EST_1987-
echo extracting - opc85
cat >opc85 <<'mtung-Fri_Jan_30_11-00-48_EST_1987-'
"nop",	0,
"lxi b, ",	2,
"stax b",	0,
"inx b",	0,
"inr b",	0,
"dcr b",	0,
"mvi b, ",	1,
"rlc",	0,
".byte 0x08",	0,
"dad b",	0,
"ldax b",	0,
"dcx b",	0,
"inr c",	0,
"dcr c",	0,
"mvi c, ",	1,
"rrc",	0,
".byte 0x10",	0,
"lxi d, ",	2,
"stax d",	0,
"inx d",	0,
"inr d",	0,
"dcr d",	0,
"mvi d, ",	1,
"ral",	0,
".byte 0x18",	0,
"dad d",	0,
"ldax d",	0,
"dcx d",	0,
"inr e",	0,
"dcr e",	0,
"mvi e, ",	1,
"rar",	0,
"rim",	0,
"lxi h, ",	2,
"shld",	2,
"inx h",	0,
"inr h",	0,
"dcr h",	0,
"mvi h, ",	1,
"daa",	0,
".byte 0x28",	0,
"dad h",	0,
"lhld",	2,
"dcx h",	0,
"inr l",	0,
"dcr l",	0,
"mvi l, ",	1,
"cma",	0,
"sim",	0,
"lxi sp, ",	2,
"sta",	2,
"inx sp",	0,
"inr m",	0,
"dcr m",	0,
"mvi m, ",	1,
"stc",	0,
".byte 0x38",	0,
"dad sp",	0,
"lda",	2,
"dcx sp",	0,
"inr a",	0,
"dcr a",	0,
"mvi a, ",	1,
"cmc",	0,
"mov b,b",	0,
"mov b,c",	0,
"mov b,d",	0,
"mov b,e",	0,
"mov b,h",	0,
"mov b,l",	0,
"mov b,m",	0,
"mov b,a",	0,
"mov c,b",	0,
"mov c,c",	0,
"mov c,d",	0,
"mov c,e",	0,
"mov c,h",	0,
"mov c,l",	0,
"mov c,m",	0,
"mov c,a",	0,
"mov d,b",	0,
"mov d,c",	0,
"mov d,d",	0,
"mov d,e",	0,
"mov d,h",	0,
"mov d,l",	0,
"mov d,m",	0,
"mov d,a",	0,
"mov e,b",	0,
"mov e,c",	0,
"mov e,d",	0,
"mov e,e",	0,
"mov e,h",	0,
"mov e,l",	0,
"mov e,m",	0,
"mov e,a",	0,
"mov h,b",	0,
"mov h,c",	0,
"mov h,d",	0,
"mov h,e",	0,
"mov h,h",	0,
"mov h,l",	0,
"mov h,m",	0,
"mov h,a",	0,
"mov l,b",	0,
"mov l,c",	0,
"mov l,d",	0,
"mov l,e",	0,
"mov l,h",	0,
"mov l,l",	0,
"mov l,m",	0,
"mov l,a",	0,
"mov m,b",	0,
"mov m,c",	0,
"mov m,d",	0,
"mov m,e",	0,
"mov m,h",	0,
"mov m,l",	0,
"hlt",	0,
"mov m,a",	0,
"mov a,b",	0,
"mov a,c",	0,
"mov a,d",	0,
"mov a,e",	0,
"mov a,h",	0,
"mov a,l",	0,
"mov a,m",	0,
"mov a,a",	0,
"add b",	0,
"add c",	0,
"add d",	0,
"add e",	0,
"add h",	0,
"add l",	0,
"add m",	0,
"add a",	0,
"adc b",	0,
"adc c",	0,
"adc d",	0,
"adc e",	0,
"adc h",	0,
"adc l",	0,
"adc m",	0,
"adc a",	0,
"sub b",	0,
"sub c",	0,
"sub d",	0,
"sub e",	0,
"sub h",	0,
"sub l",	0,
"sub m",	0,
"sub a",	0,
"sbb b",	0,
"sbb c",	0,
"sbb d",	0,
"sbb e",	0,
"sbb h",	0,
"sbb l",	0,
"sbb m",	0,
"sbb a",	0,
"ana b",	0,
"ana c",	0,
"ana d",	0,
"ana e",	0,
"ana h",	0,
"ana l",	0,
"ana m",	0,
"ana a",	0,
"xra b",	0,
"xra c",	0,
"xra d",	0,
"xra e",	0,
"xra h",	0,
"xra l",	0,
"xra m",	0,
"xra a",	0,
"ora b",	0,
"ora c",	0,
"ora d",	0,
"ora e",	0,
"ora h",	0,
"ora l",	0,
"ora m",	0,
"ora a",	0,
"cmp b",	0,
"cmp c",	0,
"cmp d",	0,
"cmp e",	0,
"cmp h",	0,
"cmp l",	0,
"cmp m",	0,
"cmp a",	0,
"rnz",	0,
"pop b",	0,
"jnz",	2,
"jmp",	2,
"cnz",	2,
"push b",	0,
"adi",	1,
"rst 0",	0,
"rz",	0,
"ret",	0,
"jz",	2,
".byte 0xcb",	0,
"cz",	2,
"call",	2,
"aci",	1,
"rst 1",	0,
"rnc",	0,
"pop d",	0,
"jnc",	2,
"out",	1,
"cnc",	2,
"push d",	0,
"sui",	1,
"rst 2",	0,
"rc",	0,
".byte 0xd9",	0,
"jc",	2,
"in",	1,
"cc",	2,
".byte 0xdd",	0,
"sbi",	1,
"rst 3",	0,
"rpo",	0,
"pop h",	0,
"jpo",	2,
"xthl",	0,
"cpo",	2,
"push h",	0,
"ani ",	1,
"rst 4",	0,
"rpe",	0,
"pchl",	0,
"jpe",	2,
"xchg",	0,
"cpe",	2,
".byte 0xed",	0,
"xri",	1,
"rst 5",	0,
"rp",	0,
"pop psw",	0,
"jp",	2,
"di",	0,
"cp",	2,
"push psw",	0,
"ori",	1,
"rst 6",	0,
"rm",	0,
"sphl",	0,
"jm",	2,
"ei",	0,
"cm",	2,
".byte 0xfd",	0,
"cpi",	1,
"rst 7",	0
mtung-Fri_Jan_30_11-00-48_EST_1987-
#--------- cut here --------
-- 
			Paul Fox, AT&T Information Systems, Middletown NJ.
			  [ihnp4|vax135]!mtung!pgf (201)957-2698