Changed trace instruction logger to be more efficient.

This commit is contained in:
Matthew Budd 2020-10-01 07:04:52 -04:00
parent 2524667d12
commit 0b3d377e18
2 changed files with 122 additions and 15 deletions

View File

@ -66,7 +66,7 @@ static char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTA
static char str_tabs[LOG_TABS_MASK+1] = {0}, str_address[LOG_ADDRESS_MAX_LEN] = {0}, str_data[LOG_DATA_MAX_LEN] = {0}, str_disassembly[LOG_DISASSEMBLY_MAX_LEN] = {0};
static char str_result[LOG_LINE_MAX_LEN] = {0};
static char str_temp[LOG_LINE_MAX_LEN] = {0};
static char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
//static char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
//static char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
//static char* tracer_decoration_comment = 0;
//static char* tracer_decoration_comment_end_pos = 0;
@ -215,19 +215,86 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void)
}
}
//----------------------------------------------------
traceRecord_t::traceRecord_t(void)
{
cpu.PC = 0;
cpu.A = 0;
cpu.X = 0;
cpu.Y = 0;
cpu.S = 0;
cpu.P = 0;
opCode[0] = 0;
opCode[1] = 0;
opCode[2] = 0;
opSize = 0;
asmTxtSize = 0;
asmTxt[0] = 0;
cycleCount = 0;
instrCount = 0;
flags = 0;
callAddr = -1;
romAddr = -1;
bank = -1;
skippedLines = 0;
}
//----------------------------------------------------
int traceRecord_t::appendAsmText( const char *txt )
{
int i=0;
while ( txt[i] != 0 )
{
asmTxt[ asmTxtSize ] = txt[i]; i++; asmTxtSize++;
}
asmTxt[ asmTxtSize ] = 0;
return 0;
}
//----------------------------------------------------
//todo: really speed this up
void FCEUD_TraceInstruction(uint8 *opcode, int size)
{
if (!logging)
return;
traceRecord_t rec;
unsigned int addr = X.PC;
uint8 tmp;
static int unloggedlines = 0;
rec.cpu.PC = X.PC;
rec.cpu.A = X.A;
rec.cpu.X = X.X;
rec.cpu.Y = X.Y;
rec.cpu.S = X.S;
rec.cpu.P = X.P;
for (int i=0; i<size; i++)
{
rec.opCode[i] = opcode[i];
}
rec.opSize = size;
rec.romAddr = GetPRGAddress(addr);
rec.bank = getBank(addr);
rec.frameCount = currFrameCounter;
rec.instrCount = total_instructions;
int64 counter_value = timestampbase + (uint64)timestamp - total_cycles_base;
if (counter_value < 0) // sanity check
{
ResetDebugStatisticsCounters();
counter_value = 0;
}
rec.cycleCount = counter_value;
// if instruction executed from the RAM, skip this, log all instead
// TODO: loops folding mame-lyke style
if (GetPRGAddress(addr) != -1)
if (rec.romAddr != -1)
{
if (((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) ||
((logging_options & LOG_NEW_DATA) && (olddatacount != datacount)))
@ -235,10 +302,11 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
//something new was logged
oldcodecount = codecount;
olddatacount = datacount;
if(unloggedlines > 0)
if (unloggedlines > 0)
{
sprintf(str_result, "(%d lines skipped)", unloggedlines);
//sprintf(str_result, "(%d lines skipped)", unloggedlines);
//OutputLogLine(str_result);
rec.skippedLines = unloggedlines;
unloggedlines = 0;
}
}
@ -258,8 +326,9 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
if ((addr + size) > 0xFFFF)
{
sprintf(str_data, "%02X ", opcode[0]);
sprintf(str_disassembly, "OVERFLOW");
//sprintf(str_data, "%02X ", opcode[0]);
//sprintf(str_disassembly, "OVERFLOW");
rec.flags |= 0x01;
}
else
{
@ -267,12 +336,13 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
switch (size)
{
case 0:
sprintf(str_data, "%02X ", opcode[0]);
sprintf(str_disassembly,"UNDEFINED");
//sprintf(str_data, "%02X ", opcode[0]);
//sprintf(str_disassembly,"UNDEFINED");
rec.flags |= 0x02;
break;
case 1:
{
sprintf(str_data, "%02X ", opcode[0]);
//sprintf(str_data, "%02X ", opcode[0]);
a = Disassemble(addr + 1, opcode);
// special case: an RTS opcode
if (opcode[0] == 0x60)
@ -283,18 +353,19 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
{
// this was a JSR instruction - take the subroutine address from it
unsigned int call_addr = GetMem(caller_addr + 1) + (GetMem(caller_addr + 2) << 8);
sprintf(str_decoration, " (from $%04X)", call_addr);
strcat(a, str_decoration);
//sprintf(str_decoration, " (from $%04X)", call_addr);
//strcat(a, str_decoration);
rec.callAddr = call_addr;
}
}
break;
}
case 2:
sprintf(str_data, "%02X %02X ", opcode[0],opcode[1]);
//sprintf(str_data, "%02X %02X ", opcode[0],opcode[1]);
a = Disassemble(addr + 2, opcode);
break;
case 3:
sprintf(str_data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]);
//sprintf(str_data, "%02X %02X %02X ", opcode[0],opcode[1],opcode[2]);
a = Disassemble(addr + 3, opcode);
break;
}
@ -343,10 +414,15 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
// // replaceNames(pageNames[i], a, &tempAddressesLog);
// //}
//}
strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
//strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
//str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
rec.appendAsmText(a);
}
}
return; // TEST
// All of the following log text creation is very cpu intensive, to keep emulation
// running realtime save data and have a separate thread do this translation.
if (size == 1 && GetMem(addr) == 0x60)
{

View File

@ -17,6 +17,37 @@
#include <QScrollBar>
#include <QCloseEvent>
struct traceRecord_t
{
struct {
uint16_t PC;
uint8_t A;
uint8_t X;
uint8_t Y;
uint8_t S;
uint8_t P;
} cpu;
uint8_t opCode[3];
uint8_t opSize;
uint8_t asmTxtSize;
char asmTxt[46];
uint64_t frameCount;
uint64_t cycleCount;
uint64_t instrCount;
uint64_t flags;
int32_t callAddr;
int32_t romAddr;
int32_t bank;
int32_t skippedLines;
traceRecord_t(void);
int appendAsmText( const char *txt );
};
class QTraceLogView : public QWidget
{
Q_OBJECT