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 "rk65c02.h"
#include "instruction.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
debug_breakpoint_remove(rk65c02emu_t *e, uint16_t address)
{

View File

@ -5,10 +5,15 @@
#include <stdbool.h>
#include "rk65c02.h"
#include "instruction.h"
bool debug_PC_is_breakpoint(rk65c02emu_t *);
bool debug_breakpoint_add(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_ */

View File

@ -31,6 +31,7 @@ rk65c02_init(bus_t *b)
e.irq = false;
e.bps_head = NULL;
e.trace_head = NULL;
return e;
}
@ -88,6 +89,9 @@ rk65c02_exec(rk65c02emu_t *e)
{
instruction_t i;
instrdef_t id;
uint16_t tpc; /* saved PC for tracing */
tpc = e->regs.PC;
if (e->irq && (!(e->regs.P & P_IRQ_DISABLE)))
rk65c02_irq(e);
@ -107,6 +111,7 @@ rk65c02_exec(rk65c02emu_t *e)
if (id.emul != NULL) {
id.emul(e, &id, &i);
if (!instruction_modify_pc(&id))
program_counter_increment(e, &id);
} else {
@ -115,6 +120,10 @@ rk65c02_exec(rk65c02emu_t *e)
e->state = STOPPED;
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
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: ",
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");
else
printf("-");
if (e->regs.P & P_SIGN_OVERFLOW)
if (regs.P & P_SIGN_OVERFLOW)
printf("V");
else
printf("-");
if (e->regs.P & P_UNDEFINED)
if (regs.P & P_UNDEFINED)
printf("1");
else
printf("-");
if (e->regs.P & P_BREAK)
if (regs.P & P_BREAK)
printf("B");
else
printf("-");
if (e->regs.P & P_DECIMAL)
if (regs.P & P_DECIMAL)
printf("D");
else
printf("-");
if (e->regs.P & P_IRQ_DISABLE)
if (regs.P & P_IRQ_DISABLE)
printf("I");
else
printf("-");
if (e->regs.P & P_ZERO)
if (regs.P & P_ZERO)
printf("Z");
else
printf("-");
if (e->regs.P & P_CARRY)
if (regs.P & P_CARRY)
printf("C");
else
printf("-");

View File

@ -54,14 +54,24 @@ typedef struct breakpoint_t {
struct breakpoint_t *next;
} 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 {
emu_state_t state;
bus_t *bus;
reg_state_t regs;
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 */
bool trace; /* tracing mode enable/disable */
trace_t *trace_head; /* pointer to linked list with trace log */
};
typedef struct rk65c02emu rk65c02emu_t;
@ -69,7 +79,7 @@ typedef struct rk65c02emu rk65c02emu_t;
rk65c02emu_t rk65c02_init(bus_t *);
void rk65c02_start(rk65c02emu_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_irq(rk65c02emu_t *e);