Debugger: BPMR & BPMW (PR #710)
Extended BPM to also support BPMR and BPMW Fixed BPM[R|W] 0:FFFF (ie. support a range of 0x10000)
This commit is contained in:
parent
13588165ff
commit
2f64795e2e
8 changed files with 106 additions and 30 deletions
|
@ -62,7 +62,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
Bookmark_t g_aBookmarks[ MAX_BOOKMARKS ];
|
||||
|
||||
// Breakpoints ________________________________________________________________
|
||||
|
||||
// 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;
|
||||
|
@ -72,7 +71,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
int g_nBreakpoints = 0;
|
||||
Breakpoint_t g_aBreakpoints[ MAX_BREAKPOINTS ];
|
||||
|
||||
// NOTE: Breakpoint_Source_t and g_aBreakpointSource must match!
|
||||
// NOTE: BreakpointSource_t and g_aBreakpointSource must match!
|
||||
const char *g_aBreakpointSource[ NUM_BREAKPOINT_SOURCES ] =
|
||||
{ // Used to be one char, since ArgsCook also uses // TODO/FIXME: Parser use Param[] ?
|
||||
// Used for both Input & Output!
|
||||
|
@ -95,8 +94,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
"N", // 1--- ---- Sign
|
||||
// Misc
|
||||
"OP", // Opcode/Instruction/Mnemonic
|
||||
// Memory
|
||||
"M" // Main
|
||||
"M", // Mem RW
|
||||
"M", // Mem READ_ONLY
|
||||
"M", // Mem WRITE_ONLY
|
||||
// TODO: M0 ram bank 0, M1 aux ram ?
|
||||
};
|
||||
|
||||
|
@ -1087,11 +1087,11 @@ bool _CheckBreakpointValue( Breakpoint_t *pBP, int nVal )
|
|||
bStatus = true;
|
||||
break;
|
||||
case BP_OP_EQUAL : // Range is like C++ STL: [,) (inclusive,not-inclusive)
|
||||
if ((nVal >= pBP->nAddress) && (nVal < (pBP->nAddress + pBP->nLength)))
|
||||
if ((nVal >= pBP->nAddress) && ((UINT)nVal < (pBP->nAddress + pBP->nLength)))
|
||||
bStatus = true;
|
||||
break;
|
||||
case BP_OP_NOT_EQUAL : // Rnage is: (,] (not-inclusive, inclusive)
|
||||
if ((nVal < pBP->nAddress) || (nVal >= (pBP->nAddress + pBP->nLength)))
|
||||
if ((nVal < pBP->nAddress) || ((UINT)nVal >= (pBP->nAddress + pBP->nLength)))
|
||||
bStatus = true;
|
||||
break;
|
||||
case BP_OP_GREATER_THAN :
|
||||
|
@ -1141,12 +1141,31 @@ int CheckBreakpointsIO ()
|
|||
Breakpoint_t *pBP = &g_aBreakpoints[iBreakpoint];
|
||||
if (_BreakpointValid( pBP ))
|
||||
{
|
||||
if (pBP->eSource == BP_SRC_MEM_1)
|
||||
if (pBP->eSource == BP_SRC_MEM_RW || pBP->eSource == BP_SRC_MEM_READ_ONLY || pBP->eSource == BP_SRC_MEM_WRITE_ONLY)
|
||||
{
|
||||
if (_CheckBreakpointValue( pBP, nAddress ))
|
||||
{
|
||||
g_uBreakMemoryAddress = (WORD) nAddress;
|
||||
return BP_HIT_MEM;
|
||||
BYTE opcode = mem[regs.pc];
|
||||
|
||||
if (pBP->eSource == BP_SRC_MEM_RW)
|
||||
{
|
||||
return BP_HIT_MEM;
|
||||
}
|
||||
else if (pBP->eSource == BP_SRC_MEM_READ_ONLY)
|
||||
{
|
||||
if (g_aOpcodes[opcode].nMemoryAccess & (MEM_RI|MEM_R))
|
||||
return BP_HIT_MEMR;
|
||||
}
|
||||
else if (pBP->eSource == BP_SRC_MEM_WRITE_ONLY)
|
||||
{
|
||||
if (g_aOpcodes[opcode].nMemoryAccess & (MEM_WI|MEM_W))
|
||||
return BP_HIT_MEMW;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1335,6 +1354,9 @@ bool _CmdBreakpointAddReg( Breakpoint_t *pBP, BreakpointSource_t iSrc, Breakpoin
|
|||
|
||||
if (pBP)
|
||||
{
|
||||
_ASSERT(nLen <= _6502_MEM_LEN);
|
||||
if (nLen > _6502_MEM_LEN) nLen = _6502_MEM_LEN;
|
||||
|
||||
pBP->eSource = iSrc;
|
||||
pBP->eOperator = iCmp;
|
||||
pBP->nAddress = nAddress;
|
||||
|
@ -1470,12 +1492,26 @@ Update_t CmdBreakpointAddIO (int nArgs)
|
|||
// return UPDATE_BREAKPOINTS | UPDATE_CONSOLE_DISPLAY;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdBreakpointAddMem (int nArgs)
|
||||
Update_t CmdBreakpointAddMemA(int nArgs)
|
||||
{
|
||||
BreakpointSource_t iSrc = BP_SRC_MEM_1;
|
||||
BreakpointOperator_t iCmp = BP_OP_EQUAL ;
|
||||
return CmdBreakpointAddMem(nArgs);
|
||||
}
|
||||
//===========================================================================
|
||||
Update_t CmdBreakpointAddMemR(int nArgs)
|
||||
{
|
||||
return CmdBreakpointAddMem(nArgs, BP_SRC_MEM_READ_ONLY);
|
||||
}
|
||||
//===========================================================================
|
||||
Update_t CmdBreakpointAddMemW(int nArgs)
|
||||
{
|
||||
return CmdBreakpointAddMem(nArgs, BP_SRC_MEM_WRITE_ONLY);
|
||||
}
|
||||
//===========================================================================
|
||||
Update_t CmdBreakpointAddMem (int nArgs, BreakpointSource_t bpSrc /*= BP_SRC_MEM_RW*/)
|
||||
{
|
||||
BreakpointSource_t iSrc = bpSrc;
|
||||
BreakpointOperator_t iCmp = BP_OP_EQUAL;
|
||||
|
||||
int iArg = 0;
|
||||
|
||||
|
@ -1647,11 +1683,16 @@ void _BWZ_List( const Breakpoint_t * aBreakWatchZero, const int iBWZ ) //, bool
|
|||
pSymbol = sName;
|
||||
}
|
||||
|
||||
ConsoleBufferPushFormat( sText, " #%d %c %04X %s",
|
||||
char cBPM = aBreakWatchZero[iBWZ].eSource == BP_SRC_MEM_READ_ONLY ? 'R'
|
||||
: aBreakWatchZero[iBWZ].eSource == BP_SRC_MEM_WRITE_ONLY ? 'W'
|
||||
: ' ';
|
||||
|
||||
ConsoleBufferPushFormat( sText, " #%d %c %04X %c %s",
|
||||
// (bZeroBased ? iBWZ + 1 : iBWZ),
|
||||
iBWZ,
|
||||
sFlags[ (int) aBreakWatchZero[ iBWZ ].bEnabled ],
|
||||
aBreakWatchZero[ iBWZ ].nAddress,
|
||||
cBPM,
|
||||
pSymbol
|
||||
);
|
||||
}
|
||||
|
@ -8657,7 +8698,11 @@ void DebugContinueStepping ()
|
|||
else if (g_bDebugBreakpointHit & BP_HIT_REG)
|
||||
pszStopReason = TEXT("Register matches value");
|
||||
else if (g_bDebugBreakpointHit & BP_HIT_MEM)
|
||||
sprintf_s(szStopMessage, sizeof(szStopMessage), "Memory accessed at $%04X", g_uBreakMemoryAddress);
|
||||
sprintf_s(szStopMessage, sizeof(szStopMessage), "Memory access at $%04X", g_uBreakMemoryAddress);
|
||||
else if (g_bDebugBreakpointHit & BP_HIT_MEMW)
|
||||
sprintf_s(szStopMessage, sizeof(szStopMessage), "Write access at $%04X", g_uBreakMemoryAddress);
|
||||
else if (g_bDebugBreakpointHit & BP_HIT_MEMR)
|
||||
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
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
// Breakpoints
|
||||
enum BreakpointHit_t
|
||||
{
|
||||
BP_HIT_NONE = 0
|
||||
,BP_HIT_INVALID = (1 << 0)
|
||||
,BP_HIT_OPCODE = (1 << 1)
|
||||
,BP_HIT_REG = (1 << 2)
|
||||
,BP_HIT_MEM = (1 << 3)
|
||||
,BP_HIT_PC_READ_FLOATING_BUS_OR_IO_MEM = (1 << 4)
|
||||
BP_HIT_NONE = 0
|
||||
, BP_HIT_INVALID = (1 << 0)
|
||||
, BP_HIT_OPCODE = (1 << 1)
|
||||
, BP_HIT_REG = (1 << 2)
|
||||
, BP_HIT_MEM = (1 << 3)
|
||||
, BP_HIT_MEMR = (1 << 4)
|
||||
, BP_HIT_MEMW = (1 << 5)
|
||||
, BP_HIT_PC_READ_FLOATING_BUS_OR_IO_MEM = (1 << 6)
|
||||
};
|
||||
|
||||
extern int g_nBreakpoints;
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
const unsigned int _6502_BRK_VECTOR = 0xFFFE;
|
||||
const unsigned int _6502_MEM_BEGIN = 0x0000;
|
||||
const unsigned int _6502_MEM_END = 0xFFFF;
|
||||
const unsigned int _6502_MEM_LEN = _6502_MEM_END + 1;
|
||||
|
|
|
@ -112,7 +112,7 @@ const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ] =
|
|||
{"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"DEC", 0 , 0}, {"nop", 0 , 0 }, // 38 .. 3B
|
||||
{"BIT", AM_AX , R_}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"nop", 0 , 0 }, // 3C .. 3F
|
||||
|
||||
{"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 40 .. 43
|
||||
{"RTI", 0 , SR}, {"EOR", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 40 .. 43
|
||||
{"nop", AM_Z , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , _W}, {"nop", 0 , 0 }, // 44 .. 47
|
||||
{"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"nop", 0 , 0 }, // 48 .. 4B
|
||||
{"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , _W}, {"nop", 0 , 0 }, // 4C .. 4F
|
||||
|
@ -234,7 +234,7 @@ Fx BEQ r SBC (d),Y sbc (z) --- --- SBC d,X INC z,X --- SED SBC a,Y
|
|||
{"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"nop", 0 , 0}, {"rla", AM_AY , RW}, // 38 .. 3B
|
||||
{"nop", AM_AX , 0}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"rla", AM_AX , RW}, // 3C .. 3F
|
||||
|
||||
{"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"hlt", 0 , 0}, {"lse", AM_IZX, RW}, // 40 .. 43
|
||||
{"RTI", 0 , SR}, {"EOR", AM_IZX, R_}, {"hlt", 0 , 0}, {"lse", AM_IZX, RW}, // 40 .. 43
|
||||
{"nop", AM_Z , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , RW}, {"lse", AM_Z , RW}, // 44 .. 47
|
||||
{"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"alr", AM_M , im}, // 48 .. 4B
|
||||
{"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , RW}, {"lse", AM_A , RW}, // 4C .. 4F
|
||||
|
|
|
@ -85,7 +85,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
{TEXT("BPR") , CmdBreakpointAddReg , CMD_BREAKPOINT_ADD_REG , "Add breakpoint on register value" }, // NOTE! Different from SoftICE !!!!
|
||||
{TEXT("BPX") , CmdBreakpointAddPC , CMD_BREAKPOINT_ADD_PC , "Add breakpoint at current instruction" },
|
||||
{TEXT("BPIO") , CmdBreakpointAddIO , CMD_BREAKPOINT_ADD_IO , "Add breakpoint for IO address $C0xx" },
|
||||
{TEXT("BPM") , CmdBreakpointAddMem , CMD_BREAKPOINT_ADD_MEM , "Add breakpoint on memory access" }, // SoftICE
|
||||
{TEXT("BPM") , CmdBreakpointAddMemA , CMD_BREAKPOINT_ADD_MEM , "Add breakpoint on memory access" }, // SoftICE
|
||||
{TEXT("BPMR") , CmdBreakpointAddMemR , CMD_BREAKPOINT_ADD_MEMR , "Add breakpoint on memory read access" },
|
||||
{TEXT("BPMW") , CmdBreakpointAddMemW , CMD_BREAKPOINT_ADD_MEMW , "Add breakpoint on memory write access" },
|
||||
|
||||
{TEXT("BPC") , CmdBreakpointClear , CMD_BREAKPOINT_CLEAR , "Clear (remove) breakpoint" }, // SoftICE
|
||||
{TEXT("BPD") , CmdBreakpointDisable , CMD_BREAKPOINT_DISABLE , "Disable breakpoint- it is still in the list, just not active" }, // SoftICE
|
||||
|
|
|
@ -1078,7 +1078,7 @@ void DrawBreakpoints ( int line )
|
|||
for (iBreakpoint = 0; iBreakpoint < MAX_BREAKPOINTS; iBreakpoint++ )
|
||||
{
|
||||
Breakpoint_t *pBP = &g_aBreakpoints[iBreakpoint];
|
||||
WORD nLength = pBP->nLength;
|
||||
UINT nLength = pBP->nLength;
|
||||
|
||||
#if DEBUG_FORCE_DISPLAY
|
||||
nLength = 2;
|
||||
|
@ -1179,6 +1179,14 @@ void DrawBreakpoints ( int line )
|
|||
sprintf( sText, "%04X", nAddress1 );
|
||||
PrintTextCursorX( sText, rect2 );
|
||||
|
||||
if (nLength == 1)
|
||||
{
|
||||
if (pBP->eSource == BP_SRC_MEM_READ_ONLY)
|
||||
PrintTextCursorX("R", rect2);
|
||||
else if (pBP->eSource == BP_SRC_MEM_WRITE_ONLY)
|
||||
PrintTextCursorX("W", rect2);
|
||||
}
|
||||
|
||||
if (nLength > 1)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ) );
|
||||
|
@ -1211,6 +1219,11 @@ void DrawBreakpoints ( int line )
|
|||
#endif
|
||||
sprintf( sText, "%04X", nAddress2 );
|
||||
PrintTextCursorX( sText, rect2 );
|
||||
|
||||
if (pBP->eSource == BP_SRC_MEM_READ_ONLY)
|
||||
PrintTextCursorX("R", rect2);
|
||||
else if (pBP->eSource == BP_SRC_MEM_WRITE_ONLY)
|
||||
PrintTextCursorX("W", rect2);
|
||||
}
|
||||
|
||||
#if !USE_APPLE_FONT
|
||||
|
|
|
@ -1058,6 +1058,12 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
break;
|
||||
case CMD_BREAKPOINT_LIST:
|
||||
break;
|
||||
case CMD_BREAKPOINT_ADD_MEM:
|
||||
case CMD_BREAKPOINT_ADD_MEMR:
|
||||
case CMD_BREAKPOINT_ADD_MEMW:
|
||||
ConsoleColorizePrint(sText, " Usage: <range>");
|
||||
Help_Range();
|
||||
break;
|
||||
// Config - Load / Save
|
||||
case CMD_CONFIG_LOAD:
|
||||
ConsoleColorizePrint( sText, " Usage: [\"filename\"]" );
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
- ? no, not listed
|
||||
*/
|
||||
// NOTE: Order must match _PARAM_REGS_*
|
||||
// NOTE: Order must match Breakpoint_Source_t
|
||||
// NOTE: Order must match BreakpointSource_t
|
||||
// NOTE: Order must match g_aBreakpointSource
|
||||
enum BreakpointSource_t
|
||||
{
|
||||
|
@ -175,7 +175,9 @@
|
|||
BP_SRC_FLAG_N, // Sign
|
||||
|
||||
BP_SRC_OPCODE,
|
||||
BP_SRC_MEM_1 ,
|
||||
BP_SRC_MEM_RW,
|
||||
BP_SRC_MEM_READ_ONLY,
|
||||
BP_SRC_MEM_WRITE_ONLY,
|
||||
|
||||
NUM_BREAKPOINT_SOURCES
|
||||
};
|
||||
|
@ -201,7 +203,7 @@
|
|||
struct Breakpoint_t
|
||||
{
|
||||
WORD nAddress; // for registers, functions as nValue
|
||||
WORD nLength ;
|
||||
UINT nLength ;
|
||||
BreakpointSource_t eSource;
|
||||
BreakpointOperator_t eOperator;
|
||||
bool bSet ; // used to be called enabled pre 2.0
|
||||
|
@ -323,6 +325,8 @@
|
|||
// , CMD_BREAKPOINT_EXEC = CMD_BREAKPOINT_ADD_ADDR // alias
|
||||
, CMD_BREAKPOINT_ADD_IO // break on: [$C000-$C7FF] Load/Store
|
||||
, CMD_BREAKPOINT_ADD_MEM // break on: [$0000-$FFFF], excluding IO
|
||||
, CMD_BREAKPOINT_ADD_MEMR // break on read on: [$0000-$FFFF], excluding IO
|
||||
, CMD_BREAKPOINT_ADD_MEMW // break on write on: [$0000-$FFFF], excluding IO
|
||||
|
||||
, CMD_BREAKPOINT_CLEAR
|
||||
// , CMD_BREAKPOINT_REMOVE = CMD_BREAKPOINT_CLEAR // alias
|
||||
|
@ -613,7 +617,10 @@
|
|||
Update_t CmdBreakpointAddReg (int nArgs);
|
||||
Update_t CmdBreakpointAddPC (int nArgs);
|
||||
Update_t CmdBreakpointAddIO (int nArgs);
|
||||
Update_t CmdBreakpointAddMem (int nArgs);
|
||||
Update_t CmdBreakpointAddMem (int nArgs, BreakpointSource_t bpSrc = BP_SRC_MEM_RW);
|
||||
Update_t CmdBreakpointAddMemA (int nArgs);
|
||||
Update_t CmdBreakpointAddMemR (int nArgs);
|
||||
Update_t CmdBreakpointAddMemW (int nArgs);
|
||||
Update_t CmdBreakpointClear (int nArgs);
|
||||
Update_t CmdBreakpointDisable (int nArgs);
|
||||
Update_t CmdBreakpointEdit (int nArgs);
|
||||
|
@ -1117,7 +1124,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
|||
extern const unsigned int _6502_BRK_VECTOR ;//= 0xFFFE;
|
||||
extern const unsigned int _6502_MEM_BEGIN ;//= 0x0000;
|
||||
extern const unsigned int _6502_MEM_END ;//= 0xFFFF;
|
||||
|
||||
extern const unsigned int _6502_MEM_LEN ;//= 0x10000;
|
||||
|
||||
enum DEVICE_e
|
||||
{
|
||||
|
@ -1301,7 +1308,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
|||
|
||||
// , PARAM_SIZE // TODO: used by FONT SIZE
|
||||
|
||||
// Note: Order must match Breakpoint_Source_t
|
||||
// Note: Order must match BreakpointSource_t
|
||||
, _PARAM_REGS_BEGIN = _PARAM_BREAKPOINT_END // Daisy Chain
|
||||
// Regs
|
||||
, PARAM_REG_A = _PARAM_REGS_BEGIN
|
||||
|
|
Loading…
Add table
Reference in a new issue