Skip to content

Commit

Permalink
show device state
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertvanheusden committed May 10, 2024
1 parent e883822 commit bd0304c
Show file tree
Hide file tree
Showing 20 changed files with 182 additions and 98 deletions.
7 changes: 7 additions & 0 deletions bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_ui
}
#endif

void bus::show_state(console *const cnsl) const
{
cnsl->put_string_lf(format("Microprogram break register: %06o", microprogram_break_register));
cnsl->put_string_lf(format("Console switches: %06o", console_switches));
cnsl->put_string_lf(format("Console LEDs: %06o", console_leds));
}

void bus::set_memory_size(const int n_pages)
{
uint32_t n_bytes = n_pages * 8192l;
Expand Down
15 changes: 10 additions & 5 deletions bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <stdio.h>

#include "gen.h"
#include "device.h"
#include "dc11.h"
#include "mmu.h"
#include "rk05.h"
Expand Down Expand Up @@ -56,7 +57,7 @@ typedef struct {
bool is_psw;
} write_rc_t;

class bus
class bus: public device
{
private:
cpu *c { nullptr };
Expand Down Expand Up @@ -86,6 +87,8 @@ class bus
void reset();
void init(); // invoked by 'RESET' command

void show_state(console *const cnsl) const override;

void set_console_switches(const uint16_t new_state) { console_switches = new_state; }
void set_console_switch(const int bit, const bool state) { console_switches &= ~(1 << bit); console_switches |= state << bit; }
uint16_t get_console_switches() { return console_switches; }
Expand Down Expand Up @@ -115,16 +118,18 @@ class bus
tm_11 *getTM11() { return tm11; }

uint16_t read(const uint16_t a, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only=false, const d_i_space_t s = i_space);
uint16_t read_byte(const uint16_t a) { return read(a, wm_byte, rm_cur); }
uint16_t read_word(const uint16_t a, const d_i_space_t s = i_space);
uint8_t read_byte(const uint16_t a) override { return read(a, wm_byte, rm_cur); }
uint16_t read_word(const uint16_t a, const d_i_space_t s);
uint16_t read_word(const uint16_t a) override { return read_word(a, i_space); }
uint16_t peekWord(const uint16_t a);
uint8_t readUnibusByte(const uint32_t a);
uint16_t readPhysical(const uint32_t a);

write_rc_t write(const uint16_t a, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t s = i_space);
void writeUnibusByte(const uint32_t a, const uint8_t value);
void write_byte(const uint16_t a, const uint8_t value) { write(a, wm_byte, value, rm_cur); }
void write_word(const uint16_t a, const uint16_t value, const d_i_space_t s = i_space);
void write_byte(const uint16_t a, const uint8_t value) override { write(a, wm_byte, value, rm_cur); }
void write_word(const uint16_t a, const uint16_t value, const d_i_space_t s);
void write_word(const uint16_t a, const uint16_t value) override { write_word(a, value, i_space); }
void writePhysical(const uint32_t a, const uint16_t value);

bool is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const;
Expand Down
3 changes: 2 additions & 1 deletion console.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// (C) 2018-2023 by Folkert van Heusden
// (C) 2018-2024 by Folkert van Heusden
// Released under MIT license

#include <cassert>
#include <chrono>
#include <optional>
#include <stdarg.h>
Expand Down
7 changes: 4 additions & 3 deletions console.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// (C) 2018-2023 by Folkert van Heusden
// (C) 2018-2024 by Folkert van Heusden
// Released under MIT license

#pragma once

#include <atomic>
#include <condition_variable>
#include <optional>
#include <string>
#include <thread>
#include <vector>

#include "bus.h"

#if defined(_WIN32)
#include "win32.h"
#endif


class bus;

class console
{
private:
Expand Down
3 changes: 2 additions & 1 deletion console_ncurses.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// (C) 2018-2023 by Folkert van Heusden
// (C) 2018-2024 by Folkert van Heusden
// Released under MIT license

#include <poll.h>
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>

#include "bus.h"
#include "console_ncurses.h"
#include "cpu.h"
#include "error.h"
Expand Down
26 changes: 24 additions & 2 deletions dc11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,28 @@ dc11::~dc11()
#endif
}

void dc11::show_state(console *const cnsl) const
{
for(int i=0; i<4; i++) {
cnsl->put_string_lf(format("* LINE %d", i + 1));

if (i == serial_line) {
cnsl->put_string_lf(format(" Serial thread running: %s", serial_thread_running ? "true": "false" ));
cnsl->put_string_lf(format(" Serial enabled: %s", serial_enabled ? "true": "false" ));
}
else {
if (pfds[dc11_n_lines + i].fd != INVALID_SOCKET)
cnsl->put_string_lf(" Connected to: " + get_endpoint_name(pfds[dc11_n_lines + i].fd));
}

std::unique_lock<std::mutex> lck(input_lock[i]);
cnsl->put_string_lf(format(" Characters in buffer: %zu", recv_buffers[i].size()));

cnsl->put_string_lf(format(" RX interrupt enabled: %s", is_rx_interrupt_enabled(i) ? "true": "false" ));
cnsl->put_string_lf(format(" TX interrupt enabled: %s", is_tx_interrupt_enabled(i) ? "true": "false" ));
}
}

void dc11::trigger_interrupt(const int line_nr, const bool is_tx)
{
TRACE("DC11: interrupt for line %d, %s", line_nr, is_tx ? "TX" : "RX");
Expand Down Expand Up @@ -423,12 +445,12 @@ void dc11::reset()
{
}

bool dc11::is_rx_interrupt_enabled(const int line_nr)
bool dc11::is_rx_interrupt_enabled(const int line_nr) const
{
return !!(registers[line_nr * 4 + 0] & 64);
}

bool dc11::is_tx_interrupt_enabled(const int line_nr)
bool dc11::is_tx_interrupt_enabled(const int line_nr) const
{
return !!(registers[line_nr * 4 + 2] & 64);
}
Expand Down
9 changes: 6 additions & 3 deletions dc11.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class dc11: public device
pollfd *pfds { nullptr };
#endif
std::vector<char> recv_buffers[dc11_n_lines];
std::mutex input_lock[dc11_n_lines];
mutable std::mutex input_lock[dc11_n_lines];
std::atomic_bool serial_thread_running { false };
bool serial_enabled { false };
#if IS_POSIX
Expand All @@ -57,8 +57,8 @@ class dc11: public device
#endif

void trigger_interrupt(const int line_nr, const bool is_tx);
bool is_rx_interrupt_enabled(const int line_nr);
bool is_tx_interrupt_enabled(const int line_nr);
bool is_rx_interrupt_enabled(const int line_nr) const;
bool is_tx_interrupt_enabled(const int line_nr) const;

public:
dc11(const int base_port, bus *const b);
Expand All @@ -70,6 +70,9 @@ class dc11: public device
#endif

void reset();

void show_state(console *const cnsl) const override;

#if defined(ESP32)
void set_serial(const int bitrate, const int rx, const int tx);
void serial_handler();
Expand Down
100 changes: 20 additions & 80 deletions debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,77 +436,6 @@ std::map<std::string, std::string> split(const std::vector<std::string> & kv_arr
return out;
}

void dump_par_pdr(console *const cnsl, bus *const b, const uint16_t pdrs, const uint16_t pars, const std::string & name, const int state, const std::optional<int> & selection)
{
if (state == 0 || state == 2)
cnsl->put_string_lf(name);
else
cnsl->put_string_lf(format("%s DISABLED", name.c_str()));

cnsl->put_string_lf(" PAR PDR LEN");

for(int i=0; i<8; i++) {
if (selection.has_value() && i != selection.value())
continue;
uint16_t par_value = b->read(pars + i * 2, wm_word, rm_cur, true);
uint16_t pdr_value = b->read(pdrs + i * 2, wm_word, rm_cur, true);

uint16_t pdr_len = (((pdr_value >> 8) & 127) + 1) * 64;

cnsl->put_string_lf(format("%d] %06o %08o %06o %04o D%d A%d", i, par_value, par_value * 64, pdr_value, pdr_len, !!(pdr_value & 8), pdr_value & 7));
}
}

void dump_memory_contents(console *const cnsl, bus *const b, const uint16_t read_addr)
{
cnsl->put_string_lf(format("\tMOV #%06o,R0", read_addr));
cnsl->put_string_lf(format("\tMOV #%06o,(R0)", b->read(read_addr, wm_word, rm_cur, true)));
}

void dump_range_as_instructions(console *const cnsl, bus *const b, const uint16_t base)
{
for(int i=0; i<8; i++)
dump_memory_contents(cnsl, b, base + i * 2);
}

void mmu_dump(console *const cnsl, bus *const b, const bool verbose)
{
uint16_t mmr0 = b->getMMU()->getMMR0();
uint16_t mmr1 = b->getMMU()->getMMR1();
uint16_t mmr2 = b->getMMU()->getMMR2();
uint16_t mmr3 = b->getMMU()->getMMR3();

cnsl->put_string_lf(mmr0 & 1 ? "MMU enabled" : "MMU NOT enabled");

cnsl->put_string_lf(format("MMR0: %06o", mmr0));
cnsl->put_string_lf(format("MMR1: %06o", mmr1));
cnsl->put_string_lf(format("MMR2: %06o", mmr2));
cnsl->put_string_lf(format("MMR3: %06o", mmr3));

dump_par_pdr(cnsl, b, ADDR_PDR_SV_START, ADDR_PAR_SV_START, "supervisor i-space", 0, { });
dump_par_pdr(cnsl, b, ADDR_PDR_SV_START + 020, ADDR_PAR_SV_START + 020, "supervisor d-space", 1 + (!!(mmr3 & 2)), { });

dump_par_pdr(cnsl, b, ADDR_PDR_K_START, ADDR_PAR_K_START, "kernel i-space", 0, { });
dump_par_pdr(cnsl, b, ADDR_PDR_K_START + 020, ADDR_PAR_K_START + 020, "kernel d-space", 1 + (!!(mmr3 & 4)), { });

dump_par_pdr(cnsl, b, ADDR_PDR_U_START, ADDR_PAR_U_START, "user i-space", 0, { });
dump_par_pdr(cnsl, b, ADDR_PDR_U_START + 020, ADDR_PAR_U_START + 020, "user d-space", 1 + (!!(mmr3 & 1)), { });

if (verbose) {
dump_range_as_instructions(cnsl, b, ADDR_PDR_SV_START); // sv i
dump_range_as_instructions(cnsl, b, ADDR_PDR_SV_START + 020); // sv d
dump_range_as_instructions(cnsl, b, ADDR_PDR_K_START); // k i
dump_range_as_instructions(cnsl, b, ADDR_PDR_K_START + 020); // k d
dump_range_as_instructions(cnsl, b, ADDR_PDR_U_START); // u i
dump_range_as_instructions(cnsl, b, ADDR_PDR_U_START + 020); // u d

dump_memory_contents(cnsl, b, ADDR_MMR0);
dump_memory_contents(cnsl, b, ADDR_MMR1);
dump_memory_contents(cnsl, b, ADDR_MMR2);
dump_memory_contents(cnsl, b, ADDR_MMR3);
}
}

const char *trap_action_to_str(const trap_action_t ta)
{
if (ta == T_PROCEED)
Expand Down Expand Up @@ -534,16 +463,16 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va)
uint16_t mmr3 = b->getMMU()->getMMR3();

if (run_mode == 0) {
dump_par_pdr(cnsl, b, ADDR_PDR_K_START, ADDR_PAR_K_START, "kernel i-space", 0, data.apf);
dump_par_pdr(cnsl, b, ADDR_PDR_K_START + 020, ADDR_PAR_K_START + 020, "kernel d-space", 1 + (!!(mmr3 & 4)), data.apf);
b->getMMU()->dump_par_pdr(cnsl, 1, false, "supervisor i-space", 0, data.apf);
b->getMMU()->dump_par_pdr(cnsl, 1, true, "supervisor d-space", 1 + (!!(mmr3 & 4)), data.apf);
}
else if (run_mode == 1) {
dump_par_pdr(cnsl, b, ADDR_PDR_SV_START, ADDR_PAR_SV_START, "supervisor i-space", 0, data.apf);
dump_par_pdr(cnsl, b, ADDR_PDR_SV_START + 020, ADDR_PAR_SV_START + 020, "supervisor d-space", 1 + (!!(mmr3 & 4)), data.apf);
b->getMMU()->dump_par_pdr(cnsl, 0, false, "kernel i-space", 0, data.apf);
b->getMMU()->dump_par_pdr(cnsl, 0, true, "kernel d-space", 1 + (!!(mmr3 & 4)), data.apf);
}
else if (run_mode == 3) {
dump_par_pdr(cnsl, b, ADDR_PDR_U_START, ADDR_PAR_U_START, "user i-space", 0, data.apf);
dump_par_pdr(cnsl, b, ADDR_PDR_U_START + 020, ADDR_PAR_U_START + 020, "user d-space", 1 + (!!(mmr3 & 4)), data.apf);
b->getMMU()->dump_par_pdr(cnsl, 3, false, "user i-space", 0, data.apf);
b->getMMU()->dump_par_pdr(cnsl, 3, true, "user d-space", 1 + (!!(mmr3 & 4)), data.apf);
}

for(int i=0; i<2; i++) {
Expand Down Expand Up @@ -790,8 +719,19 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto

continue;
}
else if (parts[0] == "mmudump") {
mmu_dump(cnsl, b, parts.size() == 2 && parts[1] == "-v");
else if (parts[0] == "state") {
if (parts[1] == "rl02")
b->getRL02()->show_state(cnsl);
else if (parts[1] == "mmu")
b->getMMU() ->show_state(cnsl);
else if (parts[1] == "rk05")
b->getRK05()->show_state(cnsl);
else if (parts[1] == "dc11")
b->getDC11()->show_state(cnsl);
else if (parts[1] == "tm11")
b->getTM11()->show_state(cnsl);
else
cnsl->put_string_lf(format("Device \"%s\" is not known", parts[1].c_str()));

continue;
}
Expand Down Expand Up @@ -1072,7 +1012,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"strace x - start tracing from address - invoke without address to disable",
"trl x - set trace run-level (0...3), empty for all",
"regdump - dump register contents",
"mmudump - dump MMU settings (PARs/PDRs)",
"state x - dump state of a device: rl02, rk05, mmu, tm11 or dc11",
"mmures x - resolve a virtual address",
"qi - show queued interrupts",
"setpc x - set PC to value",
Expand Down
3 changes: 3 additions & 0 deletions device.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "console.h"

class device
{
Expand All @@ -12,6 +13,8 @@ class device

virtual void reset() = 0;

virtual void show_state(console *const cnsl) const = 0;

virtual uint8_t read_byte(const uint16_t addr) = 0;
virtual uint16_t read_word(const uint16_t addr) = 0;

Expand Down
4 changes: 2 additions & 2 deletions loaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ void set_boot_loader(bus *const b, const bootloader_t which)
bl = rl02_code;
}

for(int i=0; i<size; i++)
b->write_word(offset + i * 2, bl[i]);
for(uint16_t i=0; i<size; i++)
b->write_word(uint16_t(offset + i * 2), bl[i]);

c->setRegister(7, start);
}
Expand Down
40 changes: 40 additions & 0 deletions mmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,46 @@ void mmu::reset()
CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0;
}

void mmu::dump_par_pdr(console *const cnsl, const int run_mode, const bool d, const std::string & name, const int state, const std::optional<int> & selection) const
{
if (state == 0 || state == 2)
cnsl->put_string_lf(name);
else
cnsl->put_string_lf(format("%s DISABLED", name.c_str()));

cnsl->put_string_lf(" PAR PDR LEN");

for(int i=0; i<8; i++) {
if (selection.has_value() && i != selection.value())
continue;
uint16_t par_value = pages[run_mode][d][i].par;
uint16_t pdr_value = pages[run_mode][d][i].pdr;

uint16_t pdr_len = (((pdr_value >> 8) & 127) + 1) * 64;

cnsl->put_string_lf(format("%d] %06o %08o %06o %04o D%d A%d", i, par_value, par_value * 64, pdr_value, pdr_len, !!(pdr_value & 8), pdr_value & 7));
}
}

void mmu::show_state(console *const cnsl) const
{
cnsl->put_string_lf(MMR0 & 1 ? "MMU enabled" : "MMU NOT enabled");

cnsl->put_string_lf(format("MMR0: %06o", MMR0));
cnsl->put_string_lf(format("MMR1: %06o", MMR1));
cnsl->put_string_lf(format("MMR2: %06o", MMR2));
cnsl->put_string_lf(format("MMR3: %06o", MMR3));

dump_par_pdr(cnsl, 1, false, "supervisor i-space", 0, { });
dump_par_pdr(cnsl, 1, true, "supervisor d-space", 1 + (!!(MMR3 & 2)), { });

dump_par_pdr(cnsl, 0, false, "kernel i-space", 0, { });
dump_par_pdr(cnsl, 0, true, "kernel d-space", 1 + (!!(MMR3 & 2)), { });

dump_par_pdr(cnsl, 3, false, "user i-space", 0, { });
dump_par_pdr(cnsl, 3, true, "user d-space", 1 + (!!(MMR3 & 2)), { });
}

uint16_t mmu::read_pdr(const uint32_t a, const int run_mode)
{
int page = (a >> 1) & 7;
Expand Down
Loading

0 comments on commit bd0304c

Please sign in to comment.