Window and cursor abstractions
This commit is contained in:
parent
9db7b680d3
commit
091a5e3bf5
|
@ -3,7 +3,11 @@ add_library(DEBUG
|
||||||
memory_view.c
|
memory_view.c
|
||||||
dialog.c
|
dialog.c
|
||||||
program_view.c
|
program_view.c
|
||||||
program_view.h)
|
program_view.h
|
||||||
|
cursor.c
|
||||||
|
cursor.h
|
||||||
|
window.c
|
||||||
|
window.h)
|
||||||
|
|
||||||
find_package(Curses)
|
find_package(Curses)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
//
|
||||||
|
// Created by william on 1/12/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include "cursor.h"
|
||||||
|
|
||||||
|
void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y) {
|
||||||
|
cursor->window = window;
|
||||||
|
cursor->min_x = 1;
|
||||||
|
cursor->min_y = 1;
|
||||||
|
cursor->max_x = max_x;
|
||||||
|
cursor->max_y = max_y;
|
||||||
|
cursor->multiplier_x = 1;
|
||||||
|
cursor->multiplier_y = 1;
|
||||||
|
cursor->width = 1;
|
||||||
|
cursor->pos_x = 0;
|
||||||
|
cursor->pos_y = 0;
|
||||||
|
cursor->enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_set_at(Cursor *cursor, int at) {
|
||||||
|
int win_x = cursor->min_x + cursor->pos_x * cursor->multiplier_x;
|
||||||
|
int win_y = cursor->min_y + cursor->pos_y * cursor->multiplier_y;
|
||||||
|
|
||||||
|
mvwchgat(cursor->window, win_y, win_x, cursor->width, at, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_enable(Cursor *cursor) {
|
||||||
|
cursor_set_at(cursor, CURSOR_AT_ENABLED);
|
||||||
|
cursor->enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_disable(Cursor *cursor) {
|
||||||
|
cursor_set_at(cursor, CURSOR_AT_DISABLED);
|
||||||
|
cursor->enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_set_pos(Cursor *cursor, int x, int y) {
|
||||||
|
assert(x >= 0);
|
||||||
|
assert(y >= 0);
|
||||||
|
|
||||||
|
bool enabled = cursor->enabled;
|
||||||
|
if (enabled) {
|
||||||
|
// Remove the cursor from its old position
|
||||||
|
cursor_disable(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->pos_x = x;
|
||||||
|
cursor->pos_y = y;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
// Display the cursor in the new position
|
||||||
|
cursor_enable(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cursor_limit(int value, int limit) {
|
||||||
|
if (value < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > limit) {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_move(Cursor *cursor, int offset_x, int offset_y) {
|
||||||
|
int x = cursor->pos_x + offset_x;
|
||||||
|
x = cursor_limit(x, cursor->max_x);
|
||||||
|
|
||||||
|
int y = cursor->pos_y + offset_y;
|
||||||
|
y = cursor_limit(y, cursor->max_y);
|
||||||
|
|
||||||
|
cursor_set_pos(cursor, x, y);
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// Created by william on 1/12/24.
|
||||||
|
//
|
||||||
|
#ifndef NESEMULATOR_CURSOR_H
|
||||||
|
#define NESEMULATOR_CURSOR_H
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
|
||||||
|
#define CURSOR_OFFSET_UP (-1)
|
||||||
|
#define CURSOR_OFFSET_DOWN 1
|
||||||
|
#define CURSOR_OFFSET_LEFT (-1)
|
||||||
|
#define CURSOR_OFFSET_RIGHT 1
|
||||||
|
|
||||||
|
#define CURSOR_AT_ENABLED A_REVERSE
|
||||||
|
#define CURSOR_AT_DISABLED A_NORMAL
|
||||||
|
|
||||||
|
typedef struct cursor {
|
||||||
|
WINDOW *window;
|
||||||
|
int min_x;
|
||||||
|
int min_y;
|
||||||
|
int max_x;
|
||||||
|
int max_y;
|
||||||
|
int multiplier_x;
|
||||||
|
int multiplier_y;
|
||||||
|
int width;
|
||||||
|
int pos_x;
|
||||||
|
int pos_y;
|
||||||
|
bool enabled;
|
||||||
|
} Cursor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a cursor with default values.
|
||||||
|
*
|
||||||
|
* @param cursor A reference to the cursor to initialize
|
||||||
|
* @param window The window the cursor is in
|
||||||
|
*/
|
||||||
|
void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables a cursor, making it visible in its window.
|
||||||
|
*
|
||||||
|
* @param cursor The cursor
|
||||||
|
*/
|
||||||
|
void cursor_enable(Cursor *cursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a cursor, removing it from the display.
|
||||||
|
*
|
||||||
|
* @param cursor The cursor
|
||||||
|
*/
|
||||||
|
void cursor_disable(Cursor *cursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the cursor.
|
||||||
|
* The positions are from left to right (horizontal) and top to bottom (vertical).
|
||||||
|
*
|
||||||
|
* @param cursor The cursor
|
||||||
|
* @param x The new horizontal position
|
||||||
|
* @param y The new vertical position
|
||||||
|
*/
|
||||||
|
void cursor_set_pos(Cursor *cursor, int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position of the cursor by an offset. This function ensures that the cursor is kept in the window bounds.
|
||||||
|
* A negative offset moves the cursor position towards the 0 direction (left or top).
|
||||||
|
* A position offset moves it in the opposite direction (right or bottom).
|
||||||
|
*
|
||||||
|
* @param cursor The cursor
|
||||||
|
* @param offset_x The horizontal offset
|
||||||
|
* @param offset_y The vertical offset
|
||||||
|
*/
|
||||||
|
void cursor_move(Cursor *cursor, int offset_x, int offset_y);
|
||||||
|
|
||||||
|
#endif //NESEMULATOR_CURSOR_H
|
|
@ -25,13 +25,13 @@ void create_window() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_debugger(System *system) {
|
void start_debugger(System *system) {
|
||||||
MemoryView m_view;
|
InteractWindow windows[2];
|
||||||
ProgramView p_view;
|
InteractWindow *current_window;
|
||||||
|
|
||||||
create_window();
|
create_window();
|
||||||
|
|
||||||
memory_view_init(&m_view, system->ram, 0, 0);
|
memory_view_init(&windows[0], system->ram, 0, 0);
|
||||||
program_view_init(&p_view, MEMORY_VIEW_WIDTH, 0);
|
program_view_init(&windows[1], system->ram, MEMORY_VIEW_WIDTH, 0);
|
||||||
|
|
||||||
update_panels();
|
update_panels();
|
||||||
doupdate();
|
doupdate();
|
||||||
|
@ -39,19 +39,19 @@ void start_debugger(System *system) {
|
||||||
int keycode;
|
int keycode;
|
||||||
while ((keycode = getch()) != CTRL_KEY_EXIT) {
|
while ((keycode = getch()) != CTRL_KEY_EXIT) {
|
||||||
if (keycode == KEY_UP) {
|
if (keycode == KEY_UP) {
|
||||||
memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_DOWN);
|
current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == KEY_DOWN) {
|
if (keycode == KEY_DOWN) {
|
||||||
memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_UP);
|
current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == KEY_LEFT) {
|
if (keycode == KEY_LEFT) {
|
||||||
memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_LEFT, 0);
|
current_window->handle_cursor_move(current_window, CURSOR_OFFSET_LEFT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == KEY_RIGHT) {
|
if (keycode == KEY_RIGHT) {
|
||||||
memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_RIGHT, 0);
|
current_window->handle_cursor_move(current_window, CURSOR_OFFSET_RIGHT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == CTRL_KEY_G) {
|
if (keycode == CTRL_KEY_G) {
|
||||||
|
@ -63,7 +63,7 @@ void start_debugger(System *system) {
|
||||||
|
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
memory_view_goto(&m_view, input);
|
memory_view_goto(&m_view, input);
|
||||||
memory_view_set_cursor_addr(&m_view, input);
|
memory_view_cursor_set_addr(&m_view, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,5 +71,8 @@ void start_debugger(System *system) {
|
||||||
doupdate();
|
doupdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window_inter_deinit(&windows[0]);
|
||||||
|
window_inter_deinit(&windows[1]);
|
||||||
|
|
||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
|
@ -2,11 +2,11 @@
|
||||||
// Created by william on 1/6/24.
|
// Created by william on 1/6/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/system.h"
|
|
||||||
|
|
||||||
#ifndef NESEMULATOR_DEBUGGER_H
|
#ifndef NESEMULATOR_DEBUGGER_H
|
||||||
#define NESEMULATOR_DEBUGGER_H
|
#define NESEMULATOR_DEBUGGER_H
|
||||||
|
|
||||||
|
#include "../include/system.h"
|
||||||
|
|
||||||
void start_debugger(System *system);
|
void start_debugger(System *system);
|
||||||
|
|
||||||
#endif //NESEMULATOR_DEBUGGER_H
|
#endif //NESEMULATOR_DEBUGGER_H
|
||||||
|
|
|
@ -1,58 +1,47 @@
|
||||||
#include <curses.h>
|
|
||||||
#include <panel.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "memory_view.h"
|
#include "memory_view.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Created by william on 1/6/24.
|
// Created by william on 6/1/24.
|
||||||
//
|
//
|
||||||
|
void memory_view_write_line(MemoryView *view, int line, address base_address, byte *data) {
|
||||||
void memory_view_highlight_cursor(MemoryView *view) {
|
window_inter_print(view->window, 0, line + 1, "[%04x]", base_address);
|
||||||
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 memory_view_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++) {
|
for (int i = 0; i <= MEMORY_VIEW_LINE_BYTE_COUNT; i++) {
|
||||||
mvwprintw(window, line + 2, 8 + i * 3, "%02x", data[i]);
|
window_inter_print(view->window, 7 + i * 3, line + 1, "%02x", data[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_view_init(MemoryView *view, ram ram, int x, int y) {
|
void memory_view_cursor_init(MemoryView *view) {
|
||||||
WINDOW *window = newwin(MEMORY_VIEW_HEIGHT, MEMORY_VIEW_WIDTH, y, x);
|
Cursor *cursor = &view->window->cursor;
|
||||||
box(window, 0, 0);
|
window_inter_cursor_init(view->window, 0xf, 0xf);
|
||||||
|
cursor->min_x = 8;
|
||||||
|
cursor->min_y = 2;
|
||||||
|
cursor->multiplier_x = 3;
|
||||||
|
cursor->width = 2;
|
||||||
|
|
||||||
mvwprintw(window, 0, 1, " MEMORY VIEW ");
|
cursor_enable(cursor);
|
||||||
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);
|
void memory_view_handle_key_down(InteractWindow *window, int keycode) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void memory_view_init(InteractWindow *interact, ram ram, int x, int y) {
|
||||||
|
MemoryView *view = malloc(sizeof(MemoryView));
|
||||||
|
view->window = interact;
|
||||||
view->ram = ram;
|
view->ram = ram;
|
||||||
view->base_address = 0x0000;
|
view->base_address = 0x0000;
|
||||||
view->cursor_x = 0;
|
|
||||||
view->cursor_y = 0;
|
interact->view = view;
|
||||||
|
interact->handle_cursor_move = &memory_view_cursor_move;
|
||||||
|
interact->handle_key_down = &memory_view_handle_key_down;
|
||||||
|
window_inter_init(interact, x, y, MEMORY_VIEW_WIDTH, MEMORY_VIEW_HEIGHT, "MEMORY VIEW");
|
||||||
|
window_inter_print(interact, 0, 0, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
|
||||||
|
|
||||||
memory_view_print(view);
|
memory_view_print(view);
|
||||||
memory_view_set_cursor_pos(view, 0, 0);
|
memory_view_cursor_init(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_view_print(MemoryView *view) {
|
void memory_view_print(MemoryView *view) {
|
||||||
|
@ -60,7 +49,7 @@ void memory_view_print(MemoryView *view) {
|
||||||
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 = &view->ram[line_address];
|
byte *data = &view->ram[line_address];
|
||||||
|
|
||||||
memory_view_write_line(view->panel->win, line, line_address, data);
|
memory_view_write_line(view, line, line_address, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,14 +66,14 @@ void memory_view_goto(MemoryView *view, address target) {
|
||||||
memory_view_print(view);
|
memory_view_print(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_view_scroll(MemoryView *view, char direction) {
|
void memory_view_scroll(MemoryView *view, int direction) {
|
||||||
assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP);
|
assert(direction == CURSOR_OFFSET_DOWN || direction == CURSOR_OFFSET_UP);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
if (direction == MEMORY_VIEW_DIRECTION_DOWN && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) {
|
if (direction == CURSOR_OFFSET_UP && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) {
|
||||||
offset -= MEMORY_VIEW_LINE_BYTE_COUNT + 1;
|
offset -= MEMORY_VIEW_LINE_BYTE_COUNT + 1;
|
||||||
}
|
}
|
||||||
if (direction == MEMORY_VIEW_DIRECTION_UP && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) {
|
if (direction == CURSOR_OFFSET_DOWN && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) {
|
||||||
offset += MEMORY_VIEW_LINE_BYTE_COUNT + 1;
|
offset += MEMORY_VIEW_LINE_BYTE_COUNT + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,28 +81,23 @@ void memory_view_scroll(MemoryView *view, char direction) {
|
||||||
memory_view_goto(view, target);
|
memory_view_goto(view, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical) {
|
void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical) {
|
||||||
if (horizontal == MEMORY_VIEW_DIRECTION_UP && view->cursor_x == 0xf ||
|
MemoryView *view = (MemoryView *) window->view;
|
||||||
horizontal == MEMORY_VIEW_DIRECTION_DOWN && view->cursor_x == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertical == MEMORY_VIEW_DIRECTION_RIGHT && view->cursor_y == 0xf ||
|
if (vertical == CURSOR_OFFSET_DOWN && view->window->cursor.pos_y == 0xf ||
|
||||||
vertical == MEMORY_VIEW_DIRECTION_LEFT && view->cursor_y == 0) {
|
vertical == CURSOR_OFFSET_UP && view->window->cursor.pos_y == 0) {
|
||||||
|
// Scroll the view
|
||||||
memory_view_scroll(view, vertical);
|
memory_view_scroll(view, vertical);
|
||||||
memory_view_highlight_cursor(view);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int target_x = view->cursor_x + horizontal;
|
// We are not on any edge, move the cursor
|
||||||
int target_y = view->cursor_y + vertical;
|
cursor_move(&view->window->cursor, horizontal, vertical);
|
||||||
memory_view_set_cursor_pos(view, target_x, target_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_view_set_cursor_addr(MemoryView *view, address target) {
|
void memory_view_cursor_set_addr(MemoryView *view, address target) {
|
||||||
int view_byte = target - view->base_address;
|
int view_byte = target - view->base_address;
|
||||||
|
|
||||||
int x = view_byte & 0x0f;
|
int x = view_byte & 0x0f;
|
||||||
int y = (view_byte & 0xf0) >> 4;
|
int y = (view_byte & 0xf0) >> 4;
|
||||||
memory_view_set_cursor_pos(view, x, y);
|
cursor_set_pos(&view->window->cursor, x, y);
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Created by william on 1/6/24.
|
// Created by william on 6/1/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef NESEMULATOR_MEMORY_VIEW_H
|
#ifndef NESEMULATOR_MEMORY_VIEW_H
|
||||||
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include <panel.h>
|
#include <panel.h>
|
||||||
#include "../include/types.h"
|
#include "../include/types.h"
|
||||||
|
#include "cursor.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#define MEMORY_VIEW_HEIGHT 19
|
#define MEMORY_VIEW_HEIGHT 19
|
||||||
#define MEMORY_VIEW_WIDTH 56
|
#define MEMORY_VIEW_WIDTH 56
|
||||||
|
@ -14,17 +16,10 @@
|
||||||
#define MEMORY_VIEW_LINE_BYTE_COUNT 0xf
|
#define MEMORY_VIEW_LINE_BYTE_COUNT 0xf
|
||||||
#define MEMORY_VIEW_BYTE_COUNT 0xff
|
#define MEMORY_VIEW_BYTE_COUNT 0xff
|
||||||
|
|
||||||
#define MEMORY_VIEW_DIRECTION_UP 1
|
|
||||||
#define MEMORY_VIEW_DIRECTION_DOWN (-1)
|
|
||||||
#define MEMORY_VIEW_DIRECTION_RIGHT 1
|
|
||||||
#define MEMORY_VIEW_DIRECTION_LEFT (-1)
|
|
||||||
|
|
||||||
typedef struct memory_view {
|
typedef struct memory_view {
|
||||||
PANEL *panel;
|
InteractWindow *window;
|
||||||
byte *ram;
|
byte *ram;
|
||||||
address base_address;
|
address base_address;
|
||||||
char cursor_x;
|
|
||||||
char cursor_y;
|
|
||||||
} MemoryView;
|
} MemoryView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +29,7 @@ typedef struct memory_view {
|
||||||
* @param view A pointer to the view to initialize
|
* @param view A pointer to the view to initialize
|
||||||
* @param ram A pointer to the RAM
|
* @param ram A pointer to the RAM
|
||||||
*/
|
*/
|
||||||
void memory_view_init(MemoryView *view, ram ram, int x, int y);
|
void memory_view_init(InteractWindow *interact, ram ram, int x, int y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the RAM content from the viewer base address.
|
* Prints the RAM content from the viewer base address.
|
||||||
|
@ -57,7 +52,7 @@ void memory_view_goto(MemoryView *view, address target);
|
||||||
* @param view
|
* @param view
|
||||||
* @param direction The scroll direction
|
* @param direction The scroll direction
|
||||||
*/
|
*/
|
||||||
void memory_view_scroll(MemoryView *view, char direction);
|
void memory_view_scroll(MemoryView *view, int direction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor up, down, right or left.
|
* Moves the cursor up, down, right or left.
|
||||||
|
@ -66,7 +61,7 @@ void memory_view_scroll(MemoryView *view, char direction);
|
||||||
* @param horizontal
|
* @param horizontal
|
||||||
* @param vertical
|
* @param vertical
|
||||||
*/
|
*/
|
||||||
void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical);
|
void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor to a specific memory address.
|
* Moves the cursor to a specific memory address.
|
||||||
|
@ -75,6 +70,6 @@ void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical);
|
||||||
* @param view
|
* @param view
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
void memory_view_set_cursor_addr(MemoryView *view, address target);
|
void memory_view_cursor_set_addr(MemoryView *view, address target);
|
||||||
|
|
||||||
#endif //NESEMULATOR_MEMORY_VIEW_H
|
#endif //NESEMULATOR_MEMORY_VIEW_H
|
||||||
|
|
|
@ -2,42 +2,118 @@
|
||||||
// Created by william on 10/01/24.
|
// Created by william on 10/01/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include "program_view.h"
|
#include "program_view.h"
|
||||||
#include "../cpu/op.h"
|
#include "../cpu/op.h"
|
||||||
|
|
||||||
void decode_operands(byte *ram, address start_addr) {
|
void decode_operands(DebugOperand *operands, const byte *ram, address start_addr) {
|
||||||
int pc = start_addr;
|
int pc = start_addr;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
DebugOperand operand;
|
DebugOperand operand;
|
||||||
byte op_code = ram[pc];
|
byte op_code = ram[pc];
|
||||||
|
|
||||||
|
operand.addr = pc;
|
||||||
operand.op_code = op_code;
|
operand.op_code = op_code;
|
||||||
operand.addr_mode = get_op_addr_mode(op_code);
|
operand.addr_mode = get_op_addr_mode(op_code);
|
||||||
|
|
||||||
|
pc += 1;
|
||||||
|
|
||||||
|
if (operand.addr_mode == ADDR_MODE_ACCUMULATOR || operand.addr_mode == ADDR_MODE_IMPLICIT) {
|
||||||
|
operand.type = OPERAND_TYPE_ACCUMULATOR;
|
||||||
|
operand.value = 0;
|
||||||
|
} else if (operand.addr_mode == ADDR_MODE_IMMEDIATE) {
|
||||||
|
operand.type = OPERAND_TYPE_IMMEDIATE;
|
||||||
|
operand.value = ram[pc];
|
||||||
|
pc += 1;
|
||||||
|
} else if (operand.addr_mode == ADDR_MODE_RELATIVE) {
|
||||||
|
operand.type = OPERAND_TYPE_ADDRESS;
|
||||||
|
operand.value = ram[pc];
|
||||||
|
pc += 1;
|
||||||
|
} else {
|
||||||
|
operand.type = OPERAND_TYPE_ADDRESS;
|
||||||
|
operand.value = ram[pc];
|
||||||
|
operand.value += ram[pc + 1] << 8;
|
||||||
|
pc += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
operands[i] = operand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_view_write_line(WINDOW *window, int line, address addr) {
|
char *get_addr_mode_format_str(AddressingMode addr_mode) {
|
||||||
mvwprintw(window, line + 1, 1, "%04x:", addr);
|
switch (addr_mode) {
|
||||||
mvwprintw(window, line + 1, 7, "%s", "BRK");
|
case ADDR_MODE_ABSOLUTE:
|
||||||
}
|
return "$%04x";
|
||||||
|
case ADDR_MODE_ABSOLUTE_INDEXED_X:
|
||||||
void program_view_print(ProgramView *view) {
|
return "$%04x,x";
|
||||||
for (int line = 0; line <= 0xf; line++) {
|
case ADDR_MODE_ABSOLUTE_INDEXED_Y:
|
||||||
address addr = 0x8000 + line;
|
return "$%04x,y";
|
||||||
|
case ADDR_MODE_ACCUMULATOR:
|
||||||
program_view_write_line(view->panel->win, line, addr);
|
return "A";
|
||||||
|
case ADDR_MODE_IMMEDIATE:
|
||||||
|
return "#$%02x";
|
||||||
|
case ADDR_MODE_IMPLICIT:
|
||||||
|
return "";
|
||||||
|
case ADDR_MODE_INDIRECT_X:
|
||||||
|
return "($%04x,x)";
|
||||||
|
case ADDR_MODE_INDIRECT_JUMP:
|
||||||
|
return "($%04x)";
|
||||||
|
case ADDR_MODE_INDIRECT_Y:
|
||||||
|
return "($%04x),y";
|
||||||
|
case ADDR_MODE_RELATIVE:
|
||||||
|
return "$%04x";
|
||||||
|
case ADDR_MODE_ZERO_PAGE:
|
||||||
|
return "$%02x,y";
|
||||||
|
case ADDR_MODE_ZERO_PAGE_INDEXED_X:
|
||||||
|
return "$%02x,x";
|
||||||
|
case ADDR_MODE_ZERO_PAGE_INDEXED_Y:
|
||||||
|
return "$%02x,y";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_view_init(ProgramView *view, ram ram, int x, int y) {
|
void program_view_write_line(ProgramView *view, int line, DebugOperand *operand) {
|
||||||
WINDOW *window = newwin(PROGRAM_VIEW_HEIGHT, PROGRAM_VIEW_WIDTH, y, x);
|
char *op_name = get_op_code_name(operand->op_code);
|
||||||
box(window, 0, 0);
|
|
||||||
|
|
||||||
mvwprintw(window, 0, 1, " PROGRAM VIEW ");
|
window_inter_print(view->window, 0, line, "%04x:", operand->addr);
|
||||||
|
window_inter_print(view->window, 6, line, "%s", op_name);
|
||||||
|
|
||||||
view->panel = new_panel(window);
|
char *format = get_addr_mode_format_str(operand->addr_mode);
|
||||||
|
window_inter_print(view->window, 10, line, format, operand->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void program_view_print(ProgramView *view, DebugOperand *operands) {
|
||||||
|
for (int line = 0; line < 10; line++) {
|
||||||
|
program_view_write_line(view, line, &operands[line]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void program_view_cursor_init(ProgramView *view) {
|
||||||
|
window_inter_cursor_init(view->window, 0, 10);
|
||||||
|
view->window->cursor.width = PROGRAM_VIEW_WIDTH - 2;
|
||||||
|
cursor_enable(&view->window->cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void program_view_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 program_view_init(InteractWindow *interact, ram ram, int x, int y) {
|
||||||
|
ProgramView *view = malloc(sizeof(ProgramView));
|
||||||
|
view->window = interact;
|
||||||
view->ram = ram;
|
view->ram = ram;
|
||||||
|
|
||||||
program_view_print(view);
|
interact->view = view;
|
||||||
|
interact->handle_cursor_move = &program_view_handle_cursor_move;
|
||||||
|
interact->handle_key_down = &program_view_handle_key_down;
|
||||||
|
window_inter_init(interact, x, y, PROGRAM_VIEW_WIDTH, PROGRAM_VIEW_HEIGHT, "PROGRAM VIEW");
|
||||||
|
|
||||||
|
DebugOperand operands[10];
|
||||||
|
decode_operands(&operands[0], ram, 0xc004);
|
||||||
|
|
||||||
|
program_view_print(view, &operands[0]);
|
||||||
|
program_view_cursor_init(view);
|
||||||
}
|
}
|
|
@ -2,27 +2,32 @@
|
||||||
// Created by william on 10/01/24.
|
// Created by william on 10/01/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef NESEMULATOR_PROGRAM_VIEW_H
|
||||||
|
#define NESEMULATOR_PROGRAM_VIEW_H
|
||||||
|
|
||||||
#include <panel.h>
|
#include <panel.h>
|
||||||
#include "../include/types.h"
|
#include "../include/types.h"
|
||||||
#include "../cpu/decoding.h"
|
#include "../cpu/decoding.h"
|
||||||
|
#include "cursor.h"
|
||||||
#ifndef NESEMULATOR_PROGRAM_VIEW_H
|
#include "window.h"
|
||||||
#define NESEMULATOR_PROGRAM_VIEW_H
|
|
||||||
|
|
||||||
#define PROGRAM_VIEW_HEIGHT 19
|
#define PROGRAM_VIEW_HEIGHT 19
|
||||||
#define PROGRAM_VIEW_WIDTH 42
|
#define PROGRAM_VIEW_WIDTH 42
|
||||||
|
|
||||||
typedef struct program_view {
|
typedef struct program_view {
|
||||||
PANEL *panel;
|
InteractWindow *window;
|
||||||
byte *ram;
|
byte *ram;
|
||||||
address base_address;
|
address base_address;
|
||||||
} ProgramView;
|
} ProgramView;
|
||||||
|
|
||||||
typedef struct debug_operand {
|
typedef struct debug_operand {
|
||||||
|
address addr;
|
||||||
byte op_code;
|
byte op_code;
|
||||||
AddressingMode addr_mode;
|
AddressingMode addr_mode;
|
||||||
|
enum OperandType type;
|
||||||
|
word value;
|
||||||
} DebugOperand;
|
} DebugOperand;
|
||||||
|
|
||||||
void program_view_init(ProgramView *view, ram ram, int x, int y);
|
void program_view_init(InteractWindow *interact, ram ram, int x, int y);
|
||||||
|
|
||||||
#endif //NESEMULATOR_PROGRAM_VIEW_H
|
#endif //NESEMULATOR_PROGRAM_VIEW_H
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// Created by william on 1/12/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
void window_init(Window *window, int x, int y, int width, int height, char *title) {
|
||||||
|
assert(x >= 0);
|
||||||
|
assert(y >= 0);
|
||||||
|
assert(width > 0);
|
||||||
|
assert(height > 0);
|
||||||
|
|
||||||
|
WINDOW *curse_win = newwin(height, width, y, x);
|
||||||
|
box(curse_win, 0, 0);
|
||||||
|
|
||||||
|
mvwprintw(curse_win, 0, 1, " %s ", title);
|
||||||
|
|
||||||
|
window->panel = new_panel(curse_win);
|
||||||
|
window->width = width;
|
||||||
|
window->height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title) {
|
||||||
|
window_init(&window->window, x, y, width, height, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_print_va(Window *window, int x, int y, const char *fmt, va_list args) {
|
||||||
|
assert(x >= 0);
|
||||||
|
assert(x < window->width - 1);
|
||||||
|
assert(y >= 0);
|
||||||
|
assert(y < window->height - 1);
|
||||||
|
|
||||||
|
wmove(window->panel->win, y + 1, x + 1);
|
||||||
|
vw_printw(window->panel->win, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y) {
|
||||||
|
cursor_init(&window->cursor, window->window.panel->win, max_x, max_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_print(Window *window, int x, int y, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
window_print_va(window, x, y, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
window_print_va(&window->window, x, y, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_inter_deinit(InteractWindow *window) {
|
||||||
|
assert(window->view != NULL);
|
||||||
|
|
||||||
|
free(window->view);
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
//
|
||||||
|
// Created by william on 1/12/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NESEMULATOR_WINDOW_H
|
||||||
|
#define NESEMULATOR_WINDOW_H
|
||||||
|
|
||||||
|
#include <panel.h>
|
||||||
|
#include "cursor.h"
|
||||||
|
|
||||||
|
typedef struct window {
|
||||||
|
PANEL *panel;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} Window;
|
||||||
|
|
||||||
|
typedef struct interact_window {
|
||||||
|
Window window;
|
||||||
|
Cursor cursor;
|
||||||
|
void *view;
|
||||||
|
|
||||||
|
void (*handle_cursor_move)(struct interact_window *window, int horizontal, int vertical);
|
||||||
|
|
||||||
|
void (*handle_key_down)(struct interact_window *window, int keycode);
|
||||||
|
} InteractWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a window with a position, size and title.
|
||||||
|
*
|
||||||
|
* @param window The window to initialize
|
||||||
|
* @param x The horizontal position (left to right)
|
||||||
|
* @param y The vertical position (top to bottom)
|
||||||
|
* @param width The window width
|
||||||
|
* @param height The window height
|
||||||
|
* @param title The window title
|
||||||
|
*/
|
||||||
|
void window_init(Window *window, int x, int y, int width, int height, char *title);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an interactable window with a position, size and title.
|
||||||
|
*
|
||||||
|
* @param window The window to initialize
|
||||||
|
* @param x The horizontal position (left to right)
|
||||||
|
* @param y The vertical position (top to bottom)
|
||||||
|
* @param width The window width
|
||||||
|
* @param height The window height
|
||||||
|
* @param title The window title
|
||||||
|
*/
|
||||||
|
void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the cursor of an interactable window.
|
||||||
|
*
|
||||||
|
* @param window The window
|
||||||
|
* @param max_x The cursor's maximum horizontal position
|
||||||
|
* @param max_y The cursor's maximum vertical position
|
||||||
|
*/
|
||||||
|
void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints text on a window.
|
||||||
|
*
|
||||||
|
* @param window The window
|
||||||
|
* @param x The horizontal position (left to right)
|
||||||
|
* @param y The vertical position (top to bottom)
|
||||||
|
* @param fmt A format string
|
||||||
|
* @param ... The format string arguments
|
||||||
|
*/
|
||||||
|
void window_print(Window *window, int x, int y, const char *fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints text on an interactable window.
|
||||||
|
*
|
||||||
|
* @param window The window
|
||||||
|
* @param x The horizontal position (left to right)
|
||||||
|
* @param y The vertical position (top to bottom)
|
||||||
|
* @param fmt A format string
|
||||||
|
* @param ... The format string arguments
|
||||||
|
*/
|
||||||
|
void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...);
|
||||||
|
|
||||||
|
void window_inter_deinit(InteractWindow *window);
|
||||||
|
|
||||||
|
#endif //NESEMULATOR_WINDOW_H
|
|
@ -1,3 +1,4 @@
|
||||||
BreakPoint: startAddr=00000014 endAddr=00000000 flags=ER--X- condition="" desc=""
|
BreakPoint: startAddr=00000014 endAddr=00000000 flags=ER--X- condition="" desc=""
|
||||||
BreakPoint: startAddr=00000023 endAddr=00000000 flags=ER--X- condition="" desc=""
|
BreakPoint: startAddr=00000023 endAddr=00000000 flags=ER--X- condition="" desc=""
|
||||||
BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc=""
|
BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc=""
|
||||||
|
Bookmark: addr=C10F desc=""
|
||||||
|
|
Loading…
Reference in New Issue