diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index eeaa3f2..abbf0b3 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -12,6 +12,7 @@
+
@@ -24,59 +25,18 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -274,6 +234,11 @@
+
+
+
+
+
@@ -285,7 +250,7 @@
-
+
@@ -295,12 +260,17 @@
-
+
-
+
+
+
+
+
+
@@ -320,11 +290,6 @@
-
-
-
-
-
@@ -449,11 +414,14 @@
-
+
+
+
+
@@ -491,7 +459,9 @@
-
+
+
+
@@ -517,7 +487,15 @@
1703369431911
-
+
+
+ 1704569231622
+
+
+
+ 1704569231622
+
+
@@ -534,7 +512,8 @@
-
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0a746a7..cec06e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,12 +5,14 @@ add_subdirectory(cpu)
add_subdirectory(ppu)
add_subdirectory(mappers)
add_subdirectory(rom)
+add_subdirectory(debugger)
list(APPEND EXTRA_INCLUDES
"${PROJECT_SOURCE_DIR}/cpu"
"${PROJECT_SOURCE_DIR}/ppu"
"${PROJECT_SOURCE_DIR}/mappers"
- "${PROJECT_SOURCE_DIR}/rom")
+ "${PROJECT_SOURCE_DIR}/rom"
+ "${PROJECT_SOURCE_DIR}/debugger")
add_executable(NESEmulator main.c
system.c
@@ -19,7 +21,7 @@ add_executable(NESEmulator main.c
find_package(log.c)
-target_link_libraries(NESEmulator CPU PPU Mappers ROM log.c::log.c)
+target_link_libraries(NESEmulator CPU PPU Mappers ROM DEBUG log.c::log.c)
target_include_directories(NESEmulator PUBLIC
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES})
diff --git a/conandata.yml b/conandata.yml
index 72d8f52..69e9b4f 100644
--- a/conandata.yml
+++ b/conandata.yml
@@ -2,5 +2,6 @@
# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements
requirements:
+ - "ncurses/6.4"
- "libcheck/0.15.2"
- "log.c/cci.20200620"
\ No newline at end of file
diff --git a/debugger/CMakeLists.txt b/debugger/CMakeLists.txt
new file mode 100644
index 0000000..896d677
--- /dev/null
+++ b/debugger/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_library(DEBUG
+ debugger.c
+ memory_view.c
+ dialog.c)
+
+find_package(Curses)
+
+target_link_libraries(DEBUG Curses::Curses)
\ No newline at end of file
diff --git a/debugger/debugger.c b/debugger/debugger.c
new file mode 100644
index 0000000..48c0384
--- /dev/null
+++ b/debugger/debugger.c
@@ -0,0 +1,63 @@
+//
+// Created by william on 1/6/24.
+//
+
+#include
+#include
+#include
+#include "debugger.h"
+#include "memory_view.h"
+#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;
+
+void create_window() {
+ setenv("TERMINFO", "/usr/share/terminfo", 1);
+ setenv("TERM", "xterm", 1);
+
+ initscr();
+ raw();
+ noecho();
+// wborder(window, '|', '|', '-', '-', '+', '+', '+', '+');
+}
+
+void destroy_window() {
+ endwin();
+}
+
+void some_func(char* user_input) {
+}
+
+void start_debugger(System *system) {
+ create_window();
+
+ memory_view_init(&view, system->ram);
+
+ update_panels();
+ doupdate();
+
+ int keycode;
+ while ((keycode = getch()) != CTRL_KEY_EXIT) {
+ if (keycode == CTRL_KEY_UP) {
+ memory_view_scroll(&view, -1, system->ram);
+ }
+
+ if (keycode == CTRL_KEY_DOWN) {
+ memory_view_scroll(&view, 1, system->ram);
+ }
+
+ if (keycode == CTRL_KEY_G) {
+ Dialog dialog = dialog_create("Goto Address", &some_func);
+ }
+
+ update_panels();
+ doupdate();
+ }
+
+ endwin();
+}
\ No newline at end of file
diff --git a/debugger/debugger.h b/debugger/debugger.h
new file mode 100644
index 0000000..e27eb35
--- /dev/null
+++ b/debugger/debugger.h
@@ -0,0 +1,12 @@
+//
+// Created by william on 1/6/24.
+//
+
+#include "../include/system.h"
+
+#ifndef NESEMULATOR_DEBUGGER_H
+#define NESEMULATOR_DEBUGGER_H
+
+void start_debugger(System *system);
+
+#endif //NESEMULATOR_DEBUGGER_H
diff --git a/debugger/dialog.c b/debugger/dialog.c
new file mode 100644
index 0000000..b7b56f2
--- /dev/null
+++ b/debugger/dialog.c
@@ -0,0 +1,21 @@
+//
+// Created by william on 1/7/24.
+//
+
+#include
+#include "dialog.h"
+
+Dialog dialog_create(char *message, void (*callback)(char *user_input)) {
+ Dialog dialog;
+ int width = (int) strlen(message) + 2;
+
+ WINDOW *window = newwin(3, width, 2, 2);
+ box(window, 0, 0);
+
+ mvwprintw(window, 0, 1, "%s", message);
+
+ dialog.panel = new_panel(window);
+ dialog.callback = callback;
+
+ return dialog;
+}
diff --git a/debugger/dialog.h b/debugger/dialog.h
new file mode 100644
index 0000000..7febd66
--- /dev/null
+++ b/debugger/dialog.h
@@ -0,0 +1,18 @@
+//
+// Created by william on 1/7/24.
+//
+
+#ifndef NESEMULATOR_DIALOG_H
+#define NESEMULATOR_DIALOG_H
+
+#include
+
+typedef struct dialog {
+ PANEL *panel;
+
+ void (*callback)(char *user_input);
+} Dialog;
+
+Dialog dialog_create(char *message, void (*callback)(char *user_input));
+
+#endif //NESEMULATOR_DIALOG_H
diff --git a/debugger/memory_view.c b/debugger/memory_view.c
new file mode 100644
index 0000000..8062892
--- /dev/null
+++ b/debugger/memory_view.c
@@ -0,0 +1,65 @@
+#include
+#include
+#include
+#include "memory_view.h"
+
+//
+// Created by william on 1/6/24.
+//
+
+void write_line(WINDOW *window, int line, address base_address, byte *data) {
+ mvwprintw(window, line + 2, 1, "[%04x]", base_address);
+
+ for (int i = 0; i <= MEMORY_VIEW_LINE_BYTE_COUNT; i++) {
+ mvwprintw(window, line + 2, 8 + i * 3, "%02x", data[i]);
+ }
+}
+
+void memory_view_init(MemoryView *view, ram ram) {
+ WINDOW *window = newwin(MEMORY_VIEW_HEIGHT, MEMORY_VIEW_WIDTH, 0, 0);
+ box(window, 0, 0);
+
+ mvwprintw(window, 0, 1, " MEMORY VIEW ");
+ 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;
+
+ memory_view_print(view, ram);
+}
+
+void memory_view_print(MemoryView *view, ram ram) {
+ 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];
+
+ write_line(view->panel->win, line, line_address, data);
+ }
+}
+
+void memory_view_goto(MemoryView *view, address target, ram ram) {
+ assert(target < RAM_SIZE);
+
+ address max_base_address = RAM_SIZE - MEMORY_VIEW_BYTE_COUNT;
+ if (target > max_base_address) {
+ target = max_base_address;
+ }
+
+ view->base_address = target;
+ memory_view_print(view, ram);
+}
+
+void memory_view_scroll(MemoryView *view, char direction, ram ram) {
+ assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP);
+
+ int offset = 0;
+ if (direction == MEMORY_VIEW_DIRECTION_DOWN && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) {
+ offset -= MEMORY_VIEW_LINE_BYTE_COUNT + 1;
+ }
+ if (direction == MEMORY_VIEW_DIRECTION_UP && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) {
+ offset += MEMORY_VIEW_LINE_BYTE_COUNT + 1;
+ }
+
+ address target = view->base_address + offset;
+ memory_view_goto(view, target, ram);
+}
\ No newline at end of file
diff --git a/debugger/memory_view.h b/debugger/memory_view.h
new file mode 100644
index 0000000..42bb8d8
--- /dev/null
+++ b/debugger/memory_view.h
@@ -0,0 +1,33 @@
+//
+// Created by william on 1/6/24.
+//
+
+#ifndef NESEMULATOR_MEMORY_VIEW_H
+#define NESEMULATOR_MEMORY_VIEW_H
+
+#include
+#include "../include/types.h"
+
+#define MEMORY_VIEW_HEIGHT 19
+#define MEMORY_VIEW_WIDTH 56
+#define MEMORY_VIEW_LINE_COUNT 0xf
+#define MEMORY_VIEW_LINE_BYTE_COUNT 0xf
+#define MEMORY_VIEW_BYTE_COUNT 0xff
+
+#define MEMORY_VIEW_DIRECTION_UP 1
+#define MEMORY_VIEW_DIRECTION_DOWN -1
+
+typedef struct memory_view {
+ PANEL *panel;
+ address base_address;
+} MemoryView;
+
+void memory_view_init(MemoryView *view, ram ram);
+
+void memory_view_print(MemoryView *view, ram ram);
+
+void memory_view_goto(MemoryView *view, address target, ram ram);
+
+void memory_view_scroll(MemoryView *view, char direction, ram ram);
+
+#endif //NESEMULATOR_MEMORY_VIEW_H
diff --git a/main.c b/main.c
index 6a795f9..68d73d4 100644
--- a/main.c
+++ b/main.c
@@ -17,26 +17,50 @@
*/
#include
#include
+#include "debugger/debugger.h"
#include "include/rom.h"
#include "include/system.h"
-int main() {
- log_set_level(LOG_INFO);
+//int win() {
+// printf("NCURSES\n");
+//
+// setlocale(LC_ALL, "");
+// setenv("TERM", "xterm-256color", 1);
+// setenv("TERMINFO", "/usr/share/terminfo", 1);
+//
+// initscr();
+// printw("Hello World !!!");
+// refresh();
+// getch();
+// endwin();
+//
+// return EXIT_SUCCESS;
+//}
- char *rom_path = "../test_roms/nestest.nes";
+int main() {
System system;
+ log_set_level(LOG_INFO);
system_init(&system);
+ char *rom_path = "../test_roms/nestest.nes";
+
if (!rom_load(rom_path, &system)) {
system_uninit(&system);
return EXIT_FAILURE;
}
- system_start(&system);
- system_loop(&system);
- system_uninit(&system);
+ start_debugger(&system);
- return EXIT_SUCCESS;
+ system_uninit(&system);
+ return 0;
+//
+// system_start(&system);
+// system_loop(&system);
+// system_uninit(&system);
+
+// return EXIT_SUCCESS;
+
+// return win();
}
\ No newline at end of file