Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP From: rgb@nscpdc.UUCP Newsgroups: net.sources Subject: Atari 6502 Disassembler Message-ID: <611@nscpdc.UUCP> Date: Thu, 9-Oct-86 18:39:19 EDT Article-I.D.: nscpdc.611 Posted: Thu Oct 9 18:39:19 1986 Date-Received: Sat, 11-Oct-86 21:40:49 EDT Reply-To: rgb@nscpdc.UUCP (Robert Bond) Organization: NSC Portland, Oregon Lines: 1424 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 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 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 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