Debugger: Add IRQ support to LBR and new command to Break on Interrupt (#987, PR #990)

Extend LBR so that it includes the control-flow on a taken interrupt
Add a new command 'brkint <0|1>' to support Break on Interrupt

Internal: in core emulation loop, moved IRQ/NMI check to start of loop so that just the "interrupt vectoring" case can be single-stepped (instead of previously opcode + interrupt vector).

Debugger help chm: update Breakpoints section to include BRK, BRKOP and BRKINT
This commit is contained in:
TomCh
2021-10-16 16:57:00 +01:00
committed by GitHub
parent 4f8b30506d
commit 9553106f4e
10 changed files with 173 additions and 78 deletions
+37
View File
@@ -67,6 +67,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Any Speed Breakpoints
int g_nDebugBreakOnInvalid = 0; // Bit Flags of Invalid Opcode to break on: // iOpcodeType = AM_IMPLIED (BRK), AM_1, AM_2, AM_3
int g_iDebugBreakOnOpcode = 0;
bool g_bDebugBreakOnInterrupt = false;
static int g_bDebugBreakpointHit = 0; // See: BreakpointHit_t
@@ -989,6 +990,32 @@ Update_t CmdBreakOpcode (int nArgs) // Breakpoint IFF Full-speed!
}
//===========================================================================
Update_t CmdBreakOnInterrupt(int nArgs)
{
TCHAR sText[CONSOLE_WIDTH];
if (nArgs > 1)
return HelpLastCommand();
TCHAR sAction[CONSOLE_WIDTH] = TEXT("Current"); // default to display
if (nArgs == 1)
{
g_bDebugBreakOnInterrupt = g_aArgs[1].nValue ? true : false;
_tcscpy(sAction, TEXT("Setting"));
}
// Show what the current break opcode is
ConsoleBufferPushFormat(sText, TEXT("%s Break on Interrupt: %s")
, sAction
, g_bDebugBreakOnInterrupt ? "Enabled" : "Disabled"
);
return ConsoleUpdate();
}
// bool bBP = g_nBreakpoints && CheckBreakpoint(nOffset,nOffset == regs.pc);
//===========================================================================
bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ )
@@ -8249,10 +8276,18 @@ void DebugContinueStepping(const bool bCallerWillUpdateDisplay/*=false*/)
if (bDoSingleStep)
{
UpdateLBR();
const WORD oldPC = regs.pc;
SingleStep(g_bGoCmd_ReinitFlag);
g_bGoCmd_ReinitFlag = false;
if (IsInterruptInLastExecution())
{
g_LBR = oldPC;
if (g_bDebugBreakOnInterrupt)
g_bDebugBreakpointHit |= BP_HIT_INTERRUPT;
}
g_bDebugBreakpointHit |= CheckBreakpointsIO() | CheckBreakpointsReg();
}
@@ -8278,6 +8313,8 @@ void DebugContinueStepping(const bool bCallerWillUpdateDisplay/*=false*/)
sprintf_s(szStopMessage, sizeof(szStopMessage), "Read access at $%04X", g_uBreakMemoryAddress);
else if (g_bDebugBreakpointHit & BP_HIT_PC_READ_FLOATING_BUS_OR_IO_MEM)
pszStopReason = TEXT("PC reads from floating bus or I/O memory");
else if (g_bDebugBreakpointHit & BP_HIT_INTERRUPT)
sprintf_s(szStopMessage, sizeof(szStopMessage), "Interrupt occurred at $%04X", g_LBR);
else
pszStopReason = TEXT("Unknown!");