#include #include "breakpoint_register.h" #include "cpu.h" #include "utils.h" breakpoint_register::breakpoint_register(bus *const b, const int register_nr, const std::set & values) : breakpoint(b), c(b->getCpu()), register_nr(register_nr), values(values) { } breakpoint_register::~breakpoint_register() { } std::string breakpoint_register::get_name(hwreg_t reg) const { if (reg < 8) return format("R%d", reg); switch(reg) { case hr_mmr0: return "mmr0"; case hr_mmr1: return "mmr1"; case hr_mmr2: return "mmr2"; case hr_mmr3: return "mmr3"; case hr_psw: return "psw"; } return "???"; } std::optional breakpoint_register::is_triggered() const { uint16_t v = 0; if (register_nr < 8) v = c->getRegister(register_nr); // TODO run-mode else { hwreg_t reg = hwreg_t(register_nr); switch(reg) { case hr_mmr0: v = b->getMMU()->getMMR0(); break; case hr_mmr1: v = b->getMMU()->getMMR1(); break; case hr_mmr2: v = b->getMMU()->getMMR2(); break; case hr_mmr3: v = b->getMMU()->getMMR3(); break; case hr_psw: v = c->getPSW(); break; } } auto it = values.find(v); if (it == values.end()) return { }; return get_name(hwreg_t(register_nr)) + "=" + format("%06o", v); } std::pair > breakpoint_register::parse(bus *const b, const std::string & in) { auto parts = split(in, "="); if (parts.size() != 2) return { nullptr, "register: key or value missing" }; auto values_in = parts.at(1); auto v_parts = split(std::move(values_in), ","); std::set values; for(auto & v: v_parts) values.insert(std::stoi(v, nullptr, 8)); auto key = parts.at(0); if (key.size() < 2) return { nullptr, "register: register id invalid" }; if (toupper(key[0]) == 'R') { int nr = key[1] - '0'; if (nr < 0 || nr > 7) return { nullptr, "register: register id invalid" }; return { new breakpoint_register(b, nr, values), { } }; } else if (key == "SP" || key == "sp") { return { new breakpoint_register(b, 6, values), { } }; } else if (key == "PC" || key == "pc") { return { new breakpoint_register(b, 7, values), { } }; } else if (key.substr(0, 3) == "MMR" || key.substr(0, 3) == "mmr") { int which = key[3] - '0'; return { new breakpoint_register(b, hr_mmr0 + which, values), { } }; } else if (key.substr(0, 3) == "PSW" || key.substr(0, 3) == "psw") { return { new breakpoint_register(b, hr_psw, values), { } }; } return { nullptr, { } }; } std::string breakpoint_register::emit() const { std::string out; for(auto & v: values) { if (out.empty()) out = get_name(hwreg_t(register_nr)) + "="; else out += ","; out += format("%06o", v); } return out; }