* Debugger: don't update Debugger window at the beginning of Step command (it will update at at the end of Step) - fixes #528

* Debugger: allow Frame Advancing when Debugger is in breakpoint state
* Debugger: fixed memory leak and possible heap corruption when deleting breakpoints
* Debugger: highlighting breakpoint item in BPs list when it's triggered
* Taseditor now doesn't update when debugger is in breakpoint state
This commit is contained in:
ansstuff 2012-08-03 19:28:14 +00:00
parent e3fe4d6033
commit 0ee3771d07
5 changed files with 85 additions and 38 deletions

View File

@ -231,7 +231,7 @@ int GetNesFileAddress(int A){
int result; int result;
if((A < 0x8000) || (A > 0xFFFF))return -1; if((A < 0x8000) || (A > 0xFFFF))return -1;
result = &Page[A>>11][A]-PRGptr[0]; result = &Page[A>>11][A]-PRGptr[0];
if((result > PRGsize[0]) || (result < 0))return -1; if((result > (int)(PRGsize[0])) || (result < 0))return -1;
else return result+16; //16 bytes for the header remember else return result+16; //16 bytes for the header remember
} }
@ -462,8 +462,8 @@ static DebuggerState dbgstate;
DebuggerState &FCEUI_Debugger() { return dbgstate; } DebuggerState &FCEUI_Debugger() { return dbgstate; }
void BreakHit(bool force = false) { void BreakHit(int bp_num, bool force = false)
{
if(!force) { if(!force) {
//check to see whether we fall in any forbid zone //check to see whether we fall in any forbid zone
@ -490,7 +490,7 @@ void BreakHit(bool force = false) {
//MBG TODO - was this commented out before the gnu refactoring? //MBG TODO - was this commented out before the gnu refactoring?
//if((!logtofile) && (logging))PauseLoggingSequence(); //if((!logtofile) && (logging))PauseLoggingSequence();
FCEUD_DebugBreakpoint(); FCEUD_DebugBreakpoint(bp_num);
} }
uint8 StackAddrBackup = X.S; uint8 StackAddrBackup = X.S;
@ -508,7 +508,7 @@ void breakpoint() {
opcode[0] = GetMem(_PC); opcode[0] = GetMem(_PC);
//if the current instruction is bad, and we are breaking on bad opcodes, then hit the breakpoint //if the current instruction is bad, and we are breaking on bad opcodes, then hit the breakpoint
if(dbgstate.badopbreak && (opsize[opcode[0]] == 0)) BreakHit(true); if(dbgstate.badopbreak && (opsize[opcode[0]] == 0)) BreakHit(-1, true);
//if we're stepping out, track the nest level //if we're stepping out, track the nest level
if (dbgstate.stepout) { if (dbgstate.stepout) {
@ -526,7 +526,7 @@ void breakpoint() {
//if we're stepping, then we'll always want to break //if we're stepping, then we'll always want to break
if (dbgstate.step) { if (dbgstate.step) {
dbgstate.step = false; dbgstate.step = false;
BreakHit(true); BreakHit(-1, true);
return; return;
} }
//if we're running for a scanline, we want to check if we've hit the cycle limit //if we're running for a scanline, we want to check if we've hit the cycle limit
@ -538,7 +538,7 @@ void breakpoint() {
if (diff<=0) if (diff<=0)
{ {
dbgstate.runline=false; dbgstate.runline=false;
BreakHit(true); BreakHit(-1, true);
return; return;
} }
} }
@ -546,7 +546,7 @@ void breakpoint() {
if ((watchpoint[64].address == _PC) && (watchpoint[64].flags)) { if ((watchpoint[64].address == _PC) && (watchpoint[64].flags)) {
watchpoint[64].address = 0; watchpoint[64].address = 0;
watchpoint[64].flags = 0; watchpoint[64].flags = 0;
BreakHit(true); BreakHit(-1, true);
return; return;
} }
@ -590,28 +590,28 @@ void breakpoint() {
if (watchpoint[i].flags & BT_P) { //PPU Mem breaks if (watchpoint[i].flags & BT_P) { //PPU Mem breaks
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type) && ((A >= 0x2000) && (A < 0x4000)) && ((A&7) == 7)) { if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type) && ((A >= 0x2000) && (A < 0x4000)) && ((A&7) == 7)) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if ((watchpoint[i].address <= RefreshAddr) && (watchpoint[i].endaddress >= RefreshAddr)) BreakHit(); if ((watchpoint[i].address <= RefreshAddr) && (watchpoint[i].endaddress >= RefreshAddr)) BreakHit(i);
} }
else if (watchpoint[i].address == RefreshAddr) BreakHit(); else if (watchpoint[i].address == RefreshAddr) BreakHit(i);
} }
} }
else if (watchpoint[i].flags & BT_S) { //Sprite Mem breaks else if (watchpoint[i].flags & BT_S) { //Sprite Mem breaks
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type) && ((A >= 0x2000) && (A < 0x4000)) && ((A&7) == 4)) { if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type) && ((A >= 0x2000) && (A < 0x4000)) && ((A&7) == 4)) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if ((watchpoint[i].address <= PPU[3]) && (watchpoint[i].endaddress >= PPU[3])) BreakHit(); if ((watchpoint[i].address <= PPU[3]) && (watchpoint[i].endaddress >= PPU[3])) BreakHit(i);
} }
else if (watchpoint[i].address == PPU[3]) BreakHit(); else if (watchpoint[i].address == PPU[3]) BreakHit(i);
} }
else if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & WP_W) && (A == 0x4014)) BreakHit(); //Sprite DMA! :P else if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & WP_W) && (A == 0x4014)) BreakHit(i); //Sprite DMA! :P
} }
else { //CPU mem breaks else { //CPU mem breaks
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type)) { if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type)) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address <= A) && (watchpoint[i].endaddress >= A)) || if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address <= A) && (watchpoint[i].endaddress >= A)) ||
((watchpoint[i].flags & WP_X) && (watchpoint[i].address <= _PC) && (watchpoint[i].endaddress >= _PC))) BreakHit(); ((watchpoint[i].flags & WP_X) && (watchpoint[i].address <= _PC) && (watchpoint[i].endaddress >= _PC))) BreakHit(i);
} }
else if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address == A)) || else if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address == A)) ||
((watchpoint[i].flags & WP_X) && (watchpoint[i].address == _PC))) BreakHit(); ((watchpoint[i].flags & WP_X) && (watchpoint[i].address == _PC))) BreakHit(i);
} }
else if (watchpoint[i].flags & WP_E) { else if (watchpoint[i].flags & WP_E) {
//brk_type independant coding //brk_type independant coding
@ -623,9 +623,9 @@ void breakpoint() {
if (watchpoint[i].flags & stackop) { if (watchpoint[i].flags & stackop) {
for (j = (stackopstartaddr|0x0100); j <= (stackopendaddr|0x0100); j++) { for (j = (stackopstartaddr|0x0100); j <= (stackopendaddr|0x0100); j++) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(); if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(i);
} }
else if (watchpoint[i].address == j) BreakHit(); else if (watchpoint[i].address == j) BreakHit(i);
} }
} }
} }
@ -640,9 +640,9 @@ void breakpoint() {
if (watchpoint[i].flags & WP_W) { if (watchpoint[i].flags & WP_W) {
for (j = (X.S|0x0100); j < (StackAddrBackup|0x0100); j++) { for (j = (X.S|0x0100); j < (StackAddrBackup|0x0100); j++) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(); if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(i);
} }
else if (watchpoint[i].address == j) BreakHit(); else if (watchpoint[i].address == j) BreakHit(i);
} }
} }
} }
@ -651,9 +651,9 @@ void breakpoint() {
if (watchpoint[i].flags & WP_R) { if (watchpoint[i].flags & WP_R) {
for (j = (StackAddrBackup|0x0100); j < (X.S|0x0100); j++) { for (j = (StackAddrBackup|0x0100); j < (X.S|0x0100); j++) {
if (watchpoint[i].endaddress) { if (watchpoint[i].endaddress) {
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(); if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit(i);
} }
else if (watchpoint[i].address == j) BreakHit(); else if (watchpoint[i].address == j) BreakHit(i);
} }
} }
} }

View File

@ -312,7 +312,7 @@ void FCEUD_CmdOpen(void);
//new merge-era driver routines here: //new merge-era driver routines here:
///signals that the cpu core hit a breakpoint. this function should not return until the core is ready for the next cycle ///signals that the cpu core hit a breakpoint. this function should not return until the core is ready for the next cycle
void FCEUD_DebugBreakpoint(); void FCEUD_DebugBreakpoint(int bp_num);
///the driver should log the current instruction, if it wants (we should move the code in the win driver that does this to the shared area) ///the driver should log the current instruction, if it wants (we should move the code in the win driver that does this to the shared area)
void FCEUD_TraceInstruction(); void FCEUD_TraceInstruction();

View File

@ -78,10 +78,9 @@ bool debuggerSaveLoadDEBFiles = true;
#define MAX_NAME_SIZE 200 #define MAX_NAME_SIZE 200
#define MAX_CONDITION_SIZE 200 #define MAX_CONDITION_SIZE 200
void UpdateDebuggingDialogs() void UpdateOtherDebuggingDialogs()
{ {
//adelikat: This updates all the other dialogs such as ppu, nametable, logger, etc in one function, should be applied to all the step type buttons //adelikat: This updates all the other dialogs such as ppu, nametable, logger, etc in one function, should be applied to all the step type buttons
UpdateDebugger(); //Debugger
NTViewDoBlit(0); //Nametable Viewer NTViewDoBlit(0); //Nametable Viewer
UpdateLogWindow(); //Trace Logger UpdateLogWindow(); //Trace Logger
UpdateCDLogger(); //Code/Data Logger UpdateCDLogger(); //Code/Data Logger
@ -526,10 +525,24 @@ void UpdateRegs(HWND hwndDlg) {
///indicates whether we're under the control of the debugger ///indicates whether we're under the control of the debugger
bool inDebugger = false; bool inDebugger = false;
//this code enters the debugger. //this code enters the debugger when a breakpoint was hit
void FCEUD_DebugBreakpoint() { void FCEUD_DebugBreakpoint(int bp_num)
UpdateDebuggingDialogs(); //Keeps the debugging windows updating smoothly when stepping {
void win_debuggerLoop(); //HACK UpdateDebugger();
// highlight bp_num item in IDC_DEBUGGER_BP_LIST
if (bp_num >= 0)
{
SendDlgItemMessage(hDebug, IDC_DEBUGGER_BP_LIST, LB_SETCURSEL, (WPARAM)bp_num, 0);
EnableWindow(GetDlgItem(hDebug, IDC_DEBUGGER_BP_DEL), TRUE);
EnableWindow(GetDlgItem(hDebug, IDC_DEBUGGER_BP_EDIT), TRUE);
} else
{
SendDlgItemMessage(hDebug, IDC_DEBUGGER_BP_LIST, LB_SETCURSEL, (WPARAM)(-1), 0);
EnableWindow(GetDlgItem(hDebug, IDC_DEBUGGER_BP_DEL), FALSE);
EnableWindow(GetDlgItem(hDebug, IDC_DEBUGGER_BP_EDIT), FALSE);
}
UpdateOtherDebuggingDialogs(); // Keeps the debugging windows updating smoothly when stepping
void win_debuggerLoop(); // HACK to let user interact with the Debugger while emulator isn't updating
win_debuggerLoop(); win_debuggerLoop();
} }
@ -694,7 +707,13 @@ void EnableBreak(int sel) {
void DeleteBreak(int sel) { void DeleteBreak(int sel) {
if(sel<0) return; if(sel<0) return;
if(sel>=numWPs) return; if(sel>=numWPs) return;
if (watchpoint[sel].cond)
freeTree(watchpoint[sel].cond);
if (watchpoint[sel].condText)
free(watchpoint[sel].condText);
if (watchpoint[sel].desc)
free(watchpoint[sel].desc);
// move all BP items up in the list
for (int i = sel; i < numWPs; i++) { for (int i = sel; i < numWPs; i++) {
watchpoint[i].address = watchpoint[i+1].address; watchpoint[i].address = watchpoint[i+1].address;
watchpoint[i].endaddress = watchpoint[i+1].endaddress; watchpoint[i].endaddress = watchpoint[i+1].endaddress;
@ -705,6 +724,13 @@ void DeleteBreak(int sel) {
watchpoint[i].desc = watchpoint[i+1].desc; watchpoint[i].desc = watchpoint[i+1].desc;
// ################################## End of SP CODE ########################### // ################################## End of SP CODE ###########################
} }
// erase last BP item
watchpoint[numWPs].address = 0;
watchpoint[numWPs].endaddress = 0;
watchpoint[numWPs].flags = 0;
watchpoint[numWPs].cond = 0;
watchpoint[numWPs].condText = 0;
watchpoint[numWPs].desc = 0;
numWPs--; numWPs--;
// ################################## Start of SP CODE ########################### // ################################## Start of SP CODE ###########################
myNumWPs--; myNumWPs--;
@ -1378,7 +1404,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
} }
FCEUI_Debugger().step = true; FCEUI_Debugger().step = true;
FCEUI_SetEmulationPaused(0); FCEUI_SetEmulationPaused(0);
UpdateDebuggingDialogs(); UpdateOtherDebuggingDialogs();
break; break;
case IDC_DEBUGGER_RUN_LINE: case IDC_DEBUGGER_RUN_LINE:
@ -1395,7 +1421,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
FCEUI_Debugger().runline_end_time=ts; FCEUI_Debugger().runline_end_time=ts;
} }
FCEUI_SetEmulationPaused(0); FCEUI_SetEmulationPaused(0);
UpdateDebuggingDialogs(); UpdateOtherDebuggingDialogs();
break; break;
case IDC_DEBUGGER_RUN_FRAME2: case IDC_DEBUGGER_RUN_FRAME2:
if (FCEUI_EmulationPaused()) { if (FCEUI_EmulationPaused()) {
@ -1411,7 +1437,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//else vblankScanLines = 0; //else vblankScanLines = 0;
} }
FCEUI_SetEmulationPaused(0); FCEUI_SetEmulationPaused(0);
UpdateDebuggingDialogs(); UpdateOtherDebuggingDialogs();
break; break;
case IDC_DEBUGGER_STEP_OUT: case IDC_DEBUGGER_STEP_OUT:
//mbg merge 7/18/06 changed pausing check and set //mbg merge 7/18/06 changed pausing check and set
@ -1503,11 +1529,21 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
} }
break; break;
case LBN_SELCHANGE: case LBN_SELCHANGE:
switch(LOWORD(wParam)) { switch(LOWORD(wParam))
{
case IDC_DEBUGGER_BP_LIST: case IDC_DEBUGGER_BP_LIST:
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_DEL),TRUE); {
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_EDIT),TRUE); if (SendDlgItemMessage(hwndDlg,IDC_DEBUGGER_BP_LIST,LB_GETCURSEL,0,0) >= 0)
{
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_DEL),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_EDIT),TRUE);
} else
{
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_DEL),FALSE);
EnableWindow(GetDlgItem(hwndDlg,IDC_DEBUGGER_BP_EDIT),FALSE);
}
break; break;
}
} }
break; break;
} }

View File

@ -70,6 +70,7 @@
#include "video.h" #include "video.h"
#include "utils/xstring.h" #include "utils/xstring.h"
#include <string.h> #include <string.h>
#include "taseditor.h"
#include "taseditor/taseditor_window.h" #include "taseditor/taseditor_window.h"
extern TASEDITOR_WINDOW taseditor_window; extern TASEDITOR_WINDOW taseditor_window;
@ -868,8 +869,7 @@ void _updateWindow()
//UpdateLogWindow(); //adelikat: Moved to FCEUI_Emulate //UpdateLogWindow(); //adelikat: Moved to FCEUI_Emulate
UpdateMemWatch(); UpdateMemWatch();
NTViewDoBlit(0); NTViewDoBlit(0);
extern void UpdateTasEditor(); //UpdateTasEditor(); //AnS: moved to FCEUD_Update
UpdateTasEditor();
} }
void win_debuggerLoop() void win_debuggerLoop()
@ -881,6 +881,15 @@ void win_debuggerLoop()
Sleep(50); Sleep(50);
FCEUD_UpdateInput(); FCEUD_UpdateInput();
_updateWindow(); _updateWindow();
// HACK: break when Frame Advance is pressed
extern bool frameAdvanceRequested;
extern int frameAdvanceDelay;
if (frameAdvanceRequested && frameAdvanceDelay==0)
{
//FCEUI_SetEmulationPaused(0);
frameAdvanceDelay++;
break;
}
} }
int zzz=9; int zzz=9;
} }
@ -901,6 +910,8 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
//update debugging displays //update debugging displays
_updateWindow(); _updateWindow();
// update TAS Editor
UpdateTasEditor();
extern bool JustFrameAdvanced; extern bool JustFrameAdvanced;

View File

@ -1087,7 +1087,7 @@ BEGIN
CONTROL "Z",IDC_DEBUGGER_FLAG_Z,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,485,174,22,12 CONTROL "Z",IDC_DEBUGGER_FLAG_Z,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,485,174,22,12
CONTROL "C",IDC_DEBUGGER_FLAG_C,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,510,174,22,12 CONTROL "C",IDC_DEBUGGER_FLAG_C,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,510,174,22,12
GROUPBOX "BreakPoints",402,430,3,104,143,WS_TABSTOP GROUPBOX "BreakPoints",402,430,3,104,143,WS_TABSTOP
LISTBOX IDC_DEBUGGER_BP_LIST,437,16,90,91,LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL LISTBOX IDC_DEBUGGER_BP_LIST,437,16,90,91,LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
PUSHBUTTON "Add...",IDC_DEBUGGER_BP_ADD,437,111,30,15 PUSHBUTTON "Add...",IDC_DEBUGGER_BP_ADD,437,111,30,15
PUSHBUTTON "Delete",IDC_DEBUGGER_BP_DEL,469,111,30,15,WS_DISABLED PUSHBUTTON "Delete",IDC_DEBUGGER_BP_DEL,469,111,30,15,WS_DISABLED
PUSHBUTTON "Edit",IDC_DEBUGGER_BP_EDIT,501,111,26,15,WS_DISABLED PUSHBUTTON "Edit",IDC_DEBUGGER_BP_EDIT,501,111,26,15,WS_DISABLED