mirror of
https://github.com/brouhaha/dis6502.git
synced 2025-02-17 07:32:46 +00:00
defined addr_t. added trace queue to eliminate recursion.
This commit is contained in:
parent
42bb931493
commit
b505e98be2
6
Makefile
6
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
|
||||
|
||||
|
25
dis.h
25
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));
|
||||
|
@ -5,6 +5,7 @@
|
||||
* The -p option may be repeated.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
1
lex.l
1
lex.l
@ -1,5 +1,6 @@
|
||||
%{
|
||||
#undef ECHO
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "dis.h"
|
||||
int lineno = 0;
|
||||
|
231
main.c
231
main.c
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -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");
|
||||
|
||||
|
19
print.c
19
print.c
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@ -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());
|
||||
|
15
ref.c
15
ref.c
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user