Window and cursor abstractions
This commit is contained in:
parent
9db7b680d3
commit
091a5e3bf5
|
@ -3,7 +3,11 @@ add_library(DEBUG
|
|||
memory_view.c
|
||||
dialog.c
|
||||
program_view.c
|
||||
program_view.h)
|
||||
program_view.h
|
||||
cursor.c
|
||||
cursor.h
|
||||
window.c
|
||||
window.h)
|
||||
|
||||
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) {
|
||||
MemoryView m_view;
|
||||
ProgramView p_view;
|
||||
InteractWindow windows[2];
|
||||
InteractWindow *current_window;
|
||||
|
||||
create_window();
|
||||
|
||||
memory_view_init(&m_view, system->ram, 0, 0);
|
||||
program_view_init(&p_view, MEMORY_VIEW_WIDTH, 0);
|
||||
memory_view_init(&windows[0], system->ram, 0, 0);
|
||||
program_view_init(&windows[1], system->ram, MEMORY_VIEW_WIDTH, 0);
|
||||
|
||||
update_panels();
|
||||
doupdate();
|
||||
|
@ -39,19 +39,19 @@ void start_debugger(System *system) {
|
|||
int keycode;
|
||||
while ((keycode = getch()) != CTRL_KEY_EXIT) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
|
@ -63,7 +63,7 @@ void start_debugger(System *system) {
|
|||
|
||||
if (!cancelled) {
|
||||
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();
|
||||
}
|
||||
|
||||
window_inter_deinit(&windows[0]);
|
||||
window_inter_deinit(&windows[1]);
|
||||
|
||||
endwin();
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
// Created by william on 1/6/24.
|
||||
//
|
||||
|
||||
#include "../include/system.h"
|
||||
|
||||
#ifndef NESEMULATOR_DEBUGGER_H
|
||||
#define NESEMULATOR_DEBUGGER_H
|
||||
|
||||
#include "../include/system.h"
|
||||
|
||||
void start_debugger(System *system);
|
||||
|
||||
#endif //NESEMULATOR_DEBUGGER_H
|
||||
|
|
|
@ -1,58 +1,47 @@
|
|||
#include <curses.h>
|
||||
#include <panel.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "memory_view.h"
|
||||
|
||||
//
|
||||
// Created by william on 1/6/24.
|
||||
// Created by william on 6/1/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 memory_view_write_line(WINDOW *window, int line, address base_address, byte *data) {
|
||||
mvwprintw(window, line + 2, 1, "[%04x]", base_address);
|
||||
void memory_view_write_line(MemoryView *view, int line, address base_address, byte *data) {
|
||||
window_inter_print(view->window, 0, line + 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]);
|
||||
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) {
|
||||
WINDOW *window = newwin(MEMORY_VIEW_HEIGHT, MEMORY_VIEW_WIDTH, y, x);
|
||||
box(window, 0, 0);
|
||||
void memory_view_cursor_init(MemoryView *view) {
|
||||
Cursor *cursor = &view->window->cursor;
|
||||
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 ");
|
||||
mvwprintw(window, 1, 1, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
|
||||
cursor_enable(cursor);
|
||||
}
|
||||
|
||||
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->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_set_cursor_pos(view, 0, 0);
|
||||
memory_view_cursor_init(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);
|
||||
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);
|
||||
}
|
||||
|
||||
void memory_view_scroll(MemoryView *view, char direction) {
|
||||
assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP);
|
||||
void memory_view_scroll(MemoryView *view, int direction) {
|
||||
assert(direction == CURSOR_OFFSET_DOWN || direction == CURSOR_OFFSET_UP);
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -92,28 +81,23 @@ void memory_view_scroll(MemoryView *view, char direction) {
|
|||
memory_view_goto(view, target);
|
||||
}
|
||||
|
||||
void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical) {
|
||||
if (horizontal == MEMORY_VIEW_DIRECTION_UP && view->cursor_x == 0xf ||
|
||||
horizontal == MEMORY_VIEW_DIRECTION_DOWN && view->cursor_x == 0) {
|
||||
return;
|
||||
}
|
||||
void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical) {
|
||||
MemoryView *view = (MemoryView *) window->view;
|
||||
|
||||
if (vertical == MEMORY_VIEW_DIRECTION_RIGHT && view->cursor_y == 0xf ||
|
||||
vertical == MEMORY_VIEW_DIRECTION_LEFT && view->cursor_y == 0) {
|
||||
if (vertical == CURSOR_OFFSET_DOWN && view->window->cursor.pos_y == 0xf ||
|
||||
vertical == CURSOR_OFFSET_UP && view->window->cursor.pos_y == 0) {
|
||||
// Scroll the view
|
||||
memory_view_scroll(view, vertical);
|
||||
memory_view_highlight_cursor(view);
|
||||
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);
|
||||
// We are not on any edge, move the cursor
|
||||
cursor_move(&view->window->cursor, horizontal, vertical);
|
||||
}
|
||||
|
||||
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 x = view_byte & 0x0f;
|
||||
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
|
||||
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <panel.h>
|
||||
#include "../include/types.h"
|
||||
#include "cursor.h"
|
||||
#include "window.h"
|
||||
|
||||
#define MEMORY_VIEW_HEIGHT 19
|
||||
#define MEMORY_VIEW_WIDTH 56
|
||||
|
@ -14,17 +16,10 @@
|
|||
#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)
|
||||
#define MEMORY_VIEW_DIRECTION_RIGHT 1
|
||||
#define MEMORY_VIEW_DIRECTION_LEFT (-1)
|
||||
|
||||
typedef struct memory_view {
|
||||
PANEL *panel;
|
||||
InteractWindow *window;
|
||||
byte *ram;
|
||||
address base_address;
|
||||
char cursor_x;
|
||||
char cursor_y;
|
||||
} MemoryView;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +29,7 @@ typedef struct memory_view {
|
|||
* @param view A pointer to the view to initialize
|
||||
* @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.
|
||||
|
@ -57,7 +52,7 @@ void memory_view_goto(MemoryView *view, address target);
|
|||
* @param view
|
||||
* @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.
|
||||
|
@ -66,7 +61,7 @@ void memory_view_scroll(MemoryView *view, char direction);
|
|||
* @param horizontal
|
||||
* @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.
|
||||
|
@ -75,6 +70,6 @@ void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical);
|
|||
* @param view
|
||||
* @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
|
||||
|
|
|
@ -2,42 +2,118 @@
|
|||
// Created by william on 10/01/24.
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "program_view.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;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
DebugOperand operand;
|
||||
byte op_code = ram[pc];
|
||||
|
||||
operand.addr = pc;
|
||||
operand.op_code = 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) {
|
||||
mvwprintw(window, line + 1, 1, "%04x:", addr);
|
||||
mvwprintw(window, line + 1, 7, "%s", "BRK");
|
||||
}
|
||||
|
||||
void program_view_print(ProgramView *view) {
|
||||
for (int line = 0; line <= 0xf; line++) {
|
||||
address addr = 0x8000 + line;
|
||||
|
||||
program_view_write_line(view->panel->win, line, addr);
|
||||
char *get_addr_mode_format_str(AddressingMode addr_mode) {
|
||||
switch (addr_mode) {
|
||||
case ADDR_MODE_ABSOLUTE:
|
||||
return "$%04x";
|
||||
case ADDR_MODE_ABSOLUTE_INDEXED_X:
|
||||
return "$%04x,x";
|
||||
case ADDR_MODE_ABSOLUTE_INDEXED_Y:
|
||||
return "$%04x,y";
|
||||
case ADDR_MODE_ACCUMULATOR:
|
||||
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) {
|
||||
WINDOW *window = newwin(PROGRAM_VIEW_HEIGHT, PROGRAM_VIEW_WIDTH, y, x);
|
||||
box(window, 0, 0);
|
||||
void program_view_write_line(ProgramView *view, int line, DebugOperand *operand) {
|
||||
char *op_name = get_op_code_name(operand->op_code);
|
||||
|
||||
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;
|
||||
|
||||
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.
|
||||
//
|
||||
|
||||
#ifndef NESEMULATOR_PROGRAM_VIEW_H
|
||||
#define NESEMULATOR_PROGRAM_VIEW_H
|
||||
|
||||
#include <panel.h>
|
||||
#include "../include/types.h"
|
||||
#include "../cpu/decoding.h"
|
||||
|
||||
#ifndef NESEMULATOR_PROGRAM_VIEW_H
|
||||
#define NESEMULATOR_PROGRAM_VIEW_H
|
||||
#include "cursor.h"
|
||||
#include "window.h"
|
||||
|
||||
#define PROGRAM_VIEW_HEIGHT 19
|
||||
#define PROGRAM_VIEW_WIDTH 42
|
||||
|
||||
typedef struct program_view {
|
||||
PANEL *panel;
|
||||
InteractWindow *window;
|
||||
byte *ram;
|
||||
address base_address;
|
||||
} ProgramView;
|
||||
|
||||
typedef struct debug_operand {
|
||||
address addr;
|
||||
byte op_code;
|
||||
AddressingMode addr_mode;
|
||||
enum OperandType type;
|
||||
word value;
|
||||
} 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
|
|
@ -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=00000023 endAddr=00000000 flags=ER--X- condition="" desc=""
|
||||
BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc=""
|
||||
Bookmark: addr=C10F desc=""
|
||||
|
|
Loading…
Reference in New Issue