serialize

This commit is contained in:
folkert van heusden 2024-04-25 19:07:24 +02:00
parent 6c7529971d
commit e0bbef778d
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
9 changed files with 118 additions and 13 deletions

17
bus.cpp
View file

@ -43,7 +43,7 @@ bus::~bus()
} }
#if IS_POSIX #if IS_POSIX
json_t *bus::serialize() json_t *bus::serialize() const
{ {
json_t *j_out = json_object(); json_t *j_out = json_object();
@ -59,12 +59,15 @@ json_t *bus::serialize()
if (mmu_) if (mmu_)
json_object_set(j_out, "mmu", mmu_->serialize()); json_object_set(j_out, "mmu", mmu_->serialize());
// TODO: cpu, rl02, rk05, tm11 if (c)
json_object_set(j_out, "cpu", c->serialize());
// TODO: rl02, rk05, tm11
return j_out; return j_out;
} }
bus *bus::deserialize(const json_t *const j, console *const cnsl) bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_uint32_t *const event)
{ {
bus *b = new bus(); bus *b = new bus();
@ -94,7 +97,13 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl)
b->add_mmu(mmu_); b->add_mmu(mmu_);
} }
// TODO: mmu, cpu, rl02, rk05, tm11 temp = json_object_get(j, "cpu");
if (temp) {
cpu *cpu_ = cpu::deserialize(temp, b, event);
b->add_cpu(cpu_);
}
// TODO: rl02, rk05, tm11
return b; return b;
} }

4
bus.h
View file

@ -91,8 +91,8 @@ public:
~bus(); ~bus();
#if IS_POSIX #if IS_POSIX
json_t *serialize(); json_t *serialize() const;
static bus *deserialize(const json_t *const j, console *const cnsl); static bus *deserialize(const json_t *const j, console *const cnsl, std::atomic_uint32_t *const event);
#endif #endif
void reset(); void reset();

63
cpu.cpp
View file

@ -2395,3 +2395,66 @@ void cpu::step()
DOLOG(debug, false, "bus-trap during execution of command (%d)", exception_nr); DOLOG(debug, false, "bus-trap during execution of command (%d)", exception_nr);
} }
} }
#if IS_POSIX
json_t *cpu::serialize()
{
json_t *j = json_object();
for(int set=0; set<2; set++) {
for(int regnr=0; regnr<6; regnr++)
json_object_set(j, format("register-%d-%d", set, regnr).c_str(), json_integer(regs0_5[set][regnr]));
}
for(int spnr=0; spnr<4; spnr++)
json_object_set(j, format("sp-%d", spnr).c_str(), json_integer(sp[spnr]));
json_object_set(j, "pc", json_integer(pc));
json_object_set(j, "instruction_start", json_integer(instruction_start));
json_object_set(j, "psw", json_integer(psw));
json_object_set(j, "fpsr", json_integer(fpsr));
json_object_set(j, "stackLimitRegister", json_integer(stackLimitRegister));
json_object_set(j, "processing_trap_depth", json_integer(processing_trap_depth));
json_object_set(j, "instruction_count", json_integer(instruction_count));
json_object_set(j, "running_since", json_integer(running_since));
json_object_set(j, "wait_time", json_integer(wait_time));
json_object_set(j, "it_is_a_trap", json_boolean(it_is_a_trap));
json_object_set(j, "debug_mode", json_boolean(debug_mode));
if (trap_delay.has_value())
json_object_set(j, "trap_delay", json_integer(trap_delay.value()));
return j;
}
cpu *cpu::deserialize(const json_t *const j, bus *const b, std::atomic_uint32_t *const event)
{
cpu *c = new cpu(b, event);
for(int set=0; set<2; set++) {
for(int regnr=0; regnr<6; regnr++)
c->regs0_5[set][regnr] = json_integer_value(json_object_get(j, format("register-%d-%d", set, regnr).c_str()));
}
for(int spnr=0; spnr<4; spnr++)
c->sp[spnr] = json_integer_value(json_object_get(j, format("sp-%d", spnr).c_str()));
c->pc = json_integer_value(json_object_get(j, "pc"));
c->instruction_start = json_integer_value(json_object_get(j, "instruction_start"));
c->psw = json_integer_value(json_object_get(j, "psw"));
c->fpsr = json_integer_value(json_object_get(j, "fpsr"));
c->stackLimitRegister = json_integer_value(json_object_get(j, "stackLimitRegister"));
c->processing_trap_depth = json_integer_value(json_object_get(j, "processing_trap_depth"));
c->instruction_count = json_integer_value(json_object_get(j, "instruction_count"));
c->running_since = get_us();
c->wait_time = 0;
c->it_is_a_trap = json_boolean_value(json_object_get(j, "it_is_a_trap"));
c->debug_mode = json_boolean_value(json_object_get(j, "debug_mode"));
json_t *temp = json_object_get(j, "trap_delay");
if (temp)
c->trap_delay = json_integer_value(temp);
else
c->trap_delay.reset();
return c;
}
#endif

6
cpu.h
View file

@ -14,6 +14,7 @@
#include "breakpoint.h" #include "breakpoint.h"
#include "bus.h" #include "bus.h"
#include "gen.h"
constexpr const int initial_trap_delay = 8; constexpr const int initial_trap_delay = 8;
@ -111,6 +112,11 @@ public:
explicit cpu(bus *const b, std::atomic_uint32_t *const event); explicit cpu(bus *const b, std::atomic_uint32_t *const event);
~cpu(); ~cpu();
#if IS_POSIX
json_t *serialize();
static cpu *deserialize(const json_t *const j, bus *const b, std::atomic_uint32_t *const event);
#endif
std::optional<std::string> check_breakpoint(); std::optional<std::string> check_breakpoint();
int set_breakpoint(breakpoint *const bp); int set_breakpoint(breakpoint *const bp);
bool remove_breakpoint(const int bp_id); bool remove_breakpoint(const int bp_id);

View file

@ -722,6 +722,25 @@ void show_queued_interrupts(console *const cnsl, cpu *const c)
} }
} }
void serialize_state(console *const cnsl, const bus *const b, const std::string & filename)
{
json_t *j = b->serialize();
bool ok = false;
FILE *fh = fopen(filename.c_str(), "w");
if (fh) {
if (json_dumpf(j, fh, 0) == 0)
ok = true;
fclose(fh);
}
json_decref(j);
cnsl->put_string_lf(format("Serialize to %s: %s", filename.c_str(), ok ? "OK" : "failed"));
}
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing_in) void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing_in)
{ {
int32_t trace_start_addr = -1; int32_t trace_start_addr = -1;
@ -1069,6 +1088,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
continue; continue;
} }
else if (parts[0] == "ser" && parts.size() == 2) {
serialize_state(cnsl, b, parts.at(1));
continue;
}
else if (parts[0] == "setsl" && parts.size() == 3) { else if (parts[0] == "setsl" && parts.size() == 3) {
setloghost(parts.at(1).c_str(), parse_ll(parts[2])); setloghost(parts.at(1).c_str(), parse_ll(parts[2]));
@ -1130,6 +1153,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"stats - show run statistics", "stats - show run statistics",
"ramsize - set ram size (page count (8 kB))", "ramsize - set ram size (page count (8 kB))",
"bl - set bootload (rl02 or rk05)", "bl - set bootload (rl02 or rk05)",
#if IS_POSIX
"ser - serialize state to a file",
"dser - deserialize state from a file",
#endif
#if defined(ESP32) #if defined(ESP32)
"cfgnet - configure network (e.g. WiFi)", "cfgnet - configure network (e.g. WiFi)",
"startnet - start network", "startnet - start network",

View file

@ -29,7 +29,7 @@ void memory::reset()
} }
#if IS_POSIX #if IS_POSIX
json_t *memory::serialize() json_t *memory::serialize() const
{ {
json_t *j = json_object(); json_t *j = json_object();
@ -50,7 +50,7 @@ memory *memory::deserialize(const json_t *const j)
json_t *ja = json_object_get(j, "contents"); json_t *ja = json_object_get(j, "contents");
for(size_t i=0; i<size; i++) for(size_t i=0; i<size; i++)
m->writeByte(i, json_integer_value(json_array_get(ja, i))); m->m[i] = json_integer_value(json_array_get(ja, i));
return m; return m;
} }

View file

@ -20,7 +20,7 @@ public:
void reset(); void reset();
#if IS_POSIX #if IS_POSIX
json_t *serialize(); json_t *serialize() const;
static memory *deserialize(const json_t *const j); static memory *deserialize(const json_t *const j);
#endif #endif

View file

@ -222,7 +222,7 @@ void mmu::writeByte(const uint16_t a, const uint8_t value)
} }
#if IS_POSIX #if IS_POSIX
void mmu::add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name) void mmu::add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name) const
{ {
json_t *j = json_object(); json_t *j = json_object();
@ -239,7 +239,7 @@ void mmu::add_par_pdr(json_t *const target, const int run_mode, const bool is_d,
json_object_set(target, name.c_str(), j); json_object_set(target, name.c_str(), j);
} }
json_t *mmu::serialize() json_t *mmu::serialize() const
{ {
json_t *j = json_object(); json_t *j = json_object();

4
mmu.h
View file

@ -41,7 +41,7 @@ private:
uint16_t PIR { 0 }; uint16_t PIR { 0 };
uint16_t CSR { 0 }; uint16_t CSR { 0 };
void add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name); void add_par_pdr(json_t *const target, const int run_mode, const bool is_d, const std::string & name) const;
void set_par_pdr(const json_t *const j_in, const int run_mode, const bool is_d, const std::string & name); void set_par_pdr(const json_t *const j_in, const int run_mode, const bool is_d, const std::string & name);
public: public:
@ -49,7 +49,7 @@ public:
virtual ~mmu(); virtual ~mmu();
#if IS_POSIX #if IS_POSIX
json_t *serialize(); json_t *serialize() const;
static mmu *deserialize(const json_t *const j); static mmu *deserialize(const json_t *const j);
#endif #endif