- [FIX] Al fer break on interrupt de vegades se passava de instruccions
- [NEW] el analitzador pot mostrar les instruccions repetides des de l'ultim estat - [NEW] gestió de opcodes usats
This commit is contained in:
1
main.cpp
1
main.cpp
@@ -201,6 +201,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
zx_ula::sound_update(dt);
|
zx_ula::sound_update(dt);
|
||||||
zxscreen::refresh(dt);
|
zxscreen::refresh(dt);
|
||||||
|
if (z80debug::debugging()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
32
z80.cpp
32
z80.cpp
@@ -193,6 +193,7 @@ namespace z80
|
|||||||
{
|
{
|
||||||
WRITE_MEM_8(addr, value & 0xff);
|
WRITE_MEM_8(addr, value & 0xff);
|
||||||
WRITE_MEM_8(addr+1, (value>>8) & 0xff);
|
WRITE_MEM_8(addr+1, (value>>8) & 0xff);
|
||||||
|
//if (value==0x7229) z80debug::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PUSH(uint16_t b)
|
void PUSH(uint16_t b)
|
||||||
@@ -675,6 +676,7 @@ namespace z80
|
|||||||
if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
||||||
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
||||||
z80debug::setcursor(rPC);
|
z80debug::setcursor(rPC);
|
||||||
|
z80debug::history::store();
|
||||||
z80debug::stop();
|
z80debug::stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1081,8 +1083,10 @@ namespace z80
|
|||||||
t = 0;
|
t = 0;
|
||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
memtag[current_opcode_address] = MEMTAG_INST;
|
memtag[current_opcode_address] = MEMTAG_INST;
|
||||||
memtouched[current_opcode_address] = MEMTAG_INST;
|
memtouched[current_opcode_address] = memtouched[current_opcode_address] != MEMTAG_NONE ? MEMTAG_REPEAT : MEMTAG_INST;
|
||||||
uint16_t tmp;
|
uint16_t tmp;
|
||||||
|
|
||||||
|
if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
@@ -1370,6 +1374,9 @@ namespace z80
|
|||||||
void BIT_INSTRUCTIONS()
|
void BIT_INSTRUCTIONS()
|
||||||
{
|
{
|
||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
|
|
||||||
|
z80debug::useOpcode(opcode, 2);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: rB = RLC(rB); break;
|
case 0x00: rB = RLC(rB); break;
|
||||||
@@ -1651,6 +1658,8 @@ namespace z80
|
|||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
int8_t d;
|
int8_t d;
|
||||||
|
|
||||||
|
if (opcode!=0xCB) z80debug::useOpcode(opcode, 3);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: INVALID(opcode); break;
|
case 0x00: INVALID(opcode); break;
|
||||||
@@ -1872,6 +1881,9 @@ namespace z80
|
|||||||
const int8_t d = READ_MEM_8();
|
const int8_t d = READ_MEM_8();
|
||||||
const uint8_t opcode = READ_MEM_8();
|
const uint8_t opcode = READ_MEM_8();
|
||||||
t+=3;
|
t+=3;
|
||||||
|
|
||||||
|
z80debug::useOpcode(opcode, 4);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: rB = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
case 0x00: rB = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
||||||
@@ -2151,6 +2163,9 @@ namespace z80
|
|||||||
void MISC_INSTRUCTIONS()
|
void MISC_INSTRUCTIONS()
|
||||||
{
|
{
|
||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
|
|
||||||
|
z80debug::useOpcode(opcode, 1);
|
||||||
|
|
||||||
rR = (rR&0x80) + ((rR+1) & 0x7f);
|
rR = (rR&0x80) + ((rR+1) & 0x7f);
|
||||||
uint16_t tmp;
|
uint16_t tmp;
|
||||||
|
|
||||||
@@ -2232,6 +2247,8 @@ namespace z80
|
|||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
int8_t d;
|
int8_t d;
|
||||||
|
|
||||||
|
if (opcode!=0xCB) z80debug::useOpcode(opcode, 5);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: INVALID(opcode); break;
|
case 0x00: INVALID(opcode); break;
|
||||||
@@ -2453,6 +2470,9 @@ namespace z80
|
|||||||
const int8_t d = READ_MEM_8();
|
const int8_t d = READ_MEM_8();
|
||||||
const uint8_t opcode = READ_MEM_8();
|
const uint8_t opcode = READ_MEM_8();
|
||||||
t+=3;
|
t+=3;
|
||||||
|
|
||||||
|
z80debug::useOpcode(opcode, 6);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: rB = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
case 0x00: rB = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
||||||
@@ -2762,6 +2782,16 @@ namespace z80
|
|||||||
for (int i=0; i<65536; ++i) memtouched[i] = MEMTAG_NONE;
|
for (int i=0; i<65536; ++i) memtouched[i] = MEMTAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fixMemTouched()
|
||||||
|
{
|
||||||
|
for (int i=0; i<65536; ++i)
|
||||||
|
if ( (memtouched[i]==MEMTAG_INST) || (memtouched[i]==MEMTAG_REPEAT) )
|
||||||
|
memtouched[i] = MEMTAG_DATA;
|
||||||
|
//else if (memtouched[i]==MEMTAG_DATA)
|
||||||
|
// memtouched[i] = MEMTAG_REPEAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool getOption(const int option)
|
const bool getOption(const int option)
|
||||||
{
|
{
|
||||||
return options[option];
|
return options[option];
|
||||||
|
|||||||
2
z80.h
2
z80.h
@@ -8,6 +8,7 @@ namespace z80
|
|||||||
#define MEMTAG_INST 1
|
#define MEMTAG_INST 1
|
||||||
#define MEMTAG_CODE 2
|
#define MEMTAG_CODE 2
|
||||||
#define MEMTAG_DATA 3
|
#define MEMTAG_DATA 3
|
||||||
|
#define MEMTAG_REPEAT 4
|
||||||
|
|
||||||
#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
|
||||||
@@ -42,6 +43,7 @@ namespace z80
|
|||||||
|
|
||||||
uint8_t getMemTouched(const uint16_t addr);
|
uint8_t getMemTouched(const uint16_t addr);
|
||||||
void clearMemTouched();
|
void clearMemTouched();
|
||||||
|
void fixMemTouched();
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ namespace z80analyze
|
|||||||
{
|
{
|
||||||
if (e->type == SDL_MOUSEBUTTONUP)
|
if (e->type == SDL_MOUSEBUTTONUP)
|
||||||
{
|
{
|
||||||
z80::clearMemTouched();
|
if (e->button.button == 1)
|
||||||
|
z80::clearMemTouched();
|
||||||
|
else
|
||||||
|
z80::fixMemTouched();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
if (e->type == SDL_MOUSEMOTION)
|
if (e->type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
refreshTitle();
|
refreshTitle();
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -31,6 +35,7 @@ namespace z80analyze
|
|||||||
{
|
{
|
||||||
if (!win)
|
if (!win)
|
||||||
{
|
{
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
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);
|
||||||
@@ -60,9 +65,22 @@ namespace z80analyze
|
|||||||
for (int i=0; i<65536; ++i)
|
for (int i=0; i<65536; ++i)
|
||||||
{
|
{
|
||||||
uint8_t tag = z80::getMemTouched(i);
|
uint8_t tag = z80::getMemTouched(i);
|
||||||
pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : 0x00FF00;
|
pixels[i] = tag==MEMTAG_NONE ? 0x808080 : tag==MEMTAG_DATA ? 0x0000FF : tag==MEMTAG_REPEAT ? 0xFF0000 : 0x00FF00;
|
||||||
}
|
}
|
||||||
pixels[z80::getPC()] = 0xFF0000;
|
pixels[z80::getPC()] = 0xFFFFFF;
|
||||||
|
|
||||||
|
int mx, my;
|
||||||
|
SDL_GetMouseState(&mx, &my);
|
||||||
|
mx/=2; my/=2;
|
||||||
|
pixels[(mx-2)+(my)*256] = 0x000000;
|
||||||
|
pixels[(mx-1)+(my)*256] = 0x000000;
|
||||||
|
pixels[(mx+1)+(my)*256] = 0x000000;
|
||||||
|
pixels[(mx+2)+(my)*256] = 0x000000;
|
||||||
|
pixels[(mx)+(my-1)*256] = 0x000000;
|
||||||
|
pixels[(mx)+(my-2)*256] = 0x000000;
|
||||||
|
pixels[(mx)+(my+1)*256] = 0x000000;
|
||||||
|
pixels[(mx)+(my+2)*256] = 0x000000;
|
||||||
|
|
||||||
SDL_UnlockTexture(tex);
|
SDL_UnlockTexture(tex);
|
||||||
SDL_RenderCopy(ren, tex, NULL, NULL);
|
SDL_RenderCopy(ren, tex, NULL, NULL);
|
||||||
SDL_RenderPresent(ren);
|
SDL_RenderPresent(ren);
|
||||||
|
|||||||
75
z80debug.cpp
75
z80debug.cpp
@@ -62,6 +62,8 @@ namespace z80debug
|
|||||||
|
|
||||||
uint16_t cursor = 0;
|
uint16_t cursor = 0;
|
||||||
|
|
||||||
|
uint8_t use[7][256];
|
||||||
|
|
||||||
char temp[256];
|
char temp[256];
|
||||||
const char *tohex(int value, int numdigits)
|
const char *tohex(int value, int numdigits)
|
||||||
{
|
{
|
||||||
@@ -106,12 +108,15 @@ namespace z80debug
|
|||||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
|
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
|
||||||
z80debug::history::gototop();
|
z80debug::history::gototop();
|
||||||
z80debug::refresh();
|
z80debug::refresh();
|
||||||
|
z80analyze::refresh();
|
||||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F2) {
|
} else if (e->key.keysym.scancode==SDL_SCANCODE_F2) {
|
||||||
z80debug::history::goback();
|
z80debug::history::goback();
|
||||||
z80debug::refresh();
|
z80debug::refresh();
|
||||||
|
z80analyze::refresh();
|
||||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F3) {
|
} else if (e->key.keysym.scancode==SDL_SCANCODE_F3) {
|
||||||
z80debug::history::goforward();
|
z80debug::history::goforward();
|
||||||
z80debug::refresh();
|
z80debug::refresh();
|
||||||
|
z80analyze::refresh();
|
||||||
/*} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) {
|
/*} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) {
|
||||||
z80debug::history::gototop();
|
z80debug::history::gototop();
|
||||||
const uint8_t dt = z80::step();
|
const uint8_t dt = z80::step();
|
||||||
@@ -217,6 +222,7 @@ namespace z80debug
|
|||||||
tex = ui::createtexture(ren);
|
tex = ui::createtexture(ren);
|
||||||
}
|
}
|
||||||
focus();
|
focus();
|
||||||
|
z80analyze::refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void focus()
|
void focus()
|
||||||
@@ -611,9 +617,11 @@ namespace z80debug
|
|||||||
|
|
||||||
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
||||||
z80::step();
|
z80::step();
|
||||||
|
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();
|
||||||
z80debug::cont();
|
z80debug::cont();
|
||||||
|
z80analyze::refresh();
|
||||||
} 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=0x4000; i<=0xffff; ++i) mem[i]=0;
|
for (int i=0x4000; i<=0xffff; ++i) mem[i]=0;
|
||||||
@@ -621,6 +629,7 @@ namespace z80debug
|
|||||||
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;
|
||||||
z80debug::refresh();
|
z80debug::refresh();
|
||||||
|
z80analyze::refresh();
|
||||||
} else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) {
|
} else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) {
|
||||||
getcmd();
|
getcmd();
|
||||||
if (cmd[0] == 0) { breakpoints[z80::getPC()]=1; return; }
|
if (cmd[0] == 0) { breakpoints[z80::getPC()]=1; return; }
|
||||||
@@ -682,6 +691,7 @@ namespace z80debug
|
|||||||
//strcpy(address, cmd);
|
//strcpy(address, cmd);
|
||||||
//loadngo(filename, address);
|
//loadngo(filename, address);
|
||||||
loadstate(filename);
|
loadstate(filename);
|
||||||
|
z80analyze::refresh();
|
||||||
} else if (strcmp(cmd, "t")==0 || strcmp(cmd, "tape")==0) {
|
} else if (strcmp(cmd, "t")==0 || strcmp(cmd, "tape")==0) {
|
||||||
getcmd();
|
getcmd();
|
||||||
if (strcmp(cmd, "load")==0) {
|
if (strcmp(cmd, "load")==0) {
|
||||||
@@ -759,6 +769,17 @@ namespace z80debug
|
|||||||
sendToConsoleLog("Keyup sent for key: ");
|
sendToConsoleLog("Keyup sent for key: ");
|
||||||
sendMoreToConsoleLog(cmd);
|
sendMoreToConsoleLog(cmd);
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(cmd, "opcodes")==0) {
|
||||||
|
getcmd();
|
||||||
|
if (strcmp(cmd, "clear")==0 || strcmp(cmd, "reset")==0) {
|
||||||
|
clearUsedOpcodes();
|
||||||
|
} else if (strcmp(cmd, "mark")==0) {
|
||||||
|
markUsedOpcodes();
|
||||||
|
} else if (strcmp(cmd, "count")==0) {
|
||||||
|
printf("Num opcodes used: %i\n", getNumOpcodesUsed());
|
||||||
|
} else if (strcmp(cmd, "print")==0) {
|
||||||
|
printOpcodesUsed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,6 +852,60 @@ namespace z80debug
|
|||||||
cursor = find_previous_opcode(cursor);
|
cursor = find_previous_opcode(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void useOpcode(const uint8_t opcode, const uint8_t base)
|
||||||
|
{
|
||||||
|
if (use[base][opcode]<255) use[base][opcode]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearUsedOpcodes()
|
||||||
|
{
|
||||||
|
for (int i=0; i<7; ++i) {
|
||||||
|
for (int j=0; j<256; ++j) {
|
||||||
|
use[i][j]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void markUsedOpcodes()
|
||||||
|
{
|
||||||
|
for (int i=0; i<7; ++i) {
|
||||||
|
for (int j=0; j<256; ++j) {
|
||||||
|
if (use[i][j]==1) use[i][j]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int getNumOpcodesUsed()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (int i=0; i<7; ++i) {
|
||||||
|
for (int j=0; j<256; ++j) {
|
||||||
|
if (use[i][j]==1) count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printOpcodesUsed()
|
||||||
|
{
|
||||||
|
for (int i=0; i<7; ++i) {
|
||||||
|
for (int j=0; j<256; ++j) {
|
||||||
|
if (use[i][j]==1) {
|
||||||
|
switch (i) {
|
||||||
|
case 1: printf("ED "); break;
|
||||||
|
case 2: printf("CB "); break;
|
||||||
|
case 3: printf("DD "); break;
|
||||||
|
case 4: printf("DD CB "); break;
|
||||||
|
case 5: printf("FD "); break;
|
||||||
|
case 6: printf("FD CB "); break;
|
||||||
|
}
|
||||||
|
printf("%2X\n",j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace history
|
namespace history
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ namespace z80debug
|
|||||||
void cursorfwd();
|
void cursorfwd();
|
||||||
void cursorback();
|
void cursorback();
|
||||||
|
|
||||||
|
void useOpcode(const uint8_t opcode, const uint8_t base);
|
||||||
|
void clearUsedOpcodes();
|
||||||
|
void markUsedOpcodes();
|
||||||
|
const int getNumOpcodesUsed();
|
||||||
|
void printOpcodesUsed();
|
||||||
|
|
||||||
namespace history
|
namespace history
|
||||||
{
|
{
|
||||||
void store();
|
void store();
|
||||||
|
|||||||
Reference in New Issue
Block a user