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();
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);

View File

@ -26,17 +26,24 @@ void decode_operands(ProgramView *view) {
pc += 1;
if (operand->addr_mode == ADDR_MODE_ACCUMULATOR || operand->addr_mode == ADDR_MODE_IMPLICIT) {
operand->value = 0;
} else if (operand->addr_mode == ADDR_MODE_RELATIVE || operand->addr_mode == ADDR_MODE_IMMEDIATE ||
operand->addr_mode == ADDR_MODE_ZERO_PAGE || operand->addr_mode == ADDR_MODE_ZERO_PAGE_INDEXED_X ||
operand->addr_mode == ADDR_MODE_ZERO_PAGE_INDEXED_Y) {
operand->value = view->ram[pc];
pc += 1;
} else {
operand->value = view->ram[pc];
operand->value += view->ram[pc + 1] << 8;
pc += 2;
switch (operand->addr_mode) {
case ADDR_MODE_ACCUMULATOR:
case ADDR_MODE_IMPLICIT:
operand->value = 0;
break;
case ADDR_MODE_RELATIVE:
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];
pc += 1;
break;
default:
operand->value = view->ram[pc];
operand->value += view->ram[pc + 1] << 8;
pc += 2;
break;
}
linked_list_add(&view->operands, operand);
@ -46,31 +53,31 @@ void decode_operands(ProgramView *view) {
char *get_addr_mode_format_str(AddressingMode addr_mode) {
switch (addr_mode) {
case ADDR_MODE_ABSOLUTE:
return "$%04x";
return "$%04x ";
case ADDR_MODE_ABSOLUTE_INDEXED_X:
return "$%04x,x";
return "$%04x,x ";
case ADDR_MODE_ABSOLUTE_INDEXED_Y:
return "$%04x,y";
return "$%04x,y ";
case ADDR_MODE_ACCUMULATOR:
return "A";
return "A ";
case ADDR_MODE_IMMEDIATE:
return "#$%02x";
return "#$%02x ";
case ADDR_MODE_IMPLICIT:
return "";
return " ";
case ADDR_MODE_INDIRECT_X:
return "($%04x,x)";
return "($%04x,x) ";
case ADDR_MODE_INDIRECT_JUMP:
return "($%04x)";
return "($%04x) ";
case ADDR_MODE_INDIRECT_Y:
return "($%04x),y";
return "($%04x),y ";
case ADDR_MODE_RELATIVE:
return "$%04x";
return "$%04x ";
case ADDR_MODE_ZERO_PAGE:
return "$%02x,y";
return "$%02x,y ";
case ADDR_MODE_ZERO_PAGE_INDEXED_X:
return "$%02x,x";
return "$%02x,x ";
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) {
DebugOperand *operand = (DebugOperand *) data;
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);
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);
}
void program_view_print(ProgramView *view) {
void pv_print(ProgramView *view) {
LinkedListNode *current_node = view->first_operand_node;
int line = 0;
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;
line++;
}
}
void program_view_cursor_init(ProgramView *view) {
void pv_cursor_init(ProgramView *view) {
window_inter_cursor_init(view->window, 0, 0xf);
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);
view->first_operand_node = match;
// Move the first node back until we do not overflow the NES memory
while (RAM_SIZE - target < 0xf) {
view->first_operand_node = view->first_operand_node->previous;
target--;
view->last_operand_node = view->first_operand_node;
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;
}
}
program_view_print(view);
pv_print(view);
}
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) {
view->first_operand_node = view->first_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->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) {
@ -152,7 +162,7 @@ void pv_handle_cursor_move(InteractWindow *window, int horizontal, int 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) {
Dialog dialog = dialog_create("Goto Address");
@ -173,7 +183,7 @@ void pv_deinit(InteractWindow *window) {
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));
view->window = interact;
view->ram = system->ram;
@ -182,7 +192,7 @@ void program_view_init(InteractWindow *interact, System *system, int x, int y) {
interact->view = view;
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;
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;
program_view_print(view);
program_view_cursor_init(view);
pv_print(view);
pv_cursor_init(view);
}

View File

@ -32,6 +32,6 @@ typedef struct program_view {
LinkedListNode *last_operand_node;
} 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

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 *near_node = list->head;
int last_distance;
int current_distance = 0xffffffff >> 1;
do {
int current_distance = predicate(near_node->data, userdata);
if (current_distance == 0) {
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;
near_node = near_node->next;
current_distance = predicate(near_node->data, userdata);
} while (current_distance < last_distance && near_node->next != NULL);
current_distance = predicate(node->data, userdata);
}
// After the loop, we have found the nearest node in the list, assuming there is only one point of convergence
return near_node;