From 4a44443dc7ef774845addd6b4e49b28944a5ef6f Mon Sep 17 00:00:00 2001 From: william Date: Tue, 9 Jan 2024 14:46:20 -0500 Subject: [PATCH] Finished read-only memory debugger --- .idea/workspace.xml | 34 +++++++++++-------- debugger/debugger.c | 39 +++++++++++++-------- debugger/dialog.c | 77 +++++++++++++++++++++++++++++++++++++++--- debugger/dialog.h | 9 +++-- debugger/memory_view.c | 71 +++++++++++++++++++++++++++++++++----- debugger/memory_view.h | 15 +++++--- 6 files changed, 194 insertions(+), 51 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index abbf0b3..70af33d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -25,18 +25,13 @@ - - - - - - - - + - - - + + + + + @@ -513,7 +516,8 @@ - diff --git a/debugger/debugger.c b/debugger/debugger.c index 48c0384..54257d8 100644 --- a/debugger/debugger.c +++ b/debugger/debugger.c @@ -10,8 +10,6 @@ #include "dialog.h" #define CTRL_KEY_EXIT 3 -#define CTRL_KEY_UP 65 -#define CTRL_KEY_DOWN 66 #define CTRL_KEY_G 103 MemoryView view; @@ -23,14 +21,8 @@ void create_window() { initscr(); raw(); noecho(); -// wborder(window, '|', '|', '-', '-', '+', '+', '+', '+'); -} - -void destroy_window() { - endwin(); -} - -void some_func(char* user_input) { + curs_set(0); + keypad(stdscr, true); } void start_debugger(System *system) { @@ -43,16 +35,33 @@ void start_debugger(System *system) { int keycode; while ((keycode = getch()) != CTRL_KEY_EXIT) { - if (keycode == CTRL_KEY_UP) { - memory_view_scroll(&view, -1, system->ram); + if (keycode == KEY_UP) { + memory_view_move_cursor(&view, 0, -1); } - if (keycode == CTRL_KEY_DOWN) { - memory_view_scroll(&view, 1, system->ram); + if (keycode == KEY_DOWN) { + memory_view_move_cursor(&view, 0, 1); + } + + if (keycode == KEY_LEFT) { + memory_view_move_cursor(&view, -1, 0); + } + + if (keycode == KEY_RIGHT) { + memory_view_move_cursor(&view, 1, 0); } if (keycode == CTRL_KEY_G) { - Dialog dialog = dialog_create("Goto Address", &some_func); + Dialog dialog = dialog_create("Goto Address"); + + bool cancelled = false; + address input = dialog_get_address(&dialog, &cancelled); + dialog_remove(&dialog); + + if (!cancelled) { + memory_view_goto(&view, input); + memory_view_set_cursor_addr(&view, input); + } } update_panels(); diff --git a/debugger/dialog.c b/debugger/dialog.c index b7b56f2..560d90b 100644 --- a/debugger/dialog.c +++ b/debugger/dialog.c @@ -5,17 +5,84 @@ #include #include "dialog.h" -Dialog dialog_create(char *message, void (*callback)(char *user_input)) { - Dialog dialog; - int width = (int) strlen(message) + 2; +#define DIALOG_KEY_CONFIRM 10 +#define DIALOG_KEY_EXIT 27 +#define DIALOG_KEY_DELETE 127 +#define DIALOG_KEY_DIGIT_MIN 48 +#define DIALOG_KEY_DIGIT_MAX 57 +#define DIALOG_KEY_ALPHA_MIN 97 +#define DIALOG_KEY_ALPHA_MAX 102 - WINDOW *window = newwin(3, width, 2, 2); +Dialog dialog_create(char *message) { + Dialog dialog; + + int termHeight = getmaxy(stdscr); + int termWidth = getmaxx(stdscr); + + int height = 3; + int width = (int) strlen(message) + 2; + if (width % 2 == 1) { + width += 1; + } + + int y = termHeight / 2 - (height / 2); + int x = termWidth / 2 - (width / 2); + + WINDOW *window = newwin(height, width, y, x); box(window, 0, 0); mvwprintw(window, 0, 1, "%s", message); + wmove(window, 1, 1); dialog.panel = new_panel(window); - dialog.callback = callback; return dialog; } + +address dialog_get_address(Dialog *dialog, bool *cancelled) { + int input_length = 0; + address out = 0; + + int keycode; + while ((keycode = wgetch(dialog->panel->win)) != DIALOG_KEY_CONFIRM) { + if (keycode == DIALOG_KEY_EXIT) { + *cancelled = true; + return 0; + } + + if (input_length > 0 && keycode == DIALOG_KEY_DELETE) { + int offset = 16 - (4 * input_length); + address mask = 0xf << offset; + out &= ~mask; + + input_length--; + mvwprintw(dialog->panel->win, 1, 1 + input_length, " "); + wmove(dialog->panel->win, 1, 1 + input_length); + } + + if (input_length < 4 && keycode >= DIALOG_KEY_DIGIT_MIN && keycode <= DIALOG_KEY_ALPHA_MAX) { + int digit = keycode - DIALOG_KEY_DIGIT_MIN; // 0-9 + if (digit > 9) { + if (keycode >= DIALOG_KEY_ALPHA_MIN) { // A-F + digit -= DIALOG_KEY_ALPHA_MIN - DIALOG_KEY_DIGIT_MAX - 1; + } else { + // Anything else + continue; + } + } + + int offset = 12 - (4 * input_length); + out += digit << offset; + + mvwprintw(dialog->panel->win, 1, 1 + input_length, "%c", keycode); + + input_length++; + } + } + + return out; +} + +void dialog_remove(Dialog *dialog) { + del_panel(dialog->panel); +} \ No newline at end of file diff --git a/debugger/dialog.h b/debugger/dialog.h index 7febd66..99fc583 100644 --- a/debugger/dialog.h +++ b/debugger/dialog.h @@ -6,13 +6,16 @@ #define NESEMULATOR_DIALOG_H #include +#include "../include/types.h" typedef struct dialog { PANEL *panel; - - void (*callback)(char *user_input); } Dialog; -Dialog dialog_create(char *message, void (*callback)(char *user_input)); +Dialog dialog_create(char *message); + +address dialog_get_address(Dialog *dialog, bool *cancelled); + +void dialog_remove(Dialog *dialog); #endif //NESEMULATOR_DIALOG_H diff --git a/debugger/memory_view.c b/debugger/memory_view.c index 8062892..6281792 100644 --- a/debugger/memory_view.c +++ b/debugger/memory_view.c @@ -7,6 +7,29 @@ // Created by william on 1/6/24. // +void memory_view_highlight_cursor(MemoryView *view) { + int win_x = 8 + view->cursor_x * 3; + int win_y = 2 + view->cursor_y; + mvwchgat(view->panel->win, win_y, win_x, 2, A_REVERSE, 0, NULL); +} + +void memory_view_set_cursor_pos(MemoryView *view, int x, int y) { + assert(x >= 0); + assert(x <= 0xf); + assert(y >= 0); + assert(y <= 0xf); + + int old_win_x = 8 + view->cursor_x * 3; + int old_win_y = 2 + view->cursor_y; + + mvwchgat(view->panel->win, old_win_y, old_win_x, 2, A_NORMAL, 0, NULL); + + view->cursor_x = (char) x; + view->cursor_y = (char) y; + + memory_view_highlight_cursor(view); +} + void write_line(WINDOW *window, int line, address base_address, byte *data) { mvwprintw(window, line + 2, 1, "[%04x]", base_address); @@ -23,21 +46,25 @@ void memory_view_init(MemoryView *view, ram ram) { mvwprintw(window, 1, 1, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f"); view->panel = new_panel(window); - view->base_address = 0xfc00; + view->ram = ram; + view->base_address = 0x0000; + view->cursor_x = 0; + view->cursor_y = 0; - memory_view_print(view, ram); + memory_view_print(view); + memory_view_set_cursor_pos(view, 0, 0); } -void memory_view_print(MemoryView *view, ram ram) { +void memory_view_print(MemoryView *view) { for (int line = 0; line <= MEMORY_VIEW_LINE_COUNT; line++) { address line_address = view->base_address + line * (MEMORY_VIEW_LINE_BYTE_COUNT + 1); - byte *data = &ram[line_address]; + byte *data = &view->ram[line_address]; write_line(view->panel->win, line, line_address, data); } } -void memory_view_goto(MemoryView *view, address target, ram ram) { +void memory_view_goto(MemoryView *view, address target) { assert(target < RAM_SIZE); address max_base_address = RAM_SIZE - MEMORY_VIEW_BYTE_COUNT; @@ -45,11 +72,12 @@ void memory_view_goto(MemoryView *view, address target, ram ram) { target = max_base_address; } - view->base_address = target; - memory_view_print(view, ram); + address line_addr = target & 0xfff0; + view->base_address = line_addr; + memory_view_print(view); } -void memory_view_scroll(MemoryView *view, char direction, ram ram) { +void memory_view_scroll(MemoryView *view, char direction) { assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP); int offset = 0; @@ -61,5 +89,30 @@ void memory_view_scroll(MemoryView *view, char direction, ram ram) { } address target = view->base_address + offset; - memory_view_goto(view, target, ram); + memory_view_goto(view, target); +} + +void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical) { + if (horizontal == 1 && view->cursor_x == 0xf || + horizontal == -1 && view->cursor_x == 0) { + return; + } + + if (vertical == 1 && view->cursor_y == 0xf || + vertical == -1 && view->cursor_y == 0) { + memory_view_scroll(view, vertical); + return; + } + + int target_x = view->cursor_x + horizontal; + int target_y = view->cursor_y + vertical; + memory_view_set_cursor_pos(view, target_x, target_y); +} + +void memory_view_set_cursor_addr(MemoryView *view, address target) { + int view_byte = target - view->base_address; + + int x = view_byte & 0x0f; + int y = (view_byte & 0xf0) >> 4; + memory_view_set_cursor_pos(view, x, y); } \ No newline at end of file diff --git a/debugger/memory_view.h b/debugger/memory_view.h index 42bb8d8..e2e2882 100644 --- a/debugger/memory_view.h +++ b/debugger/memory_view.h @@ -15,19 +15,26 @@ #define MEMORY_VIEW_BYTE_COUNT 0xff #define MEMORY_VIEW_DIRECTION_UP 1 -#define MEMORY_VIEW_DIRECTION_DOWN -1 +#define MEMORY_VIEW_DIRECTION_DOWN (-1) typedef struct memory_view { PANEL *panel; + byte *ram; address base_address; + char cursor_x; + char cursor_y; } MemoryView; void memory_view_init(MemoryView *view, ram ram); -void memory_view_print(MemoryView *view, ram ram); +void memory_view_print(MemoryView *view); -void memory_view_goto(MemoryView *view, address target, ram ram); +void memory_view_goto(MemoryView *view, address target); -void memory_view_scroll(MemoryView *view, char direction, ram ram); +void memory_view_scroll(MemoryView *view, char direction); + +void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical); + +void memory_view_set_cursor_addr(MemoryView *view, address target); #endif //NESEMULATOR_MEMORY_VIEW_H