nesemu/debugger/memory_view.c

118 lines
3.5 KiB
C

#include <curses.h>
#include <panel.h>
#include <assert.h>
#include "memory_view.h"
//
// 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);
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->ram = ram;
view->base_address = 0x0000;
view->cursor_x = 0;
view->cursor_y = 0;
memory_view_print(view);
memory_view_set_cursor_pos(view, 0, 0);
}
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 = &view->ram[line_address];
write_line(view->panel->win, line, line_address, data);
}
}
void memory_view_goto(MemoryView *view, address target) {
assert(target < RAM_SIZE);
address max_base_address = RAM_SIZE - MEMORY_VIEW_BYTE_COUNT;
if (target > max_base_address) {
target = max_base_address;
}
address line_addr = target & 0xfff0;
view->base_address = line_addr;
memory_view_print(view);
}
void memory_view_scroll(MemoryView *view, char direction) {
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);
}
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;
}
if (vertical == MEMORY_VIEW_DIRECTION_RIGHT && view->cursor_y == 0xf ||
vertical == MEMORY_VIEW_DIRECTION_LEFT && 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);
}