- [FIX] Al anar de 10 en 10 steps de vegades se botaba breakpoints

- [FIX] Ara cada renderer te la seua textura de font
- [CHG] Continuar l'execució ja no tanca el debugger
- [NEW] En la memòria no tocada actual o en avanç, se "adivina" quina es la instrucció
- [FIX] Resetejar el spectrum borrava la ROM
- [NEW] Anar avant o arrere en el temps mou el cursor del desensamblador
This commit is contained in:
2024-12-10 13:56:24 +01:00
parent 68d53af1b4
commit f462afe56c
6 changed files with 81 additions and 64 deletions

View File

@@ -133,29 +133,30 @@ int main(int argc, char *argv[])
} }
if (!z80debug::debugging() && !z80debug::paused()) { if (!z80debug::debugging() && !z80debug::paused()) {
if (z80debug::isbreak(z80::getPC(), 9)) { //if (z80::getPC()==0x05C8) zx_tape::go_berserk();
z80debug::stop(); bool fastload=false;
zxscreen::redraw(); if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) { fastload=true; time = SDL_GetTicks(); }
} else { while (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD))
//if (z80::getPC()==0x05C8) zx_tape::go_berserk(); {
bool fastload=false;
if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) { fastload=true; time = SDL_GetTicks(); }
while (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD))
{
// zx_tape::update(z80::step()); // zx_tape::update(z80::step());
uint8_t dt = z80::step(); uint8_t dt = z80::step();
t_states += dt; t_states += dt;
zx_tape::update(dt); zx_tape::update(dt);
if (SDL_GetTicks()-time>=1000) { if (SDL_GetTicks()-time>=1000) {
time = SDL_GetTicks(); time = SDL_GetTicks();
zx_tape::report(); zx_tape::report();
}
//zx_ula::sound_update(dt);
//zxscreen::refresh(dt);
} }
if (fastload) { printf("%i\n", SDL_GetTicks()-time); t_states=0; } //zx_ula::sound_update(dt);
// En cada bucle fem 10 pasos de la CPU, sino s'ofega //zxscreen::refresh(dt);
for (int i=0;i<5;++i) { }
if (fastload) { printf("%i\n", SDL_GetTicks()-time); t_states=0; }
// En cada bucle fem 10 pasos de la CPU, sino s'ofega
for (int i=0;i<5;++i) {
if (z80debug::isbreak(z80::getPC(), 9)) {
z80debug::stop();
zxscreen::redraw();
break;
} else {
uint8_t dt = z80::step(); uint8_t dt = z80::step();
t_states += dt; t_states += dt;
zx_tape::update(dt); zx_tape::update(dt);
@@ -163,21 +164,23 @@ int main(int argc, char *argv[])
zx_ula::sound_update(dt); zx_ula::sound_update(dt);
zxscreen::refresh(dt); zxscreen::refresh(dt);
} }
if (t_states>=350000)
{
//if (SDL_GetTicks()>=time+1000)
//printf("%i\n", SDL_GetTicks()-(time+1000));
//else
// printf("%i\n", SDL_GetTicks()-(time+1000));
//t_states = 0;
//printf("%i: %i\n", SDL_GetTicks()-(time+1000), t_states);
while (SDL_GetTicks()<time+100) {}
t_states -= 350000;
time = SDL_GetTicks();
z80analyze::refresh();
}
} }
if (t_states>=350000)
{
//if (SDL_GetTicks()>=time+1000)
//printf("%i\n", SDL_GetTicks()-(time+1000));
//else
// printf("%i\n", SDL_GetTicks()-(time+1000));
//t_states = 0;
//printf("%i: %i\n", SDL_GetTicks()-(time+1000), t_states);
while (SDL_GetTicks()<time+100) {}
t_states -= 350000;
time = SDL_GetTicks();
z80analyze::refresh();
}
} else if (!z80debug::debugging() && z80debug::paused()) { } else if (!z80debug::debugging() && z80debug::paused()) {
zxscreen::redraw(false); zxscreen::redraw(false);
ui::menu::show(); ui::menu::show();

14
ui.cpp
View File

@@ -23,7 +23,6 @@ namespace ui
}; };
SDL_Renderer *ren = nullptr; SDL_Renderer *ren = nullptr;
SDL_Surface *surf = nullptr;
SDL_Texture *tex = nullptr; SDL_Texture *tex = nullptr;
uint8_t offset_x = 0; uint8_t offset_x = 0;
@@ -31,19 +30,18 @@ namespace ui
bool clicked = false; bool clicked = false;
void init() SDL_Texture * createtexture(SDL_Renderer *renderer)
{ {
surf = SDL_LoadBMP("font.bmp"); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("font.bmp"));
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
return texture;
} }
void setrenderer(SDL_Renderer *renderer) void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
if (!surf) init();
if (ren==renderer) return; if (ren==renderer) return;
ren = renderer; ren = renderer;
if (tex) SDL_DestroyTexture(tex); tex = texture;
tex = SDL_CreateTextureFromSurface(ren, surf);
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
offset_x = offset_y = 0; offset_x = offset_y = 0;
} }

3
ui.h
View File

@@ -23,7 +23,8 @@ namespace ui
#define COLOR_YELLOW 14 #define COLOR_YELLOW 14
#define COLOR_WHITE 15 #define COLOR_WHITE 15
void setrenderer(SDL_Renderer *renderer); SDL_Texture * createtexture(SDL_Renderer *renderer);
void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture);
void setoffset(uint8_t x, uint8_t y); void setoffset(uint8_t x, uint8_t y);
void box(int x, int y, int w, int h, uint8_t color); void box(int x, int y, int w, int h, uint8_t color);

View File

@@ -2,12 +2,14 @@
#include "z80.h" #include "z80.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "ui_window.h" #include "ui_window.h"
#include "ui.h"
namespace z80analyze namespace z80analyze
{ {
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_Texture *uitex = nullptr;
void refreshTitle(); void refreshTitle();
@@ -32,6 +34,8 @@ namespace z80analyze
win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_SHOWN); win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, 0); ren = SDL_CreateRenderer(win, -1, 0);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 256); tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 256);
uitex = ui::createtexture(ren);
ui::window::registerWindow(SDL_GetWindowID(win), handleEvent); ui::window::registerWindow(SDL_GetWindowID(win), handleEvent);
} }
refresh(); refresh();
@@ -48,6 +52,7 @@ namespace z80analyze
void refresh() void refresh()
{ {
if (!win) return; if (!win) return;
ui::setrenderer(ren, uitex);
Uint32 *pixels; Uint32 *pixels;
int pitch; int pitch;
@@ -67,8 +72,9 @@ namespace z80analyze
void hide() void hide()
{ {
ui::window::unregisterWindow(SDL_GetWindowID(win)); ui::window::unregisterWindow(SDL_GetWindowID(win));
SDL_DestroyTexture(tex); SDL_DestroyTexture(uitex); uitex = nullptr;
SDL_DestroyRenderer(ren); SDL_DestroyTexture(tex); tex = nullptr;
SDL_DestroyWindow(win); SDL_DestroyRenderer(ren); ren = nullptr;
SDL_DestroyWindow(win); win = nullptr;
} }
} }

View File

@@ -26,6 +26,7 @@ namespace z80debug
SDL_Window *win = nullptr; SDL_Window *win = nullptr;
SDL_Renderer *ren = nullptr; SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr;
bool is_debugging=false; bool is_debugging=false;
bool is_paused=false; bool is_paused=false;
@@ -140,6 +141,7 @@ namespace z80debug
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, 83*CHR_W, 34*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);
z80debug::refresh(); z80debug::refresh();
} }
@@ -147,8 +149,10 @@ namespace z80debug
void hide() void hide()
{ {
ui::window::unregisterWindow(SDL_GetWindowID(win)); ui::window::unregisterWindow(SDL_GetWindowID(win));
if (tex) SDL_DestroyTexture(tex);
if (ren) SDL_DestroyRenderer(ren); if (ren) SDL_DestroyRenderer(ren);
if (win) SDL_DestroyWindow(win); if (win) SDL_DestroyWindow(win);
tex = NULL;
ren = NULL; ren = NULL;
win = NULL; win = NULL;
} }
@@ -170,8 +174,8 @@ namespace z80debug
void cont() { void cont() {
is_debugging = is_paused = false; is_debugging = is_paused = false;
hide(); //hide();
/*refresh();*/ refresh();
zx_ula::sound_enable(); zx_ula::sound_enable();
} }
@@ -201,10 +205,11 @@ namespace z80debug
*/ */
} }
void printDissasemblerLine(const uint16_t address, const int line) void printDissasemblerLine(const uint16_t address, const int line, const bool heuristics=false)
{ {
uint8_t colors[4] = { COLOR_RED, COLOR_CYAN, COLOR_GRAY, COLOR_WHITE}; uint8_t colors[4] = { COLOR_RED, COLOR_CYAN, COLOR_GRAY, COLOR_WHITE};
if (z80::getMemTouched(address)!=MEMTAG_INST) colors[3]=COLOR_GRAY; if (z80::getMemTouched(address)!=MEMTAG_INST) colors[3]=COLOR_GRAY;
if (z80::getMemTouched(address)==MEMTAG_NONE) colors[1]=COLOR_GRAY;
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;
@@ -214,7 +219,7 @@ namespace z80debug
if (breakpoints[address]&9) ui::printtxt(0,line,"*", colors[0]); if (breakpoints[address]&9) ui::printtxt(0,line,"*", colors[0]);
ui::printtxt(1,line,tohex(address,4), colors[1]); ui::printtxt(1,line,tohex(address,4), colors[1]);
if (z80::getMemTag(address)==MEMTAG_INST) { if ( (z80::getMemTag(address)==MEMTAG_INST) || heuristics ) {
const char *sym = z80dis::getSymbol(address); const char *sym = z80dis::getSymbol(address);
if (sym[0]!=0) ui::printtxt(7,line, sym, COLOR_YELLOW); if (sym[0]!=0) ui::printtxt(7,line, sym, COLOR_YELLOW);
ui::printtxt(19,line, z80dis::getOpcode(address), colors[2]); ui::printtxt(19,line, z80dis::getOpcode(address), colors[2]);
@@ -227,7 +232,7 @@ namespace z80debug
void refresh() void refresh()
{ {
ui::setrenderer(ren); ui::setrenderer(ren, tex);
SDL_SetRenderDrawColor(ren, 30, 30, 30, 255); SDL_SetRenderDrawColor(ren, 30, 30, 30, 255);
SDL_RenderClear(ren); SDL_RenderClear(ren);
@@ -246,11 +251,11 @@ namespace z80debug
uint16_t pc = cursor; //z80::getPC(); uint16_t pc = cursor; //z80::getPC();
uint16_t pos = pc; uint16_t pos = pc;
printDissasemblerLine(pc, 8); printDissasemblerLine(pc, 8, true);
for (int i=9;i<18;++i) { for (int i=9;i<18;++i) {
pos += z80dis::getOpcodeSize(pos); pos += z80dis::getOpcodeSize(pos);
printDissasemblerLine(pos, i); printDissasemblerLine(pos, i, true);
} }
pos = pc; pos = pc;
@@ -468,7 +473,7 @@ namespace z80debug
z80debug::cont(); z80debug::cont();
} else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) { } else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) {
uint8_t *mem = z80::getMem(); uint8_t *mem = z80::getMem();
for (int i=0; i<65536; ++i) mem[i]=0; for (int i=0x4000; i<=0xffff; ++i) mem[i]=0;
z80::reset(mem); z80::reset(mem);
z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out); z80::connect_port(0xfe, zx_ula::port_in, zx_ula::port_out);
//for (int i=0; i<65536; ++i) breakpoints[i]=0; //for (int i=0; i<65536; ++i) breakpoints[i]=0;
@@ -616,7 +621,7 @@ namespace z80debug
uint8_t *memory = z80::getMem(); uint8_t *memory = z80::getMem();
FILE *f = fopen(filename, "wb"); FILE *f = fopen(filename, "wb");
fwrite(regs, 31, 1, f); fwrite(regs, 31, 1, f);
fwrite(&memory[16*1024], 48*1024, 1, f); fwrite(&memory[0x4000], 0xc000, 1, f);
fclose(f); fclose(f);
} }
@@ -626,7 +631,7 @@ namespace z80debug
uint8_t *memory = z80::getMem(); uint8_t *memory = z80::getMem();
FILE *f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");
fread(regs, 31, 1, f); fread(regs, 31, 1, f);
fread(&memory[16*1024], 48*1024, 1, f); fread(&memory[0x4000], 0xc000, 1, f);
fclose(f); fclose(f);
} }
@@ -658,18 +663,21 @@ namespace z80debug
{ {
pos = top; pos = top;
z80::setPC(buffer[pos]); z80::setPC(buffer[pos]);
cursor = z80::getPC();
} }
void goforward() void goforward()
{ {
if (pos == top) return; if (pos == top) return;
z80::setPC(buffer[++pos]); z80::setPC(buffer[++pos]);
cursor = z80::getPC();
} }
void goback() void goback()
{ {
if (uint8_t(pos-1) == top) return; if (uint8_t(pos-1) == top) return;
z80::setPC(buffer[--pos]); z80::setPC(buffer[--pos]);
cursor = z80::getPC();
} }
} }

View File

@@ -16,6 +16,8 @@ namespace zxscreen
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_Texture *uitex = nullptr;
uint8_t zoom = 1; uint8_t zoom = 1;
bool fullscreen = false; bool fullscreen = false;
int fullscreen_scale = 1; int fullscreen_scale = 1;
@@ -106,7 +108,6 @@ namespace zxscreen
if (e->type == SDL_KEYDOWN) { if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) { if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) {
z80debug::pause(); z80debug::pause();
ui::setrenderer(zxscreen::getrenderer());
zxscreen::redraw(); zxscreen::redraw();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) { } else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
zxscreen::decZoom(); zxscreen::decZoom();
@@ -133,6 +134,7 @@ namespace zxscreen
if (win) ui::window::unregisterWindow(SDL_GetWindowID(win)); if (win) ui::window::unregisterWindow(SDL_GetWindowID(win));
if (tex) SDL_DestroyTexture(tex); if (tex) SDL_DestroyTexture(tex);
if (uitex) SDL_DestroyTexture(uitex);
if (ren) SDL_DestroyRenderer(ren); if (ren) SDL_DestroyRenderer(ren);
if (win) SDL_DestroyWindow(win); if (win) SDL_DestroyWindow(win);
@@ -140,6 +142,7 @@ namespace zxscreen
win = SDL_CreateWindow("ZX Spectrum Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 352*z, 296*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN); win = SDL_CreateWindow("ZX Spectrum Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 352*z, 296*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 352, 296); tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 352, 296);
uitex = ui::createtexture(ren);
ui::window::registerWindow(SDL_GetWindowID(win), eventHandler); ui::window::registerWindow(SDL_GetWindowID(win), eventHandler);
@@ -178,15 +181,11 @@ namespace zxscreen
{ {
if (color_addr[t_screen] != 0) if (color_addr[t_screen] != 0)
{ {
if (color_addr[t_screen] == 1) if (color_addr[t_screen] == 1) {
{
*(ptr_pixel++) = border_color; *(ptr_pixel++) = border_color;
*(ptr_pixel++) = border_color; *(ptr_pixel++) = border_color;
//pixels_draw+=2; //pixels_draw+=2;
} } else {
else
{
uint8_t color = memory[color_addr[t_screen]]; uint8_t color = memory[color_addr[t_screen]];
uint8_t c1 = color&0x7, c2 = (color>>3)&0x7; uint8_t c1 = color&0x7, c2 = (color>>3)&0x7;
if ((color&0x80) && flash) { c1=c2; c2=color&0x7; } if ((color&0x80) && flash) { c1=c2; c2=color&0x7; }
@@ -230,6 +229,8 @@ namespace zxscreen
{ {
if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return; if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return;
ui::setrenderer(ren, uitex);
Uint32* pixels; Uint32* pixels;
int pitch; int pitch;
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch); SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);