Files
paco/debug.cpp

228 lines
7.8 KiB
C++

#include "debug.h"
#include <SDL.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "parser.h"
typedef unsigned char byte;
typedef unsigned short word;
static SDL_Window* debug_window = nullptr;
static SDL_Renderer* debug_renderer = nullptr;
static SDL_Texture* debug_texture = nullptr;
static SDL_Rect src, dst;
static Uint8 ink[4];
static Uint8 paper[4];
static unsigned char* debug_mem = nullptr;
static unsigned short* rX;
static unsigned char* rY;
static unsigned char* rZ;
static unsigned short* pc;
static char* program = nullptr;
static word* lines = nullptr;
static void debug_set_ink(const unsigned char r, const unsigned char g, const unsigned char b) {
ink[0] = r; ink[1] = g; ink[2] = b; ink[3] = 255;
SDL_SetRenderDrawColor(debug_renderer, ink[0], ink[1], ink[2], ink[3]);
SDL_SetTextureColorMod(debug_texture, ink[0], ink[1], ink[2]);
}
static void debug_set_paper(const unsigned char r, const unsigned char g, const unsigned char b) {
paper[0] = r; paper[1] = g; paper[2] = b; paper[3] = 255;
}
static void debug_draw_char(int x, int y, int c) {
src.x = (c & 0xf) << 3; src.y = (c >> 4) << 3;
dst.x = x << 3; dst.y = y << 3;
src.w = src.h = dst.w = dst.h = 8;
SDL_RenderCopy(debug_renderer, debug_texture, &src, &dst);
}
static void debug_print(int x, int y, const char* text) {
while (*text != 0) {
debug_draw_char(x, y, *text);
x++;
text++;
}
}
static void debug_print_ex(int x, int y, const unsigned char* text, int len) {
while (len != 0) {
debug_draw_char(x, y, *text);
x++; text++; len--;
}
}
static void debug_draw_outset(int x, int y, int w, int h) {
x = (x << 3) - 1; y = (y << 3) - 1; w = (w << 3) + 2; h = (h << 3) + 2;
SDL_SetRenderDrawColor(debug_renderer, 255, 255, 255, 255);
SDL_RenderDrawLine(debug_renderer, x, y, x, y + h);
SDL_RenderDrawLine(debug_renderer, x, y, x + w, y);
SDL_SetRenderDrawColor(debug_renderer, 0, 0, 0, 255);
SDL_RenderDrawLine(debug_renderer, x + w, y, x + w, y + h);
SDL_RenderDrawLine(debug_renderer, x, y + h, x + w, y + h);
SDL_SetRenderDrawColor(debug_renderer, ink[0], ink[1], ink[2], ink[3]);
}
static void debug_draw_inset(int x, int y, int w, int h) {
x = (x << 3) - 1; y = (y << 3) - 1; w = (w << 3) + 1; h = (h << 3) + 1;
SDL_SetRenderDrawColor(debug_renderer, 0, 0, 0, 255);
SDL_RenderDrawLine(debug_renderer, x, y, x, y + h);
SDL_RenderDrawLine(debug_renderer, x, y, x + w, y);
SDL_SetRenderDrawColor(debug_renderer, 255, 255, 255, 255);
SDL_RenderDrawLine(debug_renderer, x + w, y, x + w, y + h);
SDL_RenderDrawLine(debug_renderer, x, y + h, x + w, y + h);
SDL_SetRenderDrawColor(debug_renderer, ink[0], ink[1], ink[2], ink[3]);
}
static void debug_draw_rect(int x, int y, int w, int h) {
dst.x = (x << 3) - 1; dst.y = (y << 3) - 1; dst.w = (w << 3) + 2; dst.h = (h << 3) + 2;
SDL_RenderDrawRect(debug_renderer, &dst);
}
static void debug_fill_rect(int x, int y, int w, int h) {
dst.x = x << 3; dst.y = y << 3; dst.w = w << 3; dst.h = h << 3;
SDL_RenderFillRect(debug_renderer, &dst);
}
static void debug_clear() {
SDL_SetRenderDrawColor(debug_renderer, paper[0], paper[1], paper[2], paper[3]);
SDL_RenderClear(debug_renderer);
SDL_SetRenderDrawColor(debug_renderer, ink[0], ink[1], ink[2], ink[3]);
}
static void debug_draw_space(int x, int y, int w, int h, const char* title) {
debug_set_ink(64, 64, 64);
debug_fill_rect(x, y, w, h);
debug_draw_inset(x, y, w, h);
debug_set_ink(0, 0, 0);
debug_print(x, y-1, title);
}
static void debug_print_memory(word offset) {
debug_draw_space(1, 39, 37, 20, "MEMORY:");
debug_set_ink(255, 255, 255);
char cadena[255];
for (int i = 0; i < 20; i++) {
sprintf(cadena, "%.4X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X", offset, debug_mem[offset], debug_mem[offset + 1], debug_mem[offset + 2], debug_mem[offset + 3], debug_mem[offset + 4], debug_mem[offset + 5], debug_mem[offset + 6], debug_mem[offset + 7]);
debug_print(1, 39+i, cadena); debug_print_ex(30, 39+i, &debug_mem[offset], 8);
offset += 8;
}
}
static void debug_print_datastack(byte offset) {
debug_draw_space(72, 2, 3, 20, "DS:");
char cadena[10];
for (int i = 0; i < 20; i++) {
sprintf(cadena, "%.2X", debug_mem[0x8801 + i + offset]);
if (debug_mem[0x8800] == 1 + i + offset) debug_set_ink(255, 0, 0); else debug_set_ink(255, 255, 255);
debug_print(72, 2 + i, cadena); debug_print_ex(74, 2 + i, &debug_mem[0x8801 + i + offset], 1);
}
}
static void debug_print_callstack(byte offset) {
debug_draw_space(76, 2, 3, 20, "CS:");
char cadena[10];
for (int i = 0; i < 20; i++) {
sprintf(cadena, "%.2X", debug_mem[0x8901 + i + offset]);
if (debug_mem[0x8900] == 1 + i + offset) debug_set_ink(255, 0, 0); else debug_set_ink(255, 255, 255);
debug_print(76, 2 + i, cadena); debug_print_ex(78, 2 + i, &debug_mem[0x8901 + i + offset], 1);
}
}
static void debug_print_basic(byte offset) {
debug_draw_space(1, 2, 70, 35, "CODE:");
debug_set_ink(255, 255, 255);
int line = offset;
int row = 0;
char* prog = program;
if (lines[*pc] == line) { debug_set_ink(128, 128, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); }
else debug_set_ink(255, 255, 255);
while (line < 35 && *prog != 0) {
if (*prog == '\t') {
row += 4;
} else if (*prog == '\n') {
row = 0; line++;
if (lines[*pc] == line) { debug_set_ink(128, 128, 0); debug_fill_rect(1, 2 + line, 70, 1); debug_set_ink(255, 255, 0); }
else debug_set_ink(255, 255, 255);
} else if (*prog == 13) {
// row++;
} else {
if (row < 70) debug_draw_char(1 + row, 2 + line, *prog);
row++;
}
prog++;
}
}
static void debug_print_registers() {
debug_draw_space(72, 23, 6, 1, "rX:");
debug_draw_space(72, 25, 3, 1, "rY:");
debug_draw_space(72, 27, 3, 1, "rZ:");
debug_set_ink(255, 255, 255);
char cadena[10];
sprintf(cadena, "%.4X", *rX);
debug_print(72, 23, cadena); debug_print_ex(76, 23, &debug_mem[0xFFFA], 2);
sprintf(cadena, "%.2X", *rY);
debug_print(72, 25, cadena); debug_print_ex(74, 25, &debug_mem[0xFFFC], 1);
sprintf(cadena, "%.2X", *rZ);
debug_print(72, 27, cadena); debug_print_ex(74, 27, &debug_mem[0xFFFD], 1);
}
void debug_init(unsigned char* mem) {
debug_mem = mem;
lines = parser_get_lines();
rX = (unsigned short*)&debug_mem[0xFFFA];
rY = &debug_mem[0xFFFC];
rZ = &debug_mem[0xFFFD];
pc = (unsigned short*)&debug_mem[0xFFFE];
debug_window = SDL_CreateWindow("Definitely PaCo Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
debug_renderer = SDL_CreateRenderer(debug_window, -1, SDL_RENDERER_PRESENTVSYNC);
//SDL_RenderSetLogicalSize(debug_renderer, 152, 120);
SDL_SetRenderDrawColor(debug_renderer, 128, 128, 128, 255);
FILE* f = fopen("font.png", "rb");
int x = 128, y = 128, c;
Uint8* buffer = stbi_load_from_file(f, &x, &y, &c, 4);
debug_texture = SDL_CreateTexture(debug_renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, 128, 128);
SDL_UpdateTexture(debug_texture, NULL, buffer, 128 * sizeof(Uint32));
SDL_SetTextureBlendMode(debug_texture, SDL_BLENDMODE_BLEND);
stbi_image_free(buffer);
fclose(f);
f = fopen("test.bas", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET); //same as rewind(f);
program = (char*)malloc(fsize + 1);
fread(program, fsize, 1, f);
fclose(f);
program[fsize] = 0;
debug_update();
}
void debug_update() {
debug_set_paper(128, 128, 128);
debug_clear();
debug_set_ink(64, 64, 64);
debug_fill_rect(39, 39, 40, 20);
debug_draw_inset(39, 39, 40, 20);
debug_set_ink(0, 0, 0);
debug_print(39, 38, "DISASSEMBLY:");
debug_print_memory(0);
debug_print_datastack(0);
debug_print_callstack(0);
debug_print_registers();
debug_print_basic(0);
SDL_RenderPresent(debug_renderer);
}