mirror of
https://github.com/rkujawa/rk65c02.git
synced 2025-04-05 14:37:44 +00:00
Introduce trace functionality.
This commit is contained in:
parent
b32be45d10
commit
0b83a263d7
52
src/debug.c
52
src/debug.c
@ -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)
|
||||
{
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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("-");
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user