* 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:
parent
0e2422f90a
commit
8f9e2be234
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
node->comment = (char*)malloc(strlen(newComment) + 1);
|
if (strlen(newComment))
|
||||||
strcpy(node->comment, newComment);
|
{
|
||||||
|
node->comment = (char*)malloc(strlen(newComment) + 1);
|
||||||
|
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
|
||||||
free(node->name);
|
if (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);
|
||||||
free(node->comment);
|
if (node->comment)
|
||||||
node->comment = (char*)malloc(strlen(newComment) + 1);
|
{
|
||||||
strcpy(node->comment, newComment);
|
free(node->comment);
|
||||||
|
node->comment = 0;
|
||||||
|
}
|
||||||
|
if (strlen(newComment))
|
||||||
|
{
|
||||||
|
node->comment = (char*)malloc(strlen(newComment) + 1);
|
||||||
|
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);
|
||||||
newNode->comment = (char*)malloc(strlen(newComment) + 1);
|
if (strlen(newComment))
|
||||||
strcpy(newNode->comment, newComment);
|
{
|
||||||
|
newNode->comment = (char*)malloc(strlen(newComment) + 1);
|
||||||
|
strcpy(newNode->comment, newComment);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
newNode->comment = 0;
|
||||||
|
}
|
||||||
newNode->next = 0;
|
newNode->next = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -956,9 +980,12 @@ 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
|
||||||
free(node->offset);
|
if (node->offset)
|
||||||
free(node->name);
|
free(node->offset);
|
||||||
free(node->comment);
|
if (node->name)
|
||||||
|
free(node->name);
|
||||||
|
if (node->comment)
|
||||||
|
free(node->comment);
|
||||||
if (previousNode)
|
if (previousNode)
|
||||||
previousNode->next = node->next;
|
previousNode->next = node->next;
|
||||||
if (node == initialNode)
|
if (node == initialNode)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,9 +473,10 @@ 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)
|
||||||
{
|
{
|
||||||
if(logfilename == NULL) ShowLogDirDialog();
|
if(logfilename == NULL) ShowLogDirDialog();
|
||||||
if (!logfilename) return;
|
if (!logfilename) return;
|
||||||
|
@ -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,13 +744,14 @@ 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)
|
||||||
{
|
{
|
||||||
fputs(str, LOG_FP);
|
fputs(str, LOG_FP);
|
||||||
if (add_newline)
|
if (add_newline)
|
||||||
|
@ -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,19 +782,25 @@ 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;
|
||||||
SetDlgItemText(hTracer, IDC_BTN_START_STOP_LOGGING,"Start Logging");
|
SetDlgItemText(hTracer, IDC_BTN_START_STOP_LOGGING,"Start Logging");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -803,10 +857,8 @@ void UpdateLogText(void)
|
||||||
for (; i < last_line; i++)
|
for (; i < last_line; i++)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue