3#include "absl/strings/str_format.h"
134 uint8_t opcode)
const {
138 uint32_t bank = pc & 0xFF0000;
145 return bank | ((pc + size) & 0xFFFF);
150 uint8_t opcode)
const {
154 uint32_t bank = pc & 0xFF0000;
187 call_stack_.emplace_back(pc, target, return_addr, is_long);
202 result.
message =
"Step controller not properly configured";
206 uint32_t pc_before =
get_pc_();
210 std::optional<CallStackEntry> call_made;
215 call_made =
CallStackEntry(pc_before, target, return_addr, is_long);
220 std::optional<CallStackEntry> return_made;
233 result.
call = call_made;
234 result.
ret = return_made;
238 absl::StrFormat(
"Called $%06X from $%06X", call_made->target_address,
239 call_made->call_address);
240 }
else if (return_made) {
241 result.
message = absl::StrFormat(
"Returned to $%06X", pc_after);
243 result.
message = absl::StrFormat(
"Stepped to $%06X", pc_after);
255 result.
message =
"Step controller not properly configured";
274 result.
call = step_result.call;
276 if (!step_result.success) {
288 result.
message = absl::StrFormat(
289 "Stepped over subroutine, returned to $%06X after %u instructions",
306 call_stack_.emplace_back(pc, target, ret, is_long);
315 result.
message = absl::StrFormat(
"Step over timed out after %u instructions",
326 result.
message =
"Step controller not properly configured";
331 result.
message =
"Cannot step out - call stack is empty";
352 call_stack_.emplace_back(pc, target, ret, is_long);
356 result.
ret = returned;
363 absl::StrFormat(
"Stepped out to $%06X after %u instructions",
373 result.
message = absl::StrFormat(
"Step out timed out after %u instructions",
void ProcessInstruction(uint32_t pc)
StepResult StepInto()
Step a single instruction and update call stack.
uint32_t CalculateCallTarget(uint32_t pc, uint8_t opcode) const
uint32_t CalculateReturnAddress(uint32_t pc, uint8_t opcode) const
StepResult StepOver(uint32_t max_instructions=1000000)
Step over the current instruction.
static bool IsReturnInstruction(uint8_t opcode)
Check if an opcode is a return instruction (RTS/RTL/RTI)
static bool IsCallInstruction(uint8_t opcode)
Check if an opcode is a call instruction (JSR/JSL)
static bool IsBranchInstruction(uint8_t opcode)
Check if an opcode is a branch instruction.
static uint8_t GetInstructionSize(uint8_t opcode, bool m_flag, bool x_flag)
Get instruction size for step over calculations.
std::vector< CallStackEntry > call_stack_
StepResult StepOut(uint32_t max_instructions=1000000)
Step out of the current subroutine.
constexpr uint8_t JMP_IND
constexpr uint8_t JMP_LONG
constexpr uint8_t JMP_IND_L
constexpr uint8_t JMP_ABS
constexpr uint8_t JMP_ABS_X
Tracks call stack for intelligent stepping.
Result of a step operation.
std::optional< CallStackEntry > call
uint32_t instructions_executed
std::optional< CallStackEntry > ret