* Debugger: clicking on Symbolic names works as well as clicking on addresses

* Tracer: clicking on Symbolic names works as well as clicking on addresses
* Debugger: "Symbolic Debug" is enabled by default. "Symbolic trace", on the other hand, is not enabled by default, because it slows down tracing performance 2x (even when there's no NL files!)
This commit is contained in:
ansstuff 2013-09-20 18:12:16 +00:00
parent 0e2422f90a
commit 8f9e2be234
7 changed files with 210 additions and 75 deletions

View File

@ -82,7 +82,9 @@ char* debug_decoration_comment;
char* debug_decoration_comment_end_pos; char* debug_decoration_comment_end_pos;
// this is used to keep track of addresses that lines of Disassembly window correspond to // this is used to keep track of addresses that lines of Disassembly window correspond to
std::vector<unsigned int> disassembly_addresses; std::vector<uint16> disassembly_addresses;
// this is used to keep track of addresses in operands of each printed instruction
std::vector<std::vector<uint16>> disassembly_operands;
// this is used to autoscroll the Disassembly window while keeping relative position of the ">" pointer inside this window // this is used to autoscroll the Disassembly window while keeping relative position of the ">" pointer inside this window
unsigned int PC_pointerOffset = 0; unsigned int PC_pointerOffset = 0;
// this is used for dirty, but unavoidable hack, which is necessary to ensure the ">" pointer is visible when stepping/seeking to PC // this is used for dirty, but unavoidable hack, which is necessary to ensure the ">" pointer is visible when stepping/seeking to PC
@ -394,12 +396,11 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
PCPointerWasDrawn = false; PCPointerWasDrawn = false;
beginningOfPCPointerLine = -1; beginningOfPCPointerLine = -1;
// ################################## Start of SP CODE ###########################
if (symbDebugEnabled) if (symbDebugEnabled)
{
loadNameFiles(); loadNameFiles();
disassembly_operands.resize(0);
// ################################## End of SP CODE ########################### }
si.nPos = addr; si.nPos = addr;
SetScrollInfo(GetDlgItem(hWnd,scrollid),SB_CTL,&si,TRUE); SetScrollInfo(GetDlgItem(hWnd,scrollid),SB_CTL,&si,TRUE);
@ -418,8 +419,6 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
instruction_addr = addr; instruction_addr = addr;
// ################################## Start of SP CODE ###########################
if (symbDebugEnabled) if (symbDebugEnabled)
{ {
// insert Name and Comment lines if needed // insert Name and Comment lines if needed
@ -432,6 +431,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
strcat(debug_str, ":\r\n"); strcat(debug_str, ":\r\n");
// we added one line to the disassembly window // we added one line to the disassembly window
disassembly_addresses.push_back(addr); disassembly_addresses.push_back(addr);
disassembly_operands.resize(i + 1);
i++; i++;
} }
if (node->comment) if (node->comment)
@ -450,6 +450,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
strcat(debug_str, "\r\n"); strcat(debug_str, "\r\n");
// we added one line to the disassembly window // we added one line to the disassembly window
disassembly_addresses.push_back(addr); disassembly_addresses.push_back(addr);
disassembly_operands.resize(i + 1);
i++; i++;
debug_decoration_comment_end_pos += 2; debug_decoration_comment_end_pos += 2;
@ -460,8 +461,6 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
} }
} }
// ################################## End of SP CODE ###########################
if (addr == X.PC) if (addr == X.PC)
{ {
PC_pointerOffset = instructions_count; PC_pointerOffset = instructions_count;
@ -490,6 +489,8 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
// Add address // Add address
strcat(debug_str, chr); strcat(debug_str, chr);
disassembly_addresses.push_back(addr); disassembly_addresses.push_back(addr);
if (symbDebugEnabled)
disassembly_operands.resize(i + 1);
size = opsize[GetMem(addr)]; size = opsize[GetMem(addr)];
if (size == 0) if (size == 0)
@ -519,19 +520,15 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr)
size++; size++;
} }
// ################################## Start of SP CODE ###########################
a = Disassemble(addr, opcode); a = Disassemble(addr, opcode);
if (symbDebugEnabled) if (symbDebugEnabled)
{ {
replaceNames(ramBankNames, a); replaceNames(ramBankNames, a, &disassembly_operands[i]);
replaceNames(loadedBankNames, a); replaceNames(loadedBankNames, a, &disassembly_operands[i]);
replaceNames(lastBankNames, a); replaceNames(lastBankNames, a, &disassembly_operands[i]);
} }
// ################################## End of SP CODE ###########################
// special case: an RTS opcode // special case: an RTS opcode
if (GetMem(instruction_addr) == 0x60) if (GetMem(instruction_addr) == 0x60)
{ {
@ -1380,7 +1377,7 @@ void LoadGameDebuggerData(HWND hwndDlg = hDebug)
} }
// returns the address, or EOF if selection cursor points to something else // returns the address, or EOF if selection cursor points to something else
int Debugger_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected) int Debugger_CheckClickingOnAnAddressOrSymbolicName(unsigned int lineNumber, bool onlyCheckWhenNothingSelected)
{ {
// debug_str contains the text in the disassembly window // debug_str contains the text in the disassembly window
int sel_start, sel_end; int sel_start, sel_end;
@ -1388,6 +1385,7 @@ int Debugger_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected)
if (onlyCheckWhenNothingSelected) if (onlyCheckWhenNothingSelected)
if (sel_end > sel_start) if (sel_end > sel_start)
return EOF; return EOF;
// find the ":" or "$" before sel_start // find the ":" or "$" before sel_start
int i = sel_start - 1; int i = sel_start - 1;
for (; i > sel_start - 6; i--) for (; i > sel_start - 6; i--)
@ -1414,6 +1412,64 @@ int Debugger_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected)
} }
} }
} }
if (symbDebugEnabled && lineNumber < disassembly_addresses.size())
{
uint16 addr;
Name* node;
char* name;
int nameLen;
char* start_pos;
char* pos;
// first, try finding the name of disassembly_addresses[lineNumber]
addr = disassembly_addresses[lineNumber];
node = findNode(getNamesPointerForAddress(addr), addr);
if (node && node->name && *(node->name))
{
name = node->name;
nameLen = strlen(name);
if (sel_start - nameLen <= 0)
start_pos = debug_str;
else
start_pos = debug_str + (sel_start - nameLen);
pos = strstr(start_pos, name);
if (pos && pos <= debug_str + sel_start)
{
// clicked on the Name
// select the text
SendDlgItemMessage(hDebug, IDC_DEBUGGER_DISASSEMBLY, EM_SETSEL, (WPARAM)(int)(pos - debug_str), (LPARAM)((int)(pos - debug_str) + nameLen));
PrintOffsetToSeekAndBookmarkFields(addr);
return (int)addr;
}
}
// then, try finding the name of disassembly_operands
for (i = disassembly_operands[lineNumber].size() - 1; i >= 0; i--)
{
addr = disassembly_operands[lineNumber][i];
node = findNode(getNamesPointerForAddress(addr), addr);
if (node && node->name && *(node->name))
{
name = node->name;
nameLen = strlen(name);
if (sel_start - nameLen <= 0)
start_pos = debug_str;
else
start_pos = debug_str + (sel_start - nameLen);
pos = strstr(start_pos, name);
if (pos && pos <= debug_str + sel_start)
{
// clicked on the operand name
// select the text
SendDlgItemMessage(hDebug, IDC_DEBUGGER_DISASSEMBLY, EM_SETSEL, (WPARAM)(int)(pos - debug_str), (LPARAM)((int)(pos - debug_str) + nameLen));
PrintOffsetToSeekAndBookmarkFields(addr);
return (int)addr;
}
}
}
}
return EOF; return EOF;
} }
@ -1423,7 +1479,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
{ {
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
{ {
int offset = Debugger_CheckClickingOnAnAddress(false); int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight, false);
if (offset != EOF) if (offset != EOF)
{ {
// bring "Add Breakpoint" dialog // bring "Add Breakpoint" dialog
@ -1437,7 +1493,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
{ {
Debugger_CheckClickingOnAnAddress(true); Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight, true);
break; break;
} }
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
@ -1456,7 +1512,7 @@ BOOL CALLBACK IDC_DEBUGGER_DISASSEMBLY_WndProc(HWND hwndDlg, UINT uMsg, WPARAM w
case WM_RBUTTONUP: case WM_RBUTTONUP:
{ {
// if nothing is selected, try bringing Symbolic Debug Naming dialog // if nothing is selected, try bringing Symbolic Debug Naming dialog
int offset = Debugger_CheckClickingOnAnAddress(true); int offset = Debugger_CheckClickingOnAnAddressOrSymbolicName(GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight, true);
if (offset != EOF) if (offset != EOF)
{ {
if (DoSymbolicDebugNaming(offset, hDebug)) if (DoSymbolicDebugNaming(offset, hDebug))

View File

@ -40,7 +40,7 @@ int lastBank = -1;
int loadedBank = -1; int loadedBank = -1;
extern char LoadedRomFName[2048]; extern char LoadedRomFName[2048];
char NLfilename[2048]; char NLfilename[2048];
bool symbDebugEnabled = false; bool symbDebugEnabled = true;
int debuggerWasActive = 0; int debuggerWasActive = 0;
char temp_chr[40] = {0}; char temp_chr[40] = {0};
char delimiterChar[2] = "#"; char delimiterChar[2] = "#";
@ -463,8 +463,9 @@ void freeList(Name* n)
* *
* @param list NL list of address definitions * @param list NL list of address definitions
* @param str The string where replacing takes place. * @param str The string where replacing takes place.
* @param addressesLog Vector for collecting addresses that were replaced by names
**/ **/
void replaceNames(Name* list, char* str) void replaceNames(Name* list, char* str, std::vector<uint16>* addressesLog)
{ {
static char buff[1001]; static char buff[1001];
char* pos; char* pos;
@ -484,6 +485,8 @@ void replaceNames(Name* list, char* str)
strcat(buff, src); strcat(buff, src);
strcat(buff, list->name); strcat(buff, list->name);
src = pos + 5; // 5 = strlen(beg->offset), because all offsets are in "$XXXX" format src = pos + 5; // 5 = strlen(beg->offset), because all offsets are in "$XXXX" format
if (addressesLog)
addressesLog->push_back(list->offsetNumeric);
} }
// if any offsets were changed, replace str by buff // if any offsets were changed, replace str by buff
if (*buff) if (*buff)
@ -544,15 +547,16 @@ char* generateNLFilenameForAddress(uint16 address)
} }
Name* getNamesPointerForAddress(uint16 address) Name* getNamesPointerForAddress(uint16 address)
{ {
if (address < 0x8000) // this function is called very often (when using "Symbolic trace"), so this is sorted by frequency
if (address >= 0xC000)
{ {
return ramBankNames; return lastBankNames;
} else if (address < 0xC000) } else if (address >= 0x8000)
{ {
return loadedBankNames; return loadedBankNames;
} else } else
{ {
return lastBankNames; return ramBankNames;
} }
} }
void setNamesPointerForAddress(uint16 address, Name* newNode) void setNamesPointerForAddress(uint16 address, Name* newNode)
@ -907,8 +911,14 @@ void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char*
node->offsetNumeric = newAddress; node->offsetNumeric = newAddress;
node->name = (char*)malloc(strlen(newName) + 1); node->name = (char*)malloc(strlen(newName) + 1);
strcpy(node->name, newName); strcpy(node->name, newName);
if (strlen(newComment))
{
node->comment = (char*)malloc(strlen(newComment) + 1); node->comment = (char*)malloc(strlen(newComment) + 1);
strcpy(node->comment, newComment); strcpy(node->comment, newComment);
} else
{
node->comment = 0;
}
node->next = 0; node->next = 0;
setNamesPointerForAddress(newAddress, node); setNamesPointerForAddress(newAddress, node);
} else } else
@ -919,12 +929,20 @@ void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char*
if (node->offsetNumeric == newAddress) if (node->offsetNumeric == newAddress)
{ {
// found matching address - replace its name and comment // found matching address - replace its name and comment
if (node->name)
free(node->name); free(node->name);
node->name = (char*)malloc(strlen(newName) + 1); node->name = (char*)malloc(strlen(newName) + 1);
strcpy(node->name, newName); strcpy(node->name, newName);
if (node->comment)
{
free(node->comment); free(node->comment);
node->comment = 0;
}
if (strlen(newComment))
{
node->comment = (char*)malloc(strlen(newComment) + 1); node->comment = (char*)malloc(strlen(newComment) + 1);
strcpy(node->comment, newComment); strcpy(node->comment, newComment);
}
break; break;
} }
if (node->next) if (node->next)
@ -940,8 +958,14 @@ void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char*
newNode->offsetNumeric = newAddress; newNode->offsetNumeric = newAddress;
newNode->name = (char*)malloc(strlen(newName) + 1); newNode->name = (char*)malloc(strlen(newName) + 1);
strcpy(newNode->name, newName); strcpy(newNode->name, newName);
if (strlen(newComment))
{
newNode->comment = (char*)malloc(strlen(newComment) + 1); newNode->comment = (char*)malloc(strlen(newComment) + 1);
strcpy(newNode->comment, newComment); strcpy(newNode->comment, newComment);
} else
{
newNode->comment = 0;
}
newNode->next = 0; newNode->next = 0;
break; break;
} }
@ -956,8 +980,11 @@ void AddNewSymbolicName(uint16 newAddress, char* newOffset, char* newName, char*
if (node->offsetNumeric == newAddress) if (node->offsetNumeric == newAddress)
{ {
// found matching address - delete it // found matching address - delete it
if (node->offset)
free(node->offset); free(node->offset);
if (node->name)
free(node->name); free(node->name);
if (node->comment)
free(node->comment); free(node->comment);
if (previousNode) if (previousNode)
previousNode->next = node->next; previousNode->next = node->next;

View File

@ -47,7 +47,7 @@ char* generateNLFilenameForAddress(uint16 address);
Name* getNamesPointerForAddress(uint16 address); Name* getNamesPointerForAddress(uint16 address);
void setNamesPointerForAddress(uint16 address, Name* newNode); void setNamesPointerForAddress(uint16 address, Name* newNode);
void loadNameFiles(); void loadNameFiles();
void replaceNames(Name* list, char* str); void replaceNames(Name* list, char* str, std::vector<uint16>* addressesLog = 0);
void AddDebuggerBookmark(HWND hwnd); void AddDebuggerBookmark(HWND hwnd);
void AddDebuggerBookmark2(HWND hwnd, unsigned int addr); void AddDebuggerBookmark2(HWND hwnd, unsigned int addr);
void DeleteDebuggerBookmark(HWND hwnd); void DeleteDebuggerBookmark(HWND hwnd);

View File

@ -224,7 +224,7 @@ void AddLogText(const char *text, unsigned int add_newline)
// also log the text into Trace Logger log if needed // also log the text into Trace Logger log if needed
if (logging && (logging_options & LOG_MESSAGES)) if (logging && (logging_options & LOG_MESSAGES))
{ {
OutputLogLine(strdup(logtext[truncated_logcount()]), add_newline != 0); OutputLogLine(strdup(logtext[truncated_logcount()]), 0, add_newline != 0);
log_old_emu_paused = false; // force Trace Logger update log_old_emu_paused = false; // force Trace Logger update
} }

View File

@ -720,7 +720,7 @@ void UpdateColorTable()
temp_offset = CurOffset + i - 16; // (minus iNES header) temp_offset = CurOffset + i - 16; // (minus iNES header)
if (temp_offset >= 0) if (temp_offset >= 0)
{ {
if (temp_offset < cdloggerdataSize) if ((unsigned int)temp_offset < cdloggerdataSize)
{ {
// PRG // PRG
if ((cdloggerdata[temp_offset] & 3) == 3) if ((cdloggerdata[temp_offset] & 3) == 3)
@ -744,7 +744,7 @@ void UpdateColorTable()
} else } else
{ {
temp_offset -= cdloggerdataSize; temp_offset -= cdloggerdataSize;
if ((temp_offset < cdloggerVideoDataSize)) if (((unsigned int)temp_offset < cdloggerVideoDataSize))
{ {
// CHR // CHR
if ((cdloggervdata[temp_offset] & 3) == 3) if ((cdloggervdata[temp_offset] & 3) == 3)

View File

@ -67,7 +67,9 @@ char *logfilename = 0;
int oldcodecount, olddatacount; int oldcodecount, olddatacount;
SCROLLINFO tracesi; SCROLLINFO tracesi;
char **tracelogbuf; char **tracelogbuf;
std::vector<std::vector<uint16>> tracelogbufAddressesLog;
int tracelogbufsize, tracelogbufpos; int tracelogbufsize, tracelogbufpos;
int tracelogbufusedsize; int tracelogbufusedsize;
@ -79,6 +81,7 @@ char str_decoration[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0}; char str_decoration_comment[NL_MAX_MULTILINE_COMMENT_LEN + 10] = {0};
char* tracer_decoration_comment; char* tracer_decoration_comment;
char* tracer_decoration_comment_end_pos; char* tracer_decoration_comment_end_pos;
std::vector<uint16> tempAddressesLog;
bool log_old_emu_paused = true; // thanks to this flag the window only updates once after the game is paused bool log_old_emu_paused = true; // thanks to this flag the window only updates once after the game is paused
extern bool JustFrameAdvanced; extern bool JustFrameAdvanced;
@ -100,7 +103,7 @@ void EnableTracerMenuItems(void);
int PromptForCDLogger(void); int PromptForCDLogger(void);
// returns the address, or EOF if selection cursor points to something else // returns the address, or EOF if selection cursor points to something else
int Tracer_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected) int Tracer_CheckClickingOnAnAddressOrSymbolicName(unsigned int lineNumber, bool onlyCheckWhenNothingSelected)
{ {
// trace_str contains the text in the log window // trace_str contains the text in the log window
int sel_start, sel_end; int sel_start, sel_end;
@ -108,6 +111,7 @@ int Tracer_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected)
if (onlyCheckWhenNothingSelected) if (onlyCheckWhenNothingSelected)
if (sel_end > sel_start) if (sel_end > sel_start)
return EOF; return EOF;
// find the "$" before sel_start // find the "$" before sel_start
int i = sel_start - 1; int i = sel_start - 1;
for (; i > sel_start - 6; i--) for (; i > sel_start - 6; i--)
@ -135,6 +139,45 @@ int Tracer_CheckClickingOnAnAddress(bool onlyCheckWhenNothingSelected)
} }
} }
} }
if (tracelogbufusedsize == tracelogbufsize)
lineNumber = (tracelogbufpos + lineNumber) % tracelogbufsize;
if (lineNumber < tracelogbufAddressesLog.size())
{
uint16 addr;
Name* node;
char* name;
int nameLen;
char* start_pos;
char* pos;
for (i = tracelogbufAddressesLog[lineNumber].size() - 1; i >= 0; i--)
{
addr = tracelogbufAddressesLog[lineNumber][i];
node = findNode(getNamesPointerForAddress(addr), addr);
if (node && node->name && *(node->name))
{
name = node->name;
nameLen = strlen(name);
if (sel_start - nameLen <= 0)
start_pos = trace_str;
else
start_pos = trace_str + (sel_start - nameLen);
pos = strstr(start_pos, name);
if (pos && pos <= trace_str + sel_start)
{
// clicked on the operand name
// select the text
SendDlgItemMessage(hTracer, IDC_TRACER_LOG, EM_SETSEL, (WPARAM)(int)(pos - trace_str), (LPARAM)((int)(pos - trace_str) + nameLen));
if (hDebug)
PrintOffsetToSeekAndBookmarkFields(addr);
return (int)addr;
}
}
}
}
return EOF; return EOF;
} }
@ -144,7 +187,7 @@ BOOL CALLBACK IDC_TRACER_LOG_WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA
{ {
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
{ {
int offset = Tracer_CheckClickingOnAnAddress(false); int offset = Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), false);
if (offset != EOF) if (offset != EOF)
{ {
// open Debugger at this address // open Debugger at this address
@ -159,7 +202,7 @@ BOOL CALLBACK IDC_TRACER_LOG_WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
{ {
Tracer_CheckClickingOnAnAddress(true); Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), true);
break; break;
} }
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
@ -178,19 +221,11 @@ BOOL CALLBACK IDC_TRACER_LOG_WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA
case WM_RBUTTONUP: case WM_RBUTTONUP:
{ {
// if nothing is selected, try bringing Symbolic Debug Naming dialog // if nothing is selected, try bringing Symbolic Debug Naming dialog
int offset = Tracer_CheckClickingOnAnAddress(true); int offset = Tracer_CheckClickingOnAnAddressOrSymbolicName(tracesi.nPos + (GET_Y_LPARAM(lParam) / debugSystem->fixedFontHeight), true);
if (offset != EOF) if (offset != EOF)
{ {
if (DoSymbolicDebugNaming(offset, hTracer)) if (DoSymbolicDebugNaming(offset, hTracer))
{ {
/*
// enable "Symbolic trace" if not yet enabled
if (!(logging_options & LOG_SYMBOLIC))
{
logging_options |= LOG_SYMBOLIC;
CheckDlgButton(hTracer, IDC_CHECK_SYMBOLIC_TRACING, BST_CHECKED);
}
*/
if (hDebug) if (hDebug)
UpdateDebugger(false); UpdateDebugger(false);
if (hMemView) if (hMemView)
@ -438,7 +473,8 @@ void BeginLoggingSequence(void)
char str2[100]; char str2[100];
int i, j; int i, j;
if(!PromptForCDLogger())return; //do nothing if user selected no and CD Logger is needed if (!PromptForCDLogger())
return; //do nothing if user selected no and CD Logger is needed
if (logtofile) if (logtofile)
{ {
@ -460,14 +496,16 @@ void BeginLoggingSequence(void)
strcpy(trace_str, "Allocating Memory...\r\n"); strcpy(trace_str, "Allocating Memory...\r\n");
SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str); SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);
tracelogbufsize = j = log_optn_intlst[log_lines_option]; tracelogbufsize = j = log_optn_intlst[log_lines_option];
tracelogbuf = (char**)malloc(j*sizeof(char *)); //mbg merge 7/19/06 added cast tracelogbuf = (char**)malloc(j * sizeof(char *));
for (i = 0;i < j;i++) for (i = 0;i < j;i++)
{ {
tracelogbuf[i] = (char*)malloc(LOG_LINE_MAX_LEN); //mbg merge 7/19/06 added cast tracelogbuf[i] = (char*)malloc(LOG_LINE_MAX_LEN);
tracelogbuf[i][0] = 0; tracelogbuf[i][0] = 0;
} }
sprintf(str2, "%d Bytes Allocated...\r\n", j * LOG_LINE_MAX_LEN); sprintf(str2, "%d Bytes Allocated...\r\n", j * LOG_LINE_MAX_LEN);
strcat(trace_str, str2); strcat(trace_str, str2);
tracelogbufAddressesLog.resize(0);
tracelogbufAddressesLog.resize(tracelogbufsize);
// Assemble the message to pause the game. Uses the current hotkey mapping dynamically // Assemble the message to pause the game. Uses the current hotkey mapping dynamically
strcat(trace_str, "Pause the game (press "); strcat(trace_str, "Pause the game (press ");
strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE])); strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]));
@ -567,6 +605,7 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
{ {
if (logging_options & LOG_SYMBOLIC) if (logging_options & LOG_SYMBOLIC)
{ {
tempAddressesLog.resize(0);
// Insert Name and Comment lines if needed // Insert Name and Comment lines if needed
Name* node = findNode(getNamesPointerForAddress(addr), addr); Name* node = findNode(getNamesPointerForAddress(addr), addr);
if (node) if (node)
@ -575,7 +614,8 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
{ {
strcpy(str_decoration, node->name); strcpy(str_decoration, node->name);
strcat(str_decoration, ":"); strcat(str_decoration, ":");
OutputLogLine(str_decoration, true); tempAddressesLog.push_back(addr);
OutputLogLine(str_decoration, &tempAddressesLog);
} }
if (node->comment) if (node->comment)
{ {
@ -590,16 +630,17 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
tracer_decoration_comment_end_pos[0] = 0; // set \0 instead of \r tracer_decoration_comment_end_pos[0] = 0; // set \0 instead of \r
strcpy(str_decoration, "; "); strcpy(str_decoration, "; ");
strcat(str_decoration, tracer_decoration_comment); strcat(str_decoration, tracer_decoration_comment);
OutputLogLine(str_decoration, true); OutputLogLine(str_decoration, &tempAddressesLog);
tracer_decoration_comment_end_pos += 2; tracer_decoration_comment_end_pos += 2;
tracer_decoration_comment = tracer_decoration_comment_end_pos; tracer_decoration_comment = tracer_decoration_comment_end_pos;
tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n"); tracer_decoration_comment_end_pos = strstr(tracer_decoration_comment_end_pos, "\r\n");
} }
} }
} }
replaceNames(ramBankNames, a);
replaceNames(loadedBankNames, a); replaceNames(ramBankNames, a, &tempAddressesLog);
replaceNames(lastBankNames, a); replaceNames(loadedBankNames, a, &tempAddressesLog);
replaceNames(lastBankNames, a, &tempAddressesLog);
} }
strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN); strncpy(str_disassembly, a, LOG_DISASSEMBLY_MAX_LEN);
str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0; str_disassembly[LOG_DISASSEMBLY_MAX_LEN - 1] = 0;
@ -703,11 +744,12 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
strcat(str_result, str_procstatus); strcat(str_result, str_procstatus);
} }
OutputLogLine(str_result); OutputLogLine(str_result, &tempAddressesLog);
return; return;
} }
void OutputLogLine(const char *str, bool add_newline) void OutputLogLine(const char *str, std::vector<uint16>* addressesLog, bool add_newline)
{ {
if (logtofile) if (logtofile)
{ {
@ -727,6 +769,12 @@ void OutputLogLine(const char *str, bool add_newline)
strncpy(tracelogbuf[tracelogbufpos], str, LOG_LINE_MAX_LEN - 1); strncpy(tracelogbuf[tracelogbufpos], str, LOG_LINE_MAX_LEN - 1);
tracelogbuf[tracelogbufpos][LOG_LINE_MAX_LEN - 1] = 0; tracelogbuf[tracelogbufpos][LOG_LINE_MAX_LEN - 1] = 0;
} }
if (addressesLog)
tracelogbufAddressesLog[tracelogbufpos] = (*addressesLog);
else
tracelogbufAddressesLog[tracelogbufpos].resize(0);
tracelogbufpos++; tracelogbufpos++;
if (tracelogbufusedsize < tracelogbufsize) if (tracelogbufusedsize < tracelogbufsize)
tracelogbufusedsize++; tracelogbufusedsize++;
@ -734,16 +782,22 @@ void OutputLogLine(const char *str, bool add_newline)
} }
} }
void EndLoggingSequence(void){ void EndLoggingSequence(void)
{
int j, i; int j, i;
if(logtofile){ if (logtofile)
{
fclose(LOG_FP); fclose(LOG_FP);
} else { } else
{
j = tracelogbufsize; j = tracelogbufsize;
for(i = 0;i < j;i++){ for(i = 0;i < j;i++)
{
free(tracelogbuf[i]); free(tracelogbuf[i]);
} }
free(tracelogbuf); free(tracelogbuf);
tracelogbufAddressesLog.resize(0);
SetDlgItemText(hTracer, IDC_TRACER_LOG, "Welcome to the Trace Logger."); SetDlgItemText(hTracer, IDC_TRACER_LOG, "Welcome to the Trace Logger.");
} }
logging = 0; logging = 0;
@ -804,9 +858,7 @@ void UpdateLogText(void)
{ {
j = i; j = i;
if (tracelogbufusedsize == tracelogbufsize) if (tracelogbufusedsize == tracelogbufsize)
{
j = (tracelogbufpos + i) % tracelogbufsize; j = (tracelogbufpos + i) % tracelogbufsize;
}
strcat(trace_str, tracelogbuf[j]); strcat(trace_str, tracelogbuf[j]);
} }
SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str); SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str);

View File

@ -43,4 +43,4 @@ void EnableTracerMenuItems(void);
void LogInstruction(void); void LogInstruction(void);
void DoTracer(); void DoTracer();
void UpdateLogWindow(void); void UpdateLogWindow(void);
void OutputLogLine(const char *str, bool add_newline = true); void OutputLogLine(const char *str, std::vector<uint16>* addressesLog = 0, bool add_newline = true);