trace logger hack
This commit is contained in:
parent
afd65c12f3
commit
469e8f8dde
196
src/asm.cpp
196
src/asm.cpp
|
@ -527,3 +527,199 @@ char *Disassemble(int addr, uint8 *opcode) {
|
|||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///disassembles the opcodes in the buffer assuming the provided address. Uses GetMem() and 6502 current registers to query referenced values. returns a static string buffer.
|
||||
char *bzk_Disassemble(int addr, uint8 *opcode) {
|
||||
static char str[64] = {0};
|
||||
uint16 tmp;
|
||||
|
||||
switch (opcode[0]) {
|
||||
//Zero Page
|
||||
case 0x05: goto _zeropage; //ORA
|
||||
case 0x06: goto _zeropage; //ASL
|
||||
case 0x24: goto _zeropage; //BIT
|
||||
case 0x25: goto _zeropage; //AND
|
||||
case 0x26: goto _zeropage; //ROL
|
||||
case 0x45: goto _zeropage; //EOR
|
||||
case 0x46: goto _zeropage; //LSR
|
||||
case 0x65: goto _zeropage; //ADC
|
||||
case 0x66: goto _zeropage; //ROR
|
||||
case 0x84: goto _zeropage; //STY
|
||||
case 0x85: goto _zeropage; //STA
|
||||
case 0x86: goto _zeropage; //STX
|
||||
case 0xA4: goto _zeropage; //LDY
|
||||
case 0xA5: goto _zeropage; //LDA
|
||||
case 0xA6: goto _zeropage; //LDX
|
||||
case 0xC4: goto _zeropage; //CPY
|
||||
case 0xC5: goto _zeropage; //CMP
|
||||
case 0xC6: goto _zeropage; //DEC
|
||||
case 0xE4: goto _zeropage; //CPX
|
||||
case 0xE5: goto _zeropage; //SBC
|
||||
case 0xE6: goto _zeropage; //INC
|
||||
_zeropage:
|
||||
tmp = opcode[1];
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//Zero Page,X
|
||||
case 0x15: goto _zeropagex; //ORA
|
||||
case 0x16: goto _zeropagex; //ASL
|
||||
case 0x35: goto _zeropagex; //AND
|
||||
case 0x36: goto _zeropagex; //ROL
|
||||
case 0x55: goto _zeropagex; //EOR
|
||||
case 0x56: goto _zeropagex; //LSR
|
||||
case 0x75: goto _zeropagex; //ADC
|
||||
case 0x76: goto _zeropagex; //ROR
|
||||
case 0x94: goto _zeropagex; //STY
|
||||
case 0x95: goto _zeropagex; //STA
|
||||
case 0xB4: goto _zeropagex; //LDY
|
||||
case 0xB5: goto _zeropagex; //LDA
|
||||
case 0xD5: goto _zeropagex; //CMP
|
||||
case 0xD6: goto _zeropagex; //DEC
|
||||
case 0xF5: goto _zeropagex; //SBC
|
||||
case 0xF6: goto _zeropagex; //INC
|
||||
_zeropagex:
|
||||
tmp = (opcode[1] + X.X) & 0xFF;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//Zero Page,Y
|
||||
case 0x96: goto _zeropagey; //STX
|
||||
case 0xB6: goto _zeropagey; //LDX
|
||||
_zeropagey:
|
||||
tmp = (opcode[1] + X.Y) & 0xFF;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//Absolute
|
||||
case 0x0D: goto _absolute; //ORA
|
||||
case 0x0E: goto _absolute; //ASL
|
||||
case 0x2C: goto _absolute; //BIT
|
||||
case 0x2D: goto _absolute; //AND
|
||||
case 0x2E: goto _absolute; //ROL
|
||||
case 0x4D: goto _absolute; //EOR
|
||||
case 0x4E: goto _absolute; //LSR
|
||||
case 0x6D: goto _absolute; //ADC
|
||||
case 0x6E: goto _absolute; //ROR
|
||||
case 0x8C: goto _absolute; //STY
|
||||
case 0x8D: goto _absolute; //STA
|
||||
case 0x8E: goto _absolute; //STX
|
||||
case 0xAC: goto _absolute; //LDY
|
||||
case 0xAD: goto _absolute; //LDA
|
||||
case 0xAE: goto _absolute; //LDX
|
||||
case 0xCC: goto _absolute; //CPY
|
||||
case 0xCD: goto _absolute; //CMP
|
||||
case 0xCE: goto _absolute; //DEC
|
||||
case 0xEC: goto _absolute; //CPX
|
||||
case 0xED: goto _absolute; //SBC
|
||||
case 0xEE: goto _absolute; //INC
|
||||
_absolute:
|
||||
tmp = opcode[1] | opcode[2] << 8;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//Absolute,X
|
||||
case 0x1D: goto _absolutex; //ORA
|
||||
case 0x1E: goto _absolutex; //ASL
|
||||
case 0x3D: goto _absolutex; //AND
|
||||
case 0x3E: goto _absolutex; //ROL
|
||||
case 0x5D: goto _absolutex; //EOR
|
||||
case 0x5E: goto _absolutex; //LSR
|
||||
case 0x7D: goto _absolutex; //ADC
|
||||
case 0x7E: goto _absolutex; //ROR
|
||||
case 0x9D: goto _absolutex; //STA
|
||||
case 0xBC: goto _absolutex; //LDY
|
||||
case 0xBD: goto _absolutex; //LDA
|
||||
case 0xDD: goto _absolutex; //CMP
|
||||
case 0xDE: goto _absolutex; //DEC
|
||||
case 0xFD: goto _absolutex; //SBC
|
||||
case 0xFE: goto _absolutex; //INC
|
||||
_absolutex:
|
||||
tmp = (opcode[1] | opcode[2] << 8) + X.X;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//Absolute,Y
|
||||
case 0x19: goto _absolutey; //ORA
|
||||
case 0x39: goto _absolutey; //AND
|
||||
case 0x59: goto _absolutey; //EOR
|
||||
case 0x79: goto _absolutey; //ADC
|
||||
case 0x99: goto _absolutey; //STA
|
||||
case 0xB9: goto _absolutey; //LDA
|
||||
case 0xBE: goto _absolutey; //LDX
|
||||
case 0xD9: goto _absolutey; //CMP
|
||||
case 0xF9: goto _absolutey; //SBC
|
||||
_absolutey:
|
||||
tmp = (opcode[1] | opcode[2] << 8) + X.Y;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//branches
|
||||
case 0x10: goto _branch; //BPL
|
||||
case 0x30: goto _branch; //BMI
|
||||
case 0x50: goto _branch; //BVC
|
||||
case 0x70: goto _branch; //BVS
|
||||
case 0x90: goto _branch; //BCC
|
||||
case 0xB0: goto _branch; //BCS
|
||||
case 0xD0: goto _branch; //BNE
|
||||
case 0xF0: goto _branch; //BEQ
|
||||
_branch:
|
||||
tmp = addr + opcode[1] + 0x02;
|
||||
if (opcode[1] >= 0x80) tmp -= 0x100;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//(Indirect,X)
|
||||
case 0x01: goto _indirectx; //ORA
|
||||
case 0x21: goto _indirectx; //AND
|
||||
case 0x41: goto _indirectx; //EOR
|
||||
case 0x61: goto _indirectx; //ADC
|
||||
case 0x81: goto _indirectx; //STA
|
||||
case 0xA1: goto _indirectx; //LDA
|
||||
case 0xC1: goto _indirectx; //CMP
|
||||
case 0xE1: goto _indirectx; //SBC
|
||||
_indirectx:
|
||||
tmp = (opcode[1] + X.X) & 0xFF;
|
||||
tmp = GetMem((tmp)) | (GetMem(((tmp) + 1) & 0xFF)) << 8;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//(Indirect),Y
|
||||
case 0x11: goto _indirecty; //ORA
|
||||
case 0x31: goto _indirecty; //AND
|
||||
case 0x51: goto _indirecty; //EOR
|
||||
case 0x71: goto _indirecty; //ADC
|
||||
case 0x91: goto _indirecty; //STA
|
||||
case 0xB1: goto _indirecty; //LDA
|
||||
case 0xD1: goto _indirecty; //CMP
|
||||
case 0xF1: goto _indirecty; //SBC
|
||||
_indirecty:
|
||||
tmp = (GetMem(opcode[1]) | (GetMem((opcode[1] + 1) & 0xFF)) << 8) + X.Y;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//absolute jumps
|
||||
case 0x20: goto _jump; //JSR
|
||||
case 0x4C: goto _jump; //JMP
|
||||
_jump:
|
||||
tmp = opcode[1] | opcode[2] << 8;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//indirect jump
|
||||
case 0x6C: //JMP
|
||||
tmp = opcode[1] | opcode[2] << 8;
|
||||
tmp = GetMem(tmp) | GetMem(tmp + 1) << 8;
|
||||
sprintf(str, "%u|%u", bzk_GetNesFileAddress(tmp), bzk_getBank(tmp));
|
||||
break;
|
||||
|
||||
//for all other other opcodes, which are immediate and 1-byte instructions
|
||||
default:
|
||||
strcpy(str, "?|?");
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
int Assemble(unsigned char *output, int addr, char *str);
|
||||
char *Disassemble(int addr, uint8 *opcode);
|
||||
char *bzk_Disassemble(int addr, uint8 *opcode);
|
||||
|
|
|
@ -265,6 +265,11 @@ int getBank(int offs)
|
|||
return addr != -1 ? addr / (1<<debuggerPageSize) : -1; //formerly, dividing by 0x4000
|
||||
}
|
||||
|
||||
int bzk_getBank(int offs)
|
||||
{
|
||||
return bzk_GetNesFileAddress(offs) / 0x2000;
|
||||
}
|
||||
|
||||
int GetNesFileAddress(int A){
|
||||
int result;
|
||||
if((A < 0x6000) || (A > 0xFFFF))return -1;
|
||||
|
@ -273,6 +278,11 @@ int GetNesFileAddress(int A){
|
|||
else return result+16; //16 bytes for the header remember
|
||||
}
|
||||
|
||||
int bzk_GetNesFileAddress(int A){
|
||||
if (A >= 0x6000) return &Page[A>>11][A]-PRGptr[0]; //for 6000-FFFF
|
||||
return A + 0x80000; //for 0000-5FFF
|
||||
}
|
||||
|
||||
int GetRomAddress(int A){
|
||||
int i;
|
||||
uint8 *p = GetNesPRGPointer(A-=16);
|
||||
|
|
|
@ -64,7 +64,9 @@ extern watchpointinfo watchpoint[65]; //64 watchpoints, + 1 reserved for step ov
|
|||
|
||||
extern unsigned int debuggerPageSize;
|
||||
int getBank(int offs);
|
||||
int bzk_getBank(int offs);
|
||||
int GetNesFileAddress(int A);
|
||||
int bzk_GetNesFileAddress(int A);
|
||||
int GetPRGAddress(int A);
|
||||
int GetRomAddress(int A);
|
||||
//int GetEditHex(HWND hwndDlg, int id);
|
||||
|
|
|
@ -109,7 +109,9 @@ int log_optn_intlst[LOG_OPTION_SIZE] = {3000000, 1000000, 300000, 100000, 30000
|
|||
char *log_optn_strlst[LOG_OPTION_SIZE] = {"3 000 000", "1 000 000", "300 000", "100 000", "30 000", "10 000", "3000", "1000", "300", "100"};
|
||||
int log_lines_option = 5; // 10000 lines by default
|
||||
char *logfilename = 0;
|
||||
int oldcodecount, olddatacount;
|
||||
char bzk_filename[2100] = {0};
|
||||
char bzk_newfilename[2100] = { 0 };
|
||||
// int oldcodecount, olddatacount;
|
||||
|
||||
SCROLLINFO tracesi;
|
||||
|
||||
|
@ -121,6 +123,9 @@ int tracelogbufusedsize = 0;
|
|||
char str_axystate[LOG_AXYSTATE_MAX_LEN] = {0}, str_procstatus[LOG_PROCSTATUS_MAX_LEN] = {0};
|
||||
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};
|
||||
char str_result[LOG_LINE_MAX_LEN] = {0};
|
||||
char bzk_string[200] = {0};
|
||||
int bzk_writes_counter = 0;
|
||||
int bzk_files_counter = 0;
|
||||
char str_temp[LOG_LINE_MAX_LEN] = {0};
|
||||
char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
|
||||
char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
|
||||
|
@ -419,9 +424,9 @@ INT_PTR CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_INSERTSTRING, -1, (LPARAM)(LPSTR)log_optn_strlst[i]);
|
||||
}
|
||||
SendDlgItemMessage(hwndDlg, IDC_TRACER_LOG_SIZE, CB_SETCURSEL, (WPARAM)log_lines_option, 0);
|
||||
strcpy(trace_str, "Welcome to the Trace Logger.");
|
||||
strcpy(trace_str, "1 - delete all .log files, 2 - start logging, 3 - launch BZK script, 4 - stop logging before exit.");
|
||||
SetDlgItemText(hwndDlg, IDC_TRACER_LOG, trace_str);
|
||||
logtofile = 0;
|
||||
logtofile = 1;
|
||||
|
||||
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_REGISTERS, (logging_options & LOG_REGISTERS) ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hwndDlg, IDC_CHECK_LOG_PROCESSOR_STATUS, (logging_options & LOG_PROCESSOR_STATUS) ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
@ -532,7 +537,7 @@ INT_PTR CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
EnableTracerMenuItems();
|
||||
break;
|
||||
case IDC_RADIO_LOG_LAST:
|
||||
logtofile = 0;
|
||||
logtofile = 1;
|
||||
EnableTracerMenuItems();
|
||||
break;
|
||||
case IDC_RADIO_LOG_TO_FILE:
|
||||
|
@ -685,15 +690,47 @@ void BeginLoggingSequence(void)
|
|||
if (logtofile)
|
||||
{
|
||||
if(logfilename == NULL) ShowLogDirDialog();
|
||||
if (!logfilename) return;
|
||||
LOG_FP = fopen(logfilename,"w");
|
||||
//if (!logfilename) return;
|
||||
|
||||
// I've tried to make a "for" loop, but that doesn't work for some reason
|
||||
//for (int k = 99999; k == -1; k--) {
|
||||
// sprintf(bzk_filename, "z%05d_fceux.log", k);
|
||||
// LOG_FP = fopen(bzk_filename, "r");
|
||||
// if (LOG_FP != NULL) {
|
||||
// fclose(LOG_FP);
|
||||
// bzk_files_counter = k + 1;
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//so fuck it, I'm sticking with what's actually working
|
||||
int k = 99999;
|
||||
while (true) {
|
||||
sprintf(bzk_filename, "z%05d_fceux.log", k);
|
||||
LOG_FP = fopen(bzk_filename, "r");
|
||||
if (LOG_FP != NULL) {
|
||||
fclose(LOG_FP);
|
||||
bzk_files_counter = k + 1;
|
||||
break;
|
||||
}
|
||||
k--;
|
||||
if (k == -1) {
|
||||
bzk_files_counter = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bzk_files_counter >= 100000) bzk_files_counter = 0;
|
||||
sprintf(bzk_filename, "z%05d.log", bzk_files_counter);
|
||||
LOG_FP = fopen(bzk_filename, "w");
|
||||
|
||||
if (LOG_FP == NULL)
|
||||
{
|
||||
sprintf(trace_str, "Error Opening File %s", logfilename);
|
||||
sprintf(trace_str, "Error Opening File %s", bzk_filename);
|
||||
MessageBox(hTracer, trace_str, "File Error", MB_OK);
|
||||
return;
|
||||
}
|
||||
fprintf(LOG_FP,FCEU_NAME_AND_VERSION" - Trace Log File\n"); //mbg merge 7/19/06 changed string
|
||||
// fprintf(LOG_FP,FCEU_NAME_AND_VERSION" - Trace Log File\n"); //mbg merge 7/19/06 changed string
|
||||
} else
|
||||
{
|
||||
ClearTraceLogBuf();
|
||||
|
@ -724,8 +761,8 @@ void BeginLoggingSequence(void)
|
|||
tracelogbufpos = tracelogbufusedsize = 0;
|
||||
}
|
||||
|
||||
oldcodecount = codecount;
|
||||
olddatacount = datacount;
|
||||
// oldcodecount = codecount;
|
||||
// olddatacount = datacount;
|
||||
|
||||
logging=1;
|
||||
SetDlgItemText(hTracer, IDC_BTN_START_STOP_LOGGING,"Stop Logging");
|
||||
|
@ -739,232 +776,258 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
|
|||
return;
|
||||
|
||||
unsigned int addr = X.PC;
|
||||
uint8 tmp;
|
||||
static int unloggedlines;
|
||||
// uint8 tmp;
|
||||
// static int unloggedlines;
|
||||
|
||||
// if instruction executed from the RAM, skip this, log all instead
|
||||
// TODO: loops folding mame-lyke style
|
||||
if (GetPRGAddress(addr) != -1)
|
||||
{
|
||||
if(((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) ||
|
||||
((logging_options & LOG_NEW_DATA) && (olddatacount != datacount)))
|
||||
{
|
||||
//something new was logged
|
||||
oldcodecount = codecount;
|
||||
olddatacount = datacount;
|
||||
if(unloggedlines > 0)
|
||||
{
|
||||
sprintf(str_result, "(%d lines skipped)", unloggedlines);
|
||||
OutputLogLine(str_result);
|
||||
unloggedlines = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if((logging_options & LOG_NEW_INSTRUCTIONS) ||
|
||||
(logging_options & LOG_NEW_DATA))
|
||||
{
|
||||
if(FCEUI_GetLoggingCD())
|
||||
unloggedlines++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// // if instruction executed from the RAM, skip this, log all instead
|
||||
// // TODO: loops folding mame-lyke style
|
||||
// if (GetPRGAddress(addr) != -1)
|
||||
// {
|
||||
// if(((logging_options & LOG_NEW_INSTRUCTIONS) && (oldcodecount != codecount)) ||
|
||||
// ((logging_options & LOG_NEW_DATA) && (olddatacount != datacount)))
|
||||
// {
|
||||
// //something new was logged
|
||||
// oldcodecount = codecount;
|
||||
// olddatacount = datacount;
|
||||
// if(unloggedlines > 0)
|
||||
// {
|
||||
// sprintf(str_result, "(%d lines skipped)", unloggedlines);
|
||||
// OutputLogLine(str_result);
|
||||
// unloggedlines = 0;
|
||||
// }
|
||||
// } else
|
||||
// {
|
||||
// if((logging_options & LOG_NEW_INSTRUCTIONS) ||
|
||||
// (logging_options & LOG_NEW_DATA))
|
||||
// {
|
||||
// if(FCEUI_GetLoggingCD())
|
||||
// unloggedlines++;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ((addr + size) > 0xFFFF)
|
||||
// {
|
||||
// sprintf(str_data, "%02X ", opcode[0]);
|
||||
// sprintf(str_disassembly, "OVERFLOW");
|
||||
// } else
|
||||
// {
|
||||
// char* a = 0;
|
||||
// switch (size)
|
||||
// {
|
||||
// case 0:
|
||||
// sprintf(str_data, "%02X ", opcode[0]);
|
||||
// sprintf(str_disassembly,"UNDEFINED");
|
||||
// break;
|
||||
// case 1:
|
||||
// {
|
||||
// sprintf(str_data, "%02X ", opcode[0]);
|
||||
// a = Disassemble(addr + 1, opcode);
|
||||
// // special case: an RTS opcode
|
||||
// if (opcode[0] == 0x60)
|
||||
// {
|
||||
// // add the beginning address of the subroutine that we exit from
|
||||
// unsigned int caller_addr = GetMem(((X.S) + 1)|0x0100) + (GetMem(((X.S) + 2)|0x0100) << 8) - 0x2;
|
||||
// if (GetMem(caller_addr) == 0x20)
|
||||
// {
|
||||
// // 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);
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case 2:
|
||||
// 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]);
|
||||
// a = Disassemble(addr + 3, opcode);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (a)
|
||||
// {
|
||||
// if (logging_options & LOG_SYMBOLIC)
|
||||
// {
|
||||
// loadNameFiles();
|
||||
// tempAddressesLog.resize(0);
|
||||
// // Insert Name and Comment lines if needed
|
||||
// Name* node = findNode(getNamesPointerForAddress(addr), addr);
|
||||
// if (node)
|
||||
// {
|
||||
// if (node->name)
|
||||
// {
|
||||
// strcpy(str_decoration, node->name);
|
||||
// strcat(str_decoration, ":");
|
||||
// tempAddressesLog.push_back(addr);
|
||||
// OutputLogLine(str_decoration, &tempAddressesLog);
|
||||
// }
|
||||
// if (node->comment)
|
||||
// {
|
||||
// // make a copy
|
||||
// strcpy(str_decoration_comment, node->comment);
|
||||
// strcat(str_decoration_comment, "\r\n");
|
||||
// tracer_decoration_comment = str_decoration_comment;
|
||||
// // divide the str_decoration_comment into strings (Comment1, Comment2, ...)
|
||||
// char* tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment, "\r\n");
|
||||
// while (tracer_decoration_comment_end_pos)
|
||||
// {
|
||||
// tracer_decoration_comment_end_pos[0] = 0; // set \0 instead of \r
|
||||
// strcpy(str_decoration, "; ");
|
||||
// strcat(str_decoration, tracer_decoration_comment);
|
||||
// OutputLogLine(str_decoration, &tempAddressesLog);
|
||||
// tracer_decoration_comment_end_pos += 2;
|
||||
// tracer_decoration_comment = tracer_decoration_comment_end_pos;
|
||||
// tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// replaceNames(ramBankNames, a, &tempAddressesLog);
|
||||
// for(int i=0;i<ARRAY_SIZE(pageNames);i++)
|
||||
// replaceNames(pageNames[i], a, &tempAddressesLog);
|
||||
// }
|
||||
// strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
|
||||
// str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (size == 1 && GetMem(addr) == 0x60)
|
||||
// {
|
||||
// // special case: an RTS opcode
|
||||
// // add "----------" to emphasize the end of subroutine
|
||||
// static const char* emphasize = " -------------------------------------------------------------------------------------------------------------------------";
|
||||
// strncat(str_disassembly, emphasize, LOG_DISASSEMBLY_MAX_LEN - strlen(str_disassembly) - 1);
|
||||
// }
|
||||
// // stretch the disassembly string out if we have to output other stuff.
|
||||
// if ((logging_options & (LOG_REGISTERS|LOG_PROCESSOR_STATUS)) && !(logging_options & LOG_TO_THE_LEFT))
|
||||
// {
|
||||
// for (int i = strlen(str_disassembly); i < (LOG_DISASSEMBLY_MAX_LEN - 1); ++i)
|
||||
// str_disassembly[i] = ' ';
|
||||
// str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
|
||||
// }
|
||||
//
|
||||
// // Start filling the str_temp line: Frame count, Cycles count, Instructions count, AXYS state, Processor status, Tabs, Address, Data, Disassembly
|
||||
// if (logging_options & LOG_FRAMES_COUNT)
|
||||
// {
|
||||
// sprintf(str_result, "f%-6u ", currFrameCounter);
|
||||
// } else
|
||||
// {
|
||||
// str_result[0] = 0;
|
||||
// }
|
||||
// if (logging_options & LOG_CYCLES_COUNT)
|
||||
// {
|
||||
// int64 counter_value = timestampbase + (uint64)timestamp - total_cycles_base;
|
||||
// if (counter_value < 0) // sanity check
|
||||
// {
|
||||
// ResetDebugStatisticsCounters();
|
||||
// counter_value = 0;
|
||||
// }
|
||||
// sprintf(str_temp, "c%-11llu ", counter_value);
|
||||
// strcat(str_result, str_temp);
|
||||
// }
|
||||
// if (logging_options & LOG_INSTRUCTIONS_COUNT)
|
||||
// {
|
||||
// sprintf(str_temp, "i%-11llu ", total_instructions);
|
||||
// strcat(str_result, str_temp);
|
||||
// }
|
||||
//
|
||||
// if (logging_options & LOG_REGISTERS)
|
||||
// {
|
||||
// sprintf(str_axystate,"A:%02X X:%02X Y:%02X S:%02X ",(X.A),(X.X),(X.Y),(X.S));
|
||||
// }
|
||||
//
|
||||
// if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
// {
|
||||
// tmp = X.P^0xFF;
|
||||
// sprintf(str_procstatus,"P:%c%c%c%c%c%c%c%c ",
|
||||
// 'N'|(tmp&0x80)>>2,
|
||||
// 'V'|(tmp&0x40)>>1,
|
||||
// 'U'|(tmp&0x20),
|
||||
// 'B'|(tmp&0x10)<<1,
|
||||
// 'D'|(tmp&0x08)<<2,
|
||||
// 'I'|(tmp&0x04)<<3,
|
||||
// 'Z'|(tmp&0x02)<<4,
|
||||
// 'C'|(tmp&0x01)<<5
|
||||
// );
|
||||
// }
|
||||
// if (logging_options & LOG_TO_THE_LEFT)
|
||||
// {
|
||||
// if (logging_options & LOG_REGISTERS)
|
||||
// strcat(str_result, str_axystate);
|
||||
// if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
// strcat(str_result, str_procstatus);
|
||||
// }
|
||||
//
|
||||
// if (logging_options & LOG_CODE_TABBING)
|
||||
// {
|
||||
// // add spaces at the beginning of the line according to stack pointer
|
||||
// int spaces = (0xFF - X.S) & LOG_TABS_MASK;
|
||||
// for (int i = 0; i < spaces; i++)
|
||||
// str_tabs[i] = ' ';
|
||||
// str_tabs[spaces] = 0;
|
||||
// strcat(str_result, str_tabs);
|
||||
// } else if (logging_options & LOG_TO_THE_LEFT)
|
||||
// {
|
||||
// strcat(str_result, " ");
|
||||
// }
|
||||
//
|
||||
// if (logging_options & LOG_BANK_NUMBER)
|
||||
// {
|
||||
// if (addr >= 0x8000)
|
||||
// sprintf(str_address, "$%02X:%04X: ", getBank(addr), addr);
|
||||
// else
|
||||
// sprintf(str_address, " $%04X: ", addr);
|
||||
// } else
|
||||
// {
|
||||
// sprintf(str_address, "$%04X: ", addr);
|
||||
// }
|
||||
//
|
||||
// strcat(str_result, str_address);
|
||||
// strcat(str_result, str_data);
|
||||
// strcat(str_result, str_disassembly);
|
||||
//
|
||||
// if (!(logging_options & LOG_TO_THE_LEFT))
|
||||
// {
|
||||
// if (logging_options & LOG_REGISTERS)
|
||||
// strcat(str_result, str_axystate);
|
||||
// if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
// strcat(str_result, str_procstatus);
|
||||
// }
|
||||
//
|
||||
// OutputLogLine(str_result, &tempAddressesLog);
|
||||
|
||||
if ((addr + size) > 0xFFFF)
|
||||
{
|
||||
sprintf(str_data, "%02X ", opcode[0]);
|
||||
sprintf(str_disassembly, "OVERFLOW");
|
||||
} else
|
||||
{
|
||||
char* a = 0;
|
||||
switch (size)
|
||||
{
|
||||
case 0:
|
||||
sprintf(str_data, "%02X ", opcode[0]);
|
||||
sprintf(str_disassembly,"UNDEFINED");
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
sprintf(str_data, "%02X ", opcode[0]);
|
||||
a = Disassemble(addr + 1, opcode);
|
||||
// special case: an RTS opcode
|
||||
if (opcode[0] == 0x60)
|
||||
{
|
||||
// add the beginning address of the subroutine that we exit from
|
||||
unsigned int caller_addr = GetMem(((X.S) + 1)|0x0100) + (GetMem(((X.S) + 2)|0x0100) << 8) - 0x2;
|
||||
if (GetMem(caller_addr) == 0x20)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
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]);
|
||||
a = Disassemble(addr + 3, opcode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (a)
|
||||
{
|
||||
if (logging_options & LOG_SYMBOLIC)
|
||||
{
|
||||
loadNameFiles();
|
||||
tempAddressesLog.resize(0);
|
||||
// Insert Name and Comment lines if needed
|
||||
Name* node = findNode(getNamesPointerForAddress(addr), addr);
|
||||
if (node)
|
||||
{
|
||||
if (node->name)
|
||||
{
|
||||
strcpy(str_decoration, node->name);
|
||||
strcat(str_decoration, ":");
|
||||
tempAddressesLog.push_back(addr);
|
||||
OutputLogLine(str_decoration, &tempAddressesLog);
|
||||
}
|
||||
if (node->comment)
|
||||
{
|
||||
// make a copy
|
||||
strcpy(str_decoration_comment, node->comment);
|
||||
strcat(str_decoration_comment, "\r\n");
|
||||
tracer_decoration_comment = str_decoration_comment;
|
||||
// divide the str_decoration_comment into strings (Comment1, Comment2, ...)
|
||||
char* tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment, "\r\n");
|
||||
while (tracer_decoration_comment_end_pos)
|
||||
{
|
||||
tracer_decoration_comment_end_pos[0] = 0; // set \0 instead of \r
|
||||
strcpy(str_decoration, "; ");
|
||||
strcat(str_decoration, tracer_decoration_comment);
|
||||
OutputLogLine(str_decoration, &tempAddressesLog);
|
||||
tracer_decoration_comment_end_pos += 2;
|
||||
tracer_decoration_comment = tracer_decoration_comment_end_pos;
|
||||
tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replaceNames(ramBankNames, a, &tempAddressesLog);
|
||||
for(int i=0;i<ARRAY_SIZE(pageNames);i++)
|
||||
replaceNames(pageNames[i], a, &tempAddressesLog);
|
||||
}
|
||||
strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
|
||||
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 1 && GetMem(addr) == 0x60)
|
||||
{
|
||||
// special case: an RTS opcode
|
||||
// add "----------" to emphasize the end of subroutine
|
||||
static const char* emphasize = " -------------------------------------------------------------------------------------------------------------------------";
|
||||
strncat(str_disassembly, emphasize, LOG_DISASSEMBLY_MAX_LEN - strlen(str_disassembly) - 1);
|
||||
}
|
||||
// stretch the disassembly string out if we have to output other stuff.
|
||||
if ((logging_options & (LOG_REGISTERS|LOG_PROCESSOR_STATUS)) && !(logging_options & LOG_TO_THE_LEFT))
|
||||
{
|
||||
for (int i = strlen(str_disassembly); i < (LOG_DISASSEMBLY_MAX_LEN - 1); ++i)
|
||||
str_disassembly[i] = ' ';
|
||||
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
|
||||
}
|
||||
//sprintf(str_address, "%X ", GetNesFileAddress(addr));
|
||||
//sprintf(str_axystate, "%X %X %X %X %X ", X.A, X.X, X.Y, X.S, X.P);
|
||||
//sprintf(bzk_string, "%X %X %X %X %X %X %X %X %X %X \n", addr, bzk_GetNesFileAddress(addr), bzk_getBank(0x8000), bzk_getBank(0xA000), bzk_getBank(0xC000), bzk_getBank(0xE000), X.A, X.X, X.Y, X.P);
|
||||
//sprintf(bzk_string, "%u|%u|%u|%u|%u|%u|%u|%u|%s|\n", bzk_GetNesFileAddress(addr), bzk_getBank(0x8000), bzk_getBank(0xA000), bzk_getBank(0xC000), bzk_getBank(0xE000), X.A, X.X, X.Y, bzk_Disassemble(opcode));
|
||||
sprintf(bzk_string, "%u|%u|%u|%u|%u|%s|\n", bzk_GetNesFileAddress(addr), bzk_getBank(addr), X.A, X.X, X.Y, bzk_Disassemble(addr, opcode));
|
||||
|
||||
// Start filling the str_temp line: Frame count, Cycles count, Instructions count, AXYS state, Processor status, Tabs, Address, Data, Disassembly
|
||||
if (logging_options & LOG_FRAMES_COUNT)
|
||||
{
|
||||
sprintf(str_result, "f%-6u ", currFrameCounter);
|
||||
} else
|
||||
{
|
||||
str_result[0] = 0;
|
||||
}
|
||||
if (logging_options & LOG_CYCLES_COUNT)
|
||||
{
|
||||
int64 counter_value = timestampbase + (uint64)timestamp - total_cycles_base;
|
||||
if (counter_value < 0) // sanity check
|
||||
{
|
||||
ResetDebugStatisticsCounters();
|
||||
counter_value = 0;
|
||||
}
|
||||
sprintf(str_temp, "c%-11llu ", counter_value);
|
||||
strcat(str_result, str_temp);
|
||||
}
|
||||
if (logging_options & LOG_INSTRUCTIONS_COUNT)
|
||||
{
|
||||
sprintf(str_temp, "i%-11llu ", total_instructions);
|
||||
strcat(str_result, str_temp);
|
||||
}
|
||||
|
||||
if (logging_options & LOG_REGISTERS)
|
||||
{
|
||||
sprintf(str_axystate,"A:%02X X:%02X Y:%02X S:%02X ",(X.A),(X.X),(X.Y),(X.S));
|
||||
}
|
||||
|
||||
if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
{
|
||||
tmp = X.P^0xFF;
|
||||
sprintf(str_procstatus,"P:%c%c%c%c%c%c%c%c ",
|
||||
'N'|(tmp&0x80)>>2,
|
||||
'V'|(tmp&0x40)>>1,
|
||||
'U'|(tmp&0x20),
|
||||
'B'|(tmp&0x10)<<1,
|
||||
'D'|(tmp&0x08)<<2,
|
||||
'I'|(tmp&0x04)<<3,
|
||||
'Z'|(tmp&0x02)<<4,
|
||||
'C'|(tmp&0x01)<<5
|
||||
);
|
||||
}
|
||||
fputs(bzk_string, LOG_FP);
|
||||
bzk_writes_counter++;
|
||||
|
||||
if (logging_options & LOG_TO_THE_LEFT)
|
||||
if (bzk_writes_counter == 4999999)
|
||||
{
|
||||
if (logging_options & LOG_REGISTERS)
|
||||
strcat(str_result, str_axystate);
|
||||
if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
strcat(str_result, str_procstatus);
|
||||
bzk_writes_counter = 0;
|
||||
fflush(LOG_FP);
|
||||
fclose(LOG_FP);
|
||||
|
||||
sprintf(bzk_newfilename, "z%05d_fceux.log", bzk_files_counter);
|
||||
remove(bzk_newfilename); //delete file if exists
|
||||
rename(bzk_filename, bzk_newfilename);
|
||||
|
||||
bzk_files_counter++;
|
||||
if (bzk_files_counter >= 100000) bzk_files_counter = 0;
|
||||
sprintf(bzk_filename, "z%05d.log", bzk_files_counter);
|
||||
LOG_FP = fopen(bzk_filename, "w");
|
||||
}
|
||||
|
||||
if (logging_options & LOG_CODE_TABBING)
|
||||
{
|
||||
// add spaces at the beginning of the line according to stack pointer
|
||||
int spaces = (0xFF - X.S) & LOG_TABS_MASK;
|
||||
for (int i = 0; i < spaces; i++)
|
||||
str_tabs[i] = ' ';
|
||||
str_tabs[spaces] = 0;
|
||||
strcat(str_result, str_tabs);
|
||||
} else if (logging_options & LOG_TO_THE_LEFT)
|
||||
{
|
||||
strcat(str_result, " ");
|
||||
}
|
||||
|
||||
if (logging_options & LOG_BANK_NUMBER)
|
||||
{
|
||||
if (addr >= 0x8000)
|
||||
sprintf(str_address, "$%02X:%04X: ", getBank(addr), addr);
|
||||
else
|
||||
sprintf(str_address, " $%04X: ", addr);
|
||||
} else
|
||||
{
|
||||
sprintf(str_address, "$%04X: ", addr);
|
||||
}
|
||||
|
||||
strcat(str_result, str_address);
|
||||
strcat(str_result, str_data);
|
||||
strcat(str_result, str_disassembly);
|
||||
|
||||
if (!(logging_options & LOG_TO_THE_LEFT))
|
||||
{
|
||||
if (logging_options & LOG_REGISTERS)
|
||||
strcat(str_result, str_axystate);
|
||||
if (logging_options & LOG_PROCESSOR_STATUS)
|
||||
strcat(str_result, str_procstatus);
|
||||
}
|
||||
|
||||
OutputLogLine(str_result, &tempAddressesLog);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1083,15 @@ void EndLoggingSequence()
|
|||
{
|
||||
if (logtofile)
|
||||
{
|
||||
fflush(LOG_FP);
|
||||
fclose(LOG_FP);
|
||||
|
||||
sprintf(bzk_newfilename, "z%05d", bzk_files_counter);
|
||||
strcat(bzk_newfilename, "_fceux.log");
|
||||
rename(bzk_filename, bzk_newfilename);
|
||||
|
||||
bzk_files_counter++;
|
||||
bzk_writes_counter = 0;
|
||||
} else
|
||||
{
|
||||
strcpy(str_result, "Logging finished.");
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define LOG_AXYSTATE_MAX_LEN 21
|
||||
#define LOG_PROCSTATUS_MAX_LEN 12
|
||||
#define LOG_TABS_MASK 31
|
||||
#define LOG_ADDRESS_MAX_LEN 13
|
||||
#define LOG_ADDRESS_MAX_LEN 50
|
||||
#define LOG_DATA_MAX_LEN 11
|
||||
#define LOG_DISASSEMBLY_MAX_LEN 46
|
||||
|
||||
|
|
Loading…
Reference in New Issue