Debugger: BPM cmd: trigger on stack access for BRK,JSR,PLn,PHn,RTI,RTS (#445)

This commit is contained in:
tomcw 2017-08-04 20:52:17 +01:00
parent f1b4dea990
commit c35b863bd9
6 changed files with 81 additions and 13 deletions

View File

@ -115,6 +115,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"* ", // Read/Write
};
static WORD g_uBreakMemoryAddress = 0;
// Commands _______________________________________________________________________________________
@ -1113,10 +1114,11 @@ bool _CheckBreakpointValue( Breakpoint_t *pBP, int nVal )
//===========================================================================
int CheckBreakpointsIO ()
{
const int NUM_TARGETS = 2;
const int NUM_TARGETS = 3;
int aTarget[ NUM_TARGETS ] =
{
NO_6502_TARGET,
NO_6502_TARGET,
NO_6502_TARGET
};
@ -1126,7 +1128,7 @@ int CheckBreakpointsIO ()
int iTarget;
int nAddress;
_6502_GetTargets( regs.pc, &aTarget[0], &aTarget[1], &nBytes );
_6502_GetTargets( regs.pc, &aTarget[0], &aTarget[1], &aTarget[2], &nBytes, false );
if (nBytes)
{
@ -1144,6 +1146,7 @@ int CheckBreakpointsIO ()
{
if (_CheckBreakpointValue( pBP, nAddress ))
{
g_uBreakMemoryAddress = (WORD) nAddress;
return BP_HIT_MEM;
}
}
@ -8561,7 +8564,8 @@ void DebugContinueStepping ()
if (regs.pc == g_nDebugStepUntil || g_bDebugBreakpointHit)
{
TCHAR sText[ CONSOLE_WIDTH ];
char* pszStopReason = NULL;
char szStopMessage[CONSOLE_WIDTH];
char* pszStopReason = szStopMessage;
if (regs.pc == g_nDebugStepUntil)
pszStopReason = TEXT("PC matches 'Go until' address");
@ -8572,7 +8576,7 @@ void DebugContinueStepping ()
else if (g_bDebugBreakpointHit & BP_HIT_REG)
pszStopReason = TEXT("Register matches value");
else if (g_bDebugBreakpointHit & BP_HIT_MEM)
pszStopReason = TEXT("Memory accessed");
sprintf_s(szStopMessage, sizeof(szStopMessage), "Memory accessed 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

View File

@ -3,8 +3,10 @@
const int _6502_BRANCH_POS = +127;
const int _6502_BRANCH_NEG = -128;
const unsigned int _6502_ZEROPAGE_END = 0x00FF;
const unsigned int _6502_STACK_BEGIN = 0x0100;
const unsigned int _6502_STACK_END = 0x01FF;
const unsigned int _6502_IO_BEGIN = 0xC000;
const unsigned int _6502_IO_END = 0xC0FF;
const unsigned int _6502_BRK_VECTOR = 0xFFFE;
const unsigned int _6502_MEM_BEGIN = 0x0000;
const unsigned int _6502_MEM_END = 0xFFFF;

View File

@ -94,7 +94,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define SR MEM_S | MEM_RI
const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ] =
{
{"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 00 .. 03
{"BRK", 0 , SW}, {"ORA", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 00 .. 03
{"TSB", AM_Z , _W}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"nop", 0 , 0 }, // 04 .. 07
{"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"nop", 0 , 0 }, // 08 .. 0B
{"TSB", AM_A , _W}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"nop", 0 , 0 }, // 0C .. 0F
@ -154,7 +154,7 @@ const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ] =
{"CPY", AM_A , R_}, {"CMP", AM_A , R_}, {"DEC", AM_A , RW}, {"nop", 0 , 0 }, // CC .. CF
{"BNE", AM_R , 0}, {"CMP", AM_NZY, R_}, {"CMP", AM_NZ , 0}, {"nop", 0 , 0 }, // D0 .. D3
{"nop", AM_ZX , 0}, {"CMP", AM_ZX , R_}, {"DEC", AM_ZX , RW}, {"nop", 0 , 0 }, // D4 .. D7
{"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"PHX", 0 , 0}, {"nop", 0 , 0 }, // D8 .. DB
{"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"PHX", 0 , SW}, {"nop", 0 , 0 }, // D8 .. DB
{"nop", AM_AX , 0}, {"CMP", AM_AX , R_}, {"DEC", AM_AX , RW}, {"nop", 0 , 0 }, // DC .. DF
{"CPX", AM_M , im}, {"SBC", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // E0 .. E3
@ -163,7 +163,7 @@ const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ] =
{"CPX", AM_A , R_}, {"SBC", AM_A , R_}, {"INC", AM_A , RW}, {"nop", 0 , 0 }, // EC .. EF
{"BEQ", AM_R , 0}, {"SBC", AM_NZY, R_}, {"SBC", AM_NZ , 0}, {"nop", 0 , 0 }, // F0 .. F3
{"nop", AM_ZX , 0}, {"SBC", AM_ZX , R_}, {"INC", AM_ZX , RW}, {"nop", 0 , 0 }, // F4 .. F7
{"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"PLX", 0 , 0}, {"nop", 0 , 0 }, // F8 .. FB
{"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"PLX", 0 , SR}, {"nop", 0 , 0 }, // F8 .. FB
{"nop", AM_AX , 0}, {"SBC", AM_AX , R_}, {"INC", AM_AX , RW}, {"nop", 0 , 0 } // FF .. FF
};
@ -216,7 +216,7 @@ Fx BEQ r SBC (d),Y sbc (z) --- --- SBC d,X INC z,X --- SED SBC a,Y
(d),Y
*/
{"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"hlt", 0 , 0 }, {"aso", AM_IZX, RW}, // 00 .. 03
{"BRK", 0 , SW}, {"ORA", AM_IZX, R_}, {"hlt", 0 , 0 }, {"aso", AM_IZX, RW}, // 00 .. 03
{"nop", AM_Z , R_}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"aso", AM_Z , RW}, // 04 .. 07
{"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"anc", AM_M , im}, // 08 .. 0B
{"nop", AM_AX , 0}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"aso", AM_A , RW}, // 0C .. 0F
@ -583,13 +583,16 @@ bool _6502_GetStackReturnAddress ( WORD & nAddress_ )
//===========================================================================
bool _6502_GetTargets ( WORD nAddress, int *pTargetPartial_, int *pTargetPointer_, int * pTargetBytes_, bool bIgnoreJSRJMP, bool bIgnoreBranch )
bool _6502_GetTargets ( WORD nAddress, int *pTargetPartial_, int *pTargetPartial2_, int *pTargetPointer_, int * pTargetBytes_, bool bIgnoreJSRJMP, bool bIgnoreBranch )
{
bool bStatus = false;
if (! pTargetPartial_)
return bStatus;
if (! pTargetPartial2_)
return bStatus;
if (! pTargetPointer_)
return bStatus;
@ -597,6 +600,7 @@ bool _6502_GetTargets ( WORD nAddress, int *pTargetPartial_, int *pTargetPointer
// return bStatus;
*pTargetPartial_ = NO_6502_TARGET;
*pTargetPartial2_ = NO_6502_TARGET;
*pTargetPointer_ = NO_6502_TARGET;
if (pTargetBytes_)
@ -615,7 +619,57 @@ bool _6502_GetTargets ( WORD nAddress, int *pTargetPartial_, int *pTargetPointer
switch (eMode)
{
case AM_IMPLIED:
if (g_aOpcodes[ nOpcode ].nMemoryAccess & MEM_S) // Stack R/W?
{
if (nOpcode == OPCODE_RTI || nOpcode == OPCODE_RTS) // RTI or RTS?
{
WORD sp = regs.sp;
if (nOpcode == OPCODE_RTI)
{
//*pTargetPartial3_ = _6502_STACK_BEGIN + ((sp+1) & 0xFF); // TODO: PLP
++sp;
}
*pTargetPartial_ = _6502_STACK_BEGIN + ((sp+1) & 0xFF);
*pTargetPartial2_ = _6502_STACK_BEGIN + ((sp+2) & 0xFF);
nTarget16 = mem[*pTargetPartial_] + (mem[*pTargetPartial2_]<<8);
if (nOpcode == OPCODE_RTS)
++nTarget16;
}
else if (nOpcode == OPCODE_BRK) // BRK?
{
*pTargetPartial_ = _6502_STACK_BEGIN + ((regs.sp+0) & 0xFF);
*pTargetPartial2_ = _6502_STACK_BEGIN + ((regs.sp-1) & 0xFF);
//*pTargetPartial3_ = _6502_STACK_BEGIN + ((regs.sp-2) & 0xFF); // TODO: PHP
//*pTargetPartial4_ = _6502_BRK_VECTOR + 0; // TODO
//*pTargetPartial5_ = _6502_BRK_VECTOR + 1; // TODO
nTarget16 = *(LPWORD)(mem + _6502_BRK_VECTOR);
}
else // PHn/PLn
{
if (g_aOpcodes[ nOpcode ].nMemoryAccess & MEM_WI)
nTarget16 = _6502_STACK_BEGIN + ((regs.sp+0) & 0xFF);
else
nTarget16 = _6502_STACK_BEGIN + ((regs.sp+1) & 0xFF);
}
*pTargetPointer_ = nTarget16;
if (pTargetBytes_)
*pTargetBytes_ = 1;
}
break;
case AM_A: // $Absolute
if (nOpcode == OPCODE_JSR) // JSR?
{
*pTargetPartial_ = _6502_STACK_BEGIN + ((regs.sp+0) & 0xFF);
*pTargetPartial2_ = _6502_STACK_BEGIN + ((regs.sp-1) & 0xFF);
}
*pTargetPointer_ = nTarget16;
if (pTargetBytes_)
*pTargetBytes_ = 2;

View File

@ -193,7 +193,7 @@ extern int g_aAssemblerFirstDirective[ NUM_ASSEMBLERS ];
int _6502_GetOpmodeOpbyte( const int iAddress, int & iOpmode_, int & nOpbytes_, const DisasmData_t** pData = NULL );
void _6502_GetOpcodeOpmodeOpbyte( int & iOpcode_, int & iOpmode_, int & nOpbytes_ );
bool _6502_GetStackReturnAddress( WORD & nAddress_ );
bool _6502_GetTargets( WORD nAddress, int *pTargetPartial_, int *pTargetPointer_, int * pBytes_
bool _6502_GetTargets( WORD nAddress, int *pTargetPartial_, int *pTargetPartial2_, int *pTargetPointer_, int * pBytes_
, const bool bIgnoreJSRJMP = true, bool bIgnoreBranch = true );
bool _6502_GetTargetAddress( const WORD & nAddress, WORD & nTarget_ );
bool _6502_IsOpcodeBranch( int nOpcode );

View File

@ -1506,10 +1506,11 @@ int GetDisassemblyLine ( WORD nBaseAddress, DisasmLine_t & line_ )
// Indirect / Indexed
int nTargetPartial;
int nTargetPartial2;
int nTargetPointer;
WORD nTargetValue = 0; // de-ref
int nTargetBytes;
_6502_GetTargets( nBaseAddress, &nTargetPartial, &nTargetPointer, &nTargetBytes );
_6502_GetTargets( nBaseAddress, &nTargetPartial, &nTargetPartial2, &nTargetPointer, &nTargetBytes );
if (nTargetPointer != NO_6502_TARGET)
{
@ -3192,8 +3193,10 @@ void DrawTargets ( int line)
if (! ((g_iWindowThis == WINDOW_CODE) || ((g_iWindowThis == WINDOW_DATA))))
return;
int aTarget[2];
_6502_GetTargets( regs.pc, &aTarget[0],&aTarget[1], NULL );
int aTarget[3];
_6502_GetTargets( regs.pc, &aTarget[0],&aTarget[1],&aTarget[2], NULL );
aTarget[1] = aTarget[2]; // Move down as we only have 2 lines
RECT rect;
int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg;

View File

@ -1049,8 +1049,11 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
{
OPCODE_BRA = 0x80,
OPCODE_BRK = 0x00,
OPCODE_JSR = 0x20,
OPCODE_RTI = 0x40,
OPCODE_JMP_A = 0x4C, // Absolute
OPCODE_RTS = 0x60,
OPCODE_JMP_NA = 0x6C, // Indirect Absolute
OPCODE_JMP_IAX = 0x7C, // Indexed (Absolute Indirect, X)
@ -1101,9 +1104,11 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
extern const int _6502_BRANCH_POS ;//= +127
extern const int _6502_BRANCH_NEG ;//= -128
extern const unsigned int _6502_ZEROPAGE_END ;//= 0x00FF;
extern const unsigned int _6502_STACK_BEGIN ;//= 0x0100;
extern const unsigned int _6502_STACK_END ;//= 0x01FF;
extern const unsigned int _6502_IO_BEGIN ;//= 0xC000;
extern const unsigned int _6502_IO_END ;//= 0xC0FF;
extern const unsigned int _6502_BRK_VECTOR ;//= 0xFFFE;
extern const unsigned int _6502_MEM_BEGIN ;//= 0x0000;
extern const unsigned int _6502_MEM_END ;//= 0xFFFF;