From d851c4b9a02e3df423a6f5b011d13e45b372f65a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 08:18:27 +0200 Subject: [PATCH 01/28] 18bit mode --- bus.cpp | 3 +++ main.cpp | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index da96f68..446b244 100644 --- a/bus.cpp +++ b/bus.cpp @@ -345,6 +345,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c m_offset += p_offset; + if ((MMR3 & 16) == 0) // off is 18bit + m_offset &= 0x3ffff; + if (trap_on_failure) { if ((MMR0 & (1 << 9)) || c->get_34()) { const int access_control = pages[run_mode][0][apf].pdr & 7; diff --git a/main.cpp b/main.cpp index c5a13e8..24631da 100644 --- a/main.cpp +++ b/main.cpp @@ -60,7 +60,6 @@ int main(int argc, char *argv[]) std::vector rk05_files; std::vector rl02_files; - bool testCases = false; bool run_debugger = false; bool tracing = false; From 9d55740a0f84b090b3e62368e99733f85400c051 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 08:48:29 +0200 Subject: [PATCH 02/28] SR0 errors by KKTBD0 fixed --- bus.cpp | 19 ++++++++++++++++++- bus.h | 1 + cpu.cpp | 7 +++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/bus.cpp b/bus.cpp index 446b244..e3cb197 100644 --- a/bus.cpp +++ b/bus.cpp @@ -326,6 +326,14 @@ void bus::setMMR0Bit(const int bit) MMR0 |= 1 << bit; } +void bus::clearMMR0Bit(const int bit) +{ + assert(bit != 10 && bit != 11); + assert(bit < 16 && bit >= 0); + + MMR0 &= ~(1 << bit); +} + void bus::setMMR2(const uint16_t value) { MMR2 = value; @@ -359,6 +367,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + MMR0 &= 017777; MMR0 |= 1 << 13; // read-only MMR0 &= ~(3 << 5); @@ -367,6 +376,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 &= ~14; // add current page MMR0 |= apf << 1; + DOLOG(info, true, "MMR0: %06o", MMR0); + throw 1; } else if (!is_write) { // read @@ -377,7 +388,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - MMR0 |= 1 << 13; // read-only + MMR0 &= 017777; + if (access_control == 0 || access_control == 4) + MMR0 |= 1 << 15; // not resident + else + MMR0 |= 1 << 13; // read-only MMR0 &= ~(3 << 5); MMR0 |= run_mode << 5; @@ -398,6 +413,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192); DOLOG(info, true, "TRAP(04) (throw 3) on address %06o", a); + MMR0 &= 017777; MMR0 |= 1 << 15; // non-resident MMR0 &= ~14; // add current page @@ -415,6 +431,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(info, true, "TRAP(0250) (throw 4) on address %06o", a); c->schedule_trap(0250); // invalid access + MMR0 &= 017777; MMR0 |= 1 << 14; // length MMR0 &= ~14; // add current page diff --git a/bus.h b/bus.h index ba06211..b4c92d5 100644 --- a/bus.h +++ b/bus.h @@ -85,6 +85,7 @@ public: void addToMMR1(const int8_t delta, const uint8_t reg); void setMMR0(int value); void setMMR0Bit(const int bit); + void clearMMR0Bit(const int bit); void setMMR2(const uint16_t value); uint16_t get_switch_register() const { return switch_register; } diff --git a/cpu.cpp b/cpu.cpp index a8243b8..44b79a6 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1647,6 +1647,7 @@ void cpu::schedule_trap(const uint16_t vector) scheduled_trap = vector; } +// 'is_interrupt' is not correct naming; it is true for mmu faults and interrupts void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt) { uint16_t before_psw = getPSW(); @@ -1661,7 +1662,9 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt b->addToMMR1(-2, 6); } - if (!is_interrupt) + if (is_interrupt) + b->clearMMR0Bit(12); + else b->setMMR0Bit(12); // it's a trap setPC(b->readWord(vector + 0)); @@ -2156,7 +2159,7 @@ void cpu::step_a() b->clearMMR1(); if (scheduled_trap) { - trap(scheduled_trap, 7); + trap(scheduled_trap, 7, true); scheduled_trap = 0; From 7605c934c26a222204f9e92f30c080aafbc3c12a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 09:10:51 +0200 Subject: [PATCH 03/28] throw 3/4: add run mode --- bus.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index e3cb197..c31a944 100644 --- a/bus.cpp +++ b/bus.cpp @@ -419,8 +419,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 &= ~14; // add current page MMR0 |= apf << 1; + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - // + c->schedule_trap(04); throw 3; @@ -437,6 +440,9 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 &= ~14; // add current page MMR0 |= apf << 1; + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I throw 4; From 7427ddc226bf2e660df319bfb35349b426c35d85 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 11:42:40 +0200 Subject: [PATCH 04/28] PDR-len calculation fix(?) do not update MMR0 when already set --- bus.cpp | 87 ++++++++++++++++++++++++++++++++------------------------- cpu.cpp | 2 ++ 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/bus.cpp b/bus.cpp index c31a944..03ab696 100644 --- a/bus.cpp +++ b/bus.cpp @@ -361,66 +361,69 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c const int access_control = pages[run_mode][0][apf].pdr & 7; if (is_write && access_control != 6) { // write - DOLOG(info, true, "TRAP(0250) (throw 1) for access_control %d on address %06o", access_control, a); + DOLOG(debug, true, "TRAP(0250) (throw 1) for access_control %d on address %06o", access_control, a); c->schedule_trap(0250); // invalid address pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - MMR0 &= 017777; - MMR0 |= 1 << 13; // read-only + if ((MMR0 & 0160000) == 0) { + MMR0 &= 017777; + MMR0 |= 1 << 13; // read-only - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + MMR0 &= ~14; // add current page + MMR0 |= apf << 1; + } - DOLOG(info, true, "MMR0: %06o", MMR0); + DOLOG(debug, true, "MMR0: %06o", MMR0); throw 1; } else if (!is_write) { // read if (access_control == 0 || access_control == 1 || access_control == 3 || access_control == 4 || access_control == 7) { - DOLOG(info, true, "TRAP(4) (throw 2) for access_control %d on address %06o", access_control, a); + DOLOG(debug, true, "TRAP(4) (throw 2) for access_control %d on address %06o", access_control, a); c->schedule_trap(0250); // invalid address pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - MMR0 &= 017777; - if (access_control == 0 || access_control == 4) - MMR0 |= 1 << 15; // not resident - else - MMR0 |= 1 << 13; // read-only + if ((MMR0 & 0160000) == 0) { + MMR0 &= 017777; - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; + if (access_control == 0 || access_control == 4) + MMR0 |= 1 << 15; // not resident + else + MMR0 |= 1 << 13; // read-only - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; + + MMR0 &= ~14; // add current page + MMR0 |= apf << 1; + } throw 2; } } } - uint16_t pdr_len = (((pages[run_mode][0][apf].pdr >> 8) & 127) + 1) * 64; // TODO: D/I - - bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I - if (m_offset >= n_pages * 8192) { DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192); - DOLOG(info, true, "TRAP(04) (throw 3) on address %06o", a); + DOLOG(debug, true, "TRAP(04) (throw 3) on address %06o", a); - MMR0 &= 017777; - MMR0 |= 1 << 15; // non-resident + if ((MMR0 & 0160000) == 0) { + MMR0 &= 017777; + MMR0 |= 1 << 15; // non-resident - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + MMR0 &= ~14; // add current page + MMR0 |= apf << 1; - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; + } pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I @@ -429,19 +432,27 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c throw 3; } + uint16_t pdr_len = ((pages[run_mode][0][apf].pdr >> 8) & 127) * 64; // TODO: D/I + + bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I + + DOLOG(debug, true, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][0][apf].pdr); + if ((p_offset > pdr_len && direction == false) || (p_offset < pdr_len && direction == true)) { DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o >= %o", p_offset, pdr_len); - DOLOG(info, true, "TRAP(0250) (throw 4) on address %06o", a); + DOLOG(debug, true, "TRAP(0250) (throw 4) on address %06o", a); c->schedule_trap(0250); // invalid access - MMR0 &= 017777; - MMR0 |= 1 << 14; // length + if ((MMR0 & 0160000) == 0) { + MMR0 &= 017777; + MMR0 |= 1 << 14; // length - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + MMR0 &= ~14; // add current page + MMR0 |= apf << 1; - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; + } pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I @@ -767,9 +778,9 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo } if (a & 1) - DOLOG(info, true, "bus::writeWord: odd address UNHANDLED"); + DOLOG(debug, true, "bus::writeWord: odd address UNHANDLED"); - DOLOG(info, true, "UNHANDLED write %o(%c): %o", a, word_mode ? 'B' : ' ', value); + DOLOG(debug, true, "UNHANDLED write %o(%c): %o", a, word_mode ? 'B' : ' ', value); // c -> busError(); diff --git a/cpu.cpp b/cpu.cpp index 44b79a6..748d9b7 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1650,6 +1650,7 @@ void cpu::schedule_trap(const uint16_t vector) // 'is_interrupt' is not correct naming; it is true for mmu faults and interrupts void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt) { + DOLOG(debug, true, "*** CPU::TRAP ***"); uint16_t before_psw = getPSW(); uint16_t before_pc = getPC(); @@ -1678,6 +1679,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt pushStack(before_psw); pushStack(before_pc); + DOLOG(debug, true, "*** CPU::TRAP fin ***"); } cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const bool word_mode) const From 51670ef1991497b77e5962a8f54e228816f39f45 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 12:10:23 +0200 Subject: [PATCH 05/28] double traps odd addressing trap --- bus.cpp | 22 +++++++++++++++------- bus.h | 2 +- console_ncurses.cpp | 2 +- cpu.cpp | 9 +++++++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/bus.cpp b/bus.cpp index 03ab696..f969719 100644 --- a/bus.cpp +++ b/bus.cpp @@ -285,10 +285,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; -// if (run_mode == 1 && is_11_34) -// run_mode = 3; - - uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only); + uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only, word_mode); if (word_mode) temp = m -> readByte(m_offset); @@ -339,12 +336,13 @@ void bus::setMMR2(const uint16_t value) MMR2 = value; } -uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only) +uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const bool word_mode) { uint32_t m_offset = 0; + const uint8_t apf = a >> 13; // active page field + if (MMR0 & 1) { - const uint8_t apf = a >> 13; // active page field // TODO: D/I m_offset = pages[run_mode][0][apf].par * 64; // memory offset TODO: handle 16b int-s @@ -466,6 +464,16 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c m_offset = a; } + if ((m_offset & 1) && word_mode == 0 && peek_only == false) { + DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o", m_offset); + DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o", a); + c->schedule_trap(004); // invalid access + + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + + throw 5; + } + return m_offset; } @@ -787,7 +795,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo return; } - uint32_t m_offset = calculate_physical_address(run_mode, a, true, true, false); + uint32_t m_offset = calculate_physical_address(run_mode, a, true, true, false, word_mode); DOLOG(debug, true, "WRITE to %06o/%07o: %o", a, m_offset, value); diff --git a/bus.h b/bus.h index b4c92d5..9b8cdd6 100644 --- a/bus.h +++ b/bus.h @@ -90,5 +90,5 @@ public: uint16_t get_switch_register() const { return switch_register; } - uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only); + uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const bool word_mode); }; diff --git a/console_ncurses.cpp b/console_ncurses.cpp index a90b7b6..6a3555b 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -139,7 +139,7 @@ void console_ncurses::panel_update_thread() int run_mode = current_PSW >> 14; uint16_t current_PC = c->getPC(); - uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true); + uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true, true); uint16_t current_instr = b->readWord(current_PC); diff --git a/cpu.cpp b/cpu.cpp index 748d9b7..6d2c55b 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1657,7 +1657,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt // make sure the trap vector is retrieved from kernel space psw &= 037777; // mask off 14/15 - if ((b->getMMR0() & 0160000) == 0) { + if ((b->getMMR0() & 0160000) == 0 && vector != 4) { b->setMMR2(vector); b->addToMMR1(-2, 6); b->addToMMR1(-2, 6); @@ -2161,7 +2161,12 @@ void cpu::step_a() b->clearMMR1(); if (scheduled_trap) { - trap(scheduled_trap, 7, true); + try { + trap(scheduled_trap, 7, true); + } + catch(const int exception) { + DOLOG(debug, true, "2nd-bus-trap during execution of command (%d)", exception); + } scheduled_trap = 0; From 31edf022cc0685bb6f9003ffaecd52dadd1b02ac Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 18:05:31 +0200 Subject: [PATCH 06/28] RTI/RTT shall not change the PSW in user/supervisor mode --- cpu.cpp | 30 +++++++++++++++++++----------- cpu.h | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 6d2c55b..e28aca5 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -246,17 +246,15 @@ int cpu::getPSW_spl() const return (psw >> 5) & 7; } -void cpu::setPSW(const uint16_t v, const bool limited) +void cpu::setPSW(uint16_t v, const bool limited) { if (limited) { - psw |= v & 0174000; // current & previous mode can only be increased, 11 can only be set + v &= 0174037; - psw &= 0174000; // retain upper 5 bit - psw |= v & ~0174000; - } - else { - psw = v; + v |= psw & 0174340; } + + psw = v; } bool cpu::check_queued_interrupts() @@ -1548,10 +1546,15 @@ bool cpu::misc_operations(const uint16_t instr) case 0b0000000000000001: // WAIT return true; - case 0b0000000000000010: // RTI + case 0b0000000000000010: { // RTI setPC(popStack()); - setPSW(popStack(), !!((getPSW() >> 12) & 3)); + + uint16_t replacement_psw = popStack(); + + setPSW(replacement_psw, true); + return true; + } case 0b0000000000000011: // BPT trap(014); @@ -1561,10 +1564,15 @@ bool cpu::misc_operations(const uint16_t instr) trap(020); return true; - case 0b0000000000000110: // RTT + case 0b0000000000000110: { // RTT setPC(popStack()); - setPSW(popStack(), !!((getPSW() >> 12) & 3)); + + uint16_t replacement_psw = popStack(); + + setPSW(replacement_psw, true); + return true; + } case 0b0000000000000111: // MFPT if (emulateMFPT) diff --git a/cpu.h b/cpu.h index ba8a79f..097c0c7 100644 --- a/cpu.h +++ b/cpu.h @@ -118,7 +118,7 @@ public: void setBitPSW(const int bit, const bool v); uint16_t getPSW() const { return psw; } - void setPSW(const uint16_t v, const bool limited); + void setPSW(uint16_t v, const bool limited); uint16_t getStackLimitRegister() { return stackLimitRegister; } void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; } From 394f89e0bab265994c7dbd4c3c64009587b20ccb Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 19:44:04 +0200 Subject: [PATCH 07/28] compile fix --- ESP32/console_esp32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESP32/console_esp32.cpp b/ESP32/console_esp32.cpp index d327835..73e7d64 100644 --- a/ESP32/console_esp32.cpp +++ b/ESP32/console_esp32.cpp @@ -102,7 +102,7 @@ void console_esp32::panel_update_thread() int run_mode = current_PSW >> 14; uint16_t current_PC = c->getPC(); - uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true); + uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true, false); uint16_t current_instr = b->readWord(current_PC); From d2a4776742320fe5813bb4a6709f2e25de59236d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 18 Jun 2022 19:44:55 +0200 Subject: [PATCH 08/28] first thing is check for odd addressing --- bus.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/bus.cpp b/bus.cpp index f969719..19ec9e3 100644 --- a/bus.cpp +++ b/bus.cpp @@ -338,12 +338,28 @@ void bus::setMMR2(const uint16_t value) uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const bool word_mode) { - uint32_t m_offset = 0; + uint32_t m_offset = a; const uint8_t apf = a >> 13; // active page field - if (MMR0 & 1) { + if ((a & 1) && word_mode == 0 && peek_only == false) { + DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o run mode %d", a, run_mode); + DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o", a); + c->schedule_trap(004); // invalid access + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + + uint16_t bMMR0 = MMR0; + + MMR0 &= ~(3 << 5); + MMR0 |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? + + DOLOG(info, true, "before: %06o after %06o", bMMR0, MMR0); + + throw 5; + } + + if (MMR0 & 1) { // TODO: D/I m_offset = pages[run_mode][0][apf].par * 64; // memory offset TODO: handle 16b int-s @@ -434,7 +450,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I - DOLOG(debug, true, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][0][apf].pdr); + // DOLOG(debug, true, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][0][apf].pdr); if ((p_offset > pdr_len && direction == false) || (p_offset < pdr_len && direction == true)) { DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o >= %o", p_offset, pdr_len); @@ -460,19 +476,6 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, !peek_only, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff: %o, AC: %d)", a, m_offset, run_mode, apf, pages[run_mode][0][apf].par * 64, p_offset, pages[run_mode][0][apf].pdr & 7); // TODO: D/I } - else { - m_offset = a; - } - - if ((m_offset & 1) && word_mode == 0 && peek_only == false) { - DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o", m_offset); - DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o", a); - c->schedule_trap(004); // invalid access - - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - - throw 5; - } return m_offset; } From 82b318ea016a47dade5a785797257c8b4940a2d4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 00:19:53 +0200 Subject: [PATCH 09/28] examine/e was an implicit step --- debugger.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debugger.cpp b/debugger.cpp index 1791b72..15e3ac2 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -224,6 +224,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto if (val != -1) cnsl->put_string_lf(format("value at %06o, octal: %o, hex: %x, dec: %d\n", addr, val, val, val)); } + + continue; } else if (cmd == "reset" || cmd == "r") { #if defined(ESP32) From fdeda07d71b97e066a1ef59dff62068dd61f3254 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 00:22:04 +0200 Subject: [PATCH 10/28] current page in mmr0 for odd addressing error --- bus.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bus.cpp b/bus.cpp index 19ec9e3..57f010e 100644 --- a/bus.cpp +++ b/bus.cpp @@ -283,7 +283,7 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, return -1; } - int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; + int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; uint32_t m_offset = calculate_physical_address(run_mode, a, !peek_only, false, peek_only, word_mode); @@ -344,17 +344,15 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if ((a & 1) && word_mode == 0 && peek_only == false) { DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o run mode %d", a, run_mode); - DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o", a); + DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o, page %d", a, apf); c->schedule_trap(004); // invalid access pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - uint16_t bMMR0 = MMR0; + MMR0 &= ~14; // add current page + MMR0 |= apf << 1; - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? - - DOLOG(info, true, "before: %06o after %06o", bMMR0, MMR0); +// DOLOG(info, true, "MMR0 %06o, MMR1 %06o, MMR2 %06o, MMR3 %06o", MMR0, MMR1, MMR2, MMR3); throw 5; } From 7e1f7a810200b3993b1a67a306f94053c7118a3c Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 00:31:23 +0200 Subject: [PATCH 11/28] redundant check --- cpu.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index e28aca5..8a39870 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1515,7 +1515,7 @@ bool cpu::condition_code_operations(const uint16_t instr) void cpu::pushStack(const uint16_t v) { if (getRegister(6) == stackLimitRegister) { - DOLOG(debug, true, "stackLimitRegister reached"); + DOLOG(debug, true, "stackLimitRegister reached %06o while pushing %06o", stackLimitRegister, v); trap(123, 7); // TODO } @@ -1685,6 +1685,8 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode' setPSW(new_psw, false); +// DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); + pushStack(before_psw); pushStack(before_pc); DOLOG(debug, true, "*** CPU::TRAP fin ***"); @@ -2194,9 +2196,6 @@ void cpu::step_b() if ((b->getMMR0() & 0160000) == 0) b->setMMR2(temp_pc); - if (temp_pc & 1) - busError(); - try { uint16_t instr = b->readWord(temp_pc); From f4d991e86a906ecbfec0174cb3f39369b05e7537 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 02:33:06 +0200 Subject: [PATCH 12/28] Debugging --- bus.cpp | 6 ++---- cpu.cpp | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bus.cpp b/bus.cpp index 57f010e..cce6d3e 100644 --- a/bus.cpp +++ b/bus.cpp @@ -343,16 +343,14 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c const uint8_t apf = a >> 13; // active page field if ((a & 1) && word_mode == 0 && peek_only == false) { - DOLOG(debug, !peek_only, "bus::calculate_physical_address::m_offset %o run mode %d", a, run_mode); - DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o, page %d", a, apf); - c->schedule_trap(004); // invalid access + DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o, page %d, run mode %d, MMR0 %06o, MMR2 %06o", a, apf, run_mode, MMR0, MMR2); pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I MMR0 &= ~14; // add current page MMR0 |= apf << 1; -// DOLOG(info, true, "MMR0 %06o, MMR1 %06o, MMR2 %06o, MMR3 %06o", MMR0, MMR1, MMR2, MMR3); + c->schedule_trap(004); // invalid access throw 5; } diff --git a/cpu.cpp b/cpu.cpp index 8a39870..556dfc5 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1285,7 +1285,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b00110101: { // MFPD/MFPI // always words: word_mode-bit is to select between MFPI and MFPD - assert(!word_mode); // TODO + // NOTE: this code does not work for D/I split setups! TODO if ((b->getMMR0() & 0160000) == 0) b->addToMMR1(-2, 6); @@ -1319,7 +1319,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b00110110: { // MTPI/MTPD // always words: word_mode-bit is to select between MTPI and MTPD - assert(!word_mode); // TODO + // NOTE: this code does not work for D/I split setups! TODO if ((b->getMMR0() & 0160000) == 0) b->addToMMR1(2, 6); @@ -1689,7 +1689,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt pushStack(before_psw); pushStack(before_pc); - DOLOG(debug, true, "*** CPU::TRAP fin ***"); + DOLOG(debug, true, "*** CPU::TRAP FIN, MMR0: %06o, MMR2: %06o ***", b->getMMR0(), b->getMMR2()); } cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const bool word_mode) const From ad4423212068af51654c8ad7e31a25f9866bab96 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 15:31:26 +0200 Subject: [PATCH 13/28] double trap handling (work in progress) --- cpu.cpp | 91 ++++++++++++++++++++++++++++++++++++--------------------- cpu.h | 2 +- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 556dfc5..e513721 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1656,39 +1656,69 @@ void cpu::schedule_trap(const uint16_t vector) } // 'is_interrupt' is not correct naming; it is true for mmu faults and interrupts -void cpu::trap(const uint16_t vector, const int new_ipl, const bool is_interrupt) +void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) { DOLOG(debug, true, "*** CPU::TRAP ***"); - uint16_t before_psw = getPSW(); - uint16_t before_pc = getPC(); - // make sure the trap vector is retrieved from kernel space - psw &= 037777; // mask off 14/15 + int processing_trap_depth = 0; + uint16_t before_psw = 0; + uint16_t before_pc = 0; - if ((b->getMMR0() & 0160000) == 0 && vector != 4) { - b->setMMR2(vector); - b->addToMMR1(-2, 6); - b->addToMMR1(-2, 6); + for(;;) { + try { + processing_trap_depth++; + + if (processing_trap_depth >= 2) { + vector = 4; + + if (processing_trap_depth >= 3) { + // TODO: halt? + } + } + else { + before_psw = getPSW(); + before_pc = getPC(); + } + + // make sure the trap vector is retrieved from kernel space + psw &= 037777; // mask off 14/15 + + if ((b->getMMR0() & 0160000) == 0 && vector != 4) { + b->setMMR2(vector); + b->addToMMR1(-2, 6); + b->addToMMR1(-2, 6); + } + + if (is_interrupt) + b->clearMMR0Bit(12); + else + b->setMMR0Bit(12); // it's a trap + + setPC(b->readWord(vector + 0)); + + // switch to kernel mode & update 'previous mode' + uint16_t new_psw = b->readWord(vector + 2) & 0147777; // mask off old 'previous mode' + if (new_ipl != -1) + new_psw = (new_psw & ~0xe0) | (new_ipl << 5); + new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode' + setPSW(new_psw, false); + + // DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); + + pushStack(before_psw); + pushStack(before_pc); + + // if we reach this point then the trap was processed without causing + // another trap + break; + } + catch(const int exception) { + DOLOG(debug, true, "trap during execution of trap (%d)", exception); + + setPSW(before_psw, false); + } } - if (is_interrupt) - b->clearMMR0Bit(12); - else - b->setMMR0Bit(12); // it's a trap - - setPC(b->readWord(vector + 0)); - - // switch to kernel mode & update 'previous mode' - uint16_t new_psw = b->readWord(vector + 2) & 0147777; // mask off old 'previous mode' - if (new_ipl != -1) - new_psw = (new_psw & ~0xe0) | (new_ipl << 5); - new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode' - setPSW(new_psw, false); - -// DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); - - pushStack(before_psw); - pushStack(before_pc); DOLOG(debug, true, "*** CPU::TRAP FIN, MMR0: %06o, MMR2: %06o ***", b->getMMR0(), b->getMMR2()); } @@ -2171,12 +2201,7 @@ void cpu::step_a() b->clearMMR1(); if (scheduled_trap) { - try { - trap(scheduled_trap, 7, true); - } - catch(const int exception) { - DOLOG(debug, true, "2nd-bus-trap during execution of command (%d)", exception); - } + trap(scheduled_trap, 7, true); scheduled_trap = 0; diff --git a/cpu.h b/cpu.h index 097c0c7..295d92c 100644 --- a/cpu.h +++ b/cpu.h @@ -96,7 +96,7 @@ public: void queue_interrupt(const uint8_t level, const uint8_t vector); void busError(); - void trap(const uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); + void trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); void schedule_trap(const uint16_t vector); void setEmulateMFPT(const bool v) { emulateMFPT = v; } From 88933e303c11baa90ddac43a7f877ba9af48d295 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 19 Jun 2022 15:39:46 +0200 Subject: [PATCH 14/28] Console switches configurable on command line --- bus.cpp | 4 ++-- bus.h | 5 +++-- debugger.cpp | 2 +- loaders.cpp | 6 +++--- main.cpp | 11 ++++++++++- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/bus.cpp b/bus.cpp index cce6d3e..4378d01 100644 --- a/bus.cpp +++ b/bus.cpp @@ -67,9 +67,9 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, } if (a == 0177570) { // console switch & display register - DOLOG(debug, !peek_only, "read console switch"); + DOLOG(debug, !peek_only, "read console switch (%06o)", console_switches); - return debug_mode ? 128 : 0; + return console_switches; } if (a == 0172540) { // KW11P programmable clock diff --git a/bus.h b/bus.h index 9b8cdd6..b13e352 100644 --- a/bus.h +++ b/bus.h @@ -39,7 +39,7 @@ private: uint16_t lf_csr { 0 }; - bool debug_mode { false }; + uint16_t console_switches { 0 }; public: bus(); @@ -47,7 +47,8 @@ public: void clearmem(); - void set_debug_mode(const bool state) { debug_mode = state; } + void set_console_switches(const uint16_t new_state) { console_switches = new_state; } + void set_debug_mode() { console_switches |= 128; } void add_cpu(cpu *const c) { this -> c = c; } void add_tm11(tm_11 *tm11) { this -> tm11 = tm11; } diff --git a/debugger.cpp b/debugger.cpp index 15e3ac2..88c58a2 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -120,7 +120,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto cpu *const c = b->getCpu(); - b->set_debug_mode(true); + b->set_debug_mode(); bool single_step = false; diff --git a/loaders.cpp b/loaders.cpp index 0088f42..e6f566b 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -178,7 +178,7 @@ void load_p11_x11(bus *const b, const std::string & file) break; if (n) { - uint8_t byte = strtol(buffer, NULL, 16); + uint8_t byte = strtol(buffer, nullptr, 16); b->writeByte(addr, byte); @@ -189,8 +189,8 @@ void load_p11_x11(bus *const b, const std::string & file) else { std::vector parts = split(buffer, " "); - addr = strtol(parts[0].c_str(), NULL, 16); - n = strtol(parts[1].c_str(), NULL, 16); + addr = strtol(parts[0].c_str(), nullptr, 16); + n = strtol(parts[1].c_str(), nullptr, 16); } } diff --git a/main.cpp b/main.cpp index 24631da..3fa826e 100644 --- a/main.cpp +++ b/main.cpp @@ -48,6 +48,7 @@ void help() printf("-b x enable bootloader (build-in), parameter must be \"rk05\" or \"rl02\"\n"); printf("-n ncurses UI\n"); printf("-d enable debugger\n"); + printf("-s x set console switches state - octal number\n"); printf("-t enable tracing (disassemble to stderr, requires -d as well)\n"); printf("-l x log to file x\n"); printf("-L x,y set log level for screen (x) and file (y)\n"); @@ -76,14 +77,20 @@ int main(int argc, char *argv[]) std::string tape; + uint16_t console_switches = 0; + int opt = -1; - while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3")) != -1) + while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3s:")) != -1) { switch(opt) { case 'h': help(); return 1; + case 's': + console_switches = strtol(optarg, NULL, 8); + break; + case '3': mode_34 = true; // switch from 11/70 to 11/34 break; @@ -154,6 +161,8 @@ int main(int argc, char *argv[]) bus *b = new bus(); + b->set_console_switches(console_switches); + cpu *c = new cpu(b, &event); b->add_cpu(c); From 42fc44b206f017fa863f217e2e53bc6f08133f1a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 24 Jun 2022 20:03:32 +0200 Subject: [PATCH 15/28] page written bit only when written double trap: use stack from 000004 --- bus.cpp | 30 +++++++++++++++++------------- cpu.cpp | 44 ++++++++++++++++++++++++++------------------ cpu.h | 1 - debugger.cpp | 7 +++++-- tests.h | 3 --- 5 files changed, 48 insertions(+), 37 deletions(-) delete mode 100644 tests.h diff --git a/bus.cpp b/bus.cpp index 4378d01..e264a14 100644 --- a/bus.cpp +++ b/bus.cpp @@ -278,8 +278,6 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, DOLOG(debug, !peek_only, "UNHANDLED read %o(%c)", a, word_mode ? 'B' : ' '); -// c -> busError(); - return -1; } @@ -297,7 +295,6 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, return temp; } - void bus::setMMR0(int value) { value &= ~(3 << 10); // bit 10 & 11 always read as 0 @@ -345,10 +342,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if ((a & 1) && word_mode == 0 && peek_only == false) { DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o, page %d, run mode %d, MMR0 %06o, MMR2 %06o", a, apf, run_mode, MMR0, MMR2); - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + //MMR0 &= ~14; // add current page + //MMR0 |= apf << 1; c->schedule_trap(004); // invalid access @@ -375,7 +373,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c c->schedule_trap(0250); // invalid address - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I if ((MMR0 & 0160000) == 0) { MMR0 &= 017777; @@ -398,7 +397,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c c->schedule_trap(0250); // invalid address - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I if ((MMR0 & 0160000) == 0) { MMR0 &= 017777; @@ -435,21 +435,24 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= run_mode << 5; } - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I c->schedule_trap(04); throw 3; } - uint16_t pdr_len = ((pages[run_mode][0][apf].pdr >> 8) & 127) * 64; // TODO: D/I + // uint16_t pdr_len = ((pages[run_mode][0][apf].pdr >> 8) & 127) * 64; // TODO: D/I + uint16_t pdr_len = (pages[run_mode][0][apf].pdr >> 8) & 127; + uint16_t pdr_cmp = (a >> 6) & 127; bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I // DOLOG(debug, true, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][0][apf].pdr); - if ((p_offset > pdr_len && direction == false) || (p_offset < pdr_len && direction == true)) { - DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o >= %o", p_offset, pdr_len); + if ((pdr_cmp > pdr_len && direction == false) || (pdr_cmp < pdr_len && direction == true)) { + DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o versus %o direction %d", pdr_cmp, pdr_len, direction); DOLOG(debug, true, "TRAP(0250) (throw 4) on address %06o", a); c->schedule_trap(0250); // invalid access @@ -464,7 +467,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= run_mode << 5; } - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I throw 4; } diff --git a/cpu.cpp b/cpu.cpp index e513721..cf2dbe6 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1645,11 +1645,6 @@ bool cpu::misc_operations(const uint16_t instr) return false; } -void cpu::busError() -{ - trap(4); -} - void cpu::schedule_trap(const uint16_t vector) { scheduled_trap = vector; @@ -1658,7 +1653,7 @@ void cpu::schedule_trap(const uint16_t vector) // 'is_interrupt' is not correct naming; it is true for mmu faults and interrupts void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) { - DOLOG(debug, true, "*** CPU::TRAP ***"); + DOLOG(debug, true, "*** CPU::TRAP, MMR0: %06o, MMR2: %06o ***", b->getMMR0(), b->getMMR2()); int processing_trap_depth = 0; uint16_t before_psw = 0; @@ -1668,8 +1663,15 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) try { processing_trap_depth++; + bool kernel_mode = psw >> 14; + if (processing_trap_depth >= 2) { - vector = 4; + DOLOG(debug, true, "Trap depth %d", processing_trap_depth); + + if (kernel_mode) + vector = 4; + + setRegister(6, 04); if (processing_trap_depth >= 3) { // TODO: halt? @@ -1678,22 +1680,22 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) else { before_psw = getPSW(); before_pc = getPC(); + + if ((b->getMMR0() & 0160000) == 0 && vector != 4) { + b->setMMR2(vector); + b->addToMMR1(-2, 6); + b->addToMMR1(-2, 6); + } + + if (is_interrupt) + b->clearMMR0Bit(12); + else + b->setMMR0Bit(12); // it's a trap } // make sure the trap vector is retrieved from kernel space psw &= 037777; // mask off 14/15 - if ((b->getMMR0() & 0160000) == 0 && vector != 4) { - b->setMMR2(vector); - b->addToMMR1(-2, 6); - b->addToMMR1(-2, 6); - } - - if (is_interrupt) - b->clearMMR0Bit(12); - else - b->setMMR0Bit(12); // it's a trap - setPC(b->readWord(vector + 0)); // switch to kernel mode & update 'previous mode' @@ -1704,6 +1706,9 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) setPSW(new_psw, false); // DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); + // + if (processing_trap_depth >= 2 && kernel_mode) + setRegister(6, 04); pushStack(before_psw); pushStack(before_pc); @@ -2192,6 +2197,9 @@ std::map > cpu::disassemble(const uint16_t work_values_str.push_back(format("%06o", v)); out.insert({ "work-values", work_values_str }); + out.insert({ "MMR0", { format("%06o", b->getMMR0()) } }); + out.insert({ "MMR2", { format("%06o", b->getMMR2()) } }); + return out; } diff --git a/cpu.h b/cpu.h index 295d92c..00ced1b 100644 --- a/cpu.h +++ b/cpu.h @@ -95,7 +95,6 @@ public: void init_interrupt_queue(); void queue_interrupt(const uint8_t level, const uint8_t vector); - void busError(); void trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); void schedule_trap(const uint16_t vector); diff --git a/debugger.cpp b/debugger.cpp index 88c58a2..66e7076 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -28,6 +28,9 @@ int disassemble(cpu *const c, console *const cnsl, const int pc, const bool inst std::string instruction = data["instruction-text"].at(0); + std::string MMR0 = data["MMR0"].at(0); + std::string MMR2 = data["MMR2"].at(0); + std::string result; if (instruction_only) @@ -38,13 +41,13 @@ int disassemble(cpu *const c, console *const cnsl, const int pc, const bool inst work_values.c_str() ); else - result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s, instr: %s: %s - %s", + result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s, instr: %s: %s - MMR0/2: %s/%s", registers[0].c_str(), registers[1].c_str(), registers[2].c_str(), registers[3].c_str(), registers[4].c_str(), registers[5].c_str(), registers[6].c_str(), pc, psw.c_str(), instruction_values.c_str(), instruction.c_str(), - work_values.c_str() + MMR0.c_str(), MMR2.c_str() ); if (cnsl) diff --git a/tests.h b/tests.h deleted file mode 100644 index 163bd5c..0000000 --- a/tests.h +++ /dev/null @@ -1,3 +0,0 @@ -// (C) 2018 by Folkert van Heusden -// Released under Apache License v2.0 -void tests(cpu *const c); From ea8edbf0c73d6a2ebe81ae90ec6ef3c957470883 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 25 Jun 2022 08:11:41 +0200 Subject: [PATCH 16/28] lbp fix --- debugger.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 66e7076..3d3a36a 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -160,10 +160,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto cnsl->put_string_lf("Breakpoints:"); - for(auto pc : bps) { - cnsl->put_string_lf(format(" %06o", pc)); + for(auto a : bps) { + cnsl->put_string(format(" %06o> ", a)); - pc += disassemble(c, cnsl, pc, true); + disassemble(c, cnsl, a, true); } continue; From 2717799df459a859d7edade1293d2569a6df984a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 26 Jun 2022 01:41:58 +0200 Subject: [PATCH 17/28] - fix for busy loop in console_posix (due to poll with 0ms timeout) - disable kw11-l interrupt when emulation is not running --- ESP32/main.ino | 6 +++--- console_posix.cpp | 2 +- cpu.cpp | 4 ++++ kw11-l.cpp | 17 ++++++++++++----- kw11-l.h | 4 +++- main.cpp | 4 ++-- utils.cpp | 1 + 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/ESP32/main.ino b/ESP32/main.ino index 236abca..9ae4471 100644 --- a/ESP32/main.ino +++ b/ESP32/main.ino @@ -181,14 +181,14 @@ void setup() { Serial.println(F("Connect CPU to BUS")); b->add_cpu(c); - Serial.println(F("Start line-frequency interrupt")); - kw11_l *lf = new kw11_l(b); - c->setEmulateMFPT(true); Serial.println(F("Init console")); cnsl = new console_esp32(&stop_event, b); + Serial.println(F("Start line-frequency interrupt")); + kw11_l *lf = new kw11_l(b, cnsl); + running = cnsl->get_running_flag(); Serial.println(F("Init TTY")); diff --git a/console_posix.cpp b/console_posix.cpp index 9d7b3b8..a999fb8 100644 --- a/console_posix.cpp +++ b/console_posix.cpp @@ -32,7 +32,7 @@ int console_posix::wait_for_char_ll(const short timeout) { struct pollfd fds[] = { { STDIN_FILENO, POLLIN, timeout } }; - if (poll(fds, 1, 0) == 1 && fds[0].revents) + if (poll(fds, 1, timeout) == 1 && fds[0].revents) return getchar(); return -1; diff --git a/cpu.cpp b/cpu.cpp index cf2dbe6..8496683 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -2232,6 +2232,10 @@ void cpu::step_b() try { uint16_t instr = b->readWord(temp_pc); +// FILE *fh = fopen("/home/folkert/kek.dat", "a+"); +// fprintf(fh, "%06o %06o\n", temp_pc, instr); +// fclose(fh); + addRegister(7, false, 2); if (double_operand_instructions(instr)) diff --git a/kw11-l.cpp b/kw11-l.cpp index 18637b6..e208c4b 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -1,10 +1,12 @@ #include +#include "console.h" #include "cpu.h" #include "kw11-l.h" +#include "utils.h" -kw11_l::kw11_l(bus *const b) : b(b) +kw11_l::kw11_l(bus *const b, console *const cnsl) : b(b), cnsl(cnsl) { th = new std::thread(std::ref(*this)); } @@ -21,11 +23,16 @@ kw11_l::~kw11_l() void kw11_l::operator()() { while(!stop_flag) { - b->set_lf_crs_b7(); + if (*cnsl->get_running_flag()) { + b->set_lf_crs_b7(); - if (b->get_lf_crs() & 64) - b->getCpu()->queue_interrupt(6, 0100); + if (b->get_lf_crs() & 64) + b->getCpu()->queue_interrupt(6, 0100); - usleep(1000000 / 50); + myusleep(1000000 / 50); + } + else { + myusleep(1000000 / 10); + } } } diff --git a/kw11-l.h b/kw11-l.h index 88158db..25ade31 100644 --- a/kw11-l.h +++ b/kw11-l.h @@ -8,11 +8,13 @@ class kw11_l { private: bus *const b { nullptr }; + console *const cnsl { nullptr }; + std::thread * th { nullptr }; std::atomic_bool stop_flag { false }; public: - kw11_l(bus *const b); + kw11_l(bus *const b, console *const cnsl); virtual ~kw11_l(); void operator()(); diff --git a/main.cpp b/main.cpp index 3fa826e..b5bb6da 100644 --- a/main.cpp +++ b/main.cpp @@ -168,8 +168,6 @@ int main(int argc, char *argv[]) c->set_34(mode_34); - kw11_l *lf = new kw11_l(b); - c->setEmulateMFPT(true); std::atomic_bool interrupt_emulation { false }; @@ -235,6 +233,8 @@ int main(int argc, char *argv[]) return 0; #endif + kw11_l *lf = new kw11_l(b, cnsl); + cnsl->start_thread(); if (run_debugger) diff --git a/utils.cpp b/utils.cpp index a8435cb..9583731 100644 --- a/utils.cpp +++ b/utils.cpp @@ -83,6 +83,7 @@ void myusleep(uint64_t us) struct timespec rem { 0, 0 }; int rc = nanosleep(&req, &rem); + if (rc == 0 || (rc == -1 && errno != EINTR)) break; From 55ad46c55ca14544d1cb34ef032e3c4526dc8ea5 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 28 Jun 2022 16:30:49 +0200 Subject: [PATCH 18/28] Code-cleanup (PAR/PDR read/write helper methods) --- bus.cpp | 232 ++++++++++++++++++++------------------------------------ bus.h | 5 ++ 2 files changed, 89 insertions(+), 148 deletions(-) diff --git a/bus.cpp b/bus.cpp index e264a14..765f266 100644 --- a/bus.cpp +++ b/bus.cpp @@ -51,13 +51,35 @@ void bus::init() MMR3 = 0; } +uint16_t bus::read_pdr(const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only) +{ + bool is_11_34 = c->get_34(); + int page = (a >> 1) & 7; + bool is_d = is_11_34 ? false : (a & 16); + uint16_t t = pages[run_mode][is_d][page].pdr; + + DOLOG(debug, !peek_only, "read run-mode %d: %c PDR for %d: %o", run_mode, is_d ? 'D' : 'I', page, t); + + return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; +} + +uint16_t bus::read_par(const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only) +{ + bool is_11_34 = c->get_34(); + int page = (a >> 1) & 7; + bool is_d = is_11_34 ? false : (a & 16); + uint16_t t = pages[run_mode][is_d][page].par; + + DOLOG(debug, !peek_only, "read run-mode %d: %c PAR for %d: %o (phys: %07o)", run_mode, is_d ? 'D' : 'I', page, t, t * 64); + + return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; +} + uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, const bool peek_only) { uint16_t temp = 0; if (a >= 0160000) { - bool is_11_34 = c->get_34(); - if (word_mode) DOLOG(debug, false, "READ I/O %06o in byte mode", a); @@ -93,48 +115,18 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, } /// MMU /// - if (a >= 0172200 && a < 0172240) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[001][is_d][page].pdr; - DOLOG(debug, !peek_only, "read supervisor %c PDR for %d: %o", is_d ? 'D' : 'I', page, t); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } - else if (a >= 0172240 && a < 0172300) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[001][is_d][page].par; - DOLOG(debug, !peek_only, "read supervisor %c PAR for %d: %o (phys: %07o)", is_d ? 'D' : 'I', page, t, t * 64); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } - else if (a >= 0172300 && a < 0172340) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[000][is_d][page].pdr; - DOLOG(debug, !peek_only, "read kernel %c PDR for %d: %o", is_d ? 'D' : 'I', page, t); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } - else if (a >= 0172340 && a < 0172400) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[000][is_d][page].par; - DOLOG(debug, !peek_only, "read kernel %c PAR for %d: %o (phys: %07o)", is_d ? 'D' : 'I', page, t, t * 64); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } - else if (a >= 0177600 && a < 0177640) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[003][is_d][page].pdr; - DOLOG(debug, !peek_only, "read userspace %c PDR for %d: %o", is_d ? 'D' : 'I', page, t); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } - else if (a >= 0177640 && a < 0177700) { - int page = (a >> 1) & 7; - bool is_d = is_11_34 ? false : (a & 16); - uint16_t t = pages[003][is_d][page].par; - DOLOG(debug, !peek_only, "read userspace %c PAR for %d: %o (phys: %07o)", is_d ? 'D' : 'I', page, t, t * 64); - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; - } + if (a >= 0172200 && a < 0172240) + return read_pdr(a, 1, word_mode, peek_only); + else if (a >= 0172240 && a < 0172300) + return read_par(a, 1, word_mode, peek_only); + else if (a >= 0172300 && a < 0172340) + return read_pdr(a, 0, word_mode, peek_only); + else if (a >= 0172340 && a < 0172400) + return read_par(a, 0, word_mode, peek_only); + else if (a >= 0177600 && a < 0177640) + return read_pdr(a, 3, word_mode, peek_only); + else if (a >= 0177640 && a < 0177700) + return read_par(a, 3, word_mode, peek_only); /////////// if (word_mode) { @@ -493,6 +485,48 @@ void bus::addToMMR1(const int8_t delta, const uint8_t reg) MMR1 |= reg; } +void bus::write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode) +{ + bool is_11_34 = c->get_34(); + bool is_d = is_11_34 ? false : (a & 16); + int page = (a >> 1) & 7; + + if (word_mode) { + a & 1 ? (pages[run_mode][is_d][page].pdr &= 0xff, pages[run_mode][is_d][page].pdr |= value << 8) : + (pages[run_mode][is_d][page].pdr &= 0xff00, pages[run_mode][is_d][page].pdr |= value); + } + else { + pages[run_mode][is_d][page].pdr = value; + } + + if (is_11_34) // 11/34 has no cache bit + pages[run_mode][is_d][page].pdr &= 077416; + else + pages[run_mode][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes + + DOLOG(debug, true, "write run-mode %d: %c PDR for %d: %o [%d]", run_mode, is_d ? 'D' : 'I', page, value, word_mode); +} + +void bus::write_par(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode) +{ + bool is_11_34 = c->get_34(); + bool is_d = is_11_34 ? false : (a & 16); + int page = (a >> 1) & 7; + + if (word_mode) { + a & 1 ? (pages[run_mode][is_d][page].par &= 0xff, pages[run_mode][is_d][page].par |= value << 8) : + (pages[run_mode][is_d][page].par &= 0xff00, pages[run_mode][is_d][page].par |= value); + } + else { + pages[run_mode][is_d][page].par = value; + } + + if (is_11_34) // 11/34 has 12 bit PARs + pages[run_mode][is_d][page].par &= 4095; + + DOLOG(debug, true, "write run-mode %d: %c PAR for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[run_mode][is_d][page].par * 64); +} + void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bool use_prev) { int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; @@ -505,8 +539,6 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo } if (a >= 0160000) { - bool is_11_34 = c->get_34(); - if (word_mode) { assert(value < 256); DOLOG(debug, true, "WRITE I/O %06o in byte mode", a); @@ -646,127 +678,31 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo /// MMU /// // supervisor if (a >= 0172200 && a < 0172240) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[001][is_d][page].pdr &= 0xff, pages[001][is_d][page].pdr |= value << 8) : - (pages[001][is_d][page].pdr &= 0xff00, pages[001][is_d][page].pdr |= value); - } - else { - pages[001][is_d][page].pdr = value; - } - - if (is_11_34) // 11/34 has no cache bit - pages[001][is_d][page].pdr &= 077416; - else - pages[001][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes - - DOLOG(debug, true, "write supervisor %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); - + write_pdr(a, 1, value, word_mode); return; } if (a >= 0172240 && a < 0172300) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[001][is_d][page].par &= 0xff, pages[001][is_d][page].par |= value << 8) : - (pages[001][is_d][page].par &= 0xff00, pages[001][is_d][page].par |= value); - } - else { - pages[001][is_d][page].par = value; - } - - if (is_11_34) // 11/34 has 12 bit PARs - pages[001][is_d][page].par &= 4095; - - DOLOG(debug, true, "write supervisor %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[001][is_d][page].par * 64); - + write_par(a, 1, value, word_mode); return; } // kernel if (a >= 0172300 && a < 0172340) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[000][is_d][page].pdr &= 0xff, pages[000][is_d][page].pdr |= value << 8) : - (pages[000][is_d][page].pdr &= 0xff00, pages[000][is_d][page].pdr |= value); - } - else { - pages[000][is_d][page].pdr = value; - } - - if (is_11_34) // 11/34 has no cache bit - pages[000][is_d][page].pdr &= 077416; - else - pages[000][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes - - DOLOG(debug, true, "write kernel %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); - + write_pdr(a, 0, value, word_mode); return; } if (a >= 0172340 && a < 0172400) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[000][is_d][page].par &= 0xff, pages[000][is_d][page].par |= value << 8) : - (pages[000][is_d][page].par &= 0xff00, pages[000][is_d][page].par |= value); - } - else { - pages[000][is_d][page].par = value; - } - - if (is_11_34) // 11/34 has 12 bit PARs - pages[000][is_d][page].par &= 4095; - - DOLOG(debug, true, "write kernel %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[000][is_d][page].par * 64); - + write_par(a, 0, value, word_mode); return; } // user if (a >= 0177600 && a < 0177640) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[003][is_d][page].pdr &= 0xff, pages[003][is_d][page].pdr |= value << 8) : - (pages[003][is_d][page].pdr &= 0xff00, pages[003][is_d][page].pdr |= value); - } - else { - pages[003][is_d][page].pdr = value; - } - - if (is_11_34) // 11/34 has no cache bit - pages[003][is_d][page].pdr &= 077416; - else - pages[003][is_d][page].pdr &= ~(128 + 64 + 32 + 16); // set bit 4 & 5 to 0 as they are unused and A/W are set to 0 by writes - - DOLOG(debug, true, "write user %c PDR for %d: %o [%d]", is_d ? 'D' : 'I', page, value, word_mode); - + write_pdr(a, 3, value, word_mode); return; } if (a >= 0177640 && a < 0177700) { - bool is_d = is_11_34 ? false : (a & 16); - int page = (a >> 1) & 7; - - if (word_mode) { - a & 1 ? (pages[003][is_d][page].par &= 0xff, pages[003][is_d][page].par |= value << 8) : - (pages[003][is_d][page].par &= 0xff00, pages[003][is_d][page].par |= value); - } - else { - pages[003][is_d][page].par = value; - } - - if (is_11_34) // 11/34 has 12 bit PARs - pages[003][is_d][page].par &= 4095; - - DOLOG(debug, true, "write user %c PAR for %d: %o (%07o)", is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[003][is_d][page].par * 64); - + write_par(a, 3, value, word_mode); return; } //// diff --git a/bus.h b/bus.h index b13e352..e01e99d 100644 --- a/bus.h +++ b/bus.h @@ -41,6 +41,11 @@ private: uint16_t console_switches { 0 }; + uint16_t read_pdr (const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only); + uint16_t read_par (const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only); + void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode); + void write_par(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode); + public: bus(); ~bus(); From 0d7cbe3da91af7ef638ccc510d7a885562e3e046 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 28 Jun 2022 17:57:48 +0200 Subject: [PATCH 19/28] replaced addresses by defines --- bus.cpp | 161 ++++++++++++++++++++++++--------------------------- bus.h | 41 +++++++++++++ cpu.cpp | 36 ++++++------ debugger.cpp | 12 ++-- 4 files changed, 140 insertions(+), 110 deletions(-) diff --git a/bus.cpp b/bus.cpp index 765f266..aa62131 100644 --- a/bus.cpp +++ b/bus.cpp @@ -20,7 +20,6 @@ constexpr int n_pages = 12; constexpr int n_pages = 16; #endif - bus::bus() { m = new memory(n_pages * 8192); @@ -83,158 +82,156 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, if (word_mode) DOLOG(debug, false, "READ I/O %06o in byte mode", a); - if (a == 0177750) { // MAINT + if (a == ADDR_MAINT) { // MAINT DOLOG(debug, !peek_only, "read MAINT"); return 1; // POWER OK } - if (a == 0177570) { // console switch & display register + if (a == ADDR_CONSW) { // console switch & display register DOLOG(debug, !peek_only, "read console switch (%06o)", console_switches); return console_switches; } - if (a == 0172540) { // KW11P programmable clock + if (a == ADDR_KW11P) { // KW11P programmable clock DOLOG(debug, !peek_only, "read programmable clock"); return 128; } - if (a == 0177772) { // PIR + if (a == ADDR_PIR) { // PIR DOLOG(debug, !peek_only, "read PIT"); return PIR; } - if (a == 0177546) { // line frequency clock and status register + if (a == ADDR_LFC) { // line frequency clock and status register DOLOG(debug, !peek_only, "read line freq clock"); return lf_csr; } - if (a == 0177514) { // printer, CSR register, LP11 + if (a == ADDR_LP11CSR) { // printer, CSR register, LP11 DOLOG(debug, !peek_only, "read LP11 CSR"); return 0x80; } /// MMU /// - if (a >= 0172200 && a < 0172240) + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) return read_pdr(a, 1, word_mode, peek_only); - else if (a >= 0172240 && a < 0172300) + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) return read_par(a, 1, word_mode, peek_only); - else if (a >= 0172300 && a < 0172340) + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) return read_pdr(a, 0, word_mode, peek_only); - else if (a >= 0172340 && a < 0172400) + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) return read_par(a, 0, word_mode, peek_only); - else if (a >= 0177600 && a < 0177640) + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) return read_pdr(a, 3, word_mode, peek_only); - else if (a >= 0177640 && a < 0177700) + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) return read_par(a, 3, word_mode, peek_only); /////////// if (word_mode) { - if (a == 0177776) { // PSW + if (a == ADDR_PSW) { // PSW DOLOG(debug, !peek_only, "readb PSW LSB"); return c -> getPSW() & 255; } - if (a == 0177777) { + if (a == ADDR_PSW + 1) { DOLOG(debug, !peek_only, "readb PSW MSB"); return c -> getPSW() >> 8; } - - if (a == 0177774) { // stack limit register + if (a == ADDR_STACKLIM) { // stack limit register DOLOG(debug, !peek_only, "readb stack limit register"); return c -> getStackLimitRegister() & 0xff; } - if (a == 0177775) { // stack limit register + if (a == ADDR_STACKLIM + 1) { // stack limit register DOLOG(debug, !peek_only, "readb stack limit register"); return c -> getStackLimitRegister() >> 8; } - if (a >= 0177700 && a <= 0177705) { // kernel R0-R5 - DOLOG(debug, !peek_only, "readb kernel R%d", a - 0177700); - return c -> getRegister(a - 0177700, 0, false) & 0xff; + if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 + DOLOG(debug, !peek_only, "readb kernel R%d", a - ADDR_KERNEL_R); + return c -> getRegister(a - ADDR_KERNEL_R, 0, false) & 0xff; } - if (a >= 0177710 && a <= 0177715) { // user R0-R5 - DOLOG(debug, !peek_only, "readb user R%d", a - 0177710); - return c -> getRegister(a - 0177710, 3, false) & 0xff; + if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 + DOLOG(debug, !peek_only, "readb user R%d", a - ADDR_USER_R); + return c -> getRegister(a - ADDR_USER_R, 3, false) & 0xff; } - if (a == 0177706) { // kernel SP + if (a == ADDR_KERNEL_SP) { // kernel SP DOLOG(debug, !peek_only, "readb kernel sp"); return c -> getStackPointer(0) & 0xff; } - if (a == 0177707) { // PC + if (a == ADDR_PC) { // PC DOLOG(debug, !peek_only, "readb pc"); return c -> getPC() & 0xff; } - if (a == 0177716) { // supervisor SP + if (a == ADDR_SV_SP) { // supervisor SP DOLOG(debug, !peek_only, "readb supervisor sp"); return c -> getStackPointer(1) & 0xff; } - if (a == 0177717) { // user SP + if (a == ADDR_USER_SP) { // user SP DOLOG(debug, !peek_only, "readb user sp"); return c -> getStackPointer(3) & 0xff; } - - if (a == 0177766) { // cpu error register + if (a == ADDR_CPU_ERR) { // cpu error register DOLOG(debug, !peek_only, "readb cpuerr"); return CPUERR & 0xff; } } else { - if (a == 0177572) { + if (a == ADDR_MMR0) { DOLOG(debug, !peek_only, "read MMR0"); return MMR0; } - if (a == 0177574) { // MMR1 + if (a == ADDR_MMR1) { // MMR1 DOLOG(debug, !peek_only, "read MMR1"); return MMR1; } - if (a == 0177576) { // MMR2 + if (a == ADDR_MMR2) { // MMR2 DOLOG(debug, !peek_only, "read MMR2"); return MMR2; } - if (a == 0172516) { // MMR3 + if (a == ADDR_MMR3) { // MMR3 DOLOG(debug, !peek_only, "read MMR3"); return MMR3; } - if (a == 0177776) { // PSW + if (a == ADDR_PSW) { // PSW DOLOG(debug, !peek_only, "read PSW"); return c -> getPSW(); } - if (a == 0177774) { // stack limit register + if (a == ADDR_STACKLIM) { // stack limit register return c -> getStackLimitRegister(); } - if (a >= 0177700 && a <= 0177705) { // kernel R0-R5 - DOLOG(debug, !peek_only, "read kernel R%d", a - 0177700); - return c -> getRegister(a - 0177700, 0, false); + if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 + DOLOG(debug, !peek_only, "read kernel R%d", a - ADDR_KERNEL_R); + return c -> getRegister(a - ADDR_KERNEL_R, 0, false); } - if (a >= 0177710 && a <= 0177715) { // user R0-R5 - DOLOG(debug, !peek_only, "read user R%d", a - 0177710); - return c -> getRegister(a - 0177710, 3, false); + if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 + DOLOG(debug, !peek_only, "read user R%d", a - ADDR_USER_R); + return c -> getRegister(a - ADDR_USER_R, 3, false); } - if (a == 0177706) { // kernel SP + if (a == ADDR_KERNEL_SP) { // kernel SP DOLOG(debug, !peek_only, "read kernel sp"); return c -> getStackPointer(0); } - if (a == 0177707) { // PC + if (a == ADDR_PC) { // PC DOLOG(debug, !peek_only, "read pc"); return c -> getPC(); } - if (a == 0177716) { // supervisor SP + if (a == ADDR_SV_SP) { // supervisor SP DOLOG(debug, !peek_only, "read supervisor sp"); return c -> getStackPointer(1); } - if (a == 0177717) { // user SP + if (a == ADDR_USER_SP) { // user SP DOLOG(debug, !peek_only, "read user sp"); return c -> getStackPointer(3); } - if (a == 0177766) { // cpu error register + if (a == ADDR_CPU_ERR) { // cpu error register DOLOG(debug, !peek_only, "read CPUERR"); return CPUERR; } @@ -259,10 +256,10 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, // LO size register field must be all 1s, so subtract 1 constexpr uint32_t system_size = n_pages * 8192 / 64 - 1; - if (a == 0177762) // system size HI + if (a == ADDR_SYSSIZE + 2) // system size HI return system_size >> 16; - if (a == 0177760) // system size LO + if (a == ADDR_SYSSIZE) // system size LO return system_size & 65535; if (a & 1) @@ -531,7 +528,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo { int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3; - if ((MMR0 & 1) == 1 && (a & 1) == 0 && a != 0177572) { + if ((MMR0 & 1) == 1 && (a & 1) == 0 && a != ADDR_MMR0) { const uint8_t apf = a >> 13; // active page field // TODO: D/I @@ -545,7 +542,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo } if (word_mode) { - if (a == 0177776 || a == 0177777) { // PSW + if (a == ADDR_PSW || a == ADDR_PSW + 1) { // PSW DOLOG(debug, true, "writeb PSW %s", a & 1 ? "MSB" : "LSB"); uint16_t vtemp = c -> getPSW(); @@ -561,7 +558,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo return; } - if (a == 0177774 || a == 0177775) { // stack limit register + if (a == ADDR_STACKLIM || a == ADDR_STACKLIM + 1) { // stack limit register DOLOG(debug, true, "writeb Set stack limit register: %o", value); uint16_t v = c -> getStackLimitRegister(); @@ -575,67 +572,67 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo } } else { - if (a == 0177776) { // PSW + if (a == ADDR_PSW) { // PSW DOLOG(debug, true, "write PSW %o", value); c -> setPSW(value & ~16, false); return; } - if (a == 0177774) { // stack limit register + if (a == ADDR_STACKLIM) { // stack limit register DOLOG(debug, true, "write Set stack limit register: %o", value); c -> setStackLimitRegister(value); return; } - if (a >= 0177700 && a <= 0177705) { // kernel R0-R5 - DOLOG(debug, true, "write kernel R%d: %o", a - 01777700, value); - c -> setRegister(a - 0177700, false, false, value); + if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 + DOLOG(debug, true, "write kernel R%d: %o", a - ADDR_KERNEL_R, value); + c -> setRegister(a - ADDR_KERNEL_R, false, false, value); return; } - if (a >= 0177710 && a <= 0177715) { // user R0-R5 - DOLOG(debug, true, "write user R%d: %o", a - 01777710, value); - c -> setRegister(a - 0177710, true, false, value); + if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 + DOLOG(debug, true, "write user R%d: %o", a - ADDR_USER_R, value); + c -> setRegister(a - ADDR_USER_R, true, false, value); return; } - if (a == 0177706) { // kernel SP + if (a == ADDR_KERNEL_SP) { // kernel SP DOLOG(debug, true, "write kernel SP: %o", value); c -> setStackPointer(0, value); return; } - if (a == 0177707) { // PC + if (a == ADDR_PC) { // PC DOLOG(debug, true, "write PC: %o", value); c -> setPC(value); return; } - if (a == 0177716) { // supervisor SP + if (a == ADDR_SV_SP) { // supervisor SP DOLOG(debug, true, "write supervisor sp: %o", value); c -> setStackPointer(1, value); return; } - if (a == 0177717) { // user SP + if (a == ADDR_USER_SP) { // user SP DOLOG(debug, true, "write user sp: %o", value); c -> setStackPointer(3, value); return; } - if (a == 0177770) { // microprogram break register + if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register return; } } - if (a == 0177766) { // cpu error register + if (a == ADDR_CPU_ERR) { // cpu error register DOLOG(debug, true, "write CPUERR: %o", value); CPUERR = 0; return; } - if (a == 0172516) { // MMR3 + if (a == ADDR_MMR3) { // MMR3 DOLOG(debug, true, "write set MMR3: %o", value); MMR3 = value & 067; return; } - if (a == 0177572) { // MMR0 + if (a == ADDR_MMR0) { // MMR0 DOLOG(debug, true, "write set MMR0: %o", value); setMMR0(value); @@ -643,13 +640,13 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo return; } - if (a == 0177772) { // PIR + if (a == ADDR_PIR) { // PIR DOLOG(debug, true, "write set PIR: %o", value); PIR = value; // TODO return; } - if (a == 0177546) { // line frequency clock and status register + if (a == ADDR_LFC) { // line frequency clock and status register DOLOG(debug, true, "write set LFC/SR: %o", value); lf_csr = value; return; @@ -677,56 +674,48 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo /// MMU /// // supervisor - if (a >= 0172200 && a < 0172240) { + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) { write_pdr(a, 1, value, word_mode); return; } - if (a >= 0172240 && a < 0172300) { + if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) { write_par(a, 1, value, word_mode); return; } // kernel - if (a >= 0172300 && a < 0172340) { + if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) { write_pdr(a, 0, value, word_mode); return; } - if (a >= 0172340 && a < 0172400) { + if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) { write_par(a, 0, value, word_mode); return; } // user - if (a >= 0177600 && a < 0177640) { + if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) { write_pdr(a, 3, value, word_mode); return; } - if (a >= 0177640 && a < 0177700) { + if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) { write_par(a, 3, value, word_mode); return; } //// - if (a == 0177746) { // cache control register + if (a == ADDR_CCR) { // cache control register // TODO return; } - if (a == 0177570) { // switch register + if (a == ADDR_CONSW) { // switch register switch_register = value; return; } /////////// - if (a == 0177374) { // TODO - DOLOG(debug, true, "char: %c", value & 127); - return; - } - - if (a & 1) - DOLOG(debug, true, "bus::writeWord: odd address UNHANDLED"); - DOLOG(debug, true, "UNHANDLED write %o(%c): %o", a, word_mode ? 'B' : ' ', value); // c -> busError(); diff --git a/bus.h b/bus.h index e01e99d..cbf5330 100644 --- a/bus.h +++ b/bus.h @@ -10,6 +10,47 @@ #include "rk05.h" #include "rl02.h" +#define ADDR_MMR0 0177572 +#define ADDR_MMR1 0177574 +#define ADDR_MMR2 0177576 +#define ADDR_MMR3 0172516 + +#define ADDR_PIR 0177772 +#define ADDR_LFC 0177546 // line frequency +#define ADDR_MAINT 0177750 +#define ADDR_CONSW 0177570 +#define ADDR_KW11P 0172540 +#define ADDR_LP11CSR 0177514 // printer + +#define ADDR_PDR_SV_START 0172200 +#define ADDR_PDR_SV_END 0172240 +#define ADDR_PAR_SV_START 0172240 +#define ADDR_PAR_SV_END 0172300 + +#define ADDR_PDR_K_START 0172300 +#define ADDR_PDR_K_END 0172340 +#define ADDR_PAR_K_START 0172340 +#define ADDR_PAR_K_END 0172400 + +#define ADDR_PDR_U_START 0177600 +#define ADDR_PDR_U_END 0177640 +#define ADDR_PAR_U_START 0177640 +#define ADDR_PAR_U_END 0177700 + +#define ADDR_PSW 0177776 +#define ADDR_STACKLIM 0177774 +#define ADDR_KERNEL_R 0177700 +#define ADDR_USER_R 0177710 +#define ADDR_KERNEL_SP 0177706 +#define ADDR_PC 0177707 +#define ADDR_SV_SP 0177716 +#define ADDR_USER_SP 0177717 + +#define ADDR_CPU_ERR 0177766 +#define ADDR_SYSSIZE 0177760 +#define ADDR_MICROPROG_BREAK_REG 0177770 +#define ADDR_CCR 0177746 + class cpu; class memory; class tty; diff --git a/cpu.cpp b/cpu.cpp index 8496683..7aaf9e2 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -162,7 +162,7 @@ bool cpu::put_result(const uint16_t a, const uint8_t dst_mode, const uint8_t dst b->write(a, word_mode, value, false); - return a != 0177776; + return a != ADDR_PSW; } uint16_t cpu::addRegister(const int nr, const bool prev_mode, const uint16_t value) @@ -404,7 +404,7 @@ bool cpu::putGAM(const uint8_t mode, const int reg, const bool word_mode, const break; } - return addr == -1 || addr != 0177776; + return addr == -1 || addr != ADDR_PSW; } uint16_t cpu::getGAMAddress(const uint8_t mode, const int reg, const bool word_mode, const bool prev_mode) @@ -554,7 +554,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) int16_t dst_value = b->readWord(dst_addr); int16_t result = 0; - bool set_flags = dst_addr != 0177776; + bool set_flags = dst_addr != ADDR_PSW; if (instr & 0x8000) { result = (dst_value - ssrc_value) & 0xffff; @@ -759,7 +759,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) else { b->write(a, false, vl, false); - set_flags = a != 0177776; + set_flags = a != ADDR_PSW; } if (set_flags) { @@ -816,7 +816,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) v = ((v & 0xff) << 8) | (v >> 8); - set_flags = a != 0177776; + set_flags = a != ADDR_PSW; b->writeWord(a, v); } @@ -845,7 +845,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) else { uint16_t a = getGAMAddress(dst_mode, dst_reg, word_mode, false); - set_flags = a != 0177776; + set_flags = a != ADDR_PSW; b -> write(a, word_mode, 0, false); } @@ -885,7 +885,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) else v ^= 0xffff; - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -918,7 +918,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t v = b -> read(a, word_mode, false); int32_t vl = (v + 1) & (word_mode ? 0xff : 0xffff); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(vl, word_mode)); @@ -951,7 +951,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t v = b -> read(a, word_mode, false); int32_t vl = (v - 1) & (word_mode ? 0xff : 0xffff); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(vl, word_mode)); @@ -986,7 +986,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, v, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1024,7 +1024,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, v, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1066,7 +1066,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, v, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1128,7 +1128,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, temp, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_c(new_carry); @@ -1179,7 +1179,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, temp, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_c(new_carry); @@ -1238,7 +1238,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) b->write(a, word_mode, v, false); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1269,7 +1269,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t vl = b -> read(a, word_mode, false); uint16_t v = (vl << 1) & (word_mode ? 0xff : 0xffff); - bool set_flags = a != 0177776; + bool set_flags = a != ADDR_PSW; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1299,7 +1299,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) // calculate address in current address space uint16_t a = getGAMAddress(dst_mode, dst_reg, false, false); - set_flags = a != 0177776; + set_flags = a != ADDR_PSW; // read from previous space v = b -> read(a, false, true); @@ -1334,7 +1334,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) else { uint16_t a = getGAMAddress(dst_mode, dst_reg, false, false); - set_flags = a != 0177776; + set_flags = a != ADDR_PSW; b -> write(a, false, v, true); // put in '13/12' address space } diff --git a/debugger.cpp b/debugger.cpp index 3d3a36a..0862ede 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -106,14 +106,14 @@ void mmu_dump(console *const cnsl, bus *const b) cnsl->put_string_lf(format("MMR2: %06o", b->getMMR2())); cnsl->put_string_lf(format("MMR3: %06o", mmr3)); - dump_par_pdr(cnsl, b, 0172200, 0172240, "supervisor i-space", 0); - dump_par_pdr(cnsl, b, 0172220, 0172260, "supervisor d-space", 1 + (!!(mmr3 & 2))); + 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, 0172300, 0172340, "kernel i-space", 0); - dump_par_pdr(cnsl, b, 0172320, 0172360, "kernel d-space", 1 + (!!(mmr3 & 4))); + 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, 0177600, 0177640, "user i-space", 0); - dump_par_pdr(cnsl, b, 0177620, 0177660, "user d-space", 1 + (!!(mmr3 & 1))); + 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))); } void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event, const bool tracing_in) From 9a1924b0af26a8c4edc9fee5337b2a750e30298d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 28 Jun 2022 19:25:05 +0200 Subject: [PATCH 20/28] PICO does not compile yet as std::thread and std::mutex seem to be missing --- ESP32/platformio.ini | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ESP32/platformio.ini b/ESP32/platformio.ini index 44661d8..a3b3b39 100644 --- a/ESP32/platformio.ini +++ b/ESP32/platformio.ini @@ -1,8 +1,8 @@ [platformio] -default_envs = serial32 +default_envs = ESP32 src_dir = . -[env:serial32] +[env:ESP32] lib_ldf_mode = deep+ src_filter = +<*> -<.git/> -<.svn/> - - - - - - platform = espressif32 @@ -14,3 +14,16 @@ lib_deps = greiman/SdFat@^2.1.2 adafruit/Adafruit NeoPixel@^1.10.4 build_flags = -std=gnu++17 -Ofast -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 build_unflags = -std=gnu++11 -Os + +#[env:PICO] +#lib_ldf_mode = deep+ +#src_filter = +<*> -<.git/> -<.svn/> - - - - - - +#platform = raspberrypi +#board = pico +#framework = arduino +#monitor_speed = 115200 +#upload_speed = 1000000 +#lib_deps = greiman/SdFat@^2.1.2 +# adafruit/Adafruit NeoPixel@^1.10.4 +#build_flags = -std=gnu++17 -Ofast -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 +#build_unflags = -std=gnu++11 -Os From 56e147ec098c75bcc4a4fc7c5ee069490ee4956a Mon Sep 17 00:00:00 2001 From: folkertvanheusden <85709915+folkertvanheusden@users.noreply.github.com> Date: Thu, 30 Jun 2022 08:43:43 +0200 Subject: [PATCH 21/28] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..2872009 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [ folkertvanheusden ] From 381879030fcd1336cdeed6960fa5b78b3701dfa0 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 2 Jul 2022 16:55:55 +0200 Subject: [PATCH 22/28] helpful logging --- bus.cpp | 2 +- main.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bus.cpp b/bus.cpp index aa62131..dfe55ed 100644 --- a/bus.cpp +++ b/bus.cpp @@ -716,7 +716,7 @@ void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bo /////////// - DOLOG(debug, true, "UNHANDLED write %o(%c): %o", a, word_mode ? 'B' : ' ', value); + DOLOG(debug, true, "UNHANDLED write %o(%c): %o", a, word_mode ? 'B' : 'W', value); // c -> busError(); diff --git a/main.cpp b/main.cpp index b5bb6da..5b6b66c 100644 --- a/main.cpp +++ b/main.cpp @@ -188,11 +188,19 @@ int main(int argc, char *argv[]) cnsl = new console_posix(&event, b); } - if (rk05_files.empty() == false) - b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + if (rk05_files.empty() == false) { + if (bootloader != BL_RK05) + DOLOG(warning, true, "Note: loading RK05 with no RK05 bootloader selected"); + + b->add_rk05(new rk05(rk05_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + } + + if (rl02_files.empty() == false) { + if (bootloader != BL_RL02) + DOLOG(warning, true, "Note: loading RL02 with no RL02 bootloader selected"); - if (rl02_files.empty() == false) b->add_rl02(new rl02(rl02_files, b, cnsl->get_disk_read_activity_flag(), cnsl->get_disk_write_activity_flag())); + } if (bootloader != BL_NONE) setBootLoader(b, bootloader); From f6f86ba18adf0669febe25b04383d01da09e64ee Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 2 Jul 2022 21:41:34 +0200 Subject: [PATCH 23/28] KW11-L esp32 functionality fix --- ESP32/platformio.ini | 2 +- kw11-l.cpp | 26 ++++++++++++++++++++++++-- utils.cpp | 5 ++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ESP32/platformio.ini b/ESP32/platformio.ini index a3b3b39..c05e4b0 100644 --- a/ESP32/platformio.ini +++ b/ESP32/platformio.ini @@ -4,7 +4,7 @@ src_dir = . [env:ESP32] lib_ldf_mode = deep+ -src_filter = +<*> -<.git/> -<.svn/> - - - - - - +build_src_filter = +<*> -<.git/> -<.svn/> - - - - - - platform = espressif32 board = wemos_d1_mini32 framework = arduino diff --git a/kw11-l.cpp b/kw11-l.cpp index e208c4b..91dc267 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -5,17 +5,31 @@ #include "kw11-l.h" #include "utils.h" +#if defined(ESP32) +void thread_wrapper_kw11(void *p) +{ + kw11_l *const kw11l = reinterpret_cast(p); + + kw11l->operator()(); +} +#endif kw11_l::kw11_l(bus *const b, console *const cnsl) : b(b), cnsl(cnsl) { +#if defined(ESP32) + xTaskCreatePinnedToCore(&thread_wrapper_kw11, "kw11-l", 2048, this, 1, nullptr, 0); +#else th = new std::thread(std::ref(*this)); +#endif } kw11_l::~kw11_l() { stop_flag = true; +#if !defined(ESP32) th->join(); +#endif delete th; } @@ -29,10 +43,18 @@ void kw11_l::operator()() if (b->get_lf_crs() & 64) b->getCpu()->queue_interrupt(6, 0100); - myusleep(1000000 / 50); +#if defined(ESP32) + vTaskDelay(100 / portTICK_RATE_MS); +#else + myusleep(1000000 / 50); // 20ms +#endif } else { - myusleep(1000000 / 10); +#if defined(ESP32) + vTaskDelay(100 / portTICK_RATE_MS); +#else + myusleep(1000000 / 10); // 100ms +#endif } } } diff --git a/utils.cpp b/utils.cpp index 9583731..f94e90f 100644 --- a/utils.cpp +++ b/utils.cpp @@ -72,7 +72,10 @@ int parity(int v) void myusleep(uint64_t us) { #if defined(ESP32) - delayMicroseconds(us); + if (us >= 1000) + vTaskDelay(us / 1000 / portTICK_RATE_MS); + else + delayMicroseconds(us); #else struct timespec req; From c9a2b39116eba1eb41d194836d84389c0dc8e533 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 2 Jul 2022 21:53:34 +0200 Subject: [PATCH 24/28] timing cleanup for esp32 --- kw11-l.cpp | 8 -------- utils.cpp | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/kw11-l.cpp b/kw11-l.cpp index 91dc267..2f73bd7 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -43,18 +43,10 @@ void kw11_l::operator()() if (b->get_lf_crs() & 64) b->getCpu()->queue_interrupt(6, 0100); -#if defined(ESP32) - vTaskDelay(100 / portTICK_RATE_MS); -#else myusleep(1000000 / 50); // 20ms -#endif } else { -#if defined(ESP32) - vTaskDelay(100 / portTICK_RATE_MS); -#else myusleep(1000000 / 10); // 100ms -#endif } } } diff --git a/utils.cpp b/utils.cpp index f94e90f..775f144 100644 --- a/utils.cpp +++ b/utils.cpp @@ -72,10 +72,20 @@ int parity(int v) void myusleep(uint64_t us) { #if defined(ESP32) - if (us >= 1000) - vTaskDelay(us / 1000 / portTICK_RATE_MS); - else - delayMicroseconds(us); + for(;;) { + uint64_t n_ms = us / 1000; + + if (n_ms >= portTICK_RATE_MS) { + vTaskDelay(n_ms / portTICK_RATE_MS); + + us -= n_ms * 1000; + } + else { + delayMicroseconds(us); + + break; + } + } #else struct timespec req; From 5b1d75fb74fc4ffed969d4f26e9395f241c2f1fa Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 3 Jul 2022 19:34:39 +0200 Subject: [PATCH 25/28] disassembler fix (SWAB) --- cpu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpu.cpp b/cpu.cpp index 7aaf9e2..82d89e6 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1822,7 +1822,8 @@ std::map > cpu::disassemble(const uint16_t // single_operand_instructions switch(so_opcode) { case 0b00000011: - text = "SWAB " + dst_text.operand; + if (!word_mode) + text = "SWAB " + dst_text.operand; break; case 0b000101000: From f59ae65e5eda9419a8c01c07b389dbabf7d2e64a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 29 Sep 2022 15:28:05 +0200 Subject: [PATCH 26/28] funding --- .github/FUNDING.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2872009..ccd7bcc 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ -github: [ folkertvanheusden ] +github: [folkertvanheusden] +patreon: folkertvanheusden From 4ccc53f5f264e86daf7b6ad44a42fb497714983e Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 9 Nov 2022 21:25:55 +0100 Subject: [PATCH 27/28] tweaks --- log.cpp | 3 ++- main.cpp | 1 + utils.cpp | 12 +++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/log.cpp b/log.cpp index a6c4c60..e277e41 100644 --- a/log.cpp +++ b/log.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "error.h" @@ -71,7 +72,7 @@ void dolog(const log_level_t ll, const char *fmt, ...) uint64_t now = get_us(); time_t t_now = now / 1000000; - struct tm tm { 0 }; + tm tm { 0 }; if (!localtime_r(&t_now, &tm)) error_exit(true, "localtime_r failed"); diff --git a/main.cpp b/main.cpp index 5b6b66c..45036dc 100644 --- a/main.cpp +++ b/main.cpp @@ -44,6 +44,7 @@ void help() printf("-h this help\n"); printf("-T t.bin load file as a binary tape file (like simh \"load\" command)\n"); printf("-R d.rk load file as a RK05 disk device\n"); + printf("-r d.rk load file as a RL02 disk device\n"); printf("-p 123 set CPU start pointer to decimal(!) value\n"); printf("-b x enable bootloader (build-in), parameter must be \"rk05\" or \"rl02\"\n"); printf("-n ncurses UI\n"); diff --git a/utils.cpp b/utils.cpp index 775f144..c026511 100644 --- a/utils.cpp +++ b/utils.cpp @@ -4,10 +4,12 @@ #include #endif #include +#include #include #include #include #include +#include #include #include @@ -41,7 +43,7 @@ unsigned long get_ms() #if defined(ESP32) return millis(); #else - struct timeval tv; + timeval tv; // TODO replace gettimeofday by clock_gettime gettimeofday(&tv, NULL); @@ -55,7 +57,7 @@ uint64_t get_us() #if defined(ESP32) return micros(); #else - struct timeval tv; + timeval tv; // TODO replace gettimeofday by clock_gettime gettimeofday(&tv, NULL); @@ -87,20 +89,20 @@ void myusleep(uint64_t us) } } #else - struct timespec req; + timespec req; req.tv_sec = us / 1000000l; req.tv_nsec = (us % 1000000l) * 1000l; for(;;) { - struct timespec rem { 0, 0 }; + timespec rem { 0, 0 }; int rc = nanosleep(&req, &rem); if (rc == 0 || (rc == -1 && errno != EINTR)) break; - memcpy(&req, &rem, sizeof(struct timespec)); + memcpy(&req, &rem, sizeof(timespec)); } #endif } From 13d3825d7345cfa5b676e2a015c073fe84c4d386 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 10 Nov 2022 08:50:26 +0100 Subject: [PATCH 28/28] -Q --- main.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 45036dc..8f3c283 100644 --- a/main.cpp +++ b/main.cpp @@ -80,14 +80,20 @@ int main(int argc, char *argv[]) uint16_t console_switches = 0; + std::string test; + int opt = -1; - while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3s:")) != -1) + while((opt = getopt(argc, argv, "hm:T:r:R:p:ndtL:b:l:3s:Q:")) != -1) { switch(opt) { case 'h': help(); return 1; + case 'Q': + test = optarg; + break; + case 's': console_switches = strtol(optarg, NULL, 8); break; @@ -225,6 +231,9 @@ int main(int argc, char *argv[]) sigaction(SIGTERM, &sa, nullptr); sigaction(SIGINT , &sa, nullptr); + if (test.empty() == false) + load_p11_x11(b, test); + #if 0 // loadbin(b, 0, "test.dat"); // c->setRegister(7, 0);