Finished read-only memory debugger
This commit is contained in:
parent
084cbed0f4
commit
4a44443dc7
|
@ -25,18 +25,13 @@
|
||||||
</configurations>
|
</configurations>
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="0c3b231e-0637-4ac1-8964-c60fc9e9e691" name="Changes" comment="Things">
|
<list default="true" id="0c3b231e-0637-4ac1-8964-c60fc9e9e691" name="Changes" comment="Memory debugger">
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/CMakeLists.txt" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/debugger.c" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/debugger.h" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/dialog.c" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/dialog.h" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/memory_view.c" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/debugger/memory_view.h" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/CMakeLists.txt" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/debugger/debugger.c" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/debugger.c" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/conandata.yml" beforeDir="false" afterPath="$PROJECT_DIR$/conandata.yml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/debugger/dialog.c" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/dialog.c" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/main.c" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/debugger/dialog.h" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/dialog.h" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/debugger/memory_view.c" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/memory_view.c" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/debugger/memory_view.h" beforeDir="false" afterPath="$PROJECT_DIR$/debugger/memory_view.h" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
@ -265,7 +260,7 @@
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="NESEmulator (Term)" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-- $CMakeCurrentBuildDir$/NESEmulator" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="true" PASS_PARENT_ENVS_2="true" PROJECT_NAME="NESEmulator" TARGET_NAME="NESEmulator" CONFIG_NAME="Debug" RUN_PATH="/usr/bin/gnome-terminal">
|
<configuration name="NESEmulator (Term)" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-- $CMakeCurrentBuildDir$/NESEmulator" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="NESEmulator" TARGET_NAME="NESEmulator" CONFIG_NAME="Debug" RUN_PATH="/usr/bin/gnome-terminal">
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
@ -461,7 +456,7 @@
|
||||||
<workItem from="1704501418104" duration="8204000" />
|
<workItem from="1704501418104" duration="8204000" />
|
||||||
<workItem from="1704569084127" duration="8903000" />
|
<workItem from="1704569084127" duration="8903000" />
|
||||||
<workItem from="1704582152049" duration="7863000" />
|
<workItem from="1704582152049" duration="7863000" />
|
||||||
<workItem from="1704660072645" duration="2354000" />
|
<workItem from="1704660072645" duration="15399000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="Cpu opcodes implementation">
|
<task id="LOCAL-00001" summary="Cpu opcodes implementation">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
|
@ -495,7 +490,15 @@
|
||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1704569231622</updated>
|
<updated>1704569231622</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="5" />
|
<task id="LOCAL-00005" summary="Memory debugger">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1704662439962</created>
|
||||||
|
<option name="number" value="00005" />
|
||||||
|
<option name="presentableId" value="LOCAL-00005" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1704662439962</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="6" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
@ -513,7 +516,8 @@
|
||||||
<MESSAGE value="Gitignore" />
|
<MESSAGE value="Gitignore" />
|
||||||
<MESSAGE value="Added logging for operand decoding" />
|
<MESSAGE value="Added logging for operand decoding" />
|
||||||
<MESSAGE value="Things" />
|
<MESSAGE value="Things" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Things" />
|
<MESSAGE value="Memory debugger" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Memory debugger" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
|
|
||||||
#define CTRL_KEY_EXIT 3
|
#define CTRL_KEY_EXIT 3
|
||||||
#define CTRL_KEY_UP 65
|
|
||||||
#define CTRL_KEY_DOWN 66
|
|
||||||
#define CTRL_KEY_G 103
|
#define CTRL_KEY_G 103
|
||||||
|
|
||||||
MemoryView view;
|
MemoryView view;
|
||||||
|
@ -23,14 +21,8 @@ void create_window() {
|
||||||
initscr();
|
initscr();
|
||||||
raw();
|
raw();
|
||||||
noecho();
|
noecho();
|
||||||
// wborder(window, '|', '|', '-', '-', '+', '+', '+', '+');
|
curs_set(0);
|
||||||
}
|
keypad(stdscr, true);
|
||||||
|
|
||||||
void destroy_window() {
|
|
||||||
endwin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void some_func(char* user_input) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_debugger(System *system) {
|
void start_debugger(System *system) {
|
||||||
|
@ -43,16 +35,33 @@ void start_debugger(System *system) {
|
||||||
|
|
||||||
int keycode;
|
int keycode;
|
||||||
while ((keycode = getch()) != CTRL_KEY_EXIT) {
|
while ((keycode = getch()) != CTRL_KEY_EXIT) {
|
||||||
if (keycode == CTRL_KEY_UP) {
|
if (keycode == KEY_UP) {
|
||||||
memory_view_scroll(&view, -1, system->ram);
|
memory_view_move_cursor(&view, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == CTRL_KEY_DOWN) {
|
if (keycode == KEY_DOWN) {
|
||||||
memory_view_scroll(&view, 1, system->ram);
|
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) {
|
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();
|
update_panels();
|
||||||
|
|
|
@ -5,17 +5,84 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
|
|
||||||
Dialog dialog_create(char *message, void (*callback)(char *user_input)) {
|
#define DIALOG_KEY_CONFIRM 10
|
||||||
Dialog dialog;
|
#define DIALOG_KEY_EXIT 27
|
||||||
int width = (int) strlen(message) + 2;
|
#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);
|
box(window, 0, 0);
|
||||||
|
|
||||||
mvwprintw(window, 0, 1, "%s", message);
|
mvwprintw(window, 0, 1, "%s", message);
|
||||||
|
wmove(window, 1, 1);
|
||||||
|
|
||||||
dialog.panel = new_panel(window);
|
dialog.panel = new_panel(window);
|
||||||
dialog.callback = callback;
|
|
||||||
|
|
||||||
return dialog;
|
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);
|
||||||
|
}
|
|
@ -6,13 +6,16 @@
|
||||||
#define NESEMULATOR_DIALOG_H
|
#define NESEMULATOR_DIALOG_H
|
||||||
|
|
||||||
#include <panel.h>
|
#include <panel.h>
|
||||||
|
#include "../include/types.h"
|
||||||
|
|
||||||
typedef struct dialog {
|
typedef struct dialog {
|
||||||
PANEL *panel;
|
PANEL *panel;
|
||||||
|
|
||||||
void (*callback)(char *user_input);
|
|
||||||
} Dialog;
|
} 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
|
#endif //NESEMULATOR_DIALOG_H
|
||||||
|
|
|
@ -7,6 +7,29 @@
|
||||||
// Created by william on 1/6/24.
|
// 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) {
|
void write_line(WINDOW *window, int line, address base_address, byte *data) {
|
||||||
mvwprintw(window, line + 2, 1, "[%04x]", base_address);
|
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");
|
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->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++) {
|
for (int line = 0; line <= MEMORY_VIEW_LINE_COUNT; line++) {
|
||||||
address line_address = view->base_address + line * (MEMORY_VIEW_LINE_BYTE_COUNT + 1);
|
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);
|
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);
|
assert(target < RAM_SIZE);
|
||||||
|
|
||||||
address max_base_address = RAM_SIZE - MEMORY_VIEW_BYTE_COUNT;
|
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;
|
target = max_base_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
view->base_address = target;
|
address line_addr = target & 0xfff0;
|
||||||
memory_view_print(view, ram);
|
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);
|
assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -61,5 +89,30 @@ void memory_view_scroll(MemoryView *view, char direction, ram ram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
address target = view->base_address + offset;
|
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);
|
||||||
}
|
}
|
|
@ -15,19 +15,26 @@
|
||||||
#define MEMORY_VIEW_BYTE_COUNT 0xff
|
#define MEMORY_VIEW_BYTE_COUNT 0xff
|
||||||
|
|
||||||
#define MEMORY_VIEW_DIRECTION_UP 1
|
#define MEMORY_VIEW_DIRECTION_UP 1
|
||||||
#define MEMORY_VIEW_DIRECTION_DOWN -1
|
#define MEMORY_VIEW_DIRECTION_DOWN (-1)
|
||||||
|
|
||||||
typedef struct memory_view {
|
typedef struct memory_view {
|
||||||
PANEL *panel;
|
PANEL *panel;
|
||||||
|
byte *ram;
|
||||||
address base_address;
|
address base_address;
|
||||||
|
char cursor_x;
|
||||||
|
char cursor_y;
|
||||||
} MemoryView;
|
} MemoryView;
|
||||||
|
|
||||||
void memory_view_init(MemoryView *view, ram ram);
|
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
|
#endif //NESEMULATOR_MEMORY_VIEW_H
|
||||||
|
|
Loading…
Reference in New Issue