1
0
mirror of https://github.com/rkujawa/rk65c02.git synced 2024-06-01 05:41:27 +00:00

Introduce trace functionality.

This commit is contained in:
Radosław Kujawa 2017-02-15 21:32:12 +01:00
parent b32be45d10
commit 0b83a263d7
4 changed files with 88 additions and 12 deletions

View File

@ -3,8 +3,60 @@
#include <utlist.h> #include <utlist.h>
#include "rk65c02.h" #include "rk65c02.h"
#include "instruction.h"
#include "debug.h" #include "debug.h"
void
debug_trace_set(rk65c02emu_t *e, bool state)
{
e->trace = state;
}
void
debug_trace_print_all(rk65c02emu_t *e)
{
trace_t *tr;
instruction_t i;
if (e->trace_head == NULL)
return;
DL_FOREACH(e->trace_head, tr) {
i.opcode = tr->opcode;
i.op1 = tr->op1;
i.op2 = tr->op2;
printf("TRACE %X:\t", tr->address);
instruction_print(&i);
printf("\t");
rk65c02_dump_regs(tr->regs);
}
}
void
debug_trace_savestate(rk65c02emu_t *e, uint16_t address, instrdef_t *id,
instruction_t *i)
{
trace_t *tr;
tr = (trace_t *) malloc(sizeof(trace_t));
if (tr == NULL) {
fprintf(stderr, "Error allocating trace structure.\n");
return;
}
tr->address = address;
tr->opcode = i->opcode;
tr->op1 = i->op1;
tr->op2 = i->op2;
tr->regs = e->regs;
DL_APPEND((e->trace_head), tr);
}
bool bool
debug_breakpoint_remove(rk65c02emu_t *e, uint16_t address) debug_breakpoint_remove(rk65c02emu_t *e, uint16_t address)
{ {

View File

@ -5,10 +5,15 @@
#include <stdbool.h> #include <stdbool.h>
#include "rk65c02.h" #include "rk65c02.h"
#include "instruction.h"
bool debug_PC_is_breakpoint(rk65c02emu_t *); bool debug_PC_is_breakpoint(rk65c02emu_t *);
bool debug_breakpoint_add(rk65c02emu_t *, uint16_t); bool debug_breakpoint_add(rk65c02emu_t *, uint16_t);
bool debug_breakpoint_remove(rk65c02emu_t *, uint16_t); bool debug_breakpoint_remove(rk65c02emu_t *, uint16_t);
void debug_trace_set(rk65c02emu_t *, bool);
void debug_trace_savestate(rk65c02emu_t *, uint16_t, instrdef_t *, instruction_t *);
void debug_trace_print_all(rk65c02emu_t *);
#endif /* _DEBUG_H_ */ #endif /* _DEBUG_H_ */

View File

@ -31,6 +31,7 @@ rk65c02_init(bus_t *b)
e.irq = false; e.irq = false;
e.bps_head = NULL; e.bps_head = NULL;
e.trace_head = NULL;
return e; return e;
} }
@ -88,6 +89,9 @@ rk65c02_exec(rk65c02emu_t *e)
{ {
instruction_t i; instruction_t i;
instrdef_t id; instrdef_t id;
uint16_t tpc; /* saved PC for tracing */
tpc = e->regs.PC;
if (e->irq && (!(e->regs.P & P_IRQ_DISABLE))) if (e->irq && (!(e->regs.P & P_IRQ_DISABLE)))
rk65c02_irq(e); rk65c02_irq(e);
@ -107,6 +111,7 @@ rk65c02_exec(rk65c02emu_t *e)
if (id.emul != NULL) { if (id.emul != NULL) {
id.emul(e, &id, &i); id.emul(e, &id, &i);
if (!instruction_modify_pc(&id)) if (!instruction_modify_pc(&id))
program_counter_increment(e, &id); program_counter_increment(e, &id);
} else { } else {
@ -115,6 +120,10 @@ rk65c02_exec(rk65c02emu_t *e)
e->state = STOPPED; e->state = STOPPED;
e->stopreason = EMUERROR; e->stopreason = EMUERROR;
} }
if (e->trace)
debug_trace_savestate(e, tpc, &id, &i);
} }
/* /*
@ -173,47 +182,47 @@ rk65c02_dump_stack(rk65c02emu_t *e, uint8_t n)
} }
void void
rk65c02_dump_regs(rk65c02emu_t *e) rk65c02_dump_regs(reg_state_t regs)
{ {
printf("A: %X X: %X Y: %X PC: %X SP: %X P: ", printf("A: %X X: %X Y: %X PC: %X SP: %X P: ",
e->regs.A, e->regs.X, e->regs.Y, e->regs.PC, e->regs.SP); regs.A, regs.X, regs.Y, regs.PC, regs.SP);
if (e->regs.P & P_NEGATIVE) if (regs.P & P_NEGATIVE)
printf("N"); printf("N");
else else
printf("-"); printf("-");
if (e->regs.P & P_SIGN_OVERFLOW) if (regs.P & P_SIGN_OVERFLOW)
printf("V"); printf("V");
else else
printf("-"); printf("-");
if (e->regs.P & P_UNDEFINED) if (regs.P & P_UNDEFINED)
printf("1"); printf("1");
else else
printf("-"); printf("-");
if (e->regs.P & P_BREAK) if (regs.P & P_BREAK)
printf("B"); printf("B");
else else
printf("-"); printf("-");
if (e->regs.P & P_DECIMAL) if (regs.P & P_DECIMAL)
printf("D"); printf("D");
else else
printf("-"); printf("-");
if (e->regs.P & P_IRQ_DISABLE) if (regs.P & P_IRQ_DISABLE)
printf("I"); printf("I");
else else
printf("-"); printf("-");
if (e->regs.P & P_ZERO) if (regs.P & P_ZERO)
printf("Z"); printf("Z");
else else
printf("-"); printf("-");
if (e->regs.P & P_CARRY) if (regs.P & P_CARRY)
printf("C"); printf("C");
else else
printf("-"); printf("-");

View File

@ -54,14 +54,24 @@ typedef struct breakpoint_t {
struct breakpoint_t *next; struct breakpoint_t *next;
} breakpoint_t; } breakpoint_t;
typedef struct trace_t {
uint16_t address;
uint8_t opcode, op1, op2;
reg_state_t regs;
struct trace_t *prev,*next;
} trace_t;
struct rk65c02emu { struct rk65c02emu {
emu_state_t state; emu_state_t state;
bus_t *bus; bus_t *bus;
reg_state_t regs; reg_state_t regs;
emu_stop_reason_t stopreason; emu_stop_reason_t stopreason;
bool irq; /* interrupt request line state, true is asserted */ bool irq; /* interrupt request line state, true is asserted */
breakpoint_t *bps_head; /* pointer to linked list with breakpoints */ breakpoint_t *bps_head; /* pointer to linked list with breakpoints */
bool trace; /* tracing mode enable/disable */
trace_t *trace_head; /* pointer to linked list with trace log */
}; };
typedef struct rk65c02emu rk65c02emu_t; typedef struct rk65c02emu rk65c02emu_t;
@ -69,7 +79,7 @@ typedef struct rk65c02emu rk65c02emu_t;
rk65c02emu_t rk65c02_init(bus_t *); rk65c02emu_t rk65c02_init(bus_t *);
void rk65c02_start(rk65c02emu_t *); void rk65c02_start(rk65c02emu_t *);
void rk65c02_step(rk65c02emu_t *, uint16_t); void rk65c02_step(rk65c02emu_t *, uint16_t);
void rk65c02_dump_regs(rk65c02emu_t *); void rk65c02_dump_regs(reg_state_t regs);
void rk65c02_dump_stack(rk65c02emu_t *, uint8_t); void rk65c02_dump_stack(rk65c02emu_t *, uint8_t);
void rk65c02_irq(rk65c02emu_t *e); void rk65c02_irq(rk65c02emu_t *e);