KEK/breakpoint_register.cpp
folkert van heusden e9d9659d74
missing =
2024-04-16 15:43:04 +02:00

122 lines
2.5 KiB
C++

#include <ctype.h>
#include "breakpoint_register.h"
#include "cpu.h"
#include "utils.h"
breakpoint_register::breakpoint_register(bus *const b, const int register_nr, const std::set<uint16_t> & 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";
}
return "???";
}
std::optional<std::string> 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->getMMR0();
break;
case hr_mmr1:
v = b->getMMR1();
break;
case hr_mmr2:
v = b->getMMR2();
break;
case hr_mmr3:
v = b->getMMR3();
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 *, std::optional<std::string> > 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(values_in, ",");
std::set<uint16_t> 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" or key.substr(0, 3) == "mmr") {
int which = key[3] - '0';
return { new breakpoint_register(b, hr_mmr0 + which, 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;
}