memory breakpoint
This commit is contained in:
parent
70cd49e2a9
commit
4e39cc3329
7 changed files with 122 additions and 6 deletions
|
@ -18,6 +18,7 @@ add_executable(
|
||||||
kek
|
kek
|
||||||
breakpoint.cpp
|
breakpoint.cpp
|
||||||
breakpoint_and.cpp
|
breakpoint_and.cpp
|
||||||
|
breakpoint_memory.cpp
|
||||||
breakpoint_or.cpp
|
breakpoint_or.cpp
|
||||||
breakpoint_parser.cpp
|
breakpoint_parser.cpp
|
||||||
breakpoint_register.cpp
|
breakpoint_register.cpp
|
||||||
|
|
76
breakpoint_memory.cpp
Normal file
76
breakpoint_memory.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "breakpoint_memory.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
breakpoint_memory::breakpoint_memory(bus *const b, const uint32_t addr, const word_mode_t word_mode, const bool is_virtual, const std::set<uint16_t> & values):
|
||||||
|
breakpoint(b),
|
||||||
|
addr(addr),
|
||||||
|
word_mode(word_mode),
|
||||||
|
is_virtual(is_virtual),
|
||||||
|
values(values)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpoint_memory::~breakpoint_memory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> breakpoint_memory::is_triggered() const
|
||||||
|
{
|
||||||
|
uint16_t v = 0;
|
||||||
|
|
||||||
|
if (is_virtual)
|
||||||
|
v = b->read(addr, word_mode, rm_cur, true, i_space);
|
||||||
|
else
|
||||||
|
v = b->readPhysical(addr);
|
||||||
|
|
||||||
|
auto it = values.find(v);
|
||||||
|
if (it == values.end())
|
||||||
|
return { };
|
||||||
|
|
||||||
|
return format("MEM%c%c[%08a]=%06o", word_mode == wm_byte ? 'B' : 'W', is_virtual ? 'V' : 'P', addr, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<breakpoint_memory *, std::optional<std::string> > breakpoint_memory::parse(bus *const b, const std::string & in)
|
||||||
|
{
|
||||||
|
auto parts = split(in, "=");
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return { nullptr, "memory: 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() < 8 || (key.substr(0, 3) != "MEM" && key.substr(0, 3) != "mem"))
|
||||||
|
return { nullptr, { } };
|
||||||
|
|
||||||
|
word_mode_t wm = toupper(key[3]) == 'B' ? wm_byte : wm_word;
|
||||||
|
bool is_virtual = toupper(key[4]) == 'V';
|
||||||
|
|
||||||
|
std::size_t end_marker = key.find(']');
|
||||||
|
uint32_t addr = std::stoi(key.substr(6, end_marker - 6), nullptr, 8);
|
||||||
|
|
||||||
|
return { new breakpoint_memory(b, addr, wm, is_virtual, values), { } };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string breakpoint_memory::emit() const
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
|
||||||
|
for(auto & v: values) {
|
||||||
|
if (out.empty())
|
||||||
|
out = format("MEM%c%c[%08a]=", word_mode == wm_byte ? 'B' : 'W', is_virtual ? 'V' : 'P', addr);
|
||||||
|
else
|
||||||
|
out += ",";
|
||||||
|
|
||||||
|
out += format("%06o", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
26
breakpoint_memory.h
Normal file
26
breakpoint_memory.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "breakpoint.h"
|
||||||
|
#include "bus.h"
|
||||||
|
|
||||||
|
|
||||||
|
class breakpoint_memory : public breakpoint
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const uint32_t addr { 0 };
|
||||||
|
const word_mode_t word_mode { wm_word };
|
||||||
|
const bool is_virtual { false };
|
||||||
|
std::set<uint16_t> values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
breakpoint_memory(bus *const b, const uint32_t addr, const word_mode_t word_mode, const bool is_virtual, const std::set<uint16_t> & values);
|
||||||
|
virtual ~breakpoint_memory();
|
||||||
|
|
||||||
|
virtual std::optional<std::string> is_triggered() const override;
|
||||||
|
|
||||||
|
static std::pair<breakpoint_memory *, std::optional<std::string> > parse(bus *const b, const std::string & in);
|
||||||
|
|
||||||
|
virtual std::string emit() const override;
|
||||||
|
};
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "breakpoint.h"
|
#include "breakpoint.h"
|
||||||
#include "breakpoint_and.h"
|
#include "breakpoint_and.h"
|
||||||
|
#include "breakpoint_memory.h"
|
||||||
#include "breakpoint_or.h"
|
#include "breakpoint_or.h"
|
||||||
#include "breakpoint_register.h"
|
#include "breakpoint_register.h"
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
@ -82,12 +83,22 @@ std::pair<breakpoint *, std::optional<std::string> > parse_breakpoint(bus *const
|
||||||
combine = combine_single;
|
combine = combine_single;
|
||||||
|
|
||||||
auto rc_reg = breakpoint_register::parse(b, parts[i]);
|
auto rc_reg = breakpoint_register::parse(b, parts[i]);
|
||||||
if (rc_reg.first == nullptr) {
|
if (rc_reg.first == nullptr && rc_reg.second.has_value()) {
|
||||||
delete_parsed(parsed);
|
delete_parsed(parsed);
|
||||||
return { nullptr, "not understood" };
|
return { nullptr, "not understood: " + rc_reg.second.value() };
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed.push_back(rc_reg.first);
|
if (rc_reg.first)
|
||||||
|
parsed.push_back(rc_reg.first);
|
||||||
|
|
||||||
|
auto rc_mem = breakpoint_memory::parse(b, parts[i]);
|
||||||
|
if (rc_mem.first == nullptr && rc_mem.second.has_value()) {
|
||||||
|
delete_parsed(parsed);
|
||||||
|
return { nullptr, "not understood: " + rc_mem.second.value() };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc_mem.first)
|
||||||
|
parsed.push_back(rc_mem.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ std::pair<breakpoint_register *, std::optional<std::string> > breakpoint_registe
|
||||||
return { new breakpoint_register(b, 7, values), { } };
|
return { new breakpoint_register(b, 7, values), { } };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { nullptr, "register: invalid specification" };
|
return { nullptr, { } };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string breakpoint_register::emit() const
|
std::string breakpoint_register::emit() const
|
||||||
|
|
|
@ -1024,7 +1024,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
cnsl->put_string_lf("reset/r - reset cpu/bus/etc");
|
cnsl->put_string_lf("reset/r - reset cpu/bus/etc");
|
||||||
cnsl->put_string_lf("single/s - run 1 instruction (implicit 'disassemble' command)");
|
cnsl->put_string_lf("single/s - run 1 instruction (implicit 'disassemble' command)");
|
||||||
cnsl->put_string_lf("sbp/cbp/lbp - set/clear/list breakpoint(s)");
|
cnsl->put_string_lf("sbp/cbp/lbp - set/clear/list breakpoint(s)");
|
||||||
cnsl->put_string_lf(" e.g.: (pc=0123 and r0=123 and (r4=07 or r4=0456))");
|
cnsl->put_string_lf(" e.g.: (pc=0123 and memwv[04000]=0200,0300 and (r4=07,05 or r5=0456))");
|
||||||
|
cnsl->put_string_lf(" values seperated by ',', char after mem is w/b (word/byte), then
|
||||||
|
cnsl->put_string_lf(" follows v/p (virtual/physical)");
|
||||||
cnsl->put_string_lf("trace/t - toggle tracing");
|
cnsl->put_string_lf("trace/t - toggle tracing");
|
||||||
cnsl->put_string_lf("turbo - toggle turbo mode (cannot be interrupted)");
|
cnsl->put_string_lf("turbo - toggle turbo mode (cannot be interrupted)");
|
||||||
cnsl->put_string_lf("strace - start tracing from address - invoke without address to disable");
|
cnsl->put_string_lf("strace - start tracing from address - invoke without address to disable");
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -323,7 +323,7 @@ int main(int argc, char *argv[])
|
||||||
cpu *c = new cpu(b, &event);
|
cpu *c = new cpu(b, &event);
|
||||||
b->add_cpu(c);
|
b->add_cpu(c);
|
||||||
|
|
||||||
std::pair<breakpoint *, std::optional<std::string> > rc = parse_breakpoint(b, "(pc=0123 and (r0=01456 or r2=1))");
|
std::pair<breakpoint *, std::optional<std::string> > rc = parse_breakpoint(b, "(pc=0123 and (r0=01456 or r2=1) and memWV[0444]=0222)");
|
||||||
printf("%p\n", rc.first);
|
printf("%p\n", rc.first);
|
||||||
|
|
||||||
if (rc.second.has_value())
|
if (rc.second.has_value())
|
||||||
|
|
Loading…
Add table
Reference in a new issue