- [NEW] F12 to StepOut() on debugger (break on RET, RETI or RETN)
- [FIX] Fixed visualizacion of some IX and IY opcodes - [NEW] Scroll on memory viewer with mouse wheel - [NEW] While debugging, on each step the screen refreshes, so screen redraw can be seen while happening - [NEW] Search for sequences of bytes. Example: "search AB1140" to search for the sequece $AB $11 $40. "search next" to continue searching.
This commit is contained in:
10
main.cpp
10
main.cpp
@@ -160,6 +160,16 @@ int main(int argc, char *argv[])
|
|||||||
zxscreen::redraw();
|
zxscreen::redraw();
|
||||||
z80analyze::refresh();
|
z80analyze::refresh();
|
||||||
}
|
}
|
||||||
|
} else if (e.key.keysym.scancode==SDL_SCANCODE_F12) {
|
||||||
|
if (z80debug::debugging()) {
|
||||||
|
z80debug::show();
|
||||||
|
z80debug::history::gototop();
|
||||||
|
const uint8_t dt = z80debug::stepout();
|
||||||
|
z80debug::refresh();
|
||||||
|
zxscreen::refresh(dt);
|
||||||
|
zxscreen::redraw();
|
||||||
|
z80analyze::refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = ui::window::sendEvent(e.key.windowID, &e);
|
result = ui::window::sendEvent(e.key.windowID, &e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
|
0x5e38 STACK
|
||||||
|
0xc661 CLEAR_SCR
|
||||||
|
0xed5e MAINLOOP
|
||||||
0xfed5 COUNT500
|
0xfed5 COUNT500
|
||||||
|
|||||||
31
z80.cpp
31
z80.cpp
@@ -11,6 +11,7 @@ namespace z80
|
|||||||
static uint32_t t = 0;
|
static uint32_t t = 0;
|
||||||
static uint16_t current_opcode_address = 0;
|
static uint16_t current_opcode_address = 0;
|
||||||
bool options[Z80_NUM_OPTIONS] = { true, false };
|
bool options[Z80_NUM_OPTIONS] = { true, false };
|
||||||
|
int calls_stacked = 0;
|
||||||
|
|
||||||
int (*in_ports[256])(int);
|
int (*in_ports[256])(int);
|
||||||
void (*out_ports[256])(int, int);
|
void (*out_ports[256])(int, int);
|
||||||
@@ -657,6 +658,11 @@ namespace z80
|
|||||||
{
|
{
|
||||||
PUSH(rPC);
|
PUSH(rPC);
|
||||||
rPC = addr;
|
rPC = addr;
|
||||||
|
|
||||||
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
||||||
|
calls_stacked++;
|
||||||
|
printf("CALL: calls stacked: %i", calls_stacked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,6 +680,20 @@ namespace z80
|
|||||||
{
|
{
|
||||||
POP(_rPC);
|
POP(_rPC);
|
||||||
if (cond != cNO) t++;
|
if (cond != cNO) t++;
|
||||||
|
|
||||||
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
||||||
|
if (calls_stacked>0) {
|
||||||
|
calls_stacked--;
|
||||||
|
printf("RET: calls still stacked: %i\n", calls_stacked);
|
||||||
|
} else {
|
||||||
|
printf("RET: BREAK\n");
|
||||||
|
options[Z80_OPTION_BREAK_ON_RET] = false;
|
||||||
|
z80debug::setcursor(rPC);
|
||||||
|
z80debug::history::store();
|
||||||
|
z80debug::stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
@@ -683,6 +703,13 @@ namespace z80
|
|||||||
{
|
{
|
||||||
POP(_rPC);
|
POP(_rPC);
|
||||||
iff1 = iff2;
|
iff1 = iff2;
|
||||||
|
|
||||||
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
||||||
|
options[Z80_OPTION_BREAK_ON_RET] = false;
|
||||||
|
z80debug::setcursor(rPC);
|
||||||
|
z80debug::history::store();
|
||||||
|
z80debug::stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RETI()
|
void RETI()
|
||||||
@@ -2842,4 +2869,8 @@ namespace z80
|
|||||||
options[option] = !options[option];
|
options[option] = !options[option];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetStackedCalls()
|
||||||
|
{
|
||||||
|
calls_stacked=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
5
z80.h
5
z80.h
@@ -14,7 +14,8 @@ namespace z80
|
|||||||
|
|
||||||
#define Z80_OPTION_STOP_ON_INVALID 0
|
#define Z80_OPTION_STOP_ON_INVALID 0
|
||||||
#define Z80_OPTION_BREAK_ON_INTERRUPT 1
|
#define Z80_OPTION_BREAK_ON_INTERRUPT 1
|
||||||
#define Z80_NUM_OPTIONS 2
|
#define Z80_OPTION_BREAK_ON_RET 2
|
||||||
|
#define Z80_NUM_OPTIONS 3
|
||||||
|
|
||||||
void reset(uint8_t* mem);
|
void reset(uint8_t* mem);
|
||||||
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int));
|
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int));
|
||||||
@@ -51,4 +52,6 @@ namespace z80
|
|||||||
const bool getOption(const int option);
|
const bool getOption(const int option);
|
||||||
void setOption(const int option, const bool value);
|
void setOption(const int option, const bool value);
|
||||||
void toggleOption(const int option);
|
void toggleOption(const int option);
|
||||||
|
|
||||||
|
void resetStackedCalls();
|
||||||
}
|
}
|
||||||
68
z80debug.cpp
68
z80debug.cpp
@@ -69,6 +69,10 @@ namespace z80debug
|
|||||||
int num_breakpoint_lines=0;
|
int num_breakpoint_lines=0;
|
||||||
bool sync_mem_with_cursor = false;
|
bool sync_mem_with_cursor = false;
|
||||||
|
|
||||||
|
uint8_t search_sequence[32];
|
||||||
|
int search_sequence_len=0;
|
||||||
|
uint16_t search_pos=0;
|
||||||
|
|
||||||
char temp[256];
|
char temp[256];
|
||||||
const char *tohex(int value, int numdigits)
|
const char *tohex(int value, int numdigits)
|
||||||
{
|
{
|
||||||
@@ -105,6 +109,14 @@ namespace z80debug
|
|||||||
z80debug::cursorfwd();
|
z80debug::cursorfwd();
|
||||||
z80debug::refresh();
|
z80debug::refresh();
|
||||||
}
|
}
|
||||||
|
} else if (e->wheel.mouseX<midx*CHR_W && e->wheel.mouseY>=mem_y*CHR_H && e->wheel.mouseY<con_y*CHR_H) {
|
||||||
|
if (e->wheel.y>0) {
|
||||||
|
mem_viewer_pos+=0x10;
|
||||||
|
z80debug::refresh();
|
||||||
|
} else if (e->wheel.y<0) {
|
||||||
|
mem_viewer_pos-=0x10;
|
||||||
|
z80debug::refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e->type == SDL_KEYDOWN) {
|
if (e->type == SDL_KEYDOWN) {
|
||||||
@@ -294,6 +306,7 @@ namespace z80debug
|
|||||||
//history::gototop();
|
//history::gototop();
|
||||||
zxscreen::setTitle(" (stopped)");
|
zxscreen::setTitle(" (stopped)");
|
||||||
pause();
|
pause();
|
||||||
|
z80::resetStackedCalls();
|
||||||
is_debugging = true;
|
is_debugging = true;
|
||||||
show();
|
show();
|
||||||
/*refresh();*/
|
/*refresh();*/
|
||||||
@@ -692,7 +705,10 @@ namespace z80debug
|
|||||||
getcmd();
|
getcmd();
|
||||||
|
|
||||||
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
||||||
z80::step();
|
uint8_t dt = z80::step();
|
||||||
|
zx_tape::update(dt);
|
||||||
|
zx_ula::sound_update(dt);
|
||||||
|
zxscreen::refresh(dt);
|
||||||
z80analyze::refresh();
|
z80analyze::refresh();
|
||||||
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
||||||
z80::step();
|
z80::step();
|
||||||
@@ -860,6 +876,13 @@ namespace z80debug
|
|||||||
getcmd();
|
getcmd();
|
||||||
int value = getnum(cmd);
|
int value = getnum(cmd);
|
||||||
z80::setMemTag(value, MEMTAG_IGNORE);
|
z80::setMemTag(value, MEMTAG_IGNORE);
|
||||||
|
} else if (strcmp(cmd, "search")==0) {
|
||||||
|
getcmd();
|
||||||
|
if (strcmp(cmd, "next")==0) {
|
||||||
|
search();
|
||||||
|
} else {
|
||||||
|
search(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,6 +899,14 @@ namespace z80debug
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t stepout()
|
||||||
|
{
|
||||||
|
z80::setOption(Z80_OPTION_BREAK_ON_RET, true);
|
||||||
|
const uint32_t t = z80::step();
|
||||||
|
cont();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
void setmemmodified(const uint16_t addr)
|
void setmemmodified(const uint16_t addr)
|
||||||
{
|
{
|
||||||
mem_modified[addr] = true;
|
mem_modified[addr] = true;
|
||||||
@@ -988,6 +1019,41 @@ namespace z80debug
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t hexchartonum(char chr)
|
||||||
|
{
|
||||||
|
int num = chr-48;
|
||||||
|
if (num<0) return 0;
|
||||||
|
if (num>9) {
|
||||||
|
num-=7;
|
||||||
|
if (num>15) {
|
||||||
|
num-=32;
|
||||||
|
if (num<10 || num>15) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uint8_t(num);
|
||||||
|
}
|
||||||
|
void search(const char *seq)
|
||||||
|
{
|
||||||
|
if (seq) {
|
||||||
|
search_pos = 0;
|
||||||
|
search_sequence_len=0;
|
||||||
|
while (*seq!=0) search_sequence[search_sequence_len++] = (hexchartonum(*(seq++))<<4) + hexchartonum(*(seq++));
|
||||||
|
}
|
||||||
|
int num_found=0;
|
||||||
|
uint8_t *memory = z80::getMem();
|
||||||
|
while (search_pos<65536) {
|
||||||
|
if (search_sequence[num_found] == memory[search_pos]) {
|
||||||
|
num_found++; search_pos++;
|
||||||
|
if (num_found==search_sequence_len) {
|
||||||
|
mem_viewer_pos=search_pos-search_sequence_len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
num_found=0; search_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendToConsole("Sequence not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace history
|
namespace history
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace z80debug
|
|||||||
|
|
||||||
const bool isbreak(const uint16_t address, const uint8_t type=1);
|
const bool isbreak(const uint16_t address, const uint8_t type=1);
|
||||||
uint32_t next();
|
uint32_t next();
|
||||||
|
uint32_t stepout();
|
||||||
|
|
||||||
void savestate(const char *filename);
|
void savestate(const char *filename);
|
||||||
void loadstate(const char *filename);
|
void loadstate(const char *filename);
|
||||||
@@ -40,6 +41,7 @@ namespace z80debug
|
|||||||
const int getNumOpcodesUsed();
|
const int getNumOpcodesUsed();
|
||||||
void printOpcodesUsed();
|
void printOpcodesUsed();
|
||||||
|
|
||||||
|
void search(const char *seq=nullptr);
|
||||||
namespace history
|
namespace history
|
||||||
{
|
{
|
||||||
void store();
|
void store();
|
||||||
|
|||||||
13
z80dis.cpp
13
z80dis.cpp
@@ -123,7 +123,7 @@ namespace z80dis
|
|||||||
if (strstr(buffer, "4x"))
|
if (strstr(buffer, "4x"))
|
||||||
{
|
{
|
||||||
opcode_size+=2;
|
opcode_size+=2;
|
||||||
const uint16_t word = *(uint16_t*)(memory+1);
|
const uint16_t word = *(uint16_t*)(memory+((*memory==0xFD) || (*memory==0xDD)?2:1));
|
||||||
if (symbols[word][0]!=0) {
|
if (symbols[word][0]!=0) {
|
||||||
char *p = strstr(buffer, "$");
|
char *p = strstr(buffer, "$");
|
||||||
(*p)='%'; p++;
|
(*p)='%'; p++;
|
||||||
@@ -173,11 +173,12 @@ namespace z80dis
|
|||||||
opcode_size+=1;
|
opcode_size+=1;
|
||||||
|
|
||||||
strcpy(base, buffer);
|
strcpy(base, buffer);
|
||||||
if (opcode_size>4) opcode_size=4;
|
if (opcode_size>4) {
|
||||||
sprintf(buffer, base, (int8_t)*(memory+3));
|
opcode_size=4;
|
||||||
//} else {
|
sprintf(buffer, base, (int8_t)*(memory+3));
|
||||||
// sprintf(buffer, base, (int8_t)*(memory+1));
|
} else {
|
||||||
//}
|
sprintf(buffer, base, (int8_t)*(memory+2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user