backtrace
This commit is contained in:
parent
9d4a552daf
commit
e30cba36b1
3 changed files with 75 additions and 4 deletions
42
cpu.cpp
42
cpu.cpp
|
@ -103,6 +103,27 @@ std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(c
|
|||
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
|
||||
}
|
||||
|
||||
void cpu::add_to_stack_trace(const uint16_t p)
|
||||
{
|
||||
auto da = disassemble(p);
|
||||
|
||||
stacktrace.push_back({ p, da["instruction-text"][0] });
|
||||
|
||||
while (stacktrace.size() >= max_stacktrace_depth)
|
||||
stacktrace.erase(stacktrace.begin());
|
||||
}
|
||||
|
||||
void cpu::pop_from_stack_trace()
|
||||
{
|
||||
if (!stacktrace.empty())
|
||||
stacktrace.pop_back();
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint16_t, std::string> > cpu::get_stack_trace() const
|
||||
{
|
||||
return stacktrace;
|
||||
}
|
||||
|
||||
void cpu::reset()
|
||||
{
|
||||
memset(regs0_5, 0x00, sizeof regs0_5);
|
||||
|
@ -1591,6 +1612,8 @@ bool cpu::misc_operations(const uint16_t instr)
|
|||
return true;
|
||||
|
||||
case 0b0000000000000010: // RTI
|
||||
if (debug_mode)
|
||||
pop_from_stack_trace();
|
||||
setPC(popStack());
|
||||
setPSW(popStack(), !!getPSW_runmode());
|
||||
psw &= ~020; // disable TRAP flag
|
||||
|
@ -1605,6 +1628,8 @@ bool cpu::misc_operations(const uint16_t instr)
|
|||
return true;
|
||||
|
||||
case 0b0000000000000110: // RTT
|
||||
if (debug_mode)
|
||||
pop_from_stack_trace();
|
||||
setPC(popStack());
|
||||
setPSW(popStack(), !!getPSW_runmode());
|
||||
return true;
|
||||
|
@ -1645,6 +1670,9 @@ bool cpu::misc_operations(const uint16_t instr)
|
|||
}
|
||||
|
||||
if ((instr & 0b1111111000000000) == 0b0000100000000000) { // JSR
|
||||
if (debug_mode)
|
||||
add_to_stack_trace(instruction_start);
|
||||
|
||||
int dst_mode = (instr >> 3) & 7;
|
||||
if (dst_mode == 0) // cannot jump to a register
|
||||
return false;
|
||||
|
@ -1674,6 +1702,9 @@ bool cpu::misc_operations(const uint16_t instr)
|
|||
}
|
||||
|
||||
if ((instr & 0b1111111111111000) == 0b0000000010000000) { // RTS
|
||||
if (debug_mode)
|
||||
pop_from_stack_trace();
|
||||
|
||||
const int link_reg = instr & 7;
|
||||
|
||||
// MOVE link, PC
|
||||
|
@ -1733,6 +1764,9 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt)
|
|||
// TODO set MMR2?
|
||||
}
|
||||
|
||||
if (debug_mode)
|
||||
add_to_stack_trace(instruction_start);
|
||||
|
||||
// make sure the trap vector is retrieved from kernel space
|
||||
psw &= 037777; // mask off 14/15 to make it into kernel-space
|
||||
|
||||
|
@ -2280,12 +2314,12 @@ void cpu::step()
|
|||
instruction_count++;
|
||||
|
||||
try {
|
||||
uint16_t temp_pc = getPC();
|
||||
instruction_start = getPC();
|
||||
|
||||
if (!b->isMMR1Locked())
|
||||
b->setMMR2(temp_pc);
|
||||
b->setMMR2(instruction_start);
|
||||
|
||||
uint16_t instr = b->readWord(temp_pc);
|
||||
uint16_t instr = b->readWord(instruction_start);
|
||||
|
||||
addRegister(7, rm_cur, 2);
|
||||
|
||||
|
@ -2301,7 +2335,7 @@ void cpu::step()
|
|||
if (misc_operations(instr))
|
||||
return;
|
||||
|
||||
DOLOG(warning, true, "UNHANDLED instruction %06o @ %06o", instr, temp_pc);
|
||||
DOLOG(warning, true, "UNHANDLED instruction %06o @ %06o", instr, instruction_start);
|
||||
|
||||
trap(010); // floating point nog niet geimplementeerd
|
||||
}
|
||||
|
|
13
cpu.h
13
cpu.h
|
@ -16,6 +16,8 @@
|
|||
#include "bus.h"
|
||||
|
||||
|
||||
constexpr const int max_stacktrace_depth = 16;
|
||||
|
||||
typedef struct {
|
||||
int delta;
|
||||
unsigned reg;
|
||||
|
@ -42,6 +44,7 @@ private:
|
|||
uint16_t regs0_5[2][6]; // R0...5, selected by bit 11 in PSW,
|
||||
uint16_t sp[3 + 1]; // stackpointers, MF../MT.. select via 12/13 from PSW, others via 14/15
|
||||
uint16_t pc { 0 };
|
||||
uint16_t instruction_start { 0 };
|
||||
uint16_t psw { 0 };
|
||||
uint16_t fpsr { 0 };
|
||||
uint16_t stackLimitRegister { 0377 };
|
||||
|
@ -52,6 +55,9 @@ private:
|
|||
bool it_is_a_trap { false };
|
||||
uint64_t mtpi_count { 0 };
|
||||
|
||||
bool debug_mode { false };
|
||||
std::vector<std::pair<uint16_t, std::string> > stacktrace;
|
||||
|
||||
// level, vector
|
||||
std::map<uint8_t, std::set<uint8_t> > queued_interrupts;
|
||||
#if defined(BUILD_FOR_RP2040)
|
||||
|
@ -96,6 +102,9 @@ private:
|
|||
|
||||
operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const;
|
||||
|
||||
void add_to_stack_trace(const uint16_t p);
|
||||
void pop_from_stack_trace();
|
||||
|
||||
public:
|
||||
explicit cpu(bus *const b, std::atomic_uint32_t *const event);
|
||||
~cpu();
|
||||
|
@ -115,6 +124,10 @@ public:
|
|||
uint64_t get_wait_time() const { return wait_time; }
|
||||
std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_1s) const;
|
||||
|
||||
bool get_debug() const { return debug_mode; }
|
||||
void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); }
|
||||
std::vector<std::pair<uint16_t, std::string> > get_stack_trace() const;
|
||||
|
||||
void reset();
|
||||
|
||||
void step();
|
||||
|
|
24
debugger.cpp
24
debugger.cpp
|
@ -1005,10 +1005,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else if (cmd == "turbo") {
|
||||
turbo = !turbo;
|
||||
|
||||
if (turbo)
|
||||
c->set_debug(false);
|
||||
|
||||
cnsl->put_string_lf(format("Turbo set to %s", turbo ? "ON" : "OFF"));
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (cmd == "debug") {
|
||||
bool new_mode = !c->get_debug();
|
||||
c->set_debug(new_mode);
|
||||
|
||||
cnsl->put_string_lf(format("Debug mode set to %s", new_mode ? "ON" : "OFF"));
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (cmd == "bt") {
|
||||
if (c->get_debug() == false)
|
||||
cnsl->put_string_lf("Debug mode is disabled!");
|
||||
|
||||
auto backtrace = c->get_stack_trace();
|
||||
|
||||
for(auto & element: backtrace)
|
||||
cnsl->put_string_lf(format("%06o %s", element.first, element.second.c_str()));
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (cmd == "quit" || cmd == "q") {
|
||||
#if defined(ESP32)
|
||||
ESP.restart();
|
||||
|
@ -1030,6 +1052,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(" follows v/p (virtual/physical), all octal values, mmr0-3 are registers");
|
||||
cnsl->put_string_lf("trace/t - toggle tracing");
|
||||
cnsl->put_string_lf("turbo - toggle turbo mode (cannot be interrupted)");
|
||||
cnsl->put_string_lf("debug - enable CPU debug mode");
|
||||
cnsl->put_string_lf("bt - show backtrace - need to enable debug first");
|
||||
cnsl->put_string_lf("strace - start tracing from address - invoke without address to disable");
|
||||
cnsl->put_string_lf("trl - set trace run-level, empty for all");
|
||||
cnsl->put_string_lf("regdump - dump register contents");
|
||||
|
|
Loading…
Add table
Reference in a new issue