show device state
This commit is contained in:
parent
e883822ccc
commit
bd0304c5e2
20 changed files with 182 additions and 98 deletions
7
bus.cpp
7
bus.cpp
|
@ -130,6 +130,13 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_ui
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
void bus::set_memory_size(const int n_pages)
|
||||||
{
|
{
|
||||||
uint32_t n_bytes = n_pages * 8192l;
|
uint32_t n_bytes = n_pages * 8192l;
|
||||||
|
|
15
bus.h
15
bus.h
|
@ -9,6 +9,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
|
#include "device.h"
|
||||||
#include "dc11.h"
|
#include "dc11.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "rk05.h"
|
#include "rk05.h"
|
||||||
|
@ -56,7 +57,7 @@ typedef struct {
|
||||||
bool is_psw;
|
bool is_psw;
|
||||||
} write_rc_t;
|
} write_rc_t;
|
||||||
|
|
||||||
class bus
|
class bus: public device
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
cpu *c { nullptr };
|
cpu *c { nullptr };
|
||||||
|
@ -86,6 +87,8 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
void init(); // invoked by 'RESET' command
|
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_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; }
|
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; }
|
uint16_t get_console_switches() { return console_switches; }
|
||||||
|
@ -115,16 +118,18 @@ public:
|
||||||
tm_11 *getTM11() { return tm11; }
|
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(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); }
|
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 = i_space);
|
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);
|
uint16_t peekWord(const uint16_t a);
|
||||||
uint8_t readUnibusByte(const uint32_t a);
|
uint8_t readUnibusByte(const uint32_t a);
|
||||||
uint16_t readPhysical(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);
|
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 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_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 = i_space);
|
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);
|
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;
|
bool is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// (C) 2018-2023 by Folkert van Heusden
|
// (C) 2018-2024 by Folkert van Heusden
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// (C) 2018-2023 by Folkert van Heusden
|
// (C) 2018-2024 by Folkert van Heusden
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -6,16 +6,17 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "bus.h"
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include "win32.h"
|
#include "win32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class bus;
|
||||||
|
|
||||||
class console
|
class console
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// (C) 2018-2023 by Folkert van Heusden
|
// (C) 2018-2024 by Folkert van Heusden
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
@ -6,6 +6,7 @@
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "bus.h"
|
||||||
#include "console_ncurses.h"
|
#include "console_ncurses.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
26
dc11.cpp
26
dc11.cpp
|
@ -115,6 +115,28 @@ dc11::~dc11()
|
||||||
#endif
|
#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)
|
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");
|
TRACE("DC11: interrupt for line %d, %s", line_nr, is_tx ? "TX" : "RX");
|
||||||
|
@ -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);
|
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);
|
return !!(registers[line_nr * 4 + 2] & 64);
|
||||||
}
|
}
|
||||||
|
|
9
dc11.h
9
dc11.h
|
@ -48,7 +48,7 @@ private:
|
||||||
pollfd *pfds { nullptr };
|
pollfd *pfds { nullptr };
|
||||||
#endif
|
#endif
|
||||||
std::vector<char> recv_buffers[dc11_n_lines];
|
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 };
|
std::atomic_bool serial_thread_running { false };
|
||||||
bool serial_enabled { false };
|
bool serial_enabled { false };
|
||||||
#if IS_POSIX
|
#if IS_POSIX
|
||||||
|
@ -57,8 +57,8 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void trigger_interrupt(const int line_nr, const bool is_tx);
|
void trigger_interrupt(const int line_nr, const bool is_tx);
|
||||||
bool is_rx_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);
|
bool is_tx_interrupt_enabled(const int line_nr) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dc11(const int base_port, bus *const b);
|
dc11(const int base_port, bus *const b);
|
||||||
|
@ -70,6 +70,9 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
void show_state(console *const cnsl) const override;
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
void set_serial(const int bitrate, const int rx, const int tx);
|
void set_serial(const int bitrate, const int rx, const int tx);
|
||||||
void serial_handler();
|
void serial_handler();
|
||||||
|
|
100
debugger.cpp
100
debugger.cpp
|
@ -436,77 +436,6 @@ std::map<std::string, std::string> split(const std::vector<std::string> & kv_arr
|
||||||
return out;
|
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)
|
const char *trap_action_to_str(const trap_action_t ta)
|
||||||
{
|
{
|
||||||
if (ta == T_PROCEED)
|
if (ta == T_PROCEED)
|
||||||
|
@ -534,16 +463,16 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va)
|
||||||
uint16_t mmr3 = b->getMMU()->getMMR3();
|
uint16_t mmr3 = b->getMMU()->getMMR3();
|
||||||
|
|
||||||
if (run_mode == 0) {
|
if (run_mode == 0) {
|
||||||
dump_par_pdr(cnsl, b, ADDR_PDR_K_START, ADDR_PAR_K_START, "kernel i-space", 0, data.apf);
|
b->getMMU()->dump_par_pdr(cnsl, 1, false, "supervisor 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, true, "supervisor d-space", 1 + (!!(mmr3 & 4)), data.apf);
|
||||||
}
|
}
|
||||||
else if (run_mode == 1) {
|
else if (run_mode == 1) {
|
||||||
dump_par_pdr(cnsl, b, ADDR_PDR_SV_START, ADDR_PAR_SV_START, "supervisor i-space", 0, data.apf);
|
b->getMMU()->dump_par_pdr(cnsl, 0, false, "kernel 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, true, "kernel d-space", 1 + (!!(mmr3 & 4)), data.apf);
|
||||||
}
|
}
|
||||||
else if (run_mode == 3) {
|
else if (run_mode == 3) {
|
||||||
dump_par_pdr(cnsl, b, ADDR_PDR_U_START, ADDR_PAR_U_START, "user i-space", 0, data.apf);
|
b->getMMU()->dump_par_pdr(cnsl, 3, false, "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, true, "user d-space", 1 + (!!(mmr3 & 4)), data.apf);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<2; i++) {
|
for(int i=0; i<2; i++) {
|
||||||
|
@ -790,8 +719,19 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (parts[0] == "mmudump") {
|
else if (parts[0] == "state") {
|
||||||
mmu_dump(cnsl, b, parts.size() == 2 && parts[1] == "-v");
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -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",
|
"strace x - start tracing from address - invoke without address to disable",
|
||||||
"trl x - set trace run-level (0...3), empty for all",
|
"trl x - set trace run-level (0...3), empty for all",
|
||||||
"regdump - dump register contents",
|
"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",
|
"mmures x - resolve a virtual address",
|
||||||
"qi - show queued interrupts",
|
"qi - show queued interrupts",
|
||||||
"setpc x - set PC to value",
|
"setpc x - set PC to value",
|
||||||
|
|
3
device.h
3
device.h
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
class device
|
class device
|
||||||
{
|
{
|
||||||
|
@ -12,6 +13,8 @@ public:
|
||||||
|
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
|
|
||||||
|
virtual void show_state(console *const cnsl) const = 0;
|
||||||
|
|
||||||
virtual uint8_t read_byte(const uint16_t addr) = 0;
|
virtual uint8_t read_byte(const uint16_t addr) = 0;
|
||||||
virtual uint16_t read_word(const uint16_t addr) = 0;
|
virtual uint16_t read_word(const uint16_t addr) = 0;
|
||||||
|
|
||||||
|
|
|
@ -138,8 +138,8 @@ void set_boot_loader(bus *const b, const bootloader_t which)
|
||||||
bl = rl02_code;
|
bl = rl02_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<size; i++)
|
for(uint16_t i=0; i<size; i++)
|
||||||
b->write_word(offset + i * 2, bl[i]);
|
b->write_word(uint16_t(offset + i * 2), bl[i]);
|
||||||
|
|
||||||
c->setRegister(7, start);
|
c->setRegister(7, start);
|
||||||
}
|
}
|
||||||
|
|
40
mmu.cpp
40
mmu.cpp
|
@ -30,6 +30,46 @@ void mmu::reset()
|
||||||
CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0;
|
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)
|
uint16_t mmu::read_pdr(const uint32_t a, const int run_mode)
|
||||||
{
|
{
|
||||||
int page = (a >> 1) & 7;
|
int page = (a >> 1) & 7;
|
||||||
|
|
3
mmu.h
3
mmu.h
|
@ -77,6 +77,9 @@ public:
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
void 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;
|
||||||
|
void show_state(console *const cnsl) const override;
|
||||||
|
|
||||||
bool is_enabled() const { return MMR0 & 1; }
|
bool is_enabled() const { return MMR0 & 1; }
|
||||||
bool is_locked() const { return !!(MMR0 & 0160000); }
|
bool is_locked() const { return !!(MMR0 & 0160000); }
|
||||||
|
|
||||||
|
|
11
rk05.cpp
11
rk05.cpp
|
@ -46,6 +46,17 @@ void rk05::reset()
|
||||||
memset(registers, 0x00, sizeof registers);
|
memset(registers, 0x00, sizeof registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rk05::show_state(console *const cnsl) const
|
||||||
|
{
|
||||||
|
cnsl->put_string_lf(format("DS : %06o", registers[0]));
|
||||||
|
cnsl->put_string_lf(format("ERROR : %06o", registers[1]));
|
||||||
|
cnsl->put_string_lf(format("CS : %06o", registers[2]));
|
||||||
|
cnsl->put_string_lf(format("WC : %06o", registers[3]));
|
||||||
|
cnsl->put_string_lf(format("BA : %06o", registers[4]));
|
||||||
|
cnsl->put_string_lf(format("DA : %06o", registers[5]));
|
||||||
|
cnsl->put_string_lf(format("DATABUF: %06o", registers[6]));
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t rk05::read_byte(const uint16_t addr)
|
uint8_t rk05::read_byte(const uint16_t addr)
|
||||||
{
|
{
|
||||||
uint16_t v = read_word(addr & ~1);
|
uint16_t v = read_word(addr & ~1);
|
||||||
|
|
2
rk05.h
2
rk05.h
|
@ -46,6 +46,8 @@ public:
|
||||||
void begin() override;
|
void begin() override;
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
void show_state(console *const cnsl) const override;
|
||||||
|
|
||||||
#if IS_POSIX
|
#if IS_POSIX
|
||||||
json_t *serialize() const;
|
json_t *serialize() const;
|
||||||
static rk05 *deserialize(const json_t *const j, bus *const b);
|
static rk05 *deserialize(const json_t *const j, bus *const b);
|
||||||
|
|
12
rl02.cpp
12
rl02.cpp
|
@ -60,6 +60,18 @@ void rl02::reset()
|
||||||
sector = 0;
|
sector = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rl02::show_state(console *const cnsl) const
|
||||||
|
{
|
||||||
|
cnsl->put_string_lf(format("CSR: %06o", registers[0]));
|
||||||
|
cnsl->put_string_lf(format("BAR: %06o", registers[1]));
|
||||||
|
cnsl->put_string_lf(format("DAR: %06o", registers[2]));
|
||||||
|
cnsl->put_string_lf(format("MPR: %06o / %06o / %06o", mpr[0], mpr[1], mpr[2]));
|
||||||
|
|
||||||
|
cnsl->put_string_lf(format("track : %d", track ));
|
||||||
|
cnsl->put_string_lf(format("head : %d", head ));
|
||||||
|
cnsl->put_string_lf(format("sector: %d", sector));
|
||||||
|
}
|
||||||
|
|
||||||
#if IS_POSIX
|
#if IS_POSIX
|
||||||
json_t *rl02::serialize() const
|
json_t *rl02::serialize() const
|
||||||
{
|
{
|
||||||
|
|
2
rl02.h
2
rl02.h
|
@ -53,6 +53,8 @@ public:
|
||||||
void begin() override;
|
void begin() override;
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
void show_state(console *const cnsl) const override;
|
||||||
|
|
||||||
#if IS_POSIX
|
#if IS_POSIX
|
||||||
json_t *serialize() const;
|
json_t *serialize() const;
|
||||||
static rl02 *deserialize(const json_t *const j, bus *const b);
|
static rl02 *deserialize(const json_t *const j, bus *const b);
|
||||||
|
|
12
tm-11.cpp
12
tm-11.cpp
|
@ -43,6 +43,18 @@ void tm_11::load(const std::string & file)
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tm_11::show_state(console *const cnsl) const
|
||||||
|
{
|
||||||
|
cnsl->put_string_lf(format("MTS : %06o", registers[0]));
|
||||||
|
cnsl->put_string_lf(format("MTC : %06o", registers[1]));
|
||||||
|
cnsl->put_string_lf(format("MTBRC : %06o", registers[2]));
|
||||||
|
cnsl->put_string_lf(format("MTCMA : %06o", registers[3]));
|
||||||
|
cnsl->put_string_lf(format("MTD : %06o", registers[4]));
|
||||||
|
cnsl->put_string_lf(format("MTRD : %06o", registers[5]));
|
||||||
|
cnsl->put_string_lf(format("offset: %d", offset ));
|
||||||
|
cnsl->put_string_lf(format("tape file: %s", tape_file.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
void tm_11::reset()
|
void tm_11::reset()
|
||||||
{
|
{
|
||||||
memset(registers, 0x00, sizeof registers );
|
memset(registers, 0x00, sizeof registers );
|
||||||
|
|
2
tm-11.h
2
tm-11.h
|
@ -41,6 +41,8 @@ public:
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
|
void show_state(console *const cnsl) const override;
|
||||||
|
|
||||||
uint8_t read_byte(const uint16_t addr) override;
|
uint8_t read_byte(const uint16_t addr) override;
|
||||||
uint16_t read_word(const uint16_t addr) override;
|
uint16_t read_word(const uint16_t addr) override;
|
||||||
|
|
||||||
|
|
16
utils.cpp
16
utils.cpp
|
@ -11,6 +11,7 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
@ -257,3 +258,18 @@ void set_nodelay(const int fd)
|
||||||
#endif
|
#endif
|
||||||
DOLOG(warning, true, "Cannot disable nagle algorithm");
|
DOLOG(warning, true, "Cannot disable nagle algorithm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_endpoint_name(const int fd)
|
||||||
|
{
|
||||||
|
char host[64] { "?" };
|
||||||
|
char serv[32] { "?" };
|
||||||
|
sockaddr_in6 addr { 0 };
|
||||||
|
socklen_t addr_len = sizeof addr;
|
||||||
|
|
||||||
|
if (getpeername(fd, reinterpret_cast<sockaddr *>(&addr), &addr_len) == -1)
|
||||||
|
return format("FAILED TO FIND NAME OF %d: %s", fd, strerror(errno));
|
||||||
|
|
||||||
|
getnameinfo(reinterpret_cast<sockaddr *>(&addr), addr_len, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
|
|
||||||
|
return std::string(host) + "." + std::string(serv);
|
||||||
|
}
|
||||||
|
|
3
utils.h
3
utils.h
|
@ -1,4 +1,4 @@
|
||||||
// (C) 2018-2023 by Folkert van Heusden
|
// (C) 2018-2024 by Folkert van Heusden
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -27,3 +27,4 @@ ssize_t READ(int fd, char *whereto, size_t len);
|
||||||
void update_word(uint16_t *const w, const bool msb, const uint8_t v);
|
void update_word(uint16_t *const w, const bool msb, const uint8_t v);
|
||||||
|
|
||||||
void set_nodelay(const int fd);
|
void set_nodelay(const int fd);
|
||||||
|
std::string get_endpoint_name(const int fd);
|
||||||
|
|
Loading…
Add table
Reference in a new issue