This commit is contained in:
folkert van heusden 2024-05-13 21:32:33 +02:00
parent 6d60bbe254
commit 669d8c139e
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
5 changed files with 78 additions and 100 deletions

72
bus.cpp
View file

@ -1,6 +1,7 @@
// (C) 2018-2024 by Folkert van Heusden // (C) 2018-2024 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#include <ArduinoJson.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -44,91 +45,68 @@ bus::~bus()
delete dc11_; delete dc11_;
} }
#if IS_POSIX JsonDocument bus::serialize() const
json_t *bus::serialize() const
{ {
json_t *j_out = json_object(); JsonDocument j_out;
if (m) if (m)
json_object_set(j_out, "memory", m->serialize()); j_out["memory"] = m->serialize();
if (kw11_l_) if (kw11_l_)
json_object_set(j_out, "kw11-l", kw11_l_->serialize()); j_out["kw11-l"] = kw11_l_->serialize();
if (tty_) if (tty_)
json_object_set(j_out, "tty", tty_->serialize()); j_out["tty"] = tty_->serialize();
if (mmu_) if (mmu_)
json_object_set(j_out, "mmu", mmu_->serialize()); j_out["mmu"] = mmu_->serialize();
if (c) if (c)
json_object_set(j_out, "cpu", c->serialize()); j_out["cpu"] = c->serialize();
if (rl02_) if (rl02_)
json_object_set(j_out, "rl02", rl02_->serialize()); j_out["rl02"] = rl02_->serialize();
if (rk05_) if (rk05_)
json_object_set(j_out, "rk05", rk05_->serialize()); j_out["rk05"] = rk05_->serialize();
// TODO: tm11, dc11 // TODO: tm11, dc11
return j_out; return j_out;
} }
bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_uint32_t *const event) bus *bus::deserialize(const JsonDocument j, console *const cnsl, std::atomic_uint32_t *const event)
{ {
bus *b = new bus(); bus *b = new bus();
json_t *temp = nullptr;
memory *m = nullptr; memory *m = nullptr;
temp = json_object_get(j, "memory"); if (j.containsKey("memory")) {
if (temp) { m = memory::deserialize(j["memory"]);
m = memory::deserialize(temp);
b->add_ram(m); b->add_ram(m);
} }
temp = json_object_get(j, "kw11-l"); if (j.containsKey("kw11-l"))
if (temp) { b->add_KW11_L(kw11_l::deserialize(j["kw11-l"], b, cnsl));
kw11_l *kw11_l_ = kw11_l::deserialize(temp, b, cnsl);
b->add_KW11_L(kw11_l_);
}
temp = json_object_get(j, "tty"); if (j.containsKey("tty"))
if (temp) { b->add_tty(tty::deserialize(j["tty"], b, cnsl));
tty *tty_ = tty::deserialize(temp, b, cnsl);
b->add_tty(tty_);
}
temp = json_object_get(j, "mmu"); if (j.containsKey("mmu"))
if (temp) { b->add_mmu(mmu::deserialize(j["mmu"], m));
mmu *mmu_ = mmu::deserialize(temp, m);
b->add_mmu(mmu_);
}
temp = json_object_get(j, "cpu"); if (j.containsKey("cpu"))
if (temp) { b->add_cpu(cpu::deserialize(j["cpu"], b, event));
cpu *cpu_ = cpu::deserialize(temp, b, event);
b->add_cpu(cpu_);
}
temp = json_object_get(j, "rl02"); if (j.containsKey("rl02"))
if (temp) { b->add_rl02(rl02::deserialize(j["rl02"], b));
rl02 *rl02_ = rl02::deserialize(temp, b);
b->add_rl02(rl02_);
}
temp = json_object_get(j, "rk05"); if (j.containsKey("rk05"))
if (temp) { b->add_rk05(rk05::deserialize(j["rk05"], b));
rk05 *rk05_ = rk05::deserialize(temp, b);
b->add_rk05(rk05_);
}
// TODO: tm11, dc11 // TODO: tm11, dc11
return b; return b;
} }
#endif
void bus::show_state(console *const cnsl) const void bus::show_state(console *const cnsl) const
{ {

5
bus.h
View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <ArduinoJson.h>
#include <assert.h> #include <assert.h>
#include <mutex> #include <mutex>
#include <stdint.h> #include <stdint.h>
@ -80,8 +81,8 @@ public:
~bus(); ~bus();
#if IS_POSIX #if IS_POSIX
json_t *serialize() const; JsonDocument serialize() const;
static bus *deserialize(const json_t *const j, console *const cnsl, std::atomic_uint32_t *const event); static bus *deserialize(const JsonDocument j, console *const cnsl, std::atomic_uint32_t *const event);
#endif #endif
void reset(); void reset();

91
cpu.cpp
View file

@ -2434,89 +2434,88 @@ void cpu::step()
} }
} }
#if IS_POSIX JsonDocument cpu::serialize()
json_t *cpu::serialize()
{ {
json_t *j = json_object(); JsonDocument j;
for(int set=0; set<2; set++) { for(int set=0; set<2; set++) {
for(int regnr=0; regnr<6; regnr++) 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])); j[format("register-%d-%d", set, regnr)] = regs0_5[set][regnr];
} }
for(int spnr=0; spnr<4; spnr++) for(int spnr=0; spnr<4; spnr++)
json_object_set(j, format("sp-%d", spnr).c_str(), json_integer(sp[spnr])); j[format("sp-%d", spnr)] = sp[spnr];
j["pc"] = pc;
j["instruction_start"] = instruction_start;
j["psw"] = psw;
j["fpsr"] = fpsr;
j["stackLimitRegister"] = stackLimitRegister;
j["processing_trap_depth"] = processing_trap_depth;
j["instruction_count"] = instruction_count;
j["running_since"] = running_since;
j["wait_time"] = wait_time;
j["it_is_a_trap"] = it_is_a_trap;
j["debug_mode"] = debug_mode;
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()) if (trap_delay.has_value())
json_object_set(j, "trap_delay", json_integer(trap_delay.value())); j["trap_delay"] = trap_delay.value();
json_t *j_queued_interrupts = json_object(); JsonDocument j_queued_interrupts;
for(auto & il: queued_interrupts) { for(auto & il: queued_interrupts) {
json_t *ja_qi_level = json_array(); JsonArray ja_qi_level;
for(auto & v: il.second) for(auto v: il.second)
json_array_append(ja_qi_level, json_integer(v)); ja_qi_level.add(v);
json_object_set(j_queued_interrupts, format("%d", il.first).c_str(), ja_qi_level); j_queued_interrupts[format("%d", il.first)] = ja_qi_level;
} }
json_object_set(j, "queued_interrupts", j_queued_interrupts);
json_object_set(j, "any_queued_interrupts", json_boolean(any_queued_interrupts)); j["queued_interrupts"] = j_queued_interrupts;
j["any_queued_interrupts"] = bool(any_queued_interrupts);
return j; return j;
} }
cpu *cpu::deserialize(const json_t *const j, bus *const b, std::atomic_uint32_t *const event) cpu *cpu::deserialize(const JsonDocument j, bus *const b, std::atomic_uint32_t *const event)
{ {
cpu *c = new cpu(b, event); cpu *c = new cpu(b, event);
for(int set=0; set<2; set++) { for(int set=0; set<2; set++) {
for(int regnr=0; regnr<6; regnr++) 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())); c->regs0_5[set][regnr] = j[format("register-%d-%d", set, regnr)];
} }
for(int spnr=0; spnr<4; spnr++) for(int spnr=0; spnr<4; spnr++)
c->sp[spnr] = json_integer_value(json_object_get(j, format("sp-%d", spnr).c_str())); c->sp[spnr] = j[format("sp-%d", spnr)];
c->pc = json_integer_value(json_object_get(j, "pc")); c->pc = j["pc"];
c->instruction_start = json_integer_value(json_object_get(j, "instruction_start")); c->instruction_start = j["instruction_start"];
c->psw = json_integer_value(json_object_get(j, "psw")); c->psw = j["psw"];
c->fpsr = json_integer_value(json_object_get(j, "fpsr")); c->fpsr = j["fpsr"];
c->stackLimitRegister = json_integer_value(json_object_get(j, "stackLimitRegister")); c->stackLimitRegister = j["stackLimitRegister"];
c->processing_trap_depth = json_integer_value(json_object_get(j, "processing_trap_depth")); c->processing_trap_depth = j["processing_trap_depth"];
c->instruction_count = json_integer_value(json_object_get(j, "instruction_count")); c->instruction_count = j["instruction_count"];
c->running_since = get_us(); c->running_since = get_us();
c->wait_time = 0; c->wait_time = 0;
c->it_is_a_trap = json_boolean_value(json_object_get(j, "it_is_a_trap")); c->it_is_a_trap = j["it_is_a_trap"];
c->debug_mode = json_boolean_value(json_object_get(j, "debug_mode")); c->debug_mode = j["debug_mode"];
json_t *temp = json_object_get(j, "trap_delay");
if (temp) if (j.containsKey("trap_delay"))
c->trap_delay = json_integer_value(temp); c->trap_delay = j["trap_delay"];
else else
c->trap_delay.reset(); c->trap_delay.reset();
c->any_queued_interrupts = json_boolean_value(json_object_get(j, "any_queued_interrupts"));
c->any_queued_interrupts = j["any_queued_interrupts"].as<bool>();
c->init_interrupt_queue(); c->init_interrupt_queue();
json_t *j_queued_interrupts = json_object_get(j, "queued_interrupts");
for(int level=0; level<8; level++) { for(int level=0; level<8; level++) {
auto it = c->queued_interrupts.find(level); auto it = c->queued_interrupts.find(level);
json_t *ja_qi_level = json_object_get(j_queued_interrupts, format("%d", level).c_str()); JsonArrayConst ja_qi_level = j["queued_interrupts"][format("%d", level)].as<JsonArrayConst>();
for(auto v : ja_qi_level)
for(size_t i=0; i<json_array_size(ja_qi_level); i++) it->second.insert(v.as<int>());
it->second.insert(json_integer_value(json_array_get(ja_qi_level, i)));
} }
return c; return c;
} }
#endif

5
cpu.h
View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <ArduinoJson.h>
#include <atomic> #include <atomic>
#include <cassert> #include <cassert>
#include <condition_variable> #include <condition_variable>
@ -115,8 +116,8 @@ public:
~cpu(); ~cpu();
#if IS_POSIX #if IS_POSIX
json_t *serialize(); JsonDocument serialize();
static cpu *deserialize(const json_t *const j, bus *const b, std::atomic_uint32_t *const event); static cpu *deserialize(const JsonDocument j, bus *const b, std::atomic_uint32_t *const event);
#endif #endif
std::optional<std::string> check_breakpoint(); std::optional<std::string> check_breakpoint();

View file

@ -21,8 +21,7 @@ disk_backend_file::~disk_backend_file()
close(fd); close(fd);
} }
#if IS_POSIX JsonDocument disk_backend_file::serialize() const
json_t *disk_backend_file::serialize() const
{ {
json_t *j = json_object(); json_t *j = json_object();
@ -39,9 +38,9 @@ json_t *disk_backend_file::serialize() const
disk_backend_file *disk_backend_file::deserialize(const json_t *const j) disk_backend_file *disk_backend_file::deserialize(const json_t *const j)
{ {
// TODO verify checksum of backend // TODO verify checksum of backend
// TODO overlay
return new disk_backend_file(json_string_value(json_object_get(j, "filename"))); return new disk_backend_file(json_string_value(json_object_get(j, "filename")));
} }
#endif
bool disk_backend_file::begin(const bool snapshots) bool disk_backend_file::begin(const bool snapshots)
{ {