Merge branch 'master' into serialize
This commit is contained in:
commit
dec8f92e97
5 changed files with 149 additions and 116 deletions
69
bus.cpp
69
bus.cpp
|
@ -8,6 +8,7 @@
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "kw11-l.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
|
@ -26,15 +27,14 @@ bus::bus()
|
||||||
|
|
||||||
mmu_ = new mmu();
|
mmu_ = new mmu();
|
||||||
|
|
||||||
reset();
|
kw11_l_ = new kw11_l(this);
|
||||||
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
reset();
|
||||||
xSemaphoreGive(lf_csr_lock); // initialize
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bus::~bus()
|
bus::~bus()
|
||||||
{
|
{
|
||||||
|
delete kw11_l_;
|
||||||
delete c;
|
delete c;
|
||||||
delete tm11;
|
delete tm11;
|
||||||
delete rk05_;
|
delete rk05_;
|
||||||
|
@ -220,22 +220,8 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a == ADDR_LFC) { // line frequency clock and status register
|
if (a == ADDR_LFC) // line frequency clock and status register
|
||||||
#if defined(BUILD_FOR_RP2040)
|
return kw11_l_->readWord(a);
|
||||||
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
|
||||||
#else
|
|
||||||
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint16_t temp = lf_csr;
|
|
||||||
if (!peek_only) DOLOG(debug, false, "READ-I/O line frequency clock: %o", temp);
|
|
||||||
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreGive(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a == ADDR_LP11CSR) { // printer, CSR register, LP11
|
if (a == ADDR_LP11CSR) { // printer, CSR register, LP11
|
||||||
uint16_t temp = 0x80;
|
uint16_t temp = 0x80;
|
||||||
|
@ -848,17 +834,8 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a == ADDR_LFC) { // line frequency clock and status register
|
if (a == ADDR_LFC) { // line frequency clock and status register
|
||||||
#if defined(BUILD_FOR_RP2040)
|
kw11_l_->writeWord(a, value);
|
||||||
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
|
||||||
#else
|
|
||||||
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DOLOG(debug, false, "WRITE-I/O set line frequency clock/status register: %06o", value);
|
|
||||||
lf_csr = value;
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreGive(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
return { false };
|
return { false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,35 +1000,3 @@ void bus::writeUnibusByte(const uint32_t a, const uint8_t v)
|
||||||
DOLOG(debug, false, "writeUnibusByte[%08o]=%03o", a, v);
|
DOLOG(debug, false, "writeUnibusByte[%08o]=%03o", a, v);
|
||||||
m->writeByte(a, v);
|
m->writeByte(a, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::set_lf_crs_b7()
|
|
||||||
{
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
|
||||||
#else
|
|
||||||
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lf_csr |= 128;
|
|
||||||
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreGive(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t bus::get_lf_crs()
|
|
||||||
{
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
|
||||||
#else
|
|
||||||
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t rc = lf_csr;
|
|
||||||
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
xSemaphoreGive(lf_csr_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
51
bus.h
51
bus.h
|
@ -54,6 +54,7 @@
|
||||||
#define ADDR_SYSTEM_ID 0177764
|
#define ADDR_SYSTEM_ID 0177764
|
||||||
|
|
||||||
class cpu;
|
class cpu;
|
||||||
|
class kw11_l;
|
||||||
class memory;
|
class memory;
|
||||||
class tty;
|
class tty;
|
||||||
|
|
||||||
|
@ -75,23 +76,17 @@ typedef struct {
|
||||||
class bus
|
class bus
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
cpu *c { nullptr };
|
cpu *c { nullptr };
|
||||||
tm_11 *tm11 { nullptr };
|
tm_11 *tm11 { nullptr };
|
||||||
rk05 *rk05_ { nullptr };
|
rk05 *rk05_ { nullptr };
|
||||||
rl02 *rl02_ { nullptr };
|
rl02 *rl02_ { nullptr };
|
||||||
tty *tty_ { nullptr };
|
tty *tty_ { nullptr };
|
||||||
|
kw11_l *kw11_l_ { nullptr };
|
||||||
|
|
||||||
mmu *mmu_ { nullptr };
|
mmu *mmu_ { nullptr };
|
||||||
|
|
||||||
int n_pages { DEFAULT_N_PAGES };
|
int n_pages { DEFAULT_N_PAGES };
|
||||||
memory *m { nullptr };
|
memory *m { nullptr };
|
||||||
|
|
||||||
#if defined(BUILD_FOR_RP2040)
|
|
||||||
SemaphoreHandle_t lf_csr_lock { xSemaphoreCreateBinary() };
|
|
||||||
#else
|
|
||||||
std::mutex lf_csr_lock;
|
|
||||||
#endif
|
|
||||||
uint16_t lf_csr { 0 };
|
|
||||||
|
|
||||||
uint16_t microprogram_break_register { 0 };
|
uint16_t microprogram_break_register { 0 };
|
||||||
|
|
||||||
|
@ -103,35 +98,29 @@ public:
|
||||||
~bus();
|
~bus();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
void init(); // invoked by 'RESET' command
|
||||||
|
|
||||||
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; }
|
||||||
void set_debug_mode() { console_switches |= 128; }
|
void set_debug_mode() { console_switches |= 128; }
|
||||||
|
uint16_t get_console_leds() { return console_leds; }
|
||||||
|
|
||||||
int get_memory_size() const { return n_pages; }
|
int get_memory_size() const { return n_pages; }
|
||||||
void set_memory_size(const int n_pages);
|
void set_memory_size(const int n_pages);
|
||||||
|
|
||||||
void mmudebug(const uint16_t a);
|
void mmudebug(const uint16_t a);
|
||||||
|
|
||||||
uint16_t get_console_leds() { return console_leds; }
|
void add_cpu (cpu *const c );
|
||||||
|
void add_tm11(tm_11 *const tm11 );
|
||||||
|
void add_rk05(rk05 *const rk05_);
|
||||||
|
void add_rl02(rl02 *const rl02_);
|
||||||
|
void add_tty (tty *const tty_ );
|
||||||
|
|
||||||
void add_cpu (cpu *const c);
|
cpu *getCpu() { return c; }
|
||||||
void add_tm11(tm_11 *const tm11);
|
kw11_l *getKW11_L() { return kw11_l_; }
|
||||||
void add_rk05(rk05 *const rk05_);
|
tty *getTty() { return tty_; }
|
||||||
void add_rl02(rl02 *const rl02_);
|
mmu *getMMU() { return mmu_; }
|
||||||
void add_tty (tty *const tty_);
|
|
||||||
|
|
||||||
cpu *getCpu() { return c; }
|
|
||||||
|
|
||||||
tty *getTty() { return tty_; }
|
|
||||||
|
|
||||||
mmu *getMMU() { return mmu_; }
|
|
||||||
|
|
||||||
void init(); // invoked by 'RESET' command
|
|
||||||
|
|
||||||
void set_lf_crs_b7();
|
|
||||||
uint8_t get_lf_crs();
|
|
||||||
|
|
||||||
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 readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); }
|
uint16_t readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); }
|
||||||
|
|
106
kw11-l.cpp
106
kw11-l.cpp
|
@ -25,13 +25,8 @@ void thread_wrapper_kw11(void *p)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
kw11_l::kw11_l(bus *const b, console *const cnsl) : b(b), cnsl(cnsl)
|
kw11_l::kw11_l(bus *const b): b(b)
|
||||||
{
|
{
|
||||||
#if defined(ESP32) || defined(BUILD_FOR_RP2040)
|
|
||||||
xTaskCreate(&thread_wrapper_kw11, "kw11-l", 2048, this, 1, nullptr);
|
|
||||||
#else
|
|
||||||
th = new std::thread(std::ref(*this));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kw11_l::~kw11_l()
|
kw11_l::~kw11_l()
|
||||||
|
@ -39,9 +34,26 @@ kw11_l::~kw11_l()
|
||||||
stop_flag = true;
|
stop_flag = true;
|
||||||
|
|
||||||
#if !defined(ESP32) && !defined(BUILD_FOR_RP2040)
|
#if !defined(ESP32) && !defined(BUILD_FOR_RP2040)
|
||||||
th->join();
|
if (th) {
|
||||||
|
th->join();
|
||||||
|
|
||||||
delete th;
|
delete th;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void kw11_l::begin(console *const cnsl)
|
||||||
|
{
|
||||||
|
this->cnsl = cnsl;
|
||||||
|
|
||||||
|
#if defined(ESP32) || defined(BUILD_FOR_RP2040)
|
||||||
|
xTaskCreate(&thread_wrapper_kw11, "kw11-l", 2048, this, 1, nullptr);
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreGive(lf_csr_lock); // initialize
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
th = new std::thread(std::ref(*this));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +65,9 @@ void kw11_l::operator()()
|
||||||
|
|
||||||
while(!stop_flag) {
|
while(!stop_flag) {
|
||||||
if (*cnsl->get_running_flag()) {
|
if (*cnsl->get_running_flag()) {
|
||||||
b->set_lf_crs_b7();
|
set_lf_crs_b7();
|
||||||
|
|
||||||
if (b->get_lf_crs() & 64)
|
if (get_lf_crs() & 64)
|
||||||
b->getCpu()->queue_interrupt(6, 0100);
|
b->getCpu()->queue_interrupt(6, 0100);
|
||||||
|
|
||||||
// TODO: dependant on cpu cycles processed
|
// TODO: dependant on cpu cycles processed
|
||||||
|
@ -68,3 +80,77 @@ void kw11_l::operator()()
|
||||||
|
|
||||||
DOLOG(debug, true, "KW11-L thread terminating");
|
DOLOG(debug, true, "KW11-L thread terminating");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t kw11_l::readWord(const uint16_t a)
|
||||||
|
{
|
||||||
|
if (a != ADDR_LFC) {
|
||||||
|
DOLOG(debug, true, "KW11-L readWord not for us (%06o)", a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
||||||
|
#else
|
||||||
|
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint16_t temp = lf_csr;
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreGive(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kw11_l::writeWord(const uint16_t a, const uint16_t value)
|
||||||
|
{
|
||||||
|
if (a != ADDR_LFC) {
|
||||||
|
DOLOG(debug, true, "KW11-L writeWord not for us (%06o to %06o)", value, a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
||||||
|
#else
|
||||||
|
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DOLOG(debug, false, "WRITE-I/O set line frequency clock/status register: %06o", value);
|
||||||
|
lf_csr = value;
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreGive(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void kw11_l::set_lf_crs_b7()
|
||||||
|
{
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
||||||
|
#else
|
||||||
|
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lf_csr |= 128;
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreGive(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t kw11_l::get_lf_crs()
|
||||||
|
{
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreTake(lf_csr_lock, portMAX_DELAY);
|
||||||
|
#else
|
||||||
|
std::unique_lock<std::mutex> lck(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t rc = lf_csr;
|
||||||
|
|
||||||
|
#if defined(BUILD_FOR_RP2040)
|
||||||
|
xSemaphoreGive(lf_csr_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
29
kw11-l.h
29
kw11-l.h
|
@ -1,26 +1,39 @@
|
||||||
// (C) 2018-2023 by Folkert van Heusden
|
// (C) 2018-2024 by Folkert van Heusden
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
|
|
||||||
class kw11_l
|
class kw11_l
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bus *const b { nullptr };
|
bus *const b { nullptr };
|
||||||
console *const cnsl { nullptr };
|
console *cnsl { nullptr };
|
||||||
|
|
||||||
#if !defined(BUILD_FOR_RP2040)
|
#if defined(BUILD_FOR_RP2040)
|
||||||
std::thread * th { nullptr };
|
SemaphoreHandle_t lf_csr_lock { xSemaphoreCreateBinary() };
|
||||||
|
#else
|
||||||
|
std::thread *th { nullptr };
|
||||||
|
std::mutex lf_csr_lock;
|
||||||
#endif
|
#endif
|
||||||
std::atomic_bool stop_flag { false };
|
uint16_t lf_csr { 0 };
|
||||||
|
|
||||||
|
std::atomic_bool stop_flag { false };
|
||||||
|
|
||||||
|
uint8_t get_lf_crs();
|
||||||
|
void set_lf_crs_b7();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
kw11_l(bus *const b, console *const cnsl);
|
kw11_l(bus *const b);
|
||||||
virtual ~kw11_l();
|
virtual ~kw11_l();
|
||||||
|
|
||||||
void operator()();
|
void begin(console *const cnsl);
|
||||||
|
void operator()();
|
||||||
|
|
||||||
|
uint16_t readWord (const uint16_t a);
|
||||||
|
void writeWord(const uint16_t a, const uint16_t v);
|
||||||
};
|
};
|
||||||
|
|
10
main.cpp
10
main.cpp
|
@ -584,14 +584,14 @@ int main(int argc, char *argv[])
|
||||||
if (test.empty() == false)
|
if (test.empty() == false)
|
||||||
load_p11_x11(b, test);
|
load_p11_x11(b, test);
|
||||||
|
|
||||||
kw11_l *lf = new kw11_l(b, cnsl);
|
|
||||||
|
|
||||||
std::thread *metrics_thread = nullptr;
|
std::thread *metrics_thread = nullptr;
|
||||||
if (metrics)
|
if (metrics)
|
||||||
metrics_thread = new std::thread(get_metrics, c);
|
metrics_thread = new std::thread(get_metrics, c);
|
||||||
|
|
||||||
cnsl->start_thread();
|
cnsl->start_thread();
|
||||||
|
|
||||||
|
b->getKW11_L()->begin(cnsl);
|
||||||
|
|
||||||
if (is_bic)
|
if (is_bic)
|
||||||
run_bic(cnsl, b, &event, tracing, bic_start.value());
|
run_bic(cnsl, b, &event, tracing, bic_start.value());
|
||||||
else if (run_debugger || (bootloader == BL_NONE && test.empty() && tape.empty()))
|
else if (run_debugger || (bootloader == BL_NONE && test.empty() && tape.empty()))
|
||||||
|
@ -624,11 +624,11 @@ int main(int argc, char *argv[])
|
||||||
delete metrics_thread;
|
delete metrics_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete lf;
|
cnsl->stop_thread();
|
||||||
|
|
||||||
delete cnsl;
|
|
||||||
|
|
||||||
delete b;
|
delete b;
|
||||||
|
|
||||||
|
delete cnsl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue