122 lines
2.5 KiB
C++
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;
|
|
}
|