Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugging tools #12

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/core/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#ifdef DEBUG
#include "debug/record.h"
#include "debug/event.h"
#endif

cpu_t cpu;
Expand Down Expand Up @@ -55,6 +56,11 @@ u8 cpu_step() {

#ifdef DEBUG
record_cpu_cycle();

event_t event;
event.type = EVENT_PROGRAM_COUNTER;
event.address.pc = PC;
debug_event(event);
#endif

cpu.op = mem_read_byte(PC++);
Expand Down
3 changes: 1 addition & 2 deletions src/core/joy.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
#include "debug/event.h"
#endif // DEBUG

#define SELECT_DIRECTION_BIT 0x10
#define SELECT_ACTION_BIT 0x20


joy_t joy;

Expand Down
3 changes: 3 additions & 0 deletions src/core/joy.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#define JOY_STATE_PRESSED 0x00
#define JOY_STATE_RELEASED 0x01

#define SELECT_DIRECTION_BIT 0x10
#define SELECT_ACTION_BIT 0x20

typedef struct {
u8 state;
u8 col;
Expand Down
13 changes: 13 additions & 0 deletions src/debug/break.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,22 @@ void break_disable(int id) {
breakpoints[id].enabled = 0;
}

void break_clear() {
int i;
for (i = 0; i < BREAKPOINT_BUFFER_SIZE; i++) {
break_disable(i);
}
breakpoint_cursor = 0;
}

void break_handle_event(event_t event) {
int b;
for (b = 0; b < breakpoint_cursor; b++) {
if (breakpoints[b].breakpoint.type == BREAKPOINT_ADDRESS) {
if (event.type == EVENT_PROGRAM_COUNTER && event.address.pc == breakpoints[b].breakpoint.address.pc ) {
now = 1;
}
}
if (breakpoints[b].breakpoint.type == BREAKPOINT_EVENT) {
if (event.type == EVENT_JOY_NOTICED) {
now = 1;
Expand Down
64 changes: 64 additions & 0 deletions src/debug/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ static void cmd_break(char* tail) {
int i = atoi(subsubcmd);
break_disable(i);
}
else if (!strcmp(subcmd, "pc")) {
char* bpc = word(&tail);
assert(*bpc != '\0');
bp.type = BREAKPOINT_ADDRESS;
bp.address.pc = strtol(bpc, NULL, 16);
valid_bp = 1;
}
else if (!strcmp(subcmd, "clear")) {
printf("Cleared all breakpoints\n", subcmd);
break_clear();
return;
}
else {
printf("Unknown break command '%s'\n", subcmd);
valid_bp = 0;
Expand Down Expand Up @@ -122,6 +134,11 @@ static void cmd_watch(char* tail) {
else if (!strcmp(subcmd, "mem-w")) {
watchpoint.type = WATCHPOINT_MEM_W;
}
else if (!strcmp(subcmd, "clear")) {
printf("Cleared all watches\n", subcmd);
watch_clear();
return;
}
else {
printf("Unknown watch subcommand '%s'\n", subcmd);
return;
Expand Down Expand Up @@ -149,6 +166,47 @@ static void cmd_watch(char* tail) {
watch_enable(watchpoint);
}

static void cmd_cpureg() {
printf("AF [ A = %.2X ; F = %.2X ]\n", A, F);
printf("BC [ B = %.2X ; C = %.2X ]\n", B, C);
printf("DE [ D = %.2X ; E = %.2X ]\n", D, E);
printf("HL [ H = %.2X ; L = %.2X ]\n", H, L);
printf("SP = %.4X\n", SP);
printf("PC = %.4X\n", PC);
}

static void cmd_memdump(char* tail) {
char* startaddr = word(&tail);
assert(*startaddr != '\0');
char* endaddr = word(&tail);
if (*endaddr == '\0') {
endaddr = startaddr;
}

u16 curaddr = strtol(startaddr, NULL, 16);
u16 finish = strtol(endaddr, NULL, 16);
if (finish < curaddr) {
finish = curaddr + 0x10;
}
u8 needaddrmarker = 1;
int newlineat = 16;
while (curaddr <= finish) {
if (needaddrmarker != 0) {
printf("%.4X | ", curaddr);
newlineat = 16;
needaddrmarker = 0;
}
printf("%.2X ", debug_read_byte(curaddr));
newlineat--;
if (newlineat == 0) {
needaddrmarker = 1;
printf("\n");
}
curaddr++;
}
printf("\n");
}

void debug_step() {
int continue_emulation = !break_now();

Expand Down Expand Up @@ -205,6 +263,12 @@ void debug_step() {
else if (!strcmp("w", cmd)) {
cmd_watch(trim(tail));
}
else if (!strcmp("c", cmd)) {
cmd_cpureg();
}
else if (!strcmp("m", cmd)) {
cmd_memdump(trim(tail));
}
else {
printf("Unknown cmd '%s'\n", cmd);
}
Expand Down
9 changes: 8 additions & 1 deletion src/debug/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <assert.h>

#include "core/joy.h"
#include "core/cpu.h"

#include "break.h"
#include "debug.h"
Expand Down Expand Up @@ -40,7 +41,12 @@ static void joy_input_event() {
}

static void joy_read_event() {
printf("JOY READ\n");
printf("JOY READ: Pad %.2X Buttons %.2X\n", (joy.state >> 4), (joy.state & 0x0F));
break_handle_event(current_event);
}

static void pc_address_event() {
// printf("PC: %.4X\n", PC);
break_handle_event(current_event);
}

Expand All @@ -54,6 +60,7 @@ void debug_event(event_t event) {
switch(event.type) {
case EVENT_JOY_INPUT: joy_input_event(); break;
case EVENT_JOY_NOTICED: joy_read_event(); break;
case EVENT_PROGRAM_COUNTER: pc_address_event(); break;
default:
assert(0);
}
Expand Down
7 changes: 6 additions & 1 deletion src/debug/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

typedef enum {
EVENT_JOY_INPUT,
EVENT_JOY_NOTICED
EVENT_JOY_NOTICED,
EVENT_PROGRAM_COUNTER
} EVENT_TYPE;

typedef struct {
Expand All @@ -17,6 +18,10 @@ typedef struct {
u8 button;
u8 state;
} joy;
// EVENT_PROGRAM_COUNTER
struct {
u16 pc;
} address;
};
} event_t;

Expand Down
8 changes: 8 additions & 0 deletions src/debug/watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ void watch_disable(int id) {
watchpoint_enabled[id] = 0;
}

void watch_clear() {
int i;
for (i = 0; i < WATCHPOINT_BUFFER_SIZE; i++) {
watch_disable(i);
}
watchpoint_cursor = 0;
}

void watch_event_mem_w(u16 addr, u8 a, u8 b) {
if (in_debug_scope()) {
return;
Expand Down