- [NEW] La finestra de debug es pot redimensionar i el contingut s'ajusta

- [NEW] Es poden redimensionar les seccions de la finestra de debug
- [NEW] Afegit visor de simbols al debugger
This commit is contained in:
2024-12-11 13:39:29 +01:00
parent 085712437e
commit 5f6ebbff31
4 changed files with 179 additions and 32 deletions

View File

@@ -119,6 +119,7 @@ int main(int argc, char *argv[])
bool result = true; bool result = true;
if (e.type == SDL_QUIT) { should_exit=true; break; } if (e.type == SDL_QUIT) { should_exit=true; break; }
if (e.type == SDL_MOUSEBUTTONDOWN) result = ui::window::sendEvent(e.button.windowID, &e);
if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e); if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e);
if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e); if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e);
if (e.type == SDL_WINDOWEVENT) result = ui::window::sendEvent(e.window.windowID, &e); if (e.type == SDL_WINDOWEVENT) result = ui::window::sendEvent(e.window.windowID, &e);

View File

@@ -9,9 +9,26 @@
#include "zx_screen.h" #include "zx_screen.h"
#include "z80analyze.h" #include "z80analyze.h"
#define RESIZING_NONE 0
#define RESIZING_MEMORY 1
#define RESIZING_CONSOLE 2
#define RESIZING_SYMBOLS 3
#define RESIZING_X 4
namespace z80debug namespace z80debug
{ {
#define midy 58 int midx = 58;
int mem_y = 20;
int con_y = 28;
int sym_y = 20;
int win_h = 44;
int mem_h = 8;
int con_h = 6;
int sym_h = 14;
int resizing_type = RESIZING_MEMORY;
bool resizing = false;
namespace history namespace history
{ {
uint16_t buffer[65536]; uint16_t buffer[65536];
@@ -27,6 +44,9 @@ namespace z80debug
SDL_Window *win = nullptr; SDL_Window *win = nullptr;
SDL_Renderer *ren = nullptr; SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr; SDL_Texture *tex = nullptr;
SDL_Cursor *cur_df = nullptr;
SDL_Cursor *cur_ns = nullptr;
SDL_Cursor *cur_we = nullptr;
bool is_debugging=false; bool is_debugging=false;
bool is_paused=false; bool is_paused=false;
@@ -51,6 +71,13 @@ namespace z80debug
if (z80debug::debugging()) { if (z80debug::debugging()) {
if (e->type==SDL_WINDOWEVENT) { if (e->type==SDL_WINDOWEVENT) {
if ((e->window.event==SDL_WINDOWEVENT_SHOWN) || (e->window.event==SDL_WINDOWEVENT_EXPOSED)) { if ((e->window.event==SDL_WINDOWEVENT_SHOWN) || (e->window.event==SDL_WINDOWEVENT_EXPOSED)) {
int w; int h;
SDL_GetWindowSize(win, &w, &h);
midx = (w/CHR_W) - 25;
win_h = (h/CHR_H);
mem_y = win_h - mem_h - con_h;
con_y = win_h - con_h;
sym_y = win_h - sym_h;
z80debug::refresh(); z80debug::refresh();
zxscreen::redraw(); zxscreen::redraw();
} else if (e->window.event == SDL_WINDOWEVENT_CLOSE) { } else if (e->window.event == SDL_WINDOWEVENT_CLOSE) {
@@ -59,7 +86,7 @@ namespace z80debug
} }
} }
if (e->type == SDL_MOUSEWHEEL) { if (e->type == SDL_MOUSEWHEEL) {
if (e->wheel.mouseX<midy*CHR_W && e->wheel.mouseY<20*CHR_H) { if (e->wheel.mouseX<midx*CHR_W && e->wheel.mouseY<mem_y*CHR_H) {
if (e->wheel.y>0) { if (e->wheel.y>0) {
z80debug::cursorback(); z80debug::cursorback();
z80debug::refresh(); z80debug::refresh();
@@ -98,6 +125,61 @@ namespace z80debug
z80debug::DeleteCharConsole(); z80debug::DeleteCharConsole();
} }
} }
if (e->type == SDL_MOUSEMOTION) {
if (!resizing) {
if ( (e->motion.y > (mem_y*CHR_H)-8) && (e->motion.y < (mem_y*CHR_H)+8) && ( e->motion.x < midx*CHR_W ) ) {
if (resizing_type != RESIZING_MEMORY) SDL_SetCursor(cur_ns);
resizing_type = RESIZING_MEMORY;
} else if ( (e->motion.y > (sym_y*CHR_H)-8) && (e->motion.y < (sym_y*CHR_H)+8) && ( e->motion.x >= midx*CHR_W ) ) {
if (resizing_type != RESIZING_SYMBOLS) SDL_SetCursor(cur_ns);
resizing_type = RESIZING_SYMBOLS;
} else if ( (e->motion.y > (con_y*CHR_H)-8) && (e->motion.y < (con_y*CHR_H)+8) && (e->motion.x < midx*CHR_W) ) {
if (resizing_type != RESIZING_CONSOLE) SDL_SetCursor(cur_ns);
resizing_type = RESIZING_CONSOLE;
} else {
if (resizing_type != RESIZING_NONE) SDL_SetCursor(cur_df);
resizing_type = RESIZING_NONE;
}
} else {
if (resizing_type==RESIZING_MEMORY) {
const int new_mem_y = e->motion.y/CHR_H;
const int new_mem_h = win_h - new_mem_y - con_h;
if (new_mem_y>=5 && new_mem_h>=3) {
mem_y = new_mem_y;
mem_h = new_mem_h;
refresh();
}
} else if (resizing_type==RESIZING_CONSOLE) {
const int new_con_y = e->motion.y/CHR_H;
const int new_con_h = win_h - new_con_y;
const int new_mem_y = win_h - mem_h - new_con_h;
if (new_mem_y>=5 && new_con_h>=3) {
mem_y = new_mem_y;
con_y = new_con_y;
con_h = new_con_h;
refresh();
}
} else if (resizing_type==RESIZING_SYMBOLS) {
const int new_sym_y = e->motion.y/CHR_H;
const int new_sym_h = win_h - new_sym_y;
if (new_sym_y>=12 && new_sym_h >=3) {
sym_y = new_sym_y;
sym_h = new_sym_h;
refresh();
}
}
}
}
if (e->type == SDL_MOUSEBUTTONDOWN) {
if (!resizing && resizing_type != RESIZING_NONE) {
resizing = true;
}
}
if (e->type == SDL_MOUSEBUTTONUP) {
if (resizing) {
resizing = false;
}
}
if (e->type == SDL_TEXTINPUT) { if (e->type == SDL_TEXTINPUT) {
z80debug::sendToConsole(e->text.text); z80debug::sendToConsole(e->text.text);
} }
@@ -111,13 +193,17 @@ namespace z80debug
{ {
is_debugging = is_paused = false; is_debugging = is_paused = false;
for (int i=0; i<65536; ++i) breakpoints[i]=0; for (int i=0; i<65536; ++i) breakpoints[i]=0;
if (!cur_df) cur_df = SDL_GetCursor();
if (!cur_ns) cur_ns = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
if (!cur_we) cur_we = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
//show(); //show();
} }
void show() void show()
{ {
if (!win) { if (!win) {
win = SDL_CreateWindow("Z80 Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 83*CHR_W, 34*CHR_H, SDL_WINDOW_RESIZABLE); win = SDL_CreateWindow("Z80 Debugger", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 98*CHR_W, 44*CHR_H, SDL_WINDOW_RESIZABLE);
ren = SDL_CreateRenderer(win, -1, 0); ren = SDL_CreateRenderer(win, -1, 0);
ui::window::registerWindow(SDL_GetWindowID(win), eventHandler); ui::window::registerWindow(SDL_GetWindowID(win), eventHandler);
tex = ui::createtexture(ren); tex = ui::createtexture(ren);
@@ -203,7 +289,7 @@ namespace z80debug
if (is_debugging && (address == z80::getPC())) { if (is_debugging && (address == z80::getPC())) {
for (int i=0; i<4;++i) colors[i]=COLOR_YELLOW; for (int i=0; i<4;++i) colors[i]=COLOR_YELLOW;
ui::printrect(0,line, midy-2,1, COLOR_BLUE); ui::printrect(0,line, midx-2,1, COLOR_BLUE);
} }
if (breakpoints[address]&9) ui::printtxt(0,line,"*", colors[0]); if (breakpoints[address]&9) ui::printtxt(0,line,"*", colors[0]);
@@ -230,7 +316,7 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(0,0,midy,20,COLOR_WHITE); ui::box(0,0,midx,mem_y,COLOR_WHITE);
ui::printrect(2,0, 12,1, COLOR_DARK); ui::printrect(2,0, 12,1, COLOR_DARK);
ui::printtxt(3,0, "ASSEMBLER:", COLOR_WHITE); ui::printtxt(3,0, "ASSEMBLER:", COLOR_WHITE);
@@ -240,16 +326,16 @@ namespace z80debug
uint16_t pc = cursor; //z80::getPC(); uint16_t pc = cursor; //z80::getPC();
uint16_t pos = pc; uint16_t pos = pc;
int num_lines = mem_y-2;
printDissasemblerLine(pc, (num_lines/2)-1, true);
printDissasemblerLine(pc, 8, true); for (int i=num_lines/2;i<num_lines;++i) {
for (int i=9;i<18;++i) {
pos += z80dis::getOpcodeSize(pos); pos += z80dis::getOpcodeSize(pos);
printDissasemblerLine(pos, i, true); printDissasemblerLine(pos, i, true);
} }
pos = pc; pos = pc;
for (int i=7;i>=0;--i) { for (int i=(num_lines/2)-2;i>=0;--i) {
pos = find_previous_opcode(pos); pos = find_previous_opcode(pos);
printDissasemblerLine(pos, i); printDissasemblerLine(pos, i);
} }
@@ -258,11 +344,11 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(midy,0,25,8,COLOR_WHITE); ui::box(midx,0,25,8,COLOR_WHITE);
ui::printrect(midy+2,0, 12,1, COLOR_DARK); ui::printrect(midx+2,0, 12,1, COLOR_DARK);
ui::printtxt(midy+3,0, "REGISTERS:", COLOR_WHITE); ui::printtxt(midx+3,0, "REGISTERS:", COLOR_WHITE);
ui::setoffset(midy+1, 1); ui::setoffset(midx+1, 1);
ui::printtxt(0,0, "AF AF' IX ", COLOR_WHITE); ui::printtxt(0,0, "AF AF' IX ", COLOR_WHITE);
ui::printtxt(0,1, "BC BC' IY ", COLOR_WHITE); ui::printtxt(0,1, "BC BC' IY ", COLOR_WHITE);
ui::printtxt(0,2, "DE DE' SP ", COLOR_WHITE); ui::printtxt(0,2, "DE DE' SP ", COLOR_WHITE);
@@ -306,12 +392,12 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(midy,8,11,12,COLOR_WHITE); ui::box(midx,8,11,sym_y-8,COLOR_WHITE);
ui::printrect(midy+2,8, 8,1, COLOR_DARK); ui::printrect(midx+2,8, 8,1, COLOR_DARK);
ui::printtxt(midy+3,8, "STACK:", COLOR_WHITE); ui::printtxt(midx+3,8, "STACK:", COLOR_WHITE);
ui::setoffset(midy+1, 9); ui::setoffset(midx+1, 9);
uint16_t sp = z80::getSP()-8; uint16_t sp = z80::getSP()-(((sym_y-12)>>1)<<1);
for (int i=0; i<10; ++i) { for (int i=0; i<sym_y-10; ++i) {
uint8_t c1=COLOR_CYAN, c2=COLOR_GRAY; uint8_t c1=COLOR_CYAN, c2=COLOR_GRAY;
if (sp == z80::getSP()) { if (sp == z80::getSP()) {
ui::printrect(0,i,9,1,COLOR_BLUE); ui::printrect(0,i,9,1,COLOR_BLUE);
@@ -327,10 +413,10 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(midy+11,8,14,12,COLOR_WHITE); ui::box(midx+11,8,14,sym_y-8,COLOR_WHITE);
ui::printrect(midy+13,8, 9,1, COLOR_DARK); ui::printrect(midx+13,8, 9,1, COLOR_DARK);
ui::printtxt(midy+14,8, "BREAKS:", COLOR_WHITE); ui::printtxt(midx+14,8, "BREAKS:", COLOR_WHITE);
ui::setoffset(midy+12, 9); ui::setoffset(midx+12, 9);
int line=0; int line=0;
for (int i=0; i<65536; ++i) { for (int i=0; i<65536; ++i) {
@@ -349,14 +435,14 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(0,20,83,8,COLOR_WHITE); ui::box(0,mem_y,midx,mem_h,COLOR_WHITE);
ui::printrect(2,20, 9,1, COLOR_DARK); ui::printrect(2,mem_y, 9,1, COLOR_DARK);
ui::printtxt(3,20, "MEMORY:", COLOR_WHITE); ui::printtxt(3,mem_y, "MEMORY:", COLOR_WHITE);
ui::setoffset(1, 21); ui::setoffset(1, mem_y+1);
uint16_t mem_viewer_cursor = mem_viewer_pos; uint16_t mem_viewer_cursor = mem_viewer_pos;
for (int i=0; i<6; ++i) { for (int i=0; i<mem_h-2; ++i) {
ui::printtxt(1,i, tohex(mem_viewer_cursor, 4), COLOR_CYAN); ui::printtxt(1,i, tohex(mem_viewer_cursor, 4), COLOR_CYAN);
for (int j=0; j<16; ++j) { for (int j=0; j<16; ++j) {
ui::printtxt(6+j*3, i, tohex(memory[mem_viewer_cursor],2), mem_modified[mem_viewer_cursor] ? COLOR_RED : COLOR_WHITE); ui::printtxt(6+j*3, i, tohex(memory[mem_viewer_cursor],2), mem_modified[mem_viewer_cursor] ? COLOR_RED : COLOR_WHITE);
@@ -372,16 +458,33 @@ namespace z80debug
// ****************************************** // ******************************************
ui::setoffset(0, 0); ui::setoffset(0, 0);
ui::box(0,28,83,6,COLOR_WHITE); ui::box(0,con_y,midx,con_h,COLOR_WHITE);
ui::printrect(2,28, 10,1, COLOR_DARK); ui::printrect(2,con_y, 10,1, COLOR_DARK);
ui::printtxt(3,28, "CONSOLE:", COLOR_WHITE); ui::printtxt(3,con_y, "CONSOLE:", COLOR_WHITE);
ui::setoffset(1, 29); ui::setoffset(1, con_y+1);
ui::printtxt(0,0, ">", COLOR_WHITE); ui::printtxt(0,0, ">", COLOR_WHITE);
ui::printtxt(1,0, console, COLOR_WHITE); ui::printtxt(1,0, console, COLOR_WHITE);
ui::printtxt(strlen(console)+1,0, "\x7F", COLOR_WHITE); ui::printtxt(strlen(console)+1,0, "\x7F", COLOR_WHITE);
ui::printtxt(1,1, console_error, COLOR_RED); ui::printtxt(1,1, console_error, COLOR_RED);
// SYMBOLS
// *****************************************
ui::setoffset(0, 0);
ui::box(midx,sym_y,25,sym_h,COLOR_WHITE);
ui::printrect(midx+2,sym_y, 9,1, COLOR_DARK);
ui::printtxt(midx+3,sym_y, "SYMBOLS:", COLOR_WHITE);
ui::setoffset(midx+1, sym_y+1);
const int num_symbols = z80dis::getNumSymbols();
for (int i=0;i<num_symbols;++i) {
const uint16_t address = z80dis::getSymbolAddress(i);
ui::printtxt(1, i, tohex(address,4), COLOR_GRAY);
ui::printtxt(6, i, z80dis::getSymbol(address), COLOR_WHITE);
}
if (!is_debugging) { if (!is_debugging) {
SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(ren, 0, 0, 0, 128); SDL_SetRenderDrawColor(ren, 0, 0, 0, 128);

View File

@@ -2,12 +2,15 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "z80.h" #include "z80.h"
#include <vector>
#include <bits/stdc++.h>
namespace z80dis namespace z80dis
{ {
char buffer[256]; char buffer[256];
int opcode_size = 0; int opcode_size = 0;
char symbols[65536][15]; char symbols[65536][15];
std::vector<uint16_t> used_symbols;
// $%04x // $%04x
// $%02x // $%02x
@@ -39,6 +42,7 @@ namespace z80dis
void loadSymbols() void loadSymbols()
{ {
used_symbols.clear();
for (int i=0; i<65536; ++i) symbols[i][0] = 0; for (int i=0; i<65536; ++i) symbols[i][0] = 0;
FILE *f = fopen("symbols.txt", "r"); FILE *f = fopen("symbols.txt", "r");
while (true) { while (true) {
@@ -47,6 +51,17 @@ namespace z80dis
const int result = fscanf(f, "%x %s", &address, tmp); const int result = fscanf(f, "%x %s", &address, tmp);
if (result != 2) break; if (result != 2) break;
strcpy(symbols[address], tmp); strcpy(symbols[address], tmp);
used_symbols.push_back(address);
}
fclose(f);
}
void saveSymbols()
{
FILE *f = fopen("symbols.txt", "w");
for (auto sym_addr : used_symbols)
{
fprintf(f, "0x%x %s\n", sym_addr, symbols[sym_addr]);
} }
fclose(f); fclose(f);
} }
@@ -202,4 +217,27 @@ namespace z80dis
return symbols[pos]; return symbols[pos];
} }
bool comp(uint16_t a, uint16_t b) {
return a <= b;
}
void setSymbol(const uint16_t pos, const char *sym)
{
strcpy(symbols[pos], sym);
used_symbols.push_back(pos);
sort(used_symbols.begin(), used_symbols.end(), comp);
saveSymbols();
}
const int getNumSymbols()
{
return used_symbols.size();
}
const uint16_t getSymbolAddress(const int pos)
{
return used_symbols[pos];
}
} }

View File

@@ -5,8 +5,13 @@
namespace z80dis namespace z80dis
{ {
void loadSymbols(); void loadSymbols();
void saveSymbols();
const char *getAsm(const uint16_t pos); const char *getAsm(const uint16_t pos);
const char *getOpcode(const uint16_t pos); const char *getOpcode(const uint16_t pos);
const int getOpcodeSize(const uint16_t pos); const int getOpcodeSize(const uint16_t pos);
const char *getSymbol(const uint16_t pos); const char *getSymbol(const uint16_t pos);
void setSymbol(const uint16_t pos, const char *sym);
const int getNumSymbols();
const uint16_t getSymbolAddress(const int pos);
} }