This commit is contained in:
parent
7e976f0a78
commit
517db4657a
3 changed files with 711 additions and 674 deletions
225
debugger.cpp
225
debugger.cpp
|
@ -1,6 +1,7 @@
|
|||
// (C) 2018-2024 by Folkert van Heusden
|
||||
// (C) 2018-2025 by Folkert van Heusden
|
||||
// Released under MIT license
|
||||
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include "gen.h"
|
||||
#if IS_POSIX || defined(_WIN32)
|
||||
|
@ -726,46 +727,38 @@ void set_kw11_l_interrupt_freq(console *const cnsl, bus *const b, const int freq
|
|||
cnsl->put_string_lf("Frequency out of range");
|
||||
}
|
||||
|
||||
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event)
|
||||
{
|
||||
int32_t trace_start_addr = -1;
|
||||
int n_single_step = 1;
|
||||
bool turbo = false;
|
||||
bool marker = false;
|
||||
struct debugger_state {
|
||||
int32_t trace_start_addr { -1 };
|
||||
int n_single_step { 1 };
|
||||
bool turbo { false };
|
||||
bool marker { false };
|
||||
std::optional<int> t_rl; // trace runlevel
|
||||
bool single_step { false };
|
||||
};
|
||||
|
||||
bool debugger_do(debugger_state *const state, console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const std::string & cmd)
|
||||
{
|
||||
cpu *const c = b->getCpu();
|
||||
|
||||
b->set_debug_mode();
|
||||
|
||||
bool single_step = false;
|
||||
|
||||
while(*stop_event != EVENT_TERMINATE) {
|
||||
try {
|
||||
if (marker)
|
||||
cnsl->put_string_lf("---");
|
||||
|
||||
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
|
||||
auto parts = split(cmd, " ");
|
||||
auto kv = split(parts, "=");
|
||||
|
||||
if (parts.empty())
|
||||
continue;
|
||||
return true;
|
||||
|
||||
if (cmd == "go") {
|
||||
single_step = false;
|
||||
state->single_step = false;
|
||||
|
||||
*stop_event = EVENT_NONE;
|
||||
}
|
||||
else if (cmd == "marker")
|
||||
marker = !marker;
|
||||
state->marker = !state->marker;
|
||||
else if (parts[0] == "single" || parts[0] == "s" || parts[0] == "step") {
|
||||
single_step = true;
|
||||
state->single_step = true;
|
||||
|
||||
if (parts.size() == 2)
|
||||
n_single_step = std::stoi(parts[1]);
|
||||
state->n_single_step = std::stoi(parts[1]);
|
||||
else
|
||||
n_single_step = 1;
|
||||
state->n_single_step = 1;
|
||||
|
||||
*stop_event = EVENT_NONE;
|
||||
}
|
||||
|
@ -794,7 +787,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("Breakpoint not found");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "lbp") {
|
||||
auto bps = c->list_breakpoints();
|
||||
|
@ -807,9 +800,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
if (bps.empty())
|
||||
cnsl->put_string_lf("(none)");
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "disassemble" || parts[0] == "d") {
|
||||
else if (parts[0] == "disassemble" || parts[0] == "dis") {
|
||||
uint16_t pc = kv.find("pc") != kv.end() ? std::stoi(kv.find("pc")->second, nullptr, 8) : c->getPC();
|
||||
int n = kv.find("n") != kv.end() ? std::stoi(kv.find("n") ->second, nullptr, 10) : 1;
|
||||
|
||||
|
@ -823,7 +816,16 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
show_registers = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "D" && parts.size() == 3) { // SIMH compatibility
|
||||
uint16_t v = std::stoi(parts.at(2), nullptr, 8);
|
||||
if (parts[1] == "PC")
|
||||
c->setPC(v);
|
||||
else {
|
||||
uint16_t a = std::stoi(parts.at(1), nullptr, 8);
|
||||
c->getBus()->write_word(a, v);
|
||||
}
|
||||
}
|
||||
else if (parts[0] == "setpc") {
|
||||
if (parts.size() == 2) {
|
||||
|
@ -836,12 +838,12 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("setpc requires an (octal address as) parameter");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "getpc") {
|
||||
cnsl->put_string_lf(format("PC = %06o", c->getPC()));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setreg") {
|
||||
if (parts.size() == 3) {
|
||||
|
@ -855,7 +857,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("setreg requires a register and an octal value");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "getreg") {
|
||||
if (parts.size() == 2) {
|
||||
|
@ -866,7 +868,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("getreg requires a register");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setstack") {
|
||||
if (parts.size() == 3) {
|
||||
|
@ -881,7 +883,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("setstack requires a register and an octal value");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "getstack") {
|
||||
if (parts.size() == 2) {
|
||||
|
@ -892,7 +894,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("getreg requires a stack register");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setpsw") {
|
||||
if (parts.size() == 2) {
|
||||
|
@ -905,12 +907,12 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("setpsw requires an octal value");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "getpsw") {
|
||||
cnsl->put_string_lf(format("PSW = %06o", c->getPSW()));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "getmem") {
|
||||
auto a_it = kv.find("a");
|
||||
|
@ -922,7 +924,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(format("MEM %06o = %03o", a, c->getBus()->read_byte(a)));
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setmem") {
|
||||
auto a_it = kv.find("a");
|
||||
|
@ -939,7 +941,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(format("Set %06o to %03o", a, v));
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "toggle") {
|
||||
auto s_it = kv.find("s");
|
||||
|
@ -956,14 +958,14 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(format("Set switch %d to %d", s, t));
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "trace" || parts[0] == "t") {
|
||||
settrace(!gettrace());
|
||||
|
||||
cnsl->put_string_lf(format("Tracing set to %s", gettrace() ? "ON" : "OFF"));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "state") {
|
||||
if (parts[1] == "rl02")
|
||||
|
@ -983,7 +985,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else
|
||||
cnsl->put_string_lf(format("Device \"%s\" is not known", parts[1].c_str()));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "mmures") {
|
||||
if (parts.size() == 2)
|
||||
|
@ -991,26 +993,26 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else
|
||||
cnsl->put_string_lf("Parameter missing");
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "regdump") {
|
||||
reg_dump(cnsl, c);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "strace") {
|
||||
if (parts.size() != 2) {
|
||||
trace_start_addr = -1;
|
||||
state->trace_start_addr = -1;
|
||||
|
||||
cnsl->put_string_lf("Tracing start address reset");
|
||||
}
|
||||
else {
|
||||
trace_start_addr = std::stoi(parts[1], nullptr, 8);
|
||||
state->trace_start_addr = std::stoi(parts[1], nullptr, 8);
|
||||
|
||||
cnsl->put_string_lf(format("Tracing start address set to %06o", trace_start_addr));
|
||||
cnsl->put_string_lf(format("Tracing start address set to %06o", state->trace_start_addr));
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "examine" || parts[0] == "e") {
|
||||
if (parts.size() < 3)
|
||||
|
@ -1022,7 +1024,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
if (parts[2] != "p" && parts[2] != "v") {
|
||||
cnsl->put_string_lf("expected p (physical address) or v (virtual address)");
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string out;
|
||||
|
@ -1060,45 +1062,45 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(out);
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "reset" || cmd == "r") {
|
||||
*stop_event = EVENT_NONE;
|
||||
b->reset();
|
||||
cnsl->put_string_lf("resetted");
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "cfgdisk") {
|
||||
configure_disk(b, cnsl);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
#if defined(ESP32)
|
||||
else if (cmd == "cfgnet") {
|
||||
configure_network(cnsl);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "chknet") {
|
||||
check_network(cnsl);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "startnet") {
|
||||
start_network(cnsl);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "pm" && parts.size() == 2) {
|
||||
reinterpret_cast<console_esp32 *>(cnsl)->set_panel_mode(parts[1] == "bits" ? console_esp32::PM_BITS : console_esp32::PM_POINTER);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
else if (cmd == "stats") {
|
||||
show_run_statistics(cnsl, c);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "ramsize") {
|
||||
if (parts.size() == 2)
|
||||
|
@ -1109,7 +1111,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf(format("Memory size: %u pages or %u kB (decimal)", n_pages, n_pages * 8192 / 1024));
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "bl" && parts.size() == 2) {
|
||||
if (parts.at(1) == "rk05")
|
||||
|
@ -1121,32 +1123,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else
|
||||
cnsl->put_string_lf("???");
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "trl") {
|
||||
if (parts.size() == 1)
|
||||
t_rl.reset();
|
||||
state->t_rl.reset();
|
||||
else
|
||||
t_rl = std::stoi(parts.at(1));
|
||||
state->t_rl = std::stoi(parts.at(1));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "cls") {
|
||||
const char cls[] = { 27, '[', '2', 'J', 12, 0 };
|
||||
const char cls[] = { 27, '[', '2', 'J', 27, '[', 'H', 12, 0 };
|
||||
|
||||
cnsl->put_string_lf(cls);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "turbo") {
|
||||
turbo = !turbo;
|
||||
state->turbo = !state->turbo;
|
||||
|
||||
if (turbo)
|
||||
if (state->turbo)
|
||||
c->set_debug(false);
|
||||
|
||||
cnsl->put_string_lf(format("Turbo set to %s", turbo ? "ON" : "OFF"));
|
||||
cnsl->put_string_lf(format("Turbo set to %s", state->turbo ? "ON" : "OFF"));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "debug") {
|
||||
bool new_mode = !c->get_debug();
|
||||
|
@ -1154,7 +1156,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
cnsl->put_string_lf(format("Debug mode set to %s", new_mode ? "ON" : "OFF"));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setll" && parts.size() == 2) {
|
||||
auto ll_parts = split(parts[1], ",");
|
||||
|
@ -1180,17 +1182,17 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
setll(ll_screen, ll_file);
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
#if IS_POSIX
|
||||
else if (parts[0] == "ser" && parts.size() == 2) {
|
||||
serialize_state(cnsl, b, parts.at(1));
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
else if (parts[0] == "setinthz" && parts.size() == 2) {
|
||||
set_kw11_l_interrupt_freq(cnsl, b, std::stoi(parts.at(1)));
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "setsl" && parts.size() == 3) {
|
||||
if (setloghost(parts.at(1).c_str(), parse_ll(parts[2])) == false)
|
||||
|
@ -1198,22 +1200,22 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else
|
||||
send_syslog(info, "Hello, world!");
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "pts" && parts.size() == 2) {
|
||||
cnsl->enable_timestamp(std::stoi(parts[1]));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "qi") {
|
||||
show_queued_interrupts(cnsl, c);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "log") {
|
||||
DOLOG(info, true, cmd.c_str());
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "bic" && parts.size() == 2) {
|
||||
auto rc = load_tape(b, parts[1].c_str());
|
||||
|
@ -1226,7 +1228,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
cnsl->put_string_lf("BIC/LDA failed to load");
|
||||
}
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "lt") {
|
||||
if (parts.size() == 2)
|
||||
|
@ -1234,42 +1236,42 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
else
|
||||
tm11_load_tape(cnsl, b, { });
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "dir" || cmd == "ls") {
|
||||
ls_l(cnsl);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "ult") {
|
||||
tm11_unload_tape(b);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (parts[0] == "testdc11") {
|
||||
b->getDC11()->test_ports(cmd);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "dp") {
|
||||
cnsl->stop_panel_thread();
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "cdc11") {
|
||||
configure_comm(cnsl, *b->getDC11()->get_comm_interfaces());
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "serdc11") {
|
||||
serdc11(cnsl, b);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "dserdc11") {
|
||||
deserdc11(cnsl, b);
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "bt") {
|
||||
if (c->get_debug() == false)
|
||||
|
@ -1280,17 +1282,17 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
for(auto & element: backtrace)
|
||||
cnsl->put_string_lf(format("%06o %s", element.first, element.second.c_str()));
|
||||
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else if (cmd == "quit" || cmd == "q") {
|
||||
#if defined(ESP32)
|
||||
ESP.restart();
|
||||
#endif
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
else if (cmd == "help" || cmd == "h" || cmd == "?") {
|
||||
constexpr const char *const help[] = {
|
||||
"disassemble/d - show current instruction (pc=/n=)",
|
||||
"dis[assemble] - show current instruction (pc=/n=)",
|
||||
"go - run until trap or ^e",
|
||||
#if !defined(ESP32)
|
||||
"quit/q - stop emulator",
|
||||
|
@ -1341,7 +1343,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
"dserdc11 - load DC11 device settings",
|
||||
#if IS_POSIX
|
||||
"ser x - serialize state to a file",
|
||||
// "dser - deserialize state from a file",
|
||||
// "dser - deserialize state from a file",
|
||||
#endif
|
||||
"dp - disable panel",
|
||||
#if defined(ESP32)
|
||||
|
@ -1359,11 +1361,11 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
size_t i=0;
|
||||
while(help[i])
|
||||
cnsl->put_string_lf(help[i++]);
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
cnsl->put_string_lf("?");
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
c->emulation_start();
|
||||
|
@ -1372,7 +1374,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
bool reset_cpu = true;
|
||||
|
||||
if (turbo) {
|
||||
if (state->turbo) {
|
||||
while(*stop_event == EVENT_NONE)
|
||||
c->step();
|
||||
}
|
||||
|
@ -1380,25 +1382,25 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
reset_cpu = false;
|
||||
|
||||
while(*stop_event == EVENT_NONE) {
|
||||
if (trace_start_addr != -1 && c->getPC() == trace_start_addr)
|
||||
if (state->trace_start_addr != -1 && c->getPC() == state->trace_start_addr)
|
||||
settrace(true);
|
||||
|
||||
if ((gettrace() || single_step) && (t_rl.has_value() == false || t_rl.value() == c->getPSW_runmode())) {
|
||||
if (!single_step)
|
||||
if ((gettrace() || state->single_step) && (state->t_rl.has_value() == false || state->t_rl.value() == c->getPSW_runmode())) {
|
||||
if (!state->single_step)
|
||||
TRACE("---");
|
||||
|
||||
disassemble(c, single_step ? cnsl : nullptr, c->getPC(), false);
|
||||
disassemble(c, state->single_step ? cnsl : nullptr, c->getPC(), false);
|
||||
}
|
||||
|
||||
auto bp_result = c->check_breakpoint();
|
||||
if (bp_result.has_value() && !single_step) {
|
||||
if (bp_result.has_value() && !state->single_step) {
|
||||
cnsl->put_string_lf("Breakpoint: " + bp_result.value());
|
||||
break;
|
||||
}
|
||||
|
||||
c->step();
|
||||
|
||||
if (single_step && --n_single_step == 0)
|
||||
if (state->single_step && --state->n_single_step == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1407,6 +1409,35 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
if (reset_cpu)
|
||||
c->reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const std::optional<std::string> & init)
|
||||
{
|
||||
debugger_state state;
|
||||
|
||||
b->set_debug_mode();
|
||||
|
||||
if (init.has_value()) {
|
||||
std::string line;
|
||||
std::ifstream fh;
|
||||
fh.open(init.value());
|
||||
while(std::getline(fh, line)) {
|
||||
if (debugger_do(&state, cnsl, b, stop_event, line) == false)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while(*stop_event != EVENT_TERMINATE) {
|
||||
try {
|
||||
if (state.marker)
|
||||
cnsl->put_string_lf("---");
|
||||
|
||||
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
|
||||
|
||||
if (debugger_do(&state, cnsl, b, stop_event, cmd) == false)
|
||||
break;
|
||||
}
|
||||
catch(const std::exception & e) {
|
||||
cnsl->put_string_lf(format("Exception caught: %s", e.what()));
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
|
||||
|
||||
int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool instruction_only);
|
||||
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event);
|
||||
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const std::optional<std::string> & init);
|
||||
|
||||
void run_bic(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const uint16_t bic_start);
|
||||
|
|
10
main.cpp
10
main.cpp
|
@ -258,6 +258,7 @@ void help()
|
|||
printf("-b enable bootloader (builtin)\n");
|
||||
printf("-n ncurses UI\n");
|
||||
printf("-d enable debugger\n");
|
||||
printf("-f x first process the commands from file x before entering the debugger\n");
|
||||
printf("-S x set ram size (in number of 8 kB pages)\n");
|
||||
printf("-s x,y set console switche state: set bit x (0...15) to y (0/1)\n");
|
||||
printf("-t enable tracing (disassemble to stderr, requires -d as well)\n");
|
||||
|
@ -277,6 +278,7 @@ int main(int argc, char *argv[])
|
|||
std::string disk_type = "rk05";
|
||||
|
||||
bool run_debugger = false;
|
||||
std::optional<std::string> debugger_init;
|
||||
|
||||
bool enable_bootloader = false;
|
||||
bootloader_t bootloader = BL_NONE;
|
||||
|
@ -311,13 +313,17 @@ int main(int argc, char *argv[])
|
|||
std::optional<std::string> dc11_device;
|
||||
|
||||
int opt = -1;
|
||||
while((opt = getopt(argc, argv, "hqD:MT:Br:R:p:ndtL:bl:s:Q:N:J:XS:P1:")) != -1)
|
||||
while((opt = getopt(argc, argv, "hqD:MT:Br:R:p:ndf:tL:bl:s:Q:N:J:XS:P1:")) != -1)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'h':
|
||||
help();
|
||||
return 1;
|
||||
|
||||
case 'f':
|
||||
debugger_init = optarg;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
dc11_device = optarg;
|
||||
break;
|
||||
|
@ -612,7 +618,7 @@ int main(int argc, char *argv[])
|
|||
if (is_bic)
|
||||
run_bic(cnsl, b, &event, bic_start.value());
|
||||
else if (run_debugger || (bootloader == BL_NONE && test.empty() && tape.empty()))
|
||||
debugger(cnsl, b, &event);
|
||||
debugger(cnsl, b, &event, debugger_init);
|
||||
else if (benchmark) {
|
||||
// FILL MEMORY
|
||||
memory *m = b->getRAM();
|
||||
|
|
Loading…
Add table
Reference in a new issue