diff --git a/Makefile b/Makefile index fead1be..b176266 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -OBJS = main.o initopts.o lex.o ref.o print.o tbl.o -SRCS = dis.h main.c initopts.c lex.l ref.c print.c tbl.c +OBJS = main.o initopts.o lex.o ref.o print.o tbl.o trace_queue.o +SRCS = dis.h main.c initopts.c lex.l ref.c print.c tbl.c trace_queue.c CFLAGS = -g -Wall dis6502: $(OBJS) @@ -20,6 +20,8 @@ ref.o: dis.h ref.c print.o: dis.h print.c +trace_queue.o: dis.h trace_queue.c + dis.man: dis.1 nroff -man dis.1 > dis.man diff --git a/dis.h b/dis.h index 762845f..7931ffb 100644 --- a/dis.h +++ b/dis.h @@ -1,3 +1,5 @@ +typedef uint16_t addr_t; + #define NPREDEF 10 extern char *predef[]; @@ -69,8 +71,8 @@ struct ref_chain { int who; }; -struct ref_chain *get_ref(); -char *get_name(); +struct ref_chain *get_ref(addr_t loc); +char *get_name(addr_t loc); /* lex junk */ @@ -108,16 +110,21 @@ void initopts (int argc, char *argv[]); /* in print.c: */ void dumpitout (void); int pchar (int c); -char *lname (int i); -int print_label (int i); -void print_bytes (int addr); -int print_inst(int addr); -int print_data (int i); +void print_bytes (addr_t addr); +int print_inst(addr_t addr); +int print_data (addr_t i); void print_refs (void); /* in ref.c: */ -void save_ref (int refer, int refee); -void save_name (int loc, char *name); +void save_ref (addr_t refer, addr_t refee); +void save_name (addr_t loc, char *name); + +/* in trace_queue.c: */ +void init_trace_queue (void); +int trace_queue_empty (void); +void push_trace_queue (addr_t addr); +addr_t pop_trace_queue (void); + /* in main.c: */ void crash (char *p) __attribute__ ((noreturn)); diff --git a/initopts.c b/initopts.c index 673c92e..16c5657 100644 --- a/initopts.c +++ b/initopts.c @@ -5,6 +5,7 @@ * The -p option may be repeated. */ +#include #include #include diff --git a/lex.l b/lex.l index 010b24e..29bf2ba 100644 --- a/lex.l +++ b/lex.l @@ -1,5 +1,6 @@ %{ #undef ECHO +#include #include #include "dis.h" int lineno = 0; diff --git a/main.c b/main.c index 1d63c28..7e97bd4 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,4 @@ +#include #include #include @@ -42,113 +43,136 @@ void crash (char *p) exit(1); } -void trace (unsigned int addr) + +void add_trace (addr_t addr) { - int opcode; - register struct info *ip; - int operand; - int istart; - - if (f[addr] & TDONE) - return; - else - f[addr] |= TDONE; - - istart = addr; - opcode = getbyte(addr); - ip = &optbl[opcode]; - - if (ip->flag & ILL) - return; - - f[addr] |= ISOP; - - addr++; - - /* Get the operand */ - - switch(ip->nb) { - case 1: - break; - case 2: - operand = getbyte(addr); - f[addr++] |= TDONE; - break; - case 3: - operand = getword(addr); - f[addr++] |= TDONE; - f[addr++] |= TDONE; - break; - } - - /* Mark data references */ - - switch (ip->flag & ADRMASK) { - case IMM: - case ACC: - case IMP: - case REL: - case IND: - break; - case ABS: - if (ip->flag & (JUMP | FORK)) - break; - /* Fall into */ - case ABX: - case ABY: - case INX: - case INY: - case ZPG: - case ZPX: - case ZPY: - f[operand] |= DREF; - save_ref(istart, operand); - break; - default: - crash("Optable error"); - break; - } - - /* Trace the next instruction */ - - switch (ip->flag & CTLMASK) { - case NORM: - trace(addr); - break; - case JUMP: - f[operand] |= JREF; - save_ref(istart, operand); - trace(operand); - break; - case FORK: - if (ip->flag & REL) { - if (operand > 127) - operand = (~0xff | operand); - operand = operand + addr; - f[operand] |= JREF; - } else { - f[operand] |= SREF; - } - save_ref(istart, operand); - trace(operand); - trace(addr); - break; - case STOP: - break; - default: - crash("Optable error"); - break; - } + if (f [addr] & TDONE) + return; + push_trace_queue (addr); } -void start_trace (unsigned int loc, char *name) + +void trace_inst (addr_t addr) +{ + int opcode; + register struct info *ip; + int operand; + int istart; + + for (;;) + { + if (f[addr] & TDONE) + return; + + f[addr] |= TDONE; + + istart = addr; + opcode = getbyte(addr); + ip = &optbl[opcode]; + + if (ip->flag & ILL) + return; + + f[addr] |= ISOP; + + addr++; + + /* Get the operand */ + + switch(ip->nb) + { + case 1: + break; + case 2: + operand = getbyte(addr); + f[addr++] |= TDONE; + break; + case 3: + operand = getword(addr); + f[addr++] |= TDONE; + f[addr++] |= TDONE; + break; + } + + /* Mark data references */ + + switch (ip->flag & ADRMASK) + { + case IMM: + case ACC: + case IMP: + case REL: + case IND: + break; + case ABS: + if (ip->flag & (JUMP | FORK)) + break; + /* Fall into */ + case ABX: + case ABY: + case INX: + case INY: + case ZPG: + case ZPX: + case ZPY: + f[operand] |= DREF; + save_ref(istart, operand); + break; + default: + crash("Optable error"); + break; + } + + /* Trace the next instruction */ + + switch (ip->flag & CTLMASK) + { + case NORM: + break; + case JUMP: + f[operand] |= JREF; + save_ref(istart, operand); + add_trace(operand); + return; + case FORK: + if (ip->flag & REL) + { + if (operand > 127) + operand = (~0xff | operand); + operand = operand + addr; + f[operand] |= JREF; + } + else + { + f[operand] |= SREF; + } + save_ref(istart, operand); + add_trace(operand); + break; + case STOP: + return; + default: + crash("Optable error"); + } + } +} + + +void trace_all (void) +{ + while (! trace_queue_empty ()) + trace_inst (pop_trace_queue ()); +} + + +void start_trace (addr_t loc, char *name) { fprintf(stderr, "Trace: %4x %s\n", loc, name); f[loc] |= (NAMED | SREF); if (!get_name(loc)) save_name(loc, name); save_ref(0, loc); - trace(loc); + add_trace(loc); } @@ -206,6 +230,9 @@ void do_jtab2 (void) int main (int argc, char *argv[]) { initopts(argc, argv); + + init_trace_queue (); + if (npredef > 0) { cur_file = predef[0]; pre_index++; @@ -237,6 +264,8 @@ int main (int argc, char *argv[]) do_rtstab (); do_jtab2 (); + trace_all (); + dumpitout(); exit(0); @@ -442,7 +471,7 @@ void loadfile (void) void c64loadfile (void) { FILE *fp; - unsigned int base_addr,i; + addr_t base_addr,i; int c; fp = fopen(file, "r"); @@ -468,9 +497,9 @@ void c64loadfile (void) void binaryloadfile (void) { FILE *fp; - unsigned int i; + addr_t i; int c; - unsigned int reset, irq, nmi; + addr_t reset, irq, nmi; fp = fopen (file, "r"); diff --git a/print.c b/print.c index 9f1643f..3f0f851 100644 --- a/print.c +++ b/print.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,14 +12,14 @@ char *strcpy(); char *strcat(); -static int has_offset (int i) +static int has_offset (addr_t i) { return ((i > 0) && (! (f [i] & NAMED)) && ((f [i-1] & (NAMED | DREF)) == (NAMED | DREF))); } -static char *lname (int i, int offset_ok) +static char *lname (addr_t i, int offset_ok) { static char buf[20]; char t; @@ -53,7 +54,7 @@ static char *lname (int i, int offset_ok) } -static int print_label (int i) +static int print_label (addr_t i) { if (f[i] & (NAMED | JREF | SREF | DREF)) { @@ -66,7 +67,7 @@ static int print_label (int i) void dumpitout (void) { - int i; + uint32_t i; /* must be larger than an addr_t */ for(i = 0; i<0x10000;) { @@ -120,7 +121,7 @@ int pchar (int c) return('.'); } -void print_bytes (int addr) +void print_bytes (addr_t addr) { register struct info *ip; @@ -145,7 +146,7 @@ void print_bytes (int addr) } -int print_inst(int addr) +int print_inst(addr_t addr) { int opcode; register struct info *ip; @@ -212,7 +213,7 @@ int print_inst(int addr) } -int print_data (int i) +int print_data (addr_t i) { int count; int j; @@ -249,8 +250,8 @@ void print_refs (void) char tname[50]; char cmd[200]; FILE *fp; - register struct ref_chain *rp; - register int i; + struct ref_chain *rp; + uint32_t i; /* must be larger than an addr_t */ int npline; (void)sprintf(tname, "dis.%d", getpid()); diff --git a/ref.c b/ref.c index 8ed518c..644543c 100644 --- a/ref.c +++ b/ref.c @@ -1,3 +1,4 @@ +#include #include #include "dis.h" @@ -6,14 +7,14 @@ #define HTMASK (HTSIZE-1) struct hashslot { - int addr; /* The key */ + addr_t addr; /* The key */ struct ref_chain *ref; /* Who references it */ char *name; /* The symbolic name (if it has one) */ }; struct hashslot hashtbl[HTSIZE]; /* the hash table */ -struct hashslot *hash (int loc, int allocate) +struct hashslot *hash (addr_t loc, int allocate) { int probes; register struct hashslot *hp; @@ -42,7 +43,7 @@ struct hashslot *hash (int loc, int allocate) /*NOTREACHED*/ } -void save_ref (int refer, int refee) +void save_ref (addr_t refer, addr_t refee) { struct ref_chain *rc; struct hashslot *hp; @@ -54,7 +55,7 @@ void save_ref (int refer, int refee) hp->ref = rc; } -void save_name (int loc, char *name) +void save_name (addr_t loc, char *name) { struct hashslot *hp; @@ -62,8 +63,7 @@ void save_name (int loc, char *name) hp->name = name; } -struct ref_chain * -get_ref(loc) +struct ref_chain *get_ref(addr_t loc) { struct hashslot *hp; @@ -73,8 +73,7 @@ get_ref(loc) return(hp->ref); } -char * -get_name(loc) +char * get_name(addr_t loc) { struct hashslot *hp; diff --git a/tbl.c b/tbl.c index 49691af..47603b0 100644 --- a/tbl.c +++ b/tbl.c @@ -1,4 +1,6 @@ +#include #include + #include "dis.h" struct info optbl[256] = {