Added debugger breakpoint on unlogged code/data feature request #379. Moved break on bad opcodes checkbox from debug window layout to menu (saves valuable space in debug window for other things).
This commit is contained in:
parent
7b1e171ba7
commit
f9c785ba65
|
@ -470,20 +470,29 @@ void LogCDVectors(int which){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogCDData(uint8 *opcode, uint16 A, int size) {
|
bool break_on_unlogged_code = false;
|
||||||
|
bool break_on_unlogged_data = false;
|
||||||
|
|
||||||
|
void LogCDData(uint8 *opcode, uint16 A, int size)
|
||||||
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
uint8 memop = 0;
|
uint8 memop = 0;
|
||||||
|
bool newCodeHit = false, newDataHit = false;
|
||||||
|
|
||||||
if((j = GetPRGAddress(_PC)) != -1)
|
if ((j = GetPRGAddress(_PC)) != -1)
|
||||||
for (i = 0; i < size; i++) {
|
{
|
||||||
if(cdloggerdata[j+i] & 1)continue; //this has been logged so skip
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (cdloggerdata[j+i] & 1) continue; //this has been logged so skip
|
||||||
cdloggerdata[j+i] |= 1;
|
cdloggerdata[j+i] |= 1;
|
||||||
cdloggerdata[j+i] |= ((_PC + i) >> 11) & 0x0c;
|
cdloggerdata[j+i] |= ((_PC + i) >> 11) & 0x0c;
|
||||||
cdloggerdata[j+i] |= ((_PC & 0x8000) >> 8) ^ 0x80; // 19/07/14 used last reserved bit, if bit 7 is 1, then code is running from lowe area (6000)
|
cdloggerdata[j+i] |= ((_PC & 0x8000) >> 8) ^ 0x80; // 19/07/14 used last reserved bit, if bit 7 is 1, then code is running from lowe area (6000)
|
||||||
if(indirectnext)cdloggerdata[j+i] |= 0x10;
|
if (indirectnext)cdloggerdata[j+i] |= 0x10;
|
||||||
codecount++;
|
codecount++;
|
||||||
if(!(cdloggerdata[j+i] & 2))undefinedcount--;
|
if (!(cdloggerdata[j+i] & 2))undefinedcount--;
|
||||||
|
newCodeHit = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//log instruction jumped to in an indirect jump
|
//log instruction jumped to in an indirect jump
|
||||||
if(opcode[0] == 0x6c)
|
if(opcode[0] == 0x6c)
|
||||||
|
@ -496,27 +505,44 @@ void LogCDData(uint8 *opcode, uint16 A, int size) {
|
||||||
case 4: memop = 0x20; break;
|
case 4: memop = 0x20; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((j = GetPRGAddress(A)) != -1) {
|
if ((j = GetPRGAddress(A)) != -1)
|
||||||
if (opwrite[opcode[0]] == 0) {
|
{
|
||||||
if (!(cdloggerdata[j] & 2)) {
|
if (opwrite[opcode[0]] == 0)
|
||||||
|
{
|
||||||
|
if (!(cdloggerdata[j] & 2))
|
||||||
|
{
|
||||||
cdloggerdata[j] |= 2;
|
cdloggerdata[j] |= 2;
|
||||||
cdloggerdata[j] |= (A >> 11) & 0x0c;
|
cdloggerdata[j] |= (A >> 11) & 0x0c;
|
||||||
cdloggerdata[j] |= memop;
|
cdloggerdata[j] |= memop;
|
||||||
cdloggerdata[j] |= ((A & 0x8000) >> 8) ^ 0x80;
|
cdloggerdata[j] |= ((A & 0x8000) >> 8) ^ 0x80;
|
||||||
datacount++;
|
datacount++;
|
||||||
if (!(cdloggerdata[j] & 1))undefinedcount--;
|
if (!(cdloggerdata[j] & 1))undefinedcount--;
|
||||||
|
newDataHit = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (cdloggerdata[j] & 1) {
|
else
|
||||||
|
{
|
||||||
|
if (cdloggerdata[j] & 1)
|
||||||
|
{
|
||||||
codecount--;
|
codecount--;
|
||||||
}
|
}
|
||||||
if (cdloggerdata[j] & 2) {
|
if (cdloggerdata[j] & 2)
|
||||||
|
{
|
||||||
datacount--;
|
datacount--;
|
||||||
}
|
}
|
||||||
if ((cdloggerdata[j] & 3) != 0) undefinedcount++;
|
if ((cdloggerdata[j] & 3) != 0) undefinedcount++;
|
||||||
cdloggerdata[j] = 0;
|
cdloggerdata[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( break_on_unlogged_code && newCodeHit )
|
||||||
|
{
|
||||||
|
BreakHit( BREAK_TYPE_UNLOGGED_CODE );
|
||||||
|
}
|
||||||
|
else if ( break_on_unlogged_data && newDataHit )
|
||||||
|
{
|
||||||
|
BreakHit( BREAK_TYPE_UNLOGGED_DATA );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------debugger stuff
|
//-----------debugger stuff
|
||||||
|
@ -612,7 +638,7 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||||
int i, j;
|
int i, j;
|
||||||
uint8 brk_type;
|
uint8 brk_type;
|
||||||
uint8 stackop=0;
|
uint8 stackop=0;
|
||||||
uint8 stackopstartaddr,stackopendaddr;
|
uint8 stackopstartaddr=0,stackopendaddr=0;
|
||||||
|
|
||||||
debugLastAddress = A;
|
debugLastAddress = A;
|
||||||
debugLastOpcode = opcode[0];
|
debugLastOpcode = opcode[0];
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#define BREAK_TYPE_CYCLES_EXCEED -3
|
#define BREAK_TYPE_CYCLES_EXCEED -3
|
||||||
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -4
|
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -4
|
||||||
#define BREAK_TYPE_LUA -5
|
#define BREAK_TYPE_LUA -5
|
||||||
|
#define BREAK_TYPE_UNLOGGED_CODE -6
|
||||||
|
#define BREAK_TYPE_UNLOGGED_DATA -7
|
||||||
|
|
||||||
//opbrktype is used to grab the breakpoint type that each instruction will cause.
|
//opbrktype is used to grab the breakpoint type that each instruction will cause.
|
||||||
//WP_X is not used because ALL opcodes will have the execute bit set.
|
//WP_X is not used because ALL opcodes will have the execute bit set.
|
||||||
|
@ -98,6 +100,8 @@ bool CondForbidTest(int bp_num);
|
||||||
void BreakHit(int bp_num);
|
void BreakHit(int bp_num);
|
||||||
|
|
||||||
extern bool break_asap;
|
extern bool break_asap;
|
||||||
|
extern bool break_on_unlogged_code;
|
||||||
|
extern bool break_on_unlogged_data;
|
||||||
extern uint64 total_cycles_base;
|
extern uint64 total_cycles_base;
|
||||||
extern uint64 delta_cycles_base;
|
extern uint64 delta_cycles_base;
|
||||||
extern bool break_on_cycles;
|
extern bool break_on_cycles;
|
||||||
|
|
|
@ -191,6 +191,38 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
|
||||||
|
|
||||||
debugMenu->addAction(act);
|
debugMenu->addAction(act);
|
||||||
|
|
||||||
|
debugMenu->addSeparator();
|
||||||
|
|
||||||
|
// Debug -> Break on Bad Opcodes
|
||||||
|
act = new QAction(tr("Break on Bad &Opcodes"), this);
|
||||||
|
//act->setShortcut(QKeySequence( tr("F7") ) );
|
||||||
|
act->setStatusTip(tr("Break on Bad Opcodes"));
|
||||||
|
act->setCheckable(true);
|
||||||
|
act->setChecked( FCEUI_Debugger().badopbreak );
|
||||||
|
connect( act, SIGNAL(triggered(bool)), this, SLOT(breakOnBadOpcodeCB(bool)) );
|
||||||
|
|
||||||
|
debugMenu->addAction(act);
|
||||||
|
|
||||||
|
// Debug -> Break on Unlogged Code
|
||||||
|
act = new QAction(tr("Break on Unlogged &Code"), this);
|
||||||
|
//act->setShortcut(QKeySequence( tr("F7") ) );
|
||||||
|
act->setStatusTip(tr("Break on Unlogged Code"));
|
||||||
|
act->setCheckable(true);
|
||||||
|
act->setChecked( break_on_unlogged_code );
|
||||||
|
connect( act, SIGNAL(triggered(bool)), this, SLOT(breakOnNewCodeCB(bool)) );
|
||||||
|
|
||||||
|
debugMenu->addAction(act);
|
||||||
|
|
||||||
|
// Debug -> Break on Unlogged Data
|
||||||
|
act = new QAction(tr("Break on Unlogged &Data"), this);
|
||||||
|
//act->setShortcut(QKeySequence( tr("F7") ) );
|
||||||
|
act->setStatusTip(tr("Break on Unlogged Data"));
|
||||||
|
act->setCheckable(true);
|
||||||
|
act->setChecked( break_on_unlogged_data );
|
||||||
|
connect( act, SIGNAL(triggered(bool)), this, SLOT(breakOnNewDataCB(bool)) );
|
||||||
|
|
||||||
|
debugMenu->addAction(act);
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
optMenu = menuBar->addMenu(tr("&Options"));
|
optMenu = menuBar->addMenu(tr("&Options"));
|
||||||
|
|
||||||
|
@ -443,13 +475,8 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
|
||||||
hbox->addWidget( button );
|
hbox->addWidget( button );
|
||||||
connect( button, SIGNAL(clicked(void)), this, SLOT(edit_BP_CB(void)) );
|
connect( button, SIGNAL(clicked(void)), this, SLOT(edit_BP_CB(void)) );
|
||||||
|
|
||||||
brkBadOpsCbox = new QCheckBox( tr("Break on Bad Opcodes") );
|
|
||||||
brkBadOpsCbox->setChecked( FCEUI_Debugger().badopbreak );
|
|
||||||
connect( brkBadOpsCbox, SIGNAL(stateChanged(int)), this, SLOT(breakOnBadOpcodeCB(int)) );
|
|
||||||
|
|
||||||
vbox->addWidget( bpTree );
|
vbox->addWidget( bpTree );
|
||||||
vbox->addLayout( hbox );
|
vbox->addLayout( hbox );
|
||||||
vbox->addWidget( brkBadOpsCbox );
|
|
||||||
bpFrame->setLayout( vbox );
|
bpFrame->setLayout( vbox );
|
||||||
|
|
||||||
sfFrame = new QGroupBox(tr("Status Flags"));
|
sfFrame = new QGroupBox(tr("Status Flags"));
|
||||||
|
@ -1426,10 +1453,22 @@ void ConsoleDebugger::delete_BP_CB(void)
|
||||||
//bpListUpdate( true );
|
//bpListUpdate( true );
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void ConsoleDebugger::breakOnBadOpcodeCB(int value)
|
void ConsoleDebugger::breakOnBadOpcodeCB(bool value)
|
||||||
{
|
{
|
||||||
//printf("Value:%i\n", value);
|
//printf("Value:%i\n", value);
|
||||||
FCEUI_Debugger().badopbreak = (value != Qt::Unchecked);
|
FCEUI_Debugger().badopbreak = value;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void ConsoleDebugger::breakOnNewCodeCB(bool value)
|
||||||
|
{
|
||||||
|
//printf("Code Value:%i\n", value);
|
||||||
|
break_on_unlogged_code = value;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void ConsoleDebugger::breakOnNewDataCB(bool value)
|
||||||
|
{
|
||||||
|
//printf("Data Value:%i\n", value);
|
||||||
|
break_on_unlogged_data = value;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void ConsoleDebugger::breakOnCyclesCB( int value )
|
void ConsoleDebugger::breakOnCyclesCB( int value )
|
||||||
|
|
|
@ -255,7 +255,6 @@ class ConsoleDebugger : public QDialog
|
||||||
QGroupBox *bmFrame;
|
QGroupBox *bmFrame;
|
||||||
QTreeWidget *bpTree;
|
QTreeWidget *bpTree;
|
||||||
QTreeWidget *bmTree;
|
QTreeWidget *bmTree;
|
||||||
QCheckBox *brkBadOpsCbox;
|
|
||||||
QCheckBox *N_chkbox;
|
QCheckBox *N_chkbox;
|
||||||
QCheckBox *V_chkbox;
|
QCheckBox *V_chkbox;
|
||||||
QCheckBox *U_chkbox;
|
QCheckBox *U_chkbox;
|
||||||
|
@ -325,7 +324,9 @@ class ConsoleDebugger : public QDialog
|
||||||
void registerNameEnableCB(int value);
|
void registerNameEnableCB(int value);
|
||||||
void autoOpenDebugCB( int value );
|
void autoOpenDebugCB( int value );
|
||||||
void debFileAutoLoadCB( int value );
|
void debFileAutoLoadCB( int value );
|
||||||
void breakOnBadOpcodeCB(int value);
|
void breakOnBadOpcodeCB(bool value);
|
||||||
|
void breakOnNewCodeCB(bool value);
|
||||||
|
void breakOnNewDataCB(bool value);
|
||||||
void breakOnCyclesCB( int value );
|
void breakOnCyclesCB( int value );
|
||||||
void breakOnInstructionsCB( int value );
|
void breakOnInstructionsCB( int value );
|
||||||
void bpItemClicked( QTreeWidgetItem *item, int column);
|
void bpItemClicked( QTreeWidgetItem *item, int column);
|
||||||
|
|
Loading…
Reference in New Issue