- [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);
|
||||
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+1, (value>>8) & 0xff);
|
||||
//if (value==0x7229) z80debug::stop();
|
||||
}
|
||||
|
||||
void PUSH(uint16_t b)
|
||||
@@ -675,6 +676,7 @@ namespace z80
|
||||
if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
||||
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
||||
z80debug::setcursor(rPC);
|
||||
z80debug::history::store();
|
||||
z80debug::stop();
|
||||
}
|
||||
}
|
||||
@@ -1081,8 +1083,10 @@ namespace z80
|
||||
t = 0;
|
||||
const uint8_t opcode = READ_M1();
|
||||
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;
|
||||
|
||||
if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
@@ -1370,6 +1374,9 @@ namespace z80
|
||||
void BIT_INSTRUCTIONS()
|
||||
{
|
||||
const uint8_t opcode = READ_M1();
|
||||
|
||||
z80debug::useOpcode(opcode, 2);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00: rB = RLC(rB); break;
|
||||
@@ -1651,6 +1658,8 @@ namespace z80
|
||||
const uint8_t opcode = READ_M1();
|
||||
int8_t d;
|
||||
|
||||
if (opcode!=0xCB) z80debug::useOpcode(opcode, 3);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00: INVALID(opcode); break;
|
||||
@@ -1872,6 +1881,9 @@ namespace z80
|
||||
const int8_t d = READ_MEM_8();
|
||||
const uint8_t opcode = READ_MEM_8();
|
||||
t+=3;
|
||||
|
||||
z80debug::useOpcode(opcode, 4);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00: rB = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
||||
@@ -2151,6 +2163,9 @@ namespace z80
|
||||
void MISC_INSTRUCTIONS()
|
||||
{
|
||||
const uint8_t opcode = READ_M1();
|
||||
|
||||
z80debug::useOpcode(opcode, 1);
|
||||
|
||||
rR = (rR&0x80) + ((rR+1) & 0x7f);
|
||||
uint16_t tmp;
|
||||
|
||||
@@ -2232,6 +2247,8 @@ namespace z80
|
||||
const uint8_t opcode = READ_M1();
|
||||
int8_t d;
|
||||
|
||||
if (opcode!=0xCB) z80debug::useOpcode(opcode, 5);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00: INVALID(opcode); break;
|
||||
@@ -2453,6 +2470,9 @@ namespace z80
|
||||
const int8_t d = READ_MEM_8();
|
||||
const uint8_t opcode = READ_MEM_8();
|
||||
t+=3;
|
||||
|
||||
z80debug::useOpcode(opcode, 6);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return options[option];
|
||||
|
||||
2
z80.h
2
z80.h
@@ -8,6 +8,7 @@ namespace z80
|
||||
#define MEMTAG_INST 1
|
||||
#define MEMTAG_CODE 2
|
||||
#define MEMTAG_DATA 3
|
||||
#define MEMTAG_REPEAT 4
|
||||
|
||||
#define Z80_OPTION_STOP_ON_INVALID 0
|
||||
#define Z80_OPTION_BREAK_ON_INTERRUPT 1
|
||||
@@ -42,6 +43,7 @@ namespace z80
|
||||
|
||||
uint8_t getMemTouched(const uint16_t addr);
|
||||
void clearMemTouched();
|
||||
void fixMemTouched();
|
||||
|
||||
const bool getOption(const int option);
|
||||
void setOption(const int option, const bool value);
|
||||
|
||||
@@ -17,12 +17,16 @@ namespace z80analyze
|
||||
{
|
||||
if (e->type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
z80::clearMemTouched();
|
||||
if (e->button.button == 1)
|
||||
z80::clearMemTouched();
|
||||
else
|
||||
z80::fixMemTouched();
|
||||
refresh();
|
||||
}
|
||||
if (e->type == SDL_MOUSEMOTION)
|
||||
{
|
||||
refreshTitle();
|
||||
refresh();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -31,6 +35,7 @@ namespace z80analyze
|
||||
{
|
||||
if (!win)
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
win = SDL_CreateWindow("Z80 Analyzer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_SHOWN);
|
||||
ren = SDL_CreateRenderer(win, -1, 0);
|
||||
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)
|
||||
{
|
||||
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_RenderCopy(ren, tex, NULL, NULL);
|
||||
SDL_RenderPresent(ren);
|
||||
|
||||
75
z80debug.cpp
75
z80debug.cpp
@@ -62,6 +62,8 @@ namespace z80debug
|
||||
|
||||
uint16_t cursor = 0;
|
||||
|
||||
uint8_t use[7][256];
|
||||
|
||||
char temp[256];
|
||||
const char *tohex(int value, int numdigits)
|
||||
{
|
||||
@@ -106,12 +108,15 @@ namespace z80debug
|
||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
|
||||
z80debug::history::gototop();
|
||||
z80debug::refresh();
|
||||
z80analyze::refresh();
|
||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F2) {
|
||||
z80debug::history::goback();
|
||||
z80debug::refresh();
|
||||
z80analyze::refresh();
|
||||
} else if (e->key.keysym.scancode==SDL_SCANCODE_F3) {
|
||||
z80debug::history::goforward();
|
||||
z80debug::refresh();
|
||||
z80analyze::refresh();
|
||||
/*} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) {
|
||||
z80debug::history::gototop();
|
||||
const uint8_t dt = z80::step();
|
||||
@@ -217,6 +222,7 @@ namespace z80debug
|
||||
tex = ui::createtexture(ren);
|
||||
}
|
||||
focus();
|
||||
z80analyze::refresh();
|
||||
}
|
||||
|
||||
void focus()
|
||||
@@ -611,9 +617,11 @@ namespace z80debug
|
||||
|
||||
if (strcmp(cmd, "s")==0 || strcmp(cmd, "step")==0) {
|
||||
z80::step();
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
||||
z80::step();
|
||||
z80debug::cont();
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) {
|
||||
uint8_t *mem = z80::getMem();
|
||||
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);
|
||||
//for (int i=0; i<65536; ++i) breakpoints[i]=0;
|
||||
z80debug::refresh();
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "b")==0 || strcmp(cmd, "break")==0) {
|
||||
getcmd();
|
||||
if (cmd[0] == 0) { breakpoints[z80::getPC()]=1; return; }
|
||||
@@ -682,6 +691,7 @@ namespace z80debug
|
||||
//strcpy(address, cmd);
|
||||
//loadngo(filename, address);
|
||||
loadstate(filename);
|
||||
z80analyze::refresh();
|
||||
} else if (strcmp(cmd, "t")==0 || strcmp(cmd, "tape")==0) {
|
||||
getcmd();
|
||||
if (strcmp(cmd, "load")==0) {
|
||||
@@ -759,6 +769,17 @@ namespace z80debug
|
||||
sendToConsoleLog("Keyup sent for key: ");
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -34,6 +34,12 @@ namespace z80debug
|
||||
void cursorfwd();
|
||||
void cursorback();
|
||||
|
||||
void useOpcode(const uint8_t opcode, const uint8_t base);
|
||||
void clearUsedOpcodes();
|
||||
void markUsedOpcodes();
|
||||
const int getNumOpcodesUsed();
|
||||
void printOpcodesUsed();
|
||||
|
||||
namespace history
|
||||
{
|
||||
void store();
|
||||
|
||||
Reference in New Issue
Block a user