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 @@
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
@@ -265,7 +260,7 @@
-
+
@@ -461,7 +456,7 @@
-
+
@@ -495,7 +490,15 @@
1704569231622
-
+
+
+ 1704662439962
+
+
+
+ 1704662439962
+
+
@@ -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