- [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();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
0x5e38 STACK
|
||||
0xc661 CLEAR_SCR
|
||||
0xed5e MAINLOOP
|
||||
0xfed5 COUNT500
|
||||
|
||||
31
z80.cpp
31
z80.cpp
@@ -11,6 +11,7 @@ namespace z80
|
||||
static uint32_t t = 0;
|
||||
static uint16_t current_opcode_address = 0;
|
||||
bool options[Z80_NUM_OPTIONS] = { true, false };
|
||||
int calls_stacked = 0;
|
||||
|
||||
int (*in_ports[256])(int);
|
||||
void (*out_ports[256])(int, int);
|
||||
@@ -657,6 +658,11 @@ namespace z80
|
||||
{
|
||||
PUSH(rPC);
|
||||
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);
|
||||
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 {
|
||||
t++;
|
||||
}
|
||||
@@ -683,6 +703,13 @@ namespace z80
|
||||
{
|
||||
POP(_rPC);
|
||||
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()
|
||||
@@ -2842,4 +2869,8 @@ namespace z80
|
||||
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_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 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);
|
||||
void setOption(const int option, const bool value);
|
||||
void toggleOption(const int option);
|
||||
|
||||
void resetStackedCalls();
|
||||
}
|
||||
68
z80debug.cpp
68
z80debug.cpp
@@ -69,6 +69,10 @@ namespace z80debug
|
||||
int num_breakpoint_lines=0;
|
||||
bool sync_mem_with_cursor = false;
|
||||
|
||||
uint8_t search_sequence[32];
|
||||
int search_sequence_len=0;
|
||||
uint16_t search_pos=0;
|
||||
|
||||
char temp[256];
|
||||
const char *tohex(int value, int numdigits)
|
||||
{
|
||||
@@ -105,6 +109,14 @@ namespace z80debug
|
||||
z80debug::cursorfwd();
|
||||
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) {
|
||||
@@ -294,6 +306,7 @@ namespace z80debug
|
||||
//history::gototop();
|
||||
zxscreen::setTitle(" (stopped)");
|
||||
pause();
|
||||
z80::resetStackedCalls();
|
||||
is_debugging = true;
|
||||
show();
|
||||
/*refresh();*/
|
||||
@@ -692,7 +705,10 @@ namespace z80debug
|
||||
getcmd();
|
||||
|
||||
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();
|
||||
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
||||
z80::step();
|
||||
@@ -860,6 +876,13 @@ namespace z80debug
|
||||
getcmd();
|
||||
int value = getnum(cmd);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace z80debug
|
||||
|
||||
const bool isbreak(const uint16_t address, const uint8_t type=1);
|
||||
uint32_t next();
|
||||
uint32_t stepout();
|
||||
|
||||
void savestate(const char *filename);
|
||||
void loadstate(const char *filename);
|
||||
@@ -40,6 +41,7 @@ namespace z80debug
|
||||
const int getNumOpcodesUsed();
|
||||
void printOpcodesUsed();
|
||||
|
||||
void search(const char *seq=nullptr);
|
||||
namespace history
|
||||
{
|
||||
void store();
|
||||
|
||||
13
z80dis.cpp
13
z80dis.cpp
@@ -123,7 +123,7 @@ namespace z80dis
|
||||
if (strstr(buffer, "4x"))
|
||||
{
|
||||
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) {
|
||||
char *p = strstr(buffer, "$");
|
||||
(*p)='%'; p++;
|
||||
@@ -173,11 +173,12 @@ namespace z80dis
|
||||
opcode_size+=1;
|
||||
|
||||
strcpy(base, buffer);
|
||||
if (opcode_size>4) opcode_size=4;
|
||||
sprintf(buffer, base, (int8_t)*(memory+3));
|
||||
//} else {
|
||||
// sprintf(buffer, base, (int8_t)*(memory+1));
|
||||
//}
|
||||
if (opcode_size>4) {
|
||||
opcode_size=4;
|
||||
sprintf(buffer, base, (int8_t)*(memory+3));
|
||||
} else {
|
||||
sprintf(buffer, base, (int8_t)*(memory+2));
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
Reference in New Issue
Block a user