Breakpoints on full-speed.

BRK # [ON|OFF]
BRKOP ##
This commit is contained in:
mpohoreski 2006-05-14 00:43:19 +00:00
parent ab6a9a976d
commit fb932a8d4f
5 changed files with 267 additions and 57 deletions

View File

@ -427,9 +427,34 @@ static volatile UINT32 g_bmIRQ = 0;
#define TXS regs.sp = 0x100 | regs.x;
#define TYA regs.a = regs.y; \
SETNZ(regs.a)
#define INVALID1
#define INVALID2 if (apple2e) ++regs.pc;
#define INVALID3 if (apple2e) regs.pc += 2;
void RequestDebugger()
{
PostMessage( g_hFrameWindow, WM_KEYDOWN, DEBUG_TOGGLE_KEY, 0 );
PostMessage( g_hFrameWindow, WM_KEYUP , DEBUG_TOGGLE_KEY, 0 );
}
bool CheckDebugBreak( int iOpcode )
{
// Rnning at full speed? (debugger not running)
if ((mode != MODE_DEBUG) && (mode != MODE_STEPPING))
{
if (((iOpcode == 0) && IsDebugBreakOnInvalid(0)) ||
((g_iDebugOnOpcode) && (g_iDebugOnOpcode == iOpcode))) // User wants to enter debugger on opcode?
{
RequestDebugger();
return true;
}
}
return false;
}
// Break into debugger on invalid opcodes
#define INVALID1 ; if (IsDebugBreakOnInvalid(1)) { RequestDebugger(); bBreakOnInvalid = true; }
#define INVALID2 if (apple2e) ++regs.pc ; if (IsDebugBreakOnInvalid(2)) { RequestDebugger(); bBreakOnInvalid = true; }
#define INVALID3 if (apple2e) regs.pc += 2; if (IsDebugBreakOnInvalid(3)) { RequestDebugger(); bBreakOnInvalid = true; }
/****************************************************************************
*
@ -480,24 +505,33 @@ static inline void DoIrqProfiling(DWORD cycles)
//===========================================================================
static DWORD InternalCpuExecute (DWORD totalcycles)
{
WORD addr;
BOOL flagc;
BOOL flagn;
BOOL flagv;
BOOL flagz;
WORD temp;
WORD val;
AF_TO_EF
DWORD cycles = 0;
BOOL bWrtMem; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
WORD addr;
BOOL flagc;
BOOL flagn;
BOOL flagv;
BOOL flagz;
WORD temp;
WORD val;
AF_TO_EF
DWORD cycles = 0;
BOOL bWrtMem; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
do
{
nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8);
USHORT uExtraCycles = 0;
bool bBreakOnInvalid = false;
switch (*(mem+regs.pc++))
do
{
nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8);
USHORT uExtraCycles = 0;
BYTE iOpcode = *(mem+regs.pc);
if (CheckDebugBreak( iOpcode ))
break;
regs.pc++;
switch (iOpcode)
{
case 0x00: BRK CYC(7) break;
case 0x01: INDX ORA CYC(6) break;
@ -759,23 +793,29 @@ static DWORD InternalCpuExecute (DWORD totalcycles)
case 0xFF: INVALID1 CYC(1) break;
}
if(g_bmIRQ && !(regs.ps & AF_INTERRUPT))
{
// IRQ signals are deasserted when a specific r/w operation is done on device
g_nCycleIrqStart = g_nCumulativeCycles + cycles;
PUSH(regs.pc >> 8)
PUSH(regs.pc & 0xFF)
EF_TO_AF
regs.ps |= AF_RESERVED;
PUSH(regs.ps)
regs.ps |= AF_INTERRUPT;
regs.pc = * (WORD*) (mem+0xFFFE);
CYC(7)
if(g_bmIRQ && !(regs.ps & AF_INTERRUPT))
{
// IRQ signals are deasserted when a specific r/w operation is done on device
g_nCycleIrqStart = g_nCumulativeCycles + cycles;
PUSH(regs.pc >> 8)
PUSH(regs.pc & 0xFF)
EF_TO_AF
regs.ps |= AF_RESERVED;
PUSH(regs.ps)
regs.ps |= AF_INTERRUPT;
regs.pc = * (WORD*) (mem+0xFFFE);
CYC(7)
}
if (bBreakOnInvalid)
break;
}
}
while (cycles < totalcycles);
EF_TO_AF
return cycles;
while (cycles < totalcycles);
EF_TO_AF
return cycles;
}
//

View File

@ -51,6 +51,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Breakpoints ________________________________________________________________
// Full-Speed debugging
int g_nDebugOnBreakInvalid = 0;
int g_iDebugOnOpcode = 0;
int g_nBreakpoints = 0;
Breakpoint_t g_aBreakpoints[ NUM_BREAKPOINTS ];
@ -124,6 +128,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// CPU (Main)
{TEXT("A") , CmdAssemble , CMD_ASSEMBLE , "Assemble instructions" },
{TEXT("U") , CmdUnassemble , CMD_UNASSEMBLE , "Disassemble instructions" },
{TEXT("BRK") , CmdBreakInvalid , CMD_BREAK_INVALID , "Enter debugger on BRK or INVALID" },
{TEXT("BRKOP") , CmdBreakOpcode , CMD_BREAK_OPCODE , "Enter debugger on opcode" },
{TEXT("CALC") , CmdCalculator , CMD_CALC , "Display mini calc result" },
{TEXT("GOTO") , CmdGo , CMD_GO , "Run [until PC = address]" },
{TEXT("I") , CmdInput , CMD_INPUT , "Input from IO $C0xx" },
@ -832,6 +838,144 @@ LPCTSTR FormatAddress( WORD nAddress, int nBytes )
// Breakpoints ____________________________________________________________________________________
//===========================================================================
Update_t CmdBreakInvalid (int nArgs) // Breakpoint IFF Full-speed!
{
if ((nArgs > 2) || (nArgs == 0))
goto _Help;
int iType = 0; // default to BRK
int nActive;
// if (nArgs == 2)
iType = g_aArgs[ 1 ].nVal1;
// Cases:
// 0. CMD // display
// 1a. CMD # // display
// 1b. CMD ON | OFF //set
// 1c. CMD ? // error
// 2a. CMD # ON | OFF // set
// 2b. CMD # ? // error
TCHAR sText[ CONSOLE_WIDTH ];
bool bValidParam = true;
int iParamArg = nArgs;
int iParam;
int nFound = FindParam( g_aArgs[ iParamArg ].sArg, MATCH_EXACT, iParam, _PARAM_GENERAL_BEGIN, _PARAM_GENERAL_END );
if (nFound)
{
if (iParam == PARAM_ON)
nActive = 1;
else
if (iParam == PARAM_OFF)
nActive = 0;
else
bValidParam = false;
}
else
bValidParam = false;
if (nArgs == 1)
{
if (! nFound) // bValidParam) // case 1a or 1c
{
if ((iType < 0) || (iType > AM_3))
goto _Help;
if (IsDebugBreakOnInvalid( iType ))
iParam = PARAM_ON;
else
iParam = PARAM_OFF;
}
else // case 1b
{
SetDebugBreakOnInvalid( iType, nActive );
}
if (iType == 0)
wsprintf( sText, TEXT("Enter debugger on BRK opcode: %s"), g_aParameters[ iParam ].m_sName );
else
wsprintf( sText, TEXT("Enter debugger on INVALID %1X opcode: %s"), iType, g_aParameters[ iParam ].m_sName );
ConsoleBufferPush( sText );
return ConsoleUpdate();
}
else
if (nArgs == 2)
{
if (! bValidParam) // case 2b
{
goto _Help;
}
else // case 2a (or not 2b ;-)
{
if ((iType < 0) || (iType > AM_3))
goto _Help;
SetDebugBreakOnInvalid( iType, nActive );
if (iType == 0)
wsprintf( sText, TEXT("Enter debugger on BRK opcode: %s"), g_aParameters[ iParam ].m_sName );
else
wsprintf( sText, TEXT("Enter debugger on INVALID %1X opcode: %s"), iType, g_aParameters[ iParam ].m_sName );
ConsoleBufferPush( sText );
return ConsoleUpdate();
}
}
return UPDATE_CONSOLE_DISPLAY;
_Help:
return HelpLastCommand();
}
//===========================================================================
Update_t CmdBreakOpcode (int nArgs) // Breakpoint IFF Full-speed!
{
TCHAR sText[ CONSOLE_WIDTH ];
if (nArgs > 1)
return HelpLastCommand();
TCHAR sAction[ CONSOLE_WIDTH ] = TEXT("Current"); // default to display
if (nArgs == 1)
{
int iOpcode = g_aArgs[ 1] .nVal1;
g_iDebugOnOpcode = iOpcode & 0xFF;
_tcscpy( sAction, TEXT("Setting") );
if (iOpcode >= NUM_OPCODES)
{
wsprintf( sText, TEXT("Warning: clamping opcode: %02X"), g_iDebugOnOpcode );
ConsoleBufferPush( sText );
return ConsoleUpdate();
}
}
if (g_iDebugOnOpcode == 0)
// Show what the current break opcode is
wsprintf( sText, TEXT("%s break on opcode: None")
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02[ g_iDebugOnOpcode ].sMnemonic
);
else
// Show what the current break opcode is
wsprintf( sText, TEXT("%s break on opcode: %02X %s")
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02[ g_iDebugOnOpcode ].sMnemonic
);
ConsoleBufferPush( sText );
return ConsoleUpdate();
}
// bool bBP = g_nBreakpoints && CheckBreakpoint(nOffset,nOffset == regs.pc);
//===========================================================================
bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ )
@ -1173,6 +1317,7 @@ Update_t CmdCalculator (int nArgs)
return ConsoleUpdate();
}
//===========================================================================
Update_t CmdFeedKey (int nArgs)
{
@ -2479,7 +2624,7 @@ void DisasmCalcTopFromCurAddress( bool bUpdateTop )
"\tLen: %04X\n"
"\tMissed: %04X"),
g_nDisasmCurAddress - nLen, nLen, g_nDisasmCurAddress );
MessageBox( framewindow, sText, "ERROR", MB_OK );
MessageBox( g_hFrameWindow, sText, "ERROR", MB_OK );
#endif
}
}
@ -4951,7 +5096,7 @@ void _CmdColorGet( const int iScheme, const int iColor )
{
TCHAR sText[ CONSOLE_WIDTH ];
wsprintf( sText, "Color: %d\nOut of range!", iColor );
MessageBox( framewindow, sText, TEXT("ERROR"), MB_OK );
MessageBox( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
}
}
@ -6705,13 +6850,13 @@ void DebugInitialize ()
if (_tcscmp( g_aCommands[ NUM_COMMANDS ].m_sName, TEXT(__COMMANDS_VERIFY_TXT__)))
{
wsprintf( sText, "*** ERROR *** Commands mis-matched!" );
MessageBox( framewindow, sText, TEXT("ERROR"), MB_OK );
MessageBox( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
}
if (_tcscmp( g_aParameters[ NUM_PARAMS ].m_sName, TEXT(__PARAMS_VERIFY_TXT__)))
{
wsprintf( sText, "*** ERROR *** Parameters mis-matched!" );
MessageBox( framewindow, sText, TEXT("ERROR"), MB_OK );
MessageBox( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
}
// Check all summary help to see if it fits within the console

View File

@ -25,6 +25,10 @@ using namespace std;
extern const TCHAR *g_aBreakpointSource [ NUM_BREAKPOINT_SOURCES ];
extern const TCHAR *g_aBreakpointSymbols[ NUM_BREAKPOINT_OPERATORS ];
// Full-Speed debugging
extern int g_nDebugOnBreakInvalid;
extern int g_iDebugOnOpcode ;
// Commands
extern const int NUM_COMMANDS_WITH_ALIASES; // = sizeof(g_aCommands) / sizeof (Command_t); // Determined at compile-time ;-)
extern int g_iCommand; // last command
@ -94,6 +98,22 @@ using namespace std;
// Breakpoints
bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ );
// 0 = Brk, 1 = Invalid1, .. 3 = Invalid 3
inline bool IsDebugBreakOnInvalid( int iOpcodeType )
{
bool bActive = (g_nDebugOnBreakInvalid >> iOpcodeType) & 1;
return bActive;
}
inline void SetDebugBreakOnInvalid( int iOpcodeType, int nValue )
{
if (iOpcodeType <= AM_3)
{
g_nDebugOnBreakInvalid &= ~ ( 1 << iOpcodeType);
g_nDebugOnBreakInvalid |= ((nValue & 1) << iOpcodeType);
}
}
// Color
inline COLORREF DebuggerGetColor( int iColor );
@ -117,7 +137,8 @@ using namespace std;
enum
{
DEBUG_EXIT_KEY = 0x1B // Escape
DEBUG_EXIT_KEY = 0x1B, // Escape
DEBUG_TOGGLE_KEY = VK_F1 + BTN_DEBUG
};
void DebugBegin ();

View File

@ -80,7 +80,7 @@
*/
enum AddressingMode_e // ADDRESSING_MODES_e
{
AM_IMPLIED
AM_IMPLIED // Note: SetDebugBreakOnInvalid() assumes this order of first 4 entries
, AM_1 // Invalid 1 Byte
, AM_2 // Invalid 2 Bytes
, AM_3 // Invalid 3 Bytes
@ -387,6 +387,8 @@
// Main / CPU
CMD_ASSEMBLE
, CMD_UNASSEMBLE
, CMD_BREAK_INVALID
, CMD_BREAK_OPCODE
, CMD_CALC
, CMD_GO
, CMD_INPUT
@ -590,20 +592,22 @@
// CPU
Update_t CmdAssemble (int nArgs);
Update_t CmdUnassemble (int nArgs); // code dump, aka, Unassemble
Update_t CmdCalculator (int nArgs);
Update_t CmdGo (int nArgs);
Update_t CmdInput (int nArgs);
Update_t CmdJSR (int nArgs);
Update_t CmdNOP (int nArgs);
Update_t CmdOutput (int nArgs);
Update_t CmdFeedKey (int nArgs);
Update_t CmdStepOut (int nArgs);
Update_t CmdStepOver (int nArgs);
Update_t CmdTrace (int nArgs); // alias for CmdStepIn
Update_t CmdTraceFile (int nArgs);
Update_t CmdTraceLine (int nArgs);
Update_t CmdAssemble (int nArgs);
Update_t CmdUnassemble (int nArgs); // code dump, aka, Unassemble
Update_t CmdBreakInvalid(int nArgs); // Breakpoint IFF Full-speed!
Update_t CmdBreakOpcode (int nArgs); // Breakpoint IFF Full-speed!
Update_t CmdCalculator (int nArgs);
Update_t CmdGo (int nArgs);
Update_t CmdInput (int nArgs);
Update_t CmdJSR (int nArgs);
Update_t CmdNOP (int nArgs);
Update_t CmdOutput (int nArgs);
Update_t CmdFeedKey (int nArgs);
Update_t CmdStepOut (int nArgs);
Update_t CmdStepOver (int nArgs);
Update_t CmdTrace (int nArgs); // alias for CmdStepIn
Update_t CmdTraceFile (int nArgs);
Update_t CmdTraceLine (int nArgs);
// Breakpoints
Update_t CmdBreakpointMenu (int nArgs);

View File

@ -400,7 +400,7 @@ void DiskNotifyInvalidImage (LPCTSTR imagefilename,int error)
// IGNORE OTHER ERRORS SILENTLY
return;
}
MessageBox(framewindow,
MessageBox(g_hFrameWindow,
buffer,
TITLE,
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
@ -476,7 +476,7 @@ void DiskSelectImage (int drive, LPSTR pszFilename)
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = framewindow;
ofn.hwndOwner = g_hFrameWindow;
ofn.hInstance = instance;
ofn.lpstrFilter = TEXT("All Images\0*.apl;*.bin;*.do;*.dsk;*.iie;*.nib;*.po\0")
TEXT("Disk Images (*.bin,*.do,*.dsk,*.iie,*.nib,*.po)\0*.bin;*.do;*.dsk;*.iie;*.nib;*.po\0")