[net.sources] Atari 6502 Disassembler

rgb@nscpdc.UUCP (10/10/86)

This is a disassembler for Atari 6502 binary files.  It attempts to trace
execution flow before printing the information in order to avoid disassembling
the data parts of the program.  The disassembler also accepts equate files
so that you can see references to known locations by their names.  A cross
reference is printed at the end.

The program was compiled and tested on a Vax running BSD4.2.  I have not
attempted to run it on anything else.  It keeps lots of data around as
it traces; the binary on the vax is about 220k.  It uses lex, although
the input rules are very simple.  A custom scanner would probably be easy;
if anyone builds one, I would love to see it.

Please direct comments and questions to me at nsc!nscpdc!rgb or 
tektronix!nscpdc!rgb.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	dis.man
#	Makefile
#	dis.1
#	dis.h
#	main.c
#	initopts.c
#	lex.l
#	ref.c
#	print.c
#	tbl.c
# This archive created: Thu Oct  9 15:13:02 1986
# By:	Robert Bond (NSC Portland, Oregon)
echo shar: extracting dis.man '(1892 characters)'
sed 's/^XX//' << \SHAR_EOF > dis.man
XX
XX
XX
XX     DIS6502(1)            UNIX 3.0 (1 OCT 1986)            DIS6502(1)
XX
XX
XX
XX     NAME
XX          dis6502 - Disassemble 6502 object code
XX
XX     SYNOPSIS
XX          _d_i_s_6_5_0_2 [ -_b ] [ -_p _p_f_i_l_e ] _f_i_l_e
XX
XX     DESCRIPTION
XX          _D_i_s_6_5_0_2 disassembles 6502 binary files.  Binary formats
XX          understood include Atari binary files (L menu command) and
XX          boot files.  Equate and control files can be included via
XX          the -_p option to name well known locations and to control
XX          the dissassembly process.  The output includes a cross
XX          reference.
XX
XX          The dissassembly process is a two pass operation:  First the
XX          program flow is traced starting with the init and run
XX          parameters in the file headers.  The dump routine then
XX          prints out the information.
XX
XX          The command line options are:
XX
XX          -_b   Assume that the file is a boot file, not a load file.
XX
XX          -_p _p_f_i_l_e
XX               Read in the predefine file _p_f_i_l_e.  Up to 20 -_p options
XX               may be included.
XX
XX          Lines in pfile consist of:
XX
XX           lineno name .eq number
XX
XX           .stop number
XX
XX           .trace number
XX
XX          _L_i_n_e_n_o refers to a decimal number. _N_u_m_b_e_r may be a decimal
XX          number or may be a hexadecimal number (the first character
XX          of the number should be "$").  For example, "$21b5" is the
XX          hexadecimal number 21b5.  _N_a_m_e is a sequence of numbers and
XX          characters starting with a letter.  ._t_r_a_c_e causes the trace
XX          process to continue at the address given. ._s_t_o_p causes the
XX          trace process to stop at the address given.
XX
XX     AUTHOR
XX          Robert Bond
XX
XX     BUGS
XX
XX
XX
XX
XX
XX     Page 1                                          (printed 10/9/86)
XX
XX
XX
XX
XX
XX
SHAR_EOF
if test 1892 -ne "`wc -c dis.man`"
then
echo shar: error transmitting dis.man '(should have been 1892 characters)'
fi
echo shar: extracting Makefile '(573 characters)'
sed 's/^XX//' << \SHAR_EOF > Makefile
XXOBJS = main.o initopts.o lex.o ref.o print.o tbl.o 
XXSRCS = dis.h main.c initopts.c lex.l ref.c print.c tbl.c 
XXCFLAGS = -O
XX
XXdis:		$(OBJS)
XX		cc $(OBJS) -o dis
XX
XXtbl.o:		dis.h tbl.c
XX		cc -c tbl.c
XX
XXinitopts.o:	dis.h initopts.c
XX
XXmain.o:		dis.h main.c
XX
XXlex.o:		dis.h lex.l
XX
XXref.o:		dis.h ref.c
XX
XXprint.o:	dis.h print.c
XX
XXdis.man:	dis.1
XX		nroff -man dis.1 > dis.man
XX
XXinstall:	dis
XX		cp dis /a/rgb/bin/dis6502
XX
XXclean:
XX		rm -f $(OBJS)
XX
XXclobber:	clean
XX		rm -f dis
XX
XXckpt:		$(SRCS)
XX		ci -l $(SRCS)
XX
XXshar:		Makefile dis.1 dis.man $(SRCS)
XX		shar -a dis.man Makefile dis.1 $(SRCS) > dis.shar
SHAR_EOF
if test 573 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 573 characters)'
fi
echo shar: extracting dis.1 '(1432 characters)'
sed 's/^XX//' << \SHAR_EOF > dis.1
XX.TH DIS6502 1 "1 OCT 1986"
XX.UC 4
XX.SH NAME
XXdis6502 \- Disassemble 6502 object code
XX.SH SYNOPSIS
XX.I dis6502
XX[
XX.I \-b 
XX]
XX[
XX.I -p \fIpfile\fP 
XX]
XX.I file
XX.LP
XX.SH DESCRIPTION
XX.I  Dis6502
XXdisassembles 6502 binary files.  Binary formats understood include
XXAtari binary files (L menu command) and boot files.
XXEquate and control files can be included via the
XX.I -p
XXoption to name well known locations and to control the dissassembly
XXprocess.  The output includes a cross reference.
XX.PP
XXThe dissassembly process is a two pass operation:  First the program
XXflow is traced starting with the init and run parameters in the file
XXheaders.  The dump routine then prints out the information.
XX.PP
XXThe command line options are:
XX.TP
XX.I \-b
XXAssume that the file is a boot file, not a load file.
XX.TP
XX.I \-p \fIpfile\fP 
XXRead in the predefine file \fIpfile\fP.
XXUp to 20 \fI-p\fP options may be included.
XX.PP
XXLines in pfile consist of:
XX.PP
XX lineno name .eq number
XX.PP
XX .stop number
XX.PP
XX .trace number
XX.PP 
XX.I Lineno
XXrefers to a decimal number.  
XX.I Number 
XXmay be a decimal number or
XXmay be a hexadecimal number (the first character of the number
XXshould be "$").  For example, "$21b5" is
XXthe hexadecimal number 21b5.
XX.I Name
XXis a sequence of numbers and characters starting with a
XXletter.
XX.I .trace 
XXcauses
XXthe trace process to continue at the address given.  
XX.I .stop
XXcauses the
XXtrace process to stop at the address given.
XX.SH AUTHOR
XXRobert Bond
XX.SH BUGS
SHAR_EOF
if test 1432 -ne "`wc -c dis.1`"
then
echo shar: error transmitting dis.1 '(should have been 1432 characters)'
fi
echo shar: extracting dis.h '(1613 characters)'
sed 's/^XX//' << \SHAR_EOF > dis.h
XX#include <stdio.h>
XX
XX#define NPREDEF 10
XX
XXextern char *predef[];
XXextern int  npredef;
XXextern char *file;
XXextern char *progname;
XXextern int  bopt;
XXextern unsigned char f[];
XXextern unsigned char d[];
XX
XX#define getword(x) (d[x] + (d[x+1] << 8))
XX#define getbyte(x) (d[x])
XX
XX/* f bits */
XX
XX#define LOADED 1			/* Location loaded */
XX#define JREF   2			/* Referenced as jump/branch dest */
XX#define DREF   4			/* Referenced as data */
XX#define SREF   8			/* Referenced as subroutine dest */
XX#define NAMED  0x10			/* Has a name */
XX#define TDONE  0x20			/* Has been traced */
XX#define ISOP   0x40			/* Is a valid instruction opcode */
XX
XXstruct info {
XX	char *opn;
XX	int  nb;
XX	int  flag;
XX};
XX
XXextern struct info optbl[];
XX
XX/* Flags */
XX
XX/* Where control goes */
XX
XX#define NORM 1
XX#define JUMP 2
XX#define FORK 4
XX#define STOP 8
XX
XX#define CTLMASK (NORM|JUMP|FORK|STOP)
XX
XX/* Instruction format */
XX
XX#define IMM  0x20
XX#define ABS  0x40
XX#define ACC  0x80
XX#define IMP  0x100
XX#define INX  0x200
XX#define INY  0x400
XX#define ZPX  0x800
XX#define ABX  0x1000
XX#define ABY  0x2000
XX#define REL  0x4000
XX#define IND  0x8000
XX#define ZPY  0x10000
XX#define ZPG  0x20000
XX#define ILL  0x40000
XX
XX#define ADRMASK (IMM|ABS|ACC|IMP|INX|INY|ZPX|ABX|ABY|REL|IND|ZPY|ZPG|ILL)
XX
XXstruct ref_chain {
XX	struct ref_chain *next;
XX	int who;
XX};
XX
XXstruct ref_chain *get_ref();
XXchar *get_name();
XX
XX/* lex junk */
XX
XX#define EQ 256
XX#define NUMBER 257
XX#define NAME 258
XX#define COMMENT 259
XX#define LI 260
XX#define TSTART 261
XX#define TSTOP 262
XX
XXextern FILE *yyin, *yyout;
XXint lineno;
XX
XXint yywrap(), yyerror();
XXchar *emalloc();
XX
XXtypedef union  {
XX	int ival;
XX	char *sval;
XX} VALUE;
XX
XXextern VALUE token;
SHAR_EOF
if test 1613 -ne "`wc -c dis.h`"
then
echo shar: error transmitting dis.h '(should have been 1613 characters)'
fi
echo shar: extracting main.c '(6063 characters)'
sed 's/^XX//' << \SHAR_EOF > main.c
XX#include "dis.h"
XX
XX#define NTSTART 20
XX
XXchar *cur_file = NULL;			/* the file thats open */
XXint  pre_index = 0;
XXint  tstart[NTSTART];			/* .trace directive keep locations */
XXint  tstarti = 0;
XX
XXVALUE token;
XX
XXunsigned char d[0x10000];	 	/* The data */
XXunsigned char f[0x10000];		/* Flags for memory usage */ 
XX
XX#define RUNLOC  0x2e0
XX#define INITLOC 0x2e2
XX
XXmain(argc, argv)
XXint argc;
XXchar *argv[];
XX{
XX	int i;
XX
XX	initopts(argc, argv);
XX	if (npredef > 0) {
XX		cur_file = predef[0];
XX		pre_index++;
XX		yyin = fopen(cur_file, "r");
XX		if (!yyin)
XX			crash ("Cant open predefine file");
XX		get_predef();
XX	}
XX	if (bopt)
XX		loadboot();
XX	else
XX		loadfile();
XX
XX	for (i = 0; i<tstarti; i++)
XX		start_trace(tstart[i], "*PTRACE*");
XX
XX	dumpitout();
XX	exit(0);
XX}
XX
XXcrash(p)
XXchar *p;
XX{
XX	fprintf(stderr, "%s: %s\n", progname, p);
XX	if (cur_file != NULL)
XX		fprintf(stderr, "Line %d of %s\n", lineno+1, cur_file);
XX	exit(1);
XX}
XX
XXget_predef()
XX{
XX	int loc;
XX	int tmp;
XX	char *name;
XX
XX	for(;;) 
XX		switch (yylex()) {
XX		case '\n':
XX			break;
XX		case 0:
XX			return;
XX		case TSTART:
XX			if (yylex() != NUMBER) 
XX				crash(".trace needs a number operand");
XX			loc = token.ival;
XX			if (loc > 0x10000 || loc < 0)
XX				crash("Number out of range");
XX			if (tstarti == NTSTART) 
XX				crash("Too many .trace directives");
XX			tstart[tstarti++] = loc;
XX			while ((tmp = yylex()) != '\n')
XX				;
XX			break;
XX		case TSTOP:
XX			if (yylex() != NUMBER) 
XX				crash(".stop needs a number operand");
XX			loc = token.ival;
XX			if (loc > 0x10000 || loc < 0)
XX				crash("Number out of range");
XX			f[loc] |= TDONE;
XX			while ((tmp = yylex()) != '\n')
XX				;
XX			break;
XX		case NUMBER:
XX			switch (yylex()) {
XX			case LI:
XX			case COMMENT:
XX				while ((tmp = yylex()) != '\n')
XX					;
XX				break;
XX			case '\n':
XX				break;
XX			case NAME:
XX				name = token.sval;
XX				if (yylex() != EQ) 
XX					crash("Only EQ and LI supported in defines file");
XX				if (yylex() != NUMBER)
XX					crash("EQ operand must be a number");
XX				loc = token.ival;
XX				if (loc > 0x10000 || loc < 0)
XX					crash("Number out of range");
XX				f[loc] |= NAMED;
XX				save_name(loc, name); 
XX				while (yylex() != '\n') 
XX					;
XX				break;
XX			default:
XX				crash("Invalid line in predef file");
XX			}
XX			break;
XX		default:
XX			crash("Invalid line in predef file");
XX		}
XX}
XX
XXloadboot()
XX{
XX	struct boot_hdr {
XX		unsigned char flags;
XX		unsigned char nsec;
XX		unsigned char base_low;
XX		unsigned char base_hi;
XX		unsigned char init_low;
XX		unsigned char init_hi;
XX	} bh;
XX
XX	FILE *fp;
XX	int base_addr;
XX	register int i;
XX	int len;
XX
XX	fp = fopen(file, "r");
XX	cur_file = NULL;
XX	if (!fp) { 
XX		fprintf(stderr, "Cant open %s\n", file);
XX		exit(1);
XX	}
XX
XX	if(fread(&bh, sizeof(bh), 1, fp) != 1) 
XX		crash("Input too short");
XX	
XX	base_addr = bh.base_low + (bh.base_hi << 8);
XX	len = bh.nsec * 128;
XX	rewind(fp);
XX	if (fread(&d[base_addr], 1, len, fp) != len) 
XX		crash("input too short");
XX
XX	for(i = base_addr; len > 0; len--) 
XX		f[i++] |= LOADED;
XX
XX	start_trace(base_addr+6, "**BOOT**");
XX}
XX
XXloadfile()
XX{
XX	FILE *fp;
XX	int base_addr;
XX	int last_addr;
XX	register int i;
XX	int had_header;
XX	int tmp;
XX
XX	had_header = 0;
XX	fp = fopen(file, "r");
XX	cur_file = NULL;
XX	if (!fp) { 
XX		fprintf(stderr, "Cant open %s\n", file);
XX		exit(1);
XX	}
XX	for(;;) {
XX
XX		i = getc(fp);
XX
XX		if (i == EOF) {
XX			if (f[RUNLOC] & LOADED & f[RUNLOC+1]) {
XX				i = getword(RUNLOC);
XX				start_trace(i, "**RUN**");
XX			}
XX			return;
XX		}
XX
XX		i = i | (getc(fp) << 8);
XX		if (i == 0xffff)  {
XX			had_header = 1;
XX			base_addr = getc(fp);
XX			base_addr = base_addr | (getc(fp) << 8);
XX			if (base_addr < 0 || base_addr > 0xffff) 
XX				crash("Invalid base addr in input file");
XX		} else {
XX			if (!had_header)
XX				crash("Invalid header in input file");
XX			base_addr = i;
XX		}
XX
XX		last_addr = getc(fp);
XX		last_addr = last_addr | (getc(fp) << 8);
XX		if (last_addr < base_addr || last_addr > 0xffff) 
XX			crash("Invalid length in input file");
XX
XX		printf("Load:  %4x -> %4x\n", base_addr, last_addr);
XX		for(i = base_addr; i <= last_addr; i++) {
XX			tmp = getc(fp);
XX			if (tmp == EOF) 
XX				crash("File too small");
XX			d[i] = tmp;
XX			f[i] |= LOADED;
XX		}
XX
XX		if (f[INITLOC] & LOADED & f[INITLOC+1])  {
XX			i = getword(INITLOC);
XX			start_trace(i, "**INIT**");
XX		}
XX
XX		f[INITLOC] &= ~LOADED;
XX		f[INITLOC+1] &= ~LOADED;
XX	}
XX
XX}
XX
XXstart_trace(loc, name)
XXint loc;
XXchar *name;
XX{
XX	printf("Trace: %4x %s\n", loc, name);
XX	f[loc] |= (NAMED | SREF);
XX	if (!get_name(loc))
XX		save_name(loc, name);
XX	save_ref(0, loc);
XX	trace(loc);
XX}
XX	
XXtrace(addr)
XXregister int addr;
XX{
XX	int opcode;
XX	register struct info *ip; 
XX	int operand;
XX	int istart;
XX
XX	if (f[addr] & TDONE)
XX		return;
XX	else 
XX		f[addr] |= TDONE;
XX
XX	istart = addr;
XX	opcode = getbyte(addr);
XX	ip = &optbl[opcode];
XX
XX	if (ip->flag & ILL)
XX		return;
XX
XX	f[addr] |= ISOP;
XX
XX	addr++;
XX
XX	/* Get the operand */
XX
XX	switch(ip->nb) {
XX		case 1:
XX			break;
XX		case 2:
XX			operand = getbyte(addr);
XX			f[addr++] |= TDONE;
XX			break;
XX		case 3:
XX			operand = getword(addr);
XX			f[addr++] |= TDONE;
XX			f[addr++] |= TDONE;
XX			break;
XX	}
XX
XX	/* Mark data references */
XX
XX	switch (ip->flag & ADRMASK) {
XX		case IMM:
XX		case ACC:
XX		case IMP:
XX		case REL:
XX		case IND:
XX			break;
XX		case ABS:
XX			if (ip->flag & (JUMP | FORK))
XX				break;
XX			/* Fall into */
XX		case ABX:
XX		case ABY:
XX		case INX:
XX		case INY:
XX		case ZPG:
XX		case ZPX:
XX		case ZPY:
XX			f[operand] |= DREF;
XX			save_ref(istart, operand);
XX			break;
XX		default:
XX			crash("Optable error");
XX			break;
XX	}
XX
XX	/* Trace the next instruction */
XX
XX	switch (ip->flag & CTLMASK) {
XX		case NORM:
XX			trace(addr);
XX			break;
XX		case JUMP:
XX			f[operand] |= JREF;
XX			save_ref(istart, operand);
XX			trace(operand);
XX			break;
XX		case FORK:
XX			if (ip->flag & REL) {
XX				if (operand > 127) 
XX					operand = (~0xff | operand);
XX				operand = operand + addr;
XX				f[operand] |= JREF;
XX			} else {
XX				f[operand] |= SREF;
XX			}
XX			save_ref(istart, operand);
XX			trace(operand);
XX			trace(addr);
XX			break;
XX		case STOP:
XX			break;
XX		default:
XX			crash("Optable error");
XX			break;
XX	}
XX}
XX
XXint
XXyywrap()
XX{
XX	fclose(yyin);
XX	if (npredef == pre_index) {
XX		return(1);
XX	} else  {
XX		lineno = 0;
XX		cur_file = predef[pre_index];
XX		pre_index++;
XX		yyin = fopen(cur_file, "r");
XX		if (!yyin) 
XX			crash("Can't open predefines file");
XX		return (0);
XX	}
XX}
SHAR_EOF
if test 6063 -ne "`wc -c main.c`"
then
echo shar: error transmitting main.c '(should have been 6063 characters)'
fi
echo shar: extracting initopts.c '(875 characters)'
sed 's/^XX//' << \SHAR_EOF > initopts.c
XX
XX/* 
XX * 
XX *  dis [-p predefineds] file
XX *
XX *  The -p option may be repeated.
XX */
XX
XX#include "dis.h"
XX
XXchar *predef[NPREDEF];
XXint  npredef = 0;
XXchar *file;
XXchar *progname = "dis";
XXint  bopt = 0;
XX
XXinitopts(argc,argv)
XXint argc;
XXchar *argv[];
XX{
XX    int ai;
XX    char *ca;
XX    int fileset = 0;
XX
XX    progname = argv[0];
XX
XX    while (--argc) {
XX        if ((*++argv)[0] == '-') {
XX	    ca = *argv;
XX	    for(ai = 1; ca[ai] != '\0'; ai++)
XX                switch (ca[ai]) {
XX                case 'p':
XX		    predef[npredef] = *++argv;
XX		    npredef++;
XX                    argc--;
XX                    break;
XX		case 'b':
XX		    bopt = 1;
XX		    break;
XX                default: crash("Invalid option letter");
XX                }
XX        } else if (!fileset) {
XX	    file = *argv;
XX	    fileset++;
XX	} else crash("Usage: [-p predef] file");
XX    }
XX    if (!fileset)
XX	 crash("Usage: [-p predef] file");
XX}
SHAR_EOF
if test 875 -ne "`wc -c initopts.c`"
then
echo shar: error transmitting initopts.c '(should have been 875 characters)'
fi
echo shar: extracting lex.l '(897 characters)'
sed 's/^XX//' << \SHAR_EOF > lex.l
XX%{
XX#undef ECHO
XX#include "dis.h"
XXint lineno = 0;
XX%}
XX%%
XX[ \t] { ; }
XX[\n] {	lineno++;
XX				return '\n';
XX}
XX\.EQ { 
XX				return EQ;
XX}
XX\.LI { 
XX				return LI;
XX}
XX\.eq { 
XX				return EQ;
XX}
XX\.li { 
XX				return LI;
XX}
XX".trace" {
XX				return TSTART;
XX}
XX".stop" {
XX				return TSTOP;
XX}
XX[0-9]+	{
XX				(void)sscanf(yytext, "%d", &token.ival); 
XX				return NUMBER;
XX}
XX\$[A-Fa-f0-9]+ {
XX				(void)sscanf(yytext+1, "%x", &token.ival);
XX				return NUMBER;
XX}
XX[A-Za-z][A-Za-z0-9_]* {
XX				token.sval = emalloc((unsigned) strlen(yytext)+1);
XX				(void) strcpy((char *) token.sval, (char *) yytext);
XX				return NAME;
XX}
XX\*.* {
XX				return COMMENT;
XX}
XX.			{ return yytext[0]; }
XX%%
XX
XXchar *
XXemalloc(n)
XXunsigned n;
XX{
XX	char *ptr, *malloc();
XX
XX	if ((ptr = malloc(n)) == (char *) 0) {
XX		(void) fprintf(stderr,"out of core");
XX		exit(1);
XX	}
XX	return ptr;
XX}
XX
XXint
XXyyerror(s)
XXchar *s;
XX{
XX	(void) fprintf(stderr,"%s in line %d\n", s, lineno);
XX	exit(1);
XX}
SHAR_EOF
if test 897 -ne "`wc -c lex.l`"
then
echo shar: error transmitting lex.l '(should have been 897 characters)'
fi
echo shar: extracting ref.c '(1324 characters)'
sed 's/^XX//' << \SHAR_EOF > ref.c
XX#include "dis.h"
XX
XX#define HTSIZE 0x1000			/* Power of 2 */
XX#define HTMASK (HTSIZE-1)
XX
XXstruct hashslot {
XX	int addr;			/* The key */
XX	struct ref_chain *ref;		/* Who references it */
XX	char *name;			/* The symbolic name (if it has one) */
XX};
XX
XXstruct   hashslot hashtbl[HTSIZE];	/* the hash table */
XX
XXstruct hashslot *
XXhash(loc, allocate)
XXint loc;
XXint allocate;
XX{
XX	int probes;
XX	register struct hashslot *hp;
XX
XX	hp = &hashtbl[loc & HTMASK];
XX	probes = 0;
XX
XX	while (probes< HTSIZE) {
XX		if (hp->addr == loc)
XX			return(hp);
XX		if (hp->name == NULL && hp->ref == NULL) {
XX			if (allocate) {
XX				hp->addr = loc;
XX				return(hp);
XX			} else {
XX				return(NULL);
XX			}
XX		}
XX		hp++;
XX		if (hp == &hashtbl[HTSIZE])
XX			hp = &hashtbl[0];
XX		probes++;
XX	}
XX
XX	crash("Hash table full");
XX}
XX
XXsave_ref(refer, refee) 
XXint refer;
XXint refee;
XX{
XX	struct ref_chain *rc;
XX	struct hashslot *hp;
XX
XX	rc = (struct ref_chain *)emalloc(sizeof(*rc));
XX	rc->who = refer;
XX	hp = hash(refee, 1);
XX	rc->next = hp->ref;
XX	hp->ref = rc;
XX}
XX
XXsave_name(loc, name)
XXint loc;
XXchar *name;
XX{
XX	struct hashslot *hp;
XX
XX	hp = hash(loc, 1);
XX	hp->name = name;
XX}
XX
XXstruct ref_chain *
XXget_ref(loc)
XX{
XX	struct hashslot *hp;
XX
XX	hp = hash(loc, 0);
XX	if (!hp) 
XX		return(NULL);
XX	return(hp->ref);
XX}
XX
XXchar *
XXget_name(loc)
XX{
XX	struct hashslot *hp;
XX
XX	hp = hash(loc, 0);
XX	if (!hp) 
XX		return(NULL);
XX	return(hp->name);
XX}
SHAR_EOF
if test 1324 -ne "`wc -c ref.c`"
then
echo shar: error transmitting ref.c '(should have been 1324 characters)'
fi
echo shar: extracting print.c '(3612 characters)'
sed 's/^XX//' << \SHAR_EOF > print.c
XX#include <ctype.h>
XX#include "dis.h"
XX
XXdumpitout()
XX{
XX	int i;
XX
XX	for(i = 0; i<0x10000;) {
XX		if (f[i] & LOADED) {
XX
XX			if (f[i] & SREF && f[i] & ISOP)
XX				printf("\n\n\n");
XX
XX			printf("%04x  ",i);
XX			print_bytes(i);
XX			print_label(i);
XX			if (f[i] & ISOP)
XX				i += print_inst(i);
XX			else
XX				i += print_data(i);
XX			printf("\n");
XX
XX		} else {
XX			i++;
XX		}
XX	}
XX
XX	print_refs();
XX}
XX
XXpchar(c)
XXint c;
XX{
XX	if (isascii(c) && isprint(c))
XX		return(c);
XX	return('.');
XX}
XX
XXchar *
XXlname(i)
XXint i;
XX{
XX	static char buf[20];
XX	char t;
XX
XX	if (f[i] & NAMED) 
XX		return(get_name(i));
XX	if ((i > 0) && ((f[i-1] & (NAMED | DREF)) == (NAMED | DREF))) {
XX		strcpy(buf, get_name(i-1));
XX		strcat(buf, "+1");
XX		return (buf);
XX	}
XX	if (f[i] & SREF)
XX		t = 'S';
XX	else if (f[i] & JREF)
XX		t = 'L';
XX	else if (f[i] & DREF)
XX		t = 'D';
XX	else 
XX		t = 'X';
XX	
XX	sprintf(buf, "%c%x", t, i);
XX	return (buf);
XX}
XX
XXprint_label(i)
XX{
XX	if (f[i] & (NAMED | JREF | SREF | DREF)) 
XX		printf("%-10s", lname(i));
XX	else
XX		printf("%10s"," ");
XX}
XX
XXprint_bytes(addr)
XXint addr;
XX{
XX	register struct info *ip; 
XX
XX	if ((f[addr] & ISOP) == 0) {
XX		printf("           ");
XX		return;
XX	}
XX
XX	ip = &optbl[getbyte(addr)];
XX
XX	switch (ip->nb) {
XX		case 1:
XX			printf("%02x         ", getbyte(addr));
XX			break;
XX		case 2:
XX			printf("%02x %02x      ", getbyte(addr), getbyte(addr+1));
XX			break;
XX		case 3:
XX			printf("%02x %02x %02x   ", getbyte(addr), getbyte(addr+1), getbyte(addr+2));
XX			break;
XX	}
XX}
XX		
XX
XXprint_inst(addr)
XXint addr;
XX{
XX	int opcode;
XX	register struct info *ip; 
XX	int operand;
XX	int istart;
XX
XX	istart = addr;
XX	opcode = getbyte(addr);
XX	ip = &optbl[opcode];
XX
XX	printf("%s  ", ip->opn);
XX
XX	addr++;
XX
XX	switch(ip->nb) {
XX		case 1:
XX			break;
XX		case 2:
XX			operand = getbyte(addr);
XX			break;
XX		case 3:
XX			operand = getword(addr);
XX			break;
XX	}
XX
XX	if (ip->flag & REL) {
XX		if (operand > 127) 
XX			operand = (~0xff | operand);
XX		operand = operand + ip->nb + addr - 1;
XX	}
XX
XX	switch (ip->flag & ADRMASK) {
XX		case IMM:
XX			printf("#$%02x                        * %d %c", operand, operand, pchar(operand));
XX			break;
XX		case ACC:
XX		case IMP:
XX			break;
XX		case REL:
XX		case ABS:
XX		case ZPG:
XX			printf("%s ", lname(operand));
XX			break;
XX		case IND:
XX			printf("(%s) ", lname(operand));
XX			break;
XX		case ABX:
XX		case ZPX:
XX			printf("%s,X ", lname(operand));
XX			break;
XX		case ABY:
XX		case ZPY:
XX			printf("%s,Y ", lname(operand));
XX			break;
XX		case INX:
XX			printf("(%s,X) ", lname(operand));
XX			break;
XX		case INY:
XX			printf("(%s),Y", lname(operand));
XX			break;
XX		default:
XX			break;
XX	}
XX
XX	return(ip->nb);
XX
XX}
XX
XXprint_data(i)
XX{
XX	int count;
XX	int j;
XX	int start;
XX
XX	start = i;
XX	printf(".DB  %02x ", getbyte(i));
XX	count = 1;
XX	i++;
XX
XX	for (j = 1; j < 8; j++) {
XX		if (f[i] & (JREF | SREF | DREF) || ((f[i] & LOADED) == 0)) 
XX			break;
XX		else
XX			printf("%02x ", getbyte(i));
XX		i++;
XX		count++;
XX	}
XX	for (j = count; j < 8; j++)
XX		printf("   ");
XX
XX	printf("    * ");
XX
XX	for (j = start; j < i ; j++) 
XX			printf("%c", pchar(getbyte(j)));
XX
XX	return (count);
XX}
XX
XXprint_refs()
XX{
XX	char tname[50];
XX	char cmd[200];
XX	FILE *fp;
XX	register struct ref_chain *rp;
XX	register int i;
XX
XX	sprintf(tname, "dis.%d", getpid());
XX	sprintf(cmd, "sort %s; rm %s", tname, tname);
XX
XX	fp = fopen(tname, "w");
XX	if (!fp) 
XX		crash("Cant open %s/n", tname);
XX
XX	for (i = 0; i<0x10000; i++) {
XX		if(f[i] & (JREF|SREF|DREF)) {
XX			rp = get_ref(i);
XX			if (!rp) {
XX				fprintf(stderr, "No ref %d\n", i);
XX				break;
XX			}
XX
XX			fprintf(fp, "%-8s  %04x   ", lname(i), i);
XX			while (rp) {
XX				fprintf(fp, "%04x ", rp->who);
XX				rp = rp->next;
XX			}
XX			fprintf(fp, "\n");
XX		}
XX
XX	}
XX
XX	fclose(fp);
XX
XX	printf("\n\n\n\n\nCross References\n\n");
XX	printf("%-8s  Value  References\n", "Symbol");
XX	fflush (stdout);
XX
XX	system(cmd);
XX}
SHAR_EOF
if test 3612 -ne "`wc -c print.c`"
then
echo shar: error transmitting print.c '(should have been 3612 characters)'
fi
echo shar: extracting tbl.c '(9008 characters)'
sed 's/^XX//' << \SHAR_EOF > tbl.c
XX#include "dis.h"
XX
XXstruct info optbl[256] = {
XX	/* 00 */	{ "BRK", 1, IMP|STOP, },
XX	/* 01 */	{ "ORA", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 05 */	{ "ORA", 2, ZPG|NORM, },
XX	/* 06 */	{ "ASL", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 08 */	{ "PHP", 1, IMP|NORM, },
XX	/* 09 */	{ "ORA", 2, IMM|NORM, },
XX	/* 0a */	{ "ASL", 1, ACC|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 0d */	{ "ORA", 3, ABS|NORM, },
XX	/* 0e */	{ "ASL", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 10 */	{ "BPL", 2, REL|FORK, },
XX	/* 11 */	{ "ORA", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 15 */	{ "ORA", 2, ZPX|NORM, },
XX	/* 16 */	{ "ASL", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 18 */	{ "CLC", 1, IMP|NORM, },
XX	/* 19 */	{ "ORA", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 1d */	{ "ORA", 3, ABX|NORM, },
XX	/* 1e */	{ "ASL", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 20 */	{ "JSR", 3, ABS|FORK, },
XX	/* 21 */	{ "AND", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 24 */	{ "BIT", 2, ZPG|NORM, },
XX	/* 25 */	{ "AND", 2, ZPG|NORM, },
XX	/* 26 */	{ "ROL", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 28 */	{ "PLP", 1, IMP|NORM, },
XX	/* 29 */	{ "AND", 2, IMM|NORM, },
XX	/* 2a */	{ "ROL", 1, ACC|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 2c */	{ "BIT", 3, ABS|NORM, },
XX	/* 2d */	{ "AND", 3, ABS|NORM, },
XX	/* 2e */	{ "ROL", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 30 */	{ "BMI", 2, REL|FORK, },
XX	/* 31 */	{ "AND", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 35 */	{ "AND", 2, ZPX|NORM, },
XX	/* 36 */	{ "ROL", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 38 */	{ "SEC", 1, IMP|NORM, },
XX	/* 39 */	{ "AND", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 3d */	{ "AND", 3, ABX|NORM, },
XX	/* 3e */	{ "ROL", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 40 */	{ "RTI", 1, IMP|STOP, },
XX	/* 41 */	{ "EOR", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 45 */	{ "EOR", 2, ZPG|NORM, },
XX	/* 46 */	{ "LSR", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 48 */	{ "PHA", 1, IMP|NORM, },
XX	/* 49 */	{ "EOR", 2, IMM|NORM, },
XX	/* 4a */	{ "LSR", 1, ACC|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 4c */	{ "JMP", 3, ABS|JUMP, },
XX	/* 4d */	{ "EOR", 3, ABS|NORM, },
XX	/* 4e */	{ "LSR", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 50 */	{ "BVC", 2, REL|FORK, },
XX	/* 51 */	{ "EOR", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 55 */	{ "EOR", 2, ZPX|NORM, },
XX	/* 56 */	{ "LSR", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 58 */	{ "CLI", 1, IMP|NORM, },
XX	/* 59 */	{ "EOR", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 5d */	{ "EOR", 3, ABX|NORM, },
XX	/* 5e */	{ "LSR", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 60 */	{ "RTS", 1, IMP|STOP, },
XX	/* 61 */	{ "ADC", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 65 */	{ "ADC", 2, ZPG|NORM, },
XX	/* 66 */	{ "ROR", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 68 */	{ "PLA", 1, IMP|NORM, },
XX	/* 69 */	{ "ADC", 2, IMM|NORM, },
XX	/* 6a */	{ "ROR", 1, ACC|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 6c */	{ "JMP", 3, IND|STOP, },
XX	/* 6d */	{ "ADC", 3, ABS|NORM, },
XX	/* 6e */	{ "ROR", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 70 */	{ "BVS", 2, REL|FORK, },
XX	/* 71 */	{ "ADC", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 75 */	{ "ADC", 2, ZPX|NORM, },
XX	/* 76 */	{ "ROR", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 78 */	{ "SEI", 1, IMP|NORM, },
XX	/* 79 */	{ "ADC", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 7d */	{ "ADC", 3, ABX|NORM, },
XX	/* 7e */	{ "ROR", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 81 */	{ "STA", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 84 */	{ "STY", 2, ZPG|NORM, },
XX	/* 85 */	{ "STA", 2, ZPG|NORM, },
XX	/* 86 */	{ "STX", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 88 */	{ "DEY", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 8a */	{ "TXA", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 8c */	{ "STY", 3, ABS|NORM, },
XX	/* 8d */	{ "STA", 3, ABS|NORM, },
XX	/* 8e */	{ "STX", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 90 */	{ "BCC", 2, REL|FORK, },
XX	/* 91 */	{ "STA", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 94 */	{ "STY", 2, ZPX|NORM, },
XX	/* 95 */	{ "STA", 2, ZPX|NORM, },
XX	/* 96 */	{ "STX", 2, ZPY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 98 */	{ "TYA", 1, IMP|NORM, },
XX	/* 99 */	{ "STA", 3, ABY|NORM, },
XX	/* 9a */	{ "TXS", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 9d */	{ "STA", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* a0 */	{ "LDY", 2, IMM|NORM, },
XX	/* a1 */	{ "LDA", 2, INX|NORM, },
XX	/* a2 */	{ "LDX", 2, IMM|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* a4 */	{ "LDY", 2, ZPG|NORM, },
XX	/* a5 */	{ "LDA", 2, ZPG|NORM, },
XX	/* a6 */	{ "LDX", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* a8 */	{ "TAY", 1, IMP|NORM, },
XX	/* a9 */	{ "LDA", 2, IMM|NORM, },
XX	/* aa */	{ "TAX", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* ac */	{ "LDY", 3, ABS|NORM, },
XX	/* ad */	{ "LDA", 3, ABS|NORM, },
XX	/* ae */	{ "LDX", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* b0 */	{ "BCS", 2, REL|FORK, },
XX	/* b1 */	{ "LDA", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* b4 */	{ "LDY", 2, ZPX|NORM, },
XX	/* b5 */	{ "LDA", 2, ZPX|NORM, },
XX	/* b6 */	{ "LDX", 2, ZPY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* b8 */	{ "CLV", 1, IMP|NORM, },
XX	/* b9 */	{ "LDA", 3, ABY|NORM, },
XX	/* ba */	{ "TSX", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* bc */	{ "LDY", 3, ABX|NORM, },
XX	/* bd */	{ "LDA", 3, ABX|NORM, },
XX	/* be */	{ "LDX", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* c0 */	{ "CPY", 2, IMM|NORM, },
XX	/* c1 */	{ "CMP", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* c4 */	{ "CPY", 2, ZPG|NORM, },
XX	/* c5 */	{ "CMP", 2, ZPG|NORM, },
XX	/* c6 */	{ "DEC", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* c8 */	{ "INY", 1, IMP|NORM, },
XX	/* c9 */	{ "CMP", 2, IMM|NORM, },
XX	/* ca */	{ "DEX", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* cc */	{ "CPY", 3, ABS|NORM, },
XX	/* cd */	{ "CMP", 3, ABS|NORM, },
XX	/* ce */	{ "DEC", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* d0 */	{ "BNE", 2, REL|FORK, },
XX	/* d1 */	{ "CMP", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* d5 */	{ "CMP", 2, ZPX|NORM, },
XX	/* d6 */	{ "DEC", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* d8 */	{ "CLD", 1, IMP|NORM, },
XX	/* d9 */	{ "CMP", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* dd */	{ "CMP", 3, ABX|NORM, },
XX	/* de */	{ "DEC", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* e0 */	{ "CPX", 2, IMM|NORM, },
XX	/* e1 */	{ "SBC", 2, INX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* e4 */	{ "CPX", 2, ZPG|NORM, },
XX	/* e5 */	{ "SBC", 2, ZPG|NORM, },
XX	/* e6 */	{ "INC", 2, ZPG|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* e8 */	{ "INX", 1, IMP|NORM, },
XX	/* e9 */	{ "SBC", 2, IMM|NORM, },
XX	/* ea */	{ "NOP", 1, IMP|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* ec */	{ "CPX", 3, ABS|NORM, },
XX	/* ed */	{ "SBC", 3, ABS|NORM, },
XX	/* ee */	{ "INC", 3, ABS|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* f0 */	{ "BEQ", 2, REL|FORK, },
XX	/* f1 */	{ "SBC", 2, INY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* f5 */	{ "SBC", 2, ZPX|NORM, },
XX	/* f6 */	{ "INC", 2, ZPX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* f8 */	{ "SED", 1, IMP|NORM, },
XX	/* f9 */	{ "SBC", 3, ABY|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX	/* fd */	{ "SBC", 3, ABX|NORM, },
XX	/* fe */	{ "INC", 3, ABX|NORM, },
XX	/* 00 */	{ "???", 1, ILL|NORM, },
XX};
SHAR_EOF
if test 9008 -ne "`wc -c tbl.c`"
then
echo shar: error transmitting tbl.c '(should have been 9008 characters)'
fi
#	End of shell archive
exit 0
-- 
    Robert Bond 			ihnp4!nsc!nscpdc!rgb
    National Semiconductor		tektronix!nscpdc!rgb