* 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;
if((A < 0x8000) || (A > 0xFFFF))return -1;
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
}
@ -462,8 +462,8 @@ static DebuggerState dbgstate;
DebuggerState &FCEUI_Debugger() { return dbgstate; }
void BreakHit(bool force = false) {
void BreakHit(int bp_num, bool force = false)
{
if(!force) {
//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?
//if((!logtofile) && (logging))PauseLoggingSequence();
FCEUD_DebugBreakpoint();
FCEUD_DebugBreakpoint(bp_num);
}
uint8 StackAddrBackup = X.S;
@ -508,7 +508,7 @@ void breakpoint() {
opcode[0] = GetMem(_PC);
//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 (dbgstate.stepout) {
@ -526,7 +526,7 @@ void breakpoint() {
//if we're stepping, then we'll always want to break
if (dbgstate.step) {
dbgstate.step = false;
BreakHit(true);
BreakHit(-1, true);
return;
}
//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)
{
dbgstate.runline=false;
BreakHit(true);
BreakHit(-1, true);
return;
}
}
@ -546,7 +546,7 @@ void breakpoint() {
if ((watchpoint[64].address == _PC) && (watchpoint[64].flags)) {
watchpoint[64].address = 0;
watchpoint[64].flags = 0;
BreakHit(true);
BreakHit(-1, true);
return;
}
@ -590,28 +590,28 @@ void breakpoint() {
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].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
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].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
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type)) {
if (watchpoint[i].endaddress) {
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)) ||
((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) {
//brk_type independant coding
@ -623,9 +623,9 @@ void breakpoint() {
if (watchpoint[i].flags & stackop) {
for (j = (stackopstartaddr|0x0100); j <= (stackopendaddr|0x0100); j++) {
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) {
for (j = (X.S|0x0100); j < (StackAddrBackup|0x0100); j++) {
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) {
for (j = (StackAddrBackup|0x0100); j < (X.S|0x0100); j++) {
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:
///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)
void FCEUD_TraceInstruction();

View File

@ -78,10 +78,9 @@ bool debuggerSaveLoadDEBFiles = true;
#define MAX_NAME_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
UpdateDebugger(); //Debugger
NTViewDoBlit(0); //Nametable Viewer
UpdateLogWindow(); //Trace Logger
UpdateCDLogger(); //Code/Data Logger
@ -526,10 +525,24 @@ void UpdateRegs(HWND hwndDlg) {
///indicates whether we're under the control of the debugger
bool inDebugger = false;
//this code enters the debugger.
void FCEUD_DebugBreakpoint() {
UpdateDebuggingDialogs(); //Keeps the debugging windows updating smoothly when stepping
void win_debuggerLoop(); //HACK
//this code enters the debugger when a breakpoint was hit
void FCEUD_DebugBreakpoint(int bp_num)
{
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();
}
@ -694,7 +707,13 @@ void EnableBreak(int sel) {
void DeleteBreak(int sel) {
if(sel<0) 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++) {
watchpoint[i].address = watchpoint[i+1].address;
watchpoint[i].endaddress = watchpoint[i+1].endaddress;
@ -705,6 +724,13 @@ void DeleteBreak(int sel) {
watchpoint[i].desc = watchpoint[i+1].desc;
// ################################## 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--;
// ################################## Start of SP CODE ###########################
myNumWPs--;
@ -1378,7 +1404,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
}
FCEUI_Debugger().step = true;
FCEUI_SetEmulationPaused(0);
UpdateDebuggingDialogs();
UpdateOtherDebuggingDialogs();
break;
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_SetEmulationPaused(0);
UpdateDebuggingDialogs();
UpdateOtherDebuggingDialogs();
break;
case IDC_DEBUGGER_RUN_FRAME2:
if (FCEUI_EmulationPaused()) {
@ -1411,7 +1437,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//else vblankScanLines = 0;
}
FCEUI_SetEmulationPaused(0);
UpdateDebuggingDialogs();
UpdateOtherDebuggingDialogs();
break;
case IDC_DEBUGGER_STEP_OUT:
//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;
case LBN_SELCHANGE:
switch(LOWORD(wParam)) {
switch(LOWORD(wParam))
{
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;
}

View File

@ -70,6 +70,7 @@
#include "video.h"
#include "utils/xstring.h"
#include <string.h>
#include "taseditor.h"
#include "taseditor/taseditor_window.h"
extern TASEDITOR_WINDOW taseditor_window;
@ -868,8 +869,7 @@ void _updateWindow()
//UpdateLogWindow(); //adelikat: Moved to FCEUI_Emulate
UpdateMemWatch();
NTViewDoBlit(0);
extern void UpdateTasEditor();
UpdateTasEditor();
//UpdateTasEditor(); //AnS: moved to FCEUD_Update
}
void win_debuggerLoop()
@ -881,6 +881,15 @@ void win_debuggerLoop()
Sleep(50);
FCEUD_UpdateInput();
_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;
}
@ -901,6 +910,8 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
//update debugging displays
_updateWindow();
// update TAS Editor
UpdateTasEditor();
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 "C",IDC_DEBUGGER_FLAG_C,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,510,174,22,12
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 "Delete",IDC_DEBUGGER_BP_DEL,469,111,30,15,WS_DISABLED
PUSHBUTTON "Edit",IDC_DEBUGGER_BP_EDIT,501,111,26,15,WS_DISABLED