Fix program view debugger goto

This commit is contained in:
FyloZ 2024-04-08 14:19:59 -04:00
parent 4148f80360
commit d0562fdea4
Signed by: william
GPG Key ID: 835378AE9AF4AE97
4 changed files with 65 additions and 49 deletions

View File

@ -29,7 +29,7 @@ void start_debugger(System *system) {
create_window(); create_window();
memory_view_init(&windows[0], system->ram, 0, 0); memory_view_init(&windows[0], system->ram, 0, 0);
program_view_init(&windows[1], system, MEMORY_VIEW_WIDTH, 0); pv_init(&windows[1], system, MEMORY_VIEW_WIDTH, 0);
cursor_enable(&current_window->cursor); cursor_enable(&current_window->cursor);

View File

@ -26,17 +26,24 @@ void decode_operands(ProgramView *view) {
pc += 1; pc += 1;
if (operand->addr_mode == ADDR_MODE_ACCUMULATOR || operand->addr_mode == ADDR_MODE_IMPLICIT) { switch (operand->addr_mode) {
case ADDR_MODE_ACCUMULATOR:
case ADDR_MODE_IMPLICIT:
operand->value = 0; operand->value = 0;
} else if (operand->addr_mode == ADDR_MODE_RELATIVE || operand->addr_mode == ADDR_MODE_IMMEDIATE || break;
operand->addr_mode == ADDR_MODE_ZERO_PAGE || operand->addr_mode == ADDR_MODE_ZERO_PAGE_INDEXED_X || case ADDR_MODE_RELATIVE:
operand->addr_mode == ADDR_MODE_ZERO_PAGE_INDEXED_Y) { case ADDR_MODE_IMMEDIATE:
case ADDR_MODE_ZERO_PAGE:
case ADDR_MODE_ZERO_PAGE_INDEXED_X:
case ADDR_MODE_ZERO_PAGE_INDEXED_Y:
operand->value = view->ram[pc]; operand->value = view->ram[pc];
pc += 1; pc += 1;
} else { break;
default:
operand->value = view->ram[pc]; operand->value = view->ram[pc];
operand->value += view->ram[pc + 1] << 8; operand->value += view->ram[pc + 1] << 8;
pc += 2; pc += 2;
break;
} }
linked_list_add(&view->operands, operand); linked_list_add(&view->operands, operand);
@ -46,31 +53,31 @@ void decode_operands(ProgramView *view) {
char *get_addr_mode_format_str(AddressingMode addr_mode) { char *get_addr_mode_format_str(AddressingMode addr_mode) {
switch (addr_mode) { switch (addr_mode) {
case ADDR_MODE_ABSOLUTE: case ADDR_MODE_ABSOLUTE:
return "$%04x"; return "$%04x ";
case ADDR_MODE_ABSOLUTE_INDEXED_X: case ADDR_MODE_ABSOLUTE_INDEXED_X:
return "$%04x,x"; return "$%04x,x ";
case ADDR_MODE_ABSOLUTE_INDEXED_Y: case ADDR_MODE_ABSOLUTE_INDEXED_Y:
return "$%04x,y"; return "$%04x,y ";
case ADDR_MODE_ACCUMULATOR: case ADDR_MODE_ACCUMULATOR:
return "A"; return "A ";
case ADDR_MODE_IMMEDIATE: case ADDR_MODE_IMMEDIATE:
return "#$%02x"; return "#$%02x ";
case ADDR_MODE_IMPLICIT: case ADDR_MODE_IMPLICIT:
return ""; return " ";
case ADDR_MODE_INDIRECT_X: case ADDR_MODE_INDIRECT_X:
return "($%04x,x)"; return "($%04x,x) ";
case ADDR_MODE_INDIRECT_JUMP: case ADDR_MODE_INDIRECT_JUMP:
return "($%04x)"; return "($%04x) ";
case ADDR_MODE_INDIRECT_Y: case ADDR_MODE_INDIRECT_Y:
return "($%04x),y"; return "($%04x),y ";
case ADDR_MODE_RELATIVE: case ADDR_MODE_RELATIVE:
return "$%04x"; return "$%04x ";
case ADDR_MODE_ZERO_PAGE: case ADDR_MODE_ZERO_PAGE:
return "$%02x,y"; return "$%02x,y ";
case ADDR_MODE_ZERO_PAGE_INDEXED_X: case ADDR_MODE_ZERO_PAGE_INDEXED_X:
return "$%02x,x"; return "$%02x,x ";
case ADDR_MODE_ZERO_PAGE_INDEXED_Y: case ADDR_MODE_ZERO_PAGE_INDEXED_Y:
return "$%02x,y"; return "$%02x,y ";
} }
} }
@ -83,10 +90,10 @@ bool pv_predicate_operand_by_addr(void *data, void *userdata) {
int pv_predicate_operand_distance(void *data, void *userdata) { int pv_predicate_operand_distance(void *data, void *userdata) {
DebugOperand *operand = (DebugOperand *) data; DebugOperand *operand = (DebugOperand *) data;
address *addr = (address *) userdata; address *addr = (address *) userdata;
return operand->addr - *addr; return abs(operand->addr - *addr);
} }
void program_view_write_line(ProgramView *view, int line, DebugOperand *operand) { void pv_write_line(ProgramView *view, int line, DebugOperand *operand) {
char *op_name = get_op_code_name(operand->op_code); char *op_name = get_op_code_name(operand->op_code);
window_inter_print(view->window, 0, line, "%04x:", operand->addr); window_inter_print(view->window, 0, line, "%04x:", operand->addr);
@ -96,17 +103,17 @@ void program_view_write_line(ProgramView *view, int line, DebugOperand *operand)
window_inter_print(view->window, 16, line, format, operand->value); window_inter_print(view->window, 16, line, format, operand->value);
} }
void program_view_print(ProgramView *view) { void pv_print(ProgramView *view) {
LinkedListNode *current_node = view->first_operand_node; LinkedListNode *current_node = view->first_operand_node;
int line = 0; int line = 0;
while (line <= 0xf && current_node != NULL) { while (line <= 0xf && current_node != NULL) {
program_view_write_line(view, line, (DebugOperand *) current_node->data); pv_write_line(view, line, (DebugOperand *) current_node->data);
current_node = current_node->next; current_node = current_node->next;
line++; line++;
} }
} }
void program_view_cursor_init(ProgramView *view) { void pv_cursor_init(ProgramView *view) {
window_inter_cursor_init(view->window, 0, 0xf); window_inter_cursor_init(view->window, 0, 0xf);
view->window->cursor.width = PROGRAM_VIEW_WIDTH - 2; view->window->cursor.width = PROGRAM_VIEW_WIDTH - 2;
} }
@ -117,13 +124,16 @@ void pv_goto(ProgramView *view, address target) {
LinkedListNode *match = linked_list_get_near(&view->operands, &pv_predicate_operand_distance, &target); LinkedListNode *match = linked_list_get_near(&view->operands, &pv_predicate_operand_distance, &target);
view->first_operand_node = match; view->first_operand_node = match;
// Move the first node back until we do not overflow the NES memory view->last_operand_node = view->first_operand_node;
while (RAM_SIZE - target < 0xf) { for (int i = 0; i < 0xf; i++) {
if (view->last_operand_node->next != NULL) {
view->last_operand_node = view->last_operand_node->next;
} else {
view->first_operand_node = view->first_operand_node->previous; view->first_operand_node = view->first_operand_node->previous;
target--; }
} }
program_view_print(view); pv_print(view);
} }
void pv_scroll(ProgramView *view, int direction) { void pv_scroll(ProgramView *view, int direction) {
@ -132,12 +142,12 @@ void pv_scroll(ProgramView *view, int direction) {
if (direction == CURSOR_OFFSET_UP && view->first_operand_node->previous != NULL) { if (direction == CURSOR_OFFSET_UP && view->first_operand_node->previous != NULL) {
view->first_operand_node = view->first_operand_node->previous; view->first_operand_node = view->first_operand_node->previous;
view->last_operand_node = view->last_operand_node->previous; view->last_operand_node = view->last_operand_node->previous;
} else if (view->last_operand_node->next != NULL) { } else if (direction == CURSOR_OFFSET_DOWN && view->last_operand_node->next != NULL) {
view->first_operand_node = view->first_operand_node->next; view->first_operand_node = view->first_operand_node->next;
view->last_operand_node = view->last_operand_node->next; view->last_operand_node = view->last_operand_node->next;
} }
program_view_print(view); pv_print(view);
} }
void pv_handle_cursor_move(InteractWindow *window, int horizontal, int vertical) { void pv_handle_cursor_move(InteractWindow *window, int horizontal, int vertical) {
@ -152,7 +162,7 @@ void pv_handle_cursor_move(InteractWindow *window, int horizontal, int vertical)
cursor_move(&window->cursor, horizontal, vertical); cursor_move(&window->cursor, horizontal, vertical);
} }
void program_view_handle_key_down(InteractWindow *window, int keycode) { void pv_handle_key_down(InteractWindow *window, int keycode) {
if (keycode == KEY_GOTO) { if (keycode == KEY_GOTO) {
Dialog dialog = dialog_create("Goto Address"); Dialog dialog = dialog_create("Goto Address");
@ -173,7 +183,7 @@ void pv_deinit(InteractWindow *window) {
linked_list_uninit(&view->operands); linked_list_uninit(&view->operands);
} }
void program_view_init(InteractWindow *interact, System *system, int x, int y) { void pv_init(InteractWindow *interact, System *system, int x, int y) {
ProgramView *view = malloc(sizeof(ProgramView)); ProgramView *view = malloc(sizeof(ProgramView));
view->window = interact; view->window = interact;
view->ram = system->ram; view->ram = system->ram;
@ -182,7 +192,7 @@ void program_view_init(InteractWindow *interact, System *system, int x, int y) {
interact->view = view; interact->view = view;
interact->handle_cursor_move = &pv_handle_cursor_move; interact->handle_cursor_move = &pv_handle_cursor_move;
interact->handle_key_down = &program_view_handle_key_down; interact->handle_key_down = &pv_handle_key_down;
interact->deinit = &pv_deinit; interact->deinit = &pv_deinit;
window_inter_init(interact, x, y, PROGRAM_VIEW_WIDTH, PROGRAM_VIEW_HEIGHT, "PROGRAM VIEW"); window_inter_init(interact, x, y, PROGRAM_VIEW_WIDTH, PROGRAM_VIEW_HEIGHT, "PROGRAM VIEW");
@ -194,6 +204,6 @@ void program_view_init(InteractWindow *interact, System *system, int x, int y) {
} }
view->last_operand_node = last_node; view->last_operand_node = last_node;
program_view_print(view); pv_print(view);
program_view_cursor_init(view); pv_cursor_init(view);
} }

View File

@ -32,6 +32,6 @@ typedef struct program_view {
LinkedListNode *last_operand_node; LinkedListNode *last_operand_node;
} ProgramView; } ProgramView;
void program_view_init(InteractWindow *interact, System *system, int x, int y); void pv_init(InteractWindow *interact, System *system, int x, int y);
#endif //NESEMULATOR_PROGRAM_VIEW_H #endif //NESEMULATOR_PROGRAM_VIEW_H

View File

@ -54,13 +54,19 @@ LinkedListNode *linked_list_get_if(LinkedList *list, bool(*predicate)(void *, vo
LinkedListNode *linked_list_get_near(LinkedList *list, int(*predicate)(void *, void *), void *userdata) { LinkedListNode *linked_list_get_near(LinkedList *list, int(*predicate)(void *, void *), void *userdata) {
LinkedListNode *near_node = list->head; LinkedListNode *near_node = list->head;
int last_distance; int current_distance = predicate(near_node->data, userdata);
int current_distance = 0xffffffff >> 1; if (current_distance == 0) {
do { return near_node;
}
// TODO
int last_distance = 0x7fffffff;
LinkedListNode *node = near_node->next;
while (current_distance < last_distance && near_node->next != NULL) {
node = near_node->next;
last_distance = current_distance; last_distance = current_distance;
near_node = near_node->next; current_distance = predicate(node->data, userdata);
current_distance = predicate(near_node->data, userdata); }
} while (current_distance < last_distance && near_node->next != NULL);
// After the loop, we have found the nearest node in the list, assuming there is only one point of convergence // After the loop, we have found the nearest node in the list, assuming there is only one point of convergence
return near_node; return near_node;