From fd632156d22efd0c17297007642aa6def2f837c9 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 18:09:47 +0200 Subject: [PATCH 01/23] peek_only is used relatively seldomly --- bus.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/bus.cpp b/bus.cpp index f69becb..9c50c17 100644 --- a/bus.cpp +++ b/bus.cpp @@ -283,8 +283,8 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } ///^ registers ^/// - if (!peek_only) { - if ((a & 1) && word_mode == wm_word) [[unlikely]] { + if ((a & 1) && word_mode == wm_word) [[unlikely]] { + if (!peek_only) { TRACE("READ-I/O odd address %06o UNHANDLED", a); mmu_->trap_if_odd(addr_in, run_mode, space, false); throw 0; @@ -508,11 +508,13 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return -1; } - if (peek_only == false && word_mode == wm_word && (addr_in & 1)) { - TRACE("READ from %06o - odd address!", addr_in); - mmu_->trap_if_odd(addr_in, run_mode, space, false); - throw 2; - return 0; + if ((addr_in & 1) && word_mode == wm_word) { + if (peek_only == false) { + TRACE("READ from %06o - odd address!", addr_in); + mmu_->trap_if_odd(addr_in, run_mode, space, false); + throw 2; + return 0; + } } if (m_offset >= m->get_memory_size()) { From b97deba5679901345a0eb07ee5088cba21935d1b Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 18:10:00 +0200 Subject: [PATCH 02/23] micro opt --- mmu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mmu.cpp b/mmu.cpp index 587a7b3..3695457 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -357,7 +357,6 @@ void mmu::mmudebug(const uint16_t a) void mmu::verify_page_access(cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) { const auto [ trap_action, access_control ] = get_trap_action(run_mode, d, apf, is_write); - if (trap_action == T_PROCEED) return; @@ -436,6 +435,9 @@ void mmu::verify_access_valid(cpu *const c, const uint32_t m_offset, const int r void mmu::verify_page_length(cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) { uint16_t pdr_len = get_pdr_len(run_mode, d, apf); + if (pdr_len == 127) + return; + uint16_t pdr_cmp = (virt_addr >> 6) & 127; bool direction = get_pdr_direction(run_mode, d, apf); @@ -489,7 +491,7 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const if ((getMMR3() & 16) == 0) // off is 18bit m_offset &= 0x3ffff; - if (trap_on_failure) { + if (trap_on_failure) [[likely]] { verify_page_access(c, a, run_mode, d, apf, is_write); // e.g. ram or i/o, not unmapped From 8b7057a9c0a01168b15a7d4ae260e5a73574401a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 20:59:57 +0200 Subject: [PATCH 03/23] micro opt of mmu::verify_page_length --- mmu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mmu.cpp b/mmu.cpp index 3695457..56edc3c 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -442,7 +442,7 @@ void mmu::verify_page_length(cpu *const c, const uint16_t virt_addr, const int r bool direction = get_pdr_direction(run_mode, d, apf); - if ((pdr_cmp > pdr_len && direction == false) || (pdr_cmp < pdr_len && direction == true)) [[unlikely]] { + if (direction == false ? pdr_cmp > pdr_len : pdr_cmp < pdr_len) [[unlikely]] { TRACE("mmu::calculate_physical_address::p_offset %o versus %o direction %d", pdr_cmp, pdr_len, direction); TRACE("TRAP(0250) (throw 7) on address %06o", virt_addr); @@ -485,7 +485,6 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const uint16_t p_offset = a & 8191; // page offset m_offset = get_physical_memory_offset(run_mode, d, apf); - m_offset += p_offset; if ((getMMR3() & 16) == 0) // off is 18bit From 8223536328d4c297dd9900f5d851bef161f491db Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:05:13 +0200 Subject: [PATCH 04/23] micro opt --- bus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus.cpp b/bus.cpp index 9c50c17..acbcfda 100644 --- a/bus.cpp +++ b/bus.cpp @@ -806,7 +806,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 throw 9; } - if (word_mode == wm_word && (addr_in & 1)) [[unlikely]] { + if ( (addr_in & 1) && word_mode == wm_word) [[unlikely]] { TRACE("WRITE to %06o (value: %06o) - odd address!", addr_in, value); mmu_->trap_if_odd(addr_in, run_mode, space, true); From c434d8e4d7c1442d9175ff58ae3a406aed5fda38 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:10:08 +0200 Subject: [PATCH 05/23] order --- mmu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mmu.cpp b/mmu.cpp index 56edc3c..bc4e2c6 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -478,12 +478,12 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const uint32_t m_offset = a; if (is_enabled() || (is_write && (getMMR0() & (1 << 8 /* maintenance check */)))) { - uint8_t apf = a >> 13; // active page field - bool d = space == d_space && get_use_data_space(run_mode); uint16_t p_offset = a & 8191; // page offset + uint8_t apf = a >> 13; // active page field + m_offset = get_physical_memory_offset(run_mode, d, apf); m_offset += p_offset; From 88d6092b4c4ae1eb9f04c3a4d2db5b96505ba2ea Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:10:31 +0200 Subject: [PATCH 06/23] prevent exceptions in ncurses console --- console_ncurses.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console_ncurses.cpp b/console_ncurses.cpp index 531efee..1850c88 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -146,7 +146,7 @@ void console_ncurses::panel_update_thread() int run_mode = current_PSW >> 14; uint16_t current_PC = c->getPC(); - uint32_t full_addr = b->getMMU()->calculate_physical_address(c, run_mode, current_PC, false, false, i_space); + memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); uint16_t current_instr = b->read_word(current_PC); @@ -160,7 +160,7 @@ void console_ncurses::panel_update_thread() wattron(w_panel->win, COLOR_PAIR(1 + run_mode)); for(uint8_t b=0; b<22; b++) - mvwprintw(w_panel->win, 0, 1 + 22 - b, "%c", full_addr & (1 << b) ? '1' : '0'); + mvwprintw(w_panel->win, 0, 1 + 22 - b, "%c", rc.physical_instruction & (1 << b) ? '1' : '0'); wattron(w_panel->win, COLOR_PAIR(1)); From 9441309427abec718d6640e9c3a8d0e624f8a266 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:11:17 +0200 Subject: [PATCH 07/23] new commandline scheme --- work/werkend-mu/run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/work/werkend-mu/run.sh b/work/werkend-mu/run.sh index b7d758c..f858396 100755 --- a/work/werkend-mu/run.sh +++ b/work/werkend-mu/run.sh @@ -6,9 +6,9 @@ echo 'rl(0,0)unix' rm ~/temp/ramdisk/test2.log if [ "$1" = "fast" ] ; then -./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -S 256 -L error,info -l ~/temp/ramdisk/test2.log -P +./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -S 256 -L error,info -l ~/temp/ramdisk/test2.log -P -R rl02 elif [ "$1" = "medium" ] ; then -./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -L error,info -l ~/temp/ramdisk/test2.log -d -S 256 -P +./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -L error,info -l ~/temp/ramdisk/test2.log -d -S 256 -P -R rl02 else -./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -L error,debug -l ~/temp/ramdisk/test2.log -d -t -X -S 256 -P +./build/kek -r work/werkend-mu/unix_v7m_rl0.dsk -r work/werkend-mu/unix_v7m_rl1.dsk -b -L error,debug -l ~/temp/ramdisk/test2.log -d -t -X -S 256 -P -R rl02 fi From a77d037db9388a55982d906143b7b0fe0b0d70b4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:20:04 +0200 Subject: [PATCH 08/23] micro opt --- breakpoint_memory.cpp | 2 +- bus.cpp | 5 +++-- console_ncurses.cpp | 2 +- debugger.cpp | 2 +- mmu.cpp | 16 +++++++--------- mmu.h | 2 +- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/breakpoint_memory.cpp b/breakpoint_memory.cpp index 7adfa48..3584e9e 100644 --- a/breakpoint_memory.cpp +++ b/breakpoint_memory.cpp @@ -23,7 +23,7 @@ std::optional breakpoint_memory::is_triggered() const uint16_t v = 0; if (is_virtual) - v = b->read(addr, word_mode, rm_cur, true, i_space); + v = b->peek_word(addr); else v = b->read_physical(addr); diff --git a/bus.cpp b/bus.cpp index acbcfda..2fd37ad 100644 --- a/bus.cpp +++ b/bus.cpp @@ -242,7 +242,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); - uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, !peek_only, false, space); + uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, false, space); uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; @@ -517,6 +517,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } } + // TODO: this will fail for peek & odd addressing if (m_offset >= m->get_memory_size()) { if (peek_only) { TRACE("READ from %06o - out of range!", addr_in); @@ -563,7 +564,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (mmu_->is_enabled() && (addr_in & 1) == 0 /* TODO remove this? */ && addr_in != ADDR_MMR0) mmu_->set_page_written_to(run_mode, d, apf); - uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, true, true, space); + uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, true, space); uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; diff --git a/console_ncurses.cpp b/console_ncurses.cpp index 1850c88..cd6f2cf 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -148,7 +148,7 @@ void console_ncurses::panel_update_thread() uint16_t current_PC = c->getPC(); memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); - uint16_t current_instr = b->read_word(current_PC); + uint16_t current_instr = b->peek_word(current_PC); auto data = c->disassemble(current_PC); diff --git a/debugger.cpp b/debugger.cpp index 53058c1..23eb05e 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -933,7 +933,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto for(int i=0; iread(cur_addr, wm_word, rm_cur, true) : b->read_physical(cur_addr); + int val = parts[2] == "v" ? b->peek_word(cur_addr) : b->read_physical(cur_addr); if (val == -1) { cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr)); diff --git a/mmu.cpp b/mmu.cpp index bc4e2c6..88ff8ff 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -473,7 +473,7 @@ void mmu::verify_page_length(cpu *const c, const uint16_t virt_addr, const int r } } -uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const d_i_space_t space) +uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space) { uint32_t m_offset = a; @@ -490,17 +490,15 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const if ((getMMR3() & 16) == 0) // off is 18bit m_offset &= 0x3ffff; - if (trap_on_failure) [[likely]] { - verify_page_access(c, a, run_mode, d, apf, is_write); + verify_page_access(c, a, run_mode, d, apf, is_write); - // e.g. ram or i/o, not unmapped - uint32_t io_base = get_io_base(); - bool is_io = m_offset >= io_base; + // e.g. ram or i/o, not unmapped + uint32_t io_base = get_io_base(); + bool is_io = m_offset >= io_base; - verify_access_valid(c, m_offset, run_mode, d, apf, is_io, is_write); + verify_access_valid(c, m_offset, run_mode, d, apf, is_io, is_write); - verify_page_length(c, a, run_mode, d, apf, is_write); - } + verify_page_length(c, a, run_mode, d, apf, is_write); } return m_offset; diff --git a/mmu.h b/mmu.h index c1316d4..c97987c 100644 --- a/mmu.h +++ b/mmu.h @@ -94,7 +94,7 @@ public: memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const; std::pair get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write); - uint32_t calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const d_i_space_t space); + uint32_t calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space); uint16_t getMMR0() const { return MMR0; } uint16_t getMMR1() const { return MMR1; } From b17129bf82d5efd576d0b93ab9e2b802deac6eae Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:37:16 +0200 Subject: [PATCH 09/23] peek_word tweak --- ESP32/console_esp32.cpp | 2 +- breakpoint_memory.cpp | 2 +- bus.cpp | 128 +++--- bus.cpp- | 891 ++++++++++++++++++++++++++++++++++++++++ bus.h | 4 +- console_ncurses.cpp | 2 +- cpu.cpp | 53 ++- debugger.cpp | 2 +- 8 files changed, 984 insertions(+), 100 deletions(-) create mode 100644 bus.cpp- diff --git a/ESP32/console_esp32.cpp b/ESP32/console_esp32.cpp index 3505dce..0d09997 100644 --- a/ESP32/console_esp32.cpp +++ b/ESP32/console_esp32.cpp @@ -121,7 +121,7 @@ void console_esp32::panel_update_thread() if (panel_mode == PM_BITS) { memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); - uint16_t current_instr = b->peek_word(current_PC); + uint16_t current_instr = b->peek_word(run_mode, current_PC); int pixel_offset = 0; diff --git a/breakpoint_memory.cpp b/breakpoint_memory.cpp index 3584e9e..811fcc9 100644 --- a/breakpoint_memory.cpp +++ b/breakpoint_memory.cpp @@ -23,7 +23,7 @@ std::optional breakpoint_memory::is_triggered() const uint16_t v = 0; if (is_virtual) - v = b->peek_word(addr); + v = b->peek_word(rm_cur, addr); // FIXME rm_cur else v = b->read_physical(addr); diff --git a/bus.cpp b/bus.cpp index 2fd37ad..1d30af5 100644 --- a/bus.cpp +++ b/bus.cpp @@ -238,7 +238,7 @@ void bus::init() mmu_->setMMR3(0); } -uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only, const d_i_space_t space) +uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm_selection_t mode_selection, const d_i_space_t space) { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); @@ -253,60 +253,58 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm //// REGISTERS //// if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 uint16_t temp = c->getRegister(a - ADDR_KERNEL_R) & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O kernel R%d: %06o", a - ADDR_KERNEL_R, temp); + TRACE("READ-I/O kernel R%d: %06o", a - ADDR_KERNEL_R, temp); return temp; } if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 uint16_t temp = c->getRegister(a - ADDR_USER_R) & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O user R%d: %06o", a - ADDR_USER_R, temp); + TRACE("READ-I/O user R%d: %06o", a - ADDR_USER_R, temp); return temp; } if (a == ADDR_KERNEL_SP) { // kernel SP uint16_t temp = c->getStackPointer(0) & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O kernel SP: %06o", temp); + TRACE("READ-I/O kernel SP: %06o", temp); return temp; } if (a == ADDR_PC) { // PC uint16_t temp = c->getPC() & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O PC: %06o", temp); + TRACE("READ-I/O PC: %06o", temp); return temp; } if (a == ADDR_SV_SP) { // supervisor SP uint16_t temp = c->getStackPointer(1) & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O supervisor SP: %06o", temp); + TRACE("READ-I/O supervisor SP: %06o", temp); return temp; } if (a == ADDR_USER_SP) { // user SP uint16_t temp = c->getStackPointer(3) & (word_mode == wm_byte ? 0xff : 0xffff); - if (!peek_only) TRACE("READ-I/O user SP: %06o", temp); + TRACE("READ-I/O user SP: %06o", temp); return temp; } ///^ registers ^/// if ((a & 1) && word_mode == wm_word) [[unlikely]] { - if (!peek_only) { - TRACE("READ-I/O odd address %06o UNHANDLED", a); - mmu_->trap_if_odd(addr_in, run_mode, space, false); - throw 0; - return 0; - } + TRACE("READ-I/O odd address %06o UNHANDLED", a); + mmu_->trap_if_odd(addr_in, run_mode, space, false); + throw 0; + return 0; } if (a == ADDR_CPU_ERR) { // cpu error register uint16_t temp = mmu_->getCPUERR() & 0xff; - if (!peek_only) TRACE("READ-I/O CPU error: %03o", temp); + TRACE("READ-I/O CPU error: %03o", temp); return temp; } if (a == ADDR_MAINT) { // MAINT uint16_t temp = 1; // POWER OK - if (!peek_only) TRACE("READ-I/O MAINT: %o", temp); + TRACE("READ-I/O MAINT: %o", temp); return temp; } if (a == ADDR_CONSW) { // console switch & display register uint16_t temp = console_switches; - if (!peek_only) TRACE("READ-I/O console switch: %o", temp); + TRACE("READ-I/O console switch: %o", temp); return temp; } @@ -320,13 +318,13 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm else temp = a == ADDR_PIR ? PIR & 255 : PIR >> 8; - if (!peek_only) TRACE("READ-I/O PIR: %o", temp); + TRACE("READ-I/O PIR: %o", temp); return temp; } if (a == ADDR_SYSTEM_ID) { uint16_t temp = 011064; - if (!peek_only) TRACE("READ-I/O system id: %o", temp); + TRACE("READ-I/O system id: %o", temp); return temp; } @@ -335,7 +333,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm if (a == ADDR_LP11CSR) { // printer, CSR register, LP11 uint16_t temp = 0x80; - if (!peek_only) TRACE("READ-I/O LP11 CSR: %o", temp); + TRACE("READ-I/O LP11 CSR: %o", temp); return temp; } @@ -354,133 +352,133 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others - if (!peek_only) TRACE("READ-I/O cache control register/others (%06o): %o", a, 0); + TRACE("READ-I/O cache control register/others (%06o): %o", a, 0); // TODO return 0; } if (a >= 0170200 && a <= 0170377) { // unibus map - if (!peek_only) TRACE("READ-I/O unibus map (%06o): %o", a, 0); + TRACE("READ-I/O unibus map (%06o): %o", a, 0); // TODO return 0; } if (a >= 0172100 && a <= 0172137) { // MM11-LP parity - if (!peek_only) TRACE("READ-I/O MM11-LP parity (%06o): %o", a, 1); + TRACE("READ-I/O MM11-LP parity (%06o): %o", a, 1); return 1; } if (word_mode == wm_byte) { if (a == ADDR_PSW) { // PSW uint8_t temp = c->getPSW(); - if (!peek_only) TRACE("READ-I/O PSW LSB: %03o", temp); + TRACE("READ-I/O PSW LSB: %03o", temp); return temp; } if (a == ADDR_PSW + 1) { uint8_t temp = c->getPSW() >> 8; - if (!peek_only) TRACE("READ-I/O PSW MSB: %03o", temp); + TRACE("READ-I/O PSW MSB: %03o", temp); return temp; } if (a == ADDR_STACKLIM) { // stack limit register uint8_t temp = c->getStackLimitRegister(); - if (!peek_only) TRACE("READ-I/O stack limit register (low): %03o", temp); + TRACE("READ-I/O stack limit register (low): %03o", temp); return temp; } if (a == ADDR_STACKLIM + 1) { // stack limit register uint8_t temp = c->getStackLimitRegister() >> 8; - if (!peek_only) TRACE("READ-I/O stack limit register (high): %03o", temp); + TRACE("READ-I/O stack limit register (high): %03o", temp); return temp; } if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register uint8_t temp = microprogram_break_register; - if (!peek_only) TRACE("READ-I/O microprogram break register (low): %03o", temp); + TRACE("READ-I/O microprogram break register (low): %03o", temp); return temp; } if (a == ADDR_MICROPROG_BREAK_REG + 1) { // microprogram break register uint8_t temp = microprogram_break_register >> 8; - if (!peek_only) TRACE("READ-I/O microprogram break register (high): %03o", temp); + TRACE("READ-I/O microprogram break register (high): %03o", temp); return temp; } if (a == ADDR_MMR0) { uint8_t temp = mmu_->getMMR0(); - if (!peek_only) TRACE("READ-I/O MMR0 LO: %03o", temp); + TRACE("READ-I/O MMR0 LO: %03o", temp); return temp; } if (a == ADDR_MMR0 + 1) { uint8_t temp = mmu_->getMMR0() >> 8; - if (!peek_only) TRACE("READ-I/O MMR0 HI: %03o", temp); + TRACE("READ-I/O MMR0 HI: %03o", temp); return temp; } } else { if (a == ADDR_MMR0) { uint16_t temp = mmu_->getMMR0(); - if (!peek_only) TRACE("READ-I/O MMR0: %06o", temp); + TRACE("READ-I/O MMR0: %06o", temp); return temp; } if (a == ADDR_MMR1) { // MMR1 uint16_t temp = mmu_->getMMR1(); - if (!peek_only) TRACE("READ-I/O MMR1: %06o", temp); + TRACE("READ-I/O MMR1: %06o", temp); return temp; } if (a == ADDR_MMR2) { // MMR2 uint16_t temp = mmu_->getMMR2(); - if (!peek_only) TRACE("READ-I/O MMR2: %06o", temp); + TRACE("READ-I/O MMR2: %06o", temp); return temp; } if (a == ADDR_MMR3) { // MMR3 uint16_t temp = mmu_->getMMR3(); - if (!peek_only) TRACE("READ-I/O MMR3: %06o", temp); + TRACE("READ-I/O MMR3: %06o", temp); return temp; } if (a == ADDR_PSW) { // PSW uint16_t temp = c->getPSW(); - if (!peek_only) TRACE("READ-I/O PSW: %06o", temp); + TRACE("READ-I/O PSW: %06o", temp); return temp; } if (a == ADDR_STACKLIM) { // stack limit register uint16_t temp = c->getStackLimitRegister(); - if (!peek_only) TRACE("READ-I/O stack limit register: %06o", temp); + TRACE("READ-I/O stack limit register: %06o", temp); return temp; } if (a == ADDR_CPU_ERR) { // cpu error register uint16_t temp = mmu_->getCPUERR(); - if (!peek_only) TRACE("READ-I/O CPUERR: %06o", temp); + TRACE("READ-I/O CPUERR: %06o", temp); return temp; } if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register uint16_t temp = microprogram_break_register; - if (!peek_only) TRACE("READ-I/O microprogram break register: %06o", temp); + TRACE("READ-I/O microprogram break register: %06o", temp); return temp; } } - if (tm11 && a >= TM_11_BASE && a < TM_11_END && !peek_only) + if (tm11 && a >= TM_11_BASE && a < TM_11_END) return word_mode == wm_byte ? tm11->read_byte(a) : tm11->read_word(a); - if (rk05_ && a >= RK05_BASE && a < RK05_END && !peek_only) + if (rk05_ && a >= RK05_BASE && a < RK05_END) return word_mode == wm_byte ? rk05_->read_byte(a) : rk05_->read_word(a); - if (rl02_ && a >= RL02_BASE && a < RL02_END && !peek_only) + if (rl02_ && a >= RL02_BASE && a < RL02_END) return word_mode == wm_byte ? rl02_->read_byte(a) : rl02_->read_word(a); - if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END && !peek_only) + if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END) return word_mode == wm_byte ? tty_->read_byte(a) : tty_->read_word(a); - if (dc11_ && a >= DC11_BASE && a < DC11_END && !peek_only) + if (dc11_ && a >= DC11_BASE && a < DC11_END) return word_mode == wm_byte ? dc11_->read_byte(a) : dc11_->read_word(a); - if (rp06_ && a >= RP06_BASE && a < RP06_END && !peek_only) + if (rp06_ && a >= RP06_BASE && a < RP06_END) return word_mode == wm_byte ? rp06_->read_byte(a) : rp06_->read_word(a); // LO size register field must be all 1s, so subtract 1 @@ -488,42 +486,32 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm if (a == ADDR_SYSSIZE + 2) { // system size HI uint16_t temp = system_size >> 16; - if (!peek_only) TRACE("READ-I/O accessing system size HI: %06o", temp); + TRACE("READ-I/O accessing system size HI: %06o", temp); return temp; } if (a == ADDR_SYSSIZE) { // system size LO uint16_t temp = system_size; - if (!peek_only) TRACE("READ-I/O accessing system size LO: %06o", temp); + TRACE("READ-I/O accessing system size LO: %06o", temp); return temp; } - if (!peek_only) { - TRACE("READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', mmu_->get_io_base()); + TRACE("READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', mmu_->get_io_base()); - c->trap(004); // no such i/o - throw 1; - } + c->trap(004); // no such i/o + throw 1; return -1; } if ((addr_in & 1) && word_mode == wm_word) { - if (peek_only == false) { - TRACE("READ from %06o - odd address!", addr_in); - mmu_->trap_if_odd(addr_in, run_mode, space, false); - throw 2; - return 0; - } + TRACE("READ from %06o - odd address!", addr_in); + mmu_->trap_if_odd(addr_in, run_mode, space, false); + throw 2; + return 0; } - // TODO: this will fail for peek & odd addressing if (m_offset >= m->get_memory_size()) { - if (peek_only) { - TRACE("READ from %06o - out of range!", addr_in); - return 0; - } - c->trap(004); // no such RAM throw 1; } @@ -534,7 +522,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm else temp = m->read_word(m_offset); - if (!peek_only) TRACE("READ from %06o/%07o %c %c: %06o (%s)", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode == wm_byte ? 'B' : 'W', temp, mode_selection == rm_prev ? "prev" : "cur"); + TRACE("READ from %06o/%07o %c %c: %06o (%s)", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode == wm_byte ? 'B' : 'W', temp, mode_selection == rm_prev ? "prev" : "cur"); return temp; } @@ -861,12 +849,18 @@ uint16_t bus::read_physical(const uint32_t a) uint16_t bus::read_word(const uint16_t a, const d_i_space_t s) { - return read(a, wm_word, rm_cur, false, s); + return read(a, wm_word, rm_cur, s); } -uint16_t bus::peek_word(const uint16_t a) +uint16_t bus::peek_word(const int run_mode, const uint16_t a) { - return read(a, wm_word, rm_cur, true); + auto meta = mmu_->calculate_physical_address(run_mode, a); + + uint32_t io_base = mmu_->get_io_base(); + if (meta.physical_instruction >= io_base) // TODO: I/O always returns 0xffff + return 0xffff; + + return m->read_word(meta.physical_instruction); } void bus::write_word(const uint16_t a, const uint16_t value, const d_i_space_t s) diff --git a/bus.cpp- b/bus.cpp- new file mode 100644 index 0000000..e509bbe --- /dev/null +++ b/bus.cpp- @@ -0,0 +1,891 @@ +// (C) 2018-2024 by Folkert van Heusden +// Released under MIT license + +#include "gen.h" +#include +#include +#include +#include + +#include "bus.h" +#include "cpu.h" +#include "dc11.h" +#include "kw11-l.h" +#include "log.h" +#include "memory.h" +#include "mmu.h" +#include "tm-11.h" +#include "tty.h" +#include "utils.h" + +#if defined(ESP32) +#include +#endif + + +bus::bus() +{ + mmu_ = new mmu(); + + kw11_l_ = new kw11_l(this); + + reset(); +} + +bus::~bus() +{ + delete kw11_l_; + delete c; + delete tm11; + delete rk05_; + delete rl02_; + delete tty_; + delete mmu_; + delete m; + delete dc11_; + delete rp06_; +} + +JsonDocument bus::serialize() const +{ + JsonDocument j_out; + + if (m) + j_out["memory"] = m->serialize(); + + if (kw11_l_) + j_out["kw11-l"] = kw11_l_->serialize(); + + if (tty_) + j_out["tty"] = tty_->serialize(); + + if (mmu_) + j_out["mmu"] = mmu_->serialize(); + + if (c) + j_out["cpu"] = c->serialize(); + + if (rl02_) + j_out["rl02"] = rl02_->serialize(); + + if (rk05_) + j_out["rk05"] = rk05_->serialize(); + + if (dc11_) + j_out["dc11"] = dc11_->serialize(); + + if (rp06_) + j_out["rp06"] = rp06_->serialize(); + + // TODO: tm11 + + return j_out; +} + +bus *bus::deserialize(const JsonDocument j, console *const cnsl, std::atomic_uint32_t *const event) +{ + bus *b = new bus(); + + memory *m = nullptr; + if (j.containsKey("memory")) { + m = memory::deserialize(j["memory"]); + b->add_ram(m); + } + + if (j.containsKey("tty")) + b->add_tty(tty::deserialize(j["tty"], b, cnsl)); + + if (j.containsKey("mmu")) + b->add_mmu(mmu::deserialize(j["mmu"], m)); + + if (j.containsKey("cpu")) + b->add_cpu(cpu::deserialize(j["cpu"], b, event)); + + if (j.containsKey("rl02")) + b->add_rl02(rl02::deserialize(j["rl02"], b)); + + if (j.containsKey("rk05")) + b->add_rk05(rk05::deserialize(j["rk05"], b)); + + if (j.containsKey("kw11-l")) + b->add_KW11_L(kw11_l::deserialize(j["kw11-l"], b, cnsl)); + + if (j.containsKey("dc11")) + b->add_DC11(dc11::deserialize(j["dc11"], b)); + + if (j.containsKey("rp06")) + b->add_RP06(rp06::deserialize(j["rp06"], b)); + + // TODO: tm11 + + return b; +} + +void bus::show_state(console *const cnsl) const +{ + cnsl->put_string_lf(format("Microprogram break register: %06o", microprogram_break_register)); + cnsl->put_string_lf(format("Console switches: %06o", console_switches)); + cnsl->put_string_lf(format("Console LEDs: %06o", console_leds)); +} + +void bus::set_memory_size(const int n_pages) +{ + uint32_t n_bytes = n_pages * 8192l; + + delete m; + m = new memory(n_bytes); + + mmu_->begin(m); + + TRACE("Memory is now %u kB in size", n_bytes / 1024); +} + +void bus::reset() +{ + if (m) + m->reset(); + if (mmu_) + mmu_->reset(); + if (c) + c->reset(); + if (tm11) + tm11->reset(); + if (rk05_) + rk05_->reset(); + if (rl02_) + rl02_->reset(); + if (tty_) + tty_->reset(); + if (kw11_l_) + kw11_l_->reset(); + if (dc11_) + dc11_->reset(); + if (rp06_) + rp06_->reset(); +} + +void bus::add_RP06(rp06 *const rp06_) +{ + delete this->rp06_; + this->rp06_ = rp06_; +} + +void bus::add_KW11_L(kw11_l *const kw11_l_) +{ + delete this->kw11_l_; + this->kw11_l_ = kw11_l_; +} + +void bus::add_ram(memory *const m) +{ + delete this->m; + this->m = m; + + mmu_->begin(m); +} + +void bus::add_mmu(mmu *const mmu_) +{ + delete this->mmu_; + this->mmu_ = mmu_; +} + +void bus::add_cpu(cpu *const c) +{ + delete this->c; + this->c = c; +} + +void bus::add_tm11(tm_11 *const tm11) +{ + delete this->tm11; + this->tm11= tm11; +} + +void bus::add_rk05(rk05 *const rk05_) +{ + delete this->rk05_; + this->rk05_ = rk05_; +} + +void bus::add_rl02(rl02 *const rl02_) +{ + delete this->rl02_; + this->rl02_ = rl02_; +} + +void bus::add_tty(tty *const tty_) +{ + delete this->tty_; + this->tty_ = tty_; +} + +void bus::add_DC11(dc11 *const dc11_) +{ + delete this->dc11_; + this->dc11_ = dc11_; +} + +void bus::del_DC11() +{ + delete dc11_; + dc11_ = nullptr; +} + +void bus::init() +{ + mmu_->setMMR0(0); + mmu_->setMMR3(0); +} + +uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only, const d_i_space_t space) +{ + int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); + + uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, !peek_only, false, space); + + if (m_offset >= m->get_memory_size()) { + uint32_t io_base = mmu_->get_io_base(); + bool is_io = m_offset >= io_base; + + if (is_io) { + uint16_t a = m_offset - io_base + 0160000; // TODO + + //// REGISTERS //// + if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 + uint16_t temp = c->getRegister(a - ADDR_KERNEL_R) & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O kernel R%d: %06o", a - ADDR_KERNEL_R, temp); + return temp; + } + if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 + uint16_t temp = c->getRegister(a - ADDR_USER_R) & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O user R%d: %06o", a - ADDR_USER_R, temp); + return temp; + } + if (a == ADDR_KERNEL_SP) { // kernel SP + uint16_t temp = c->getStackPointer(0) & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O kernel SP: %06o", temp); + return temp; + } + if (a == ADDR_PC) { // PC + uint16_t temp = c->getPC() & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O PC: %06o", temp); + return temp; + } + if (a == ADDR_SV_SP) { // supervisor SP + uint16_t temp = c->getStackPointer(1) & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O supervisor SP: %06o", temp); + return temp; + } + if (a == ADDR_USER_SP) { // user SP + uint16_t temp = c->getStackPointer(3) & (word_mode == wm_byte ? 0xff : 0xffff); + if (!peek_only) TRACE("READ-I/O user SP: %06o", temp); + return temp; + } + ///^ registers ^/// + + if ((a & 1) && word_mode == wm_word) [[unlikely]] { + if (!peek_only) { + TRACE("READ-I/O odd address %06o UNHANDLED", a); + mmu_->trap_if_odd(addr_in, run_mode, space, false); + throw 0; + return 0; + } + } + + if (a == ADDR_CPU_ERR) { // cpu error register + uint16_t temp = mmu_->getCPUERR() & 0xff; + if (!peek_only) TRACE("READ-I/O CPU error: %03o", temp); + return temp; + } + + if (a == ADDR_MAINT) { // MAINT + uint16_t temp = 1; // POWER OK + if (!peek_only) TRACE("READ-I/O MAINT: %o", temp); + return temp; + } + + if (a == ADDR_CONSW) { // console switch & display register + uint16_t temp = console_switches; + if (!peek_only) TRACE("READ-I/O console switch: %o", temp); + return temp; + } + + if (a == ADDR_PIR || a == ADDR_PIR + 1) { // PIR + uint16_t temp = 0; + + uint16_t PIR = mmu_->getPIR(); + + if (word_mode == wm_word) + temp = PIR; + else + temp = a == ADDR_PIR ? PIR & 255 : PIR >> 8; + + if (!peek_only) TRACE("READ-I/O PIR: %o", temp); + return temp; + } + + if (a == ADDR_SYSTEM_ID) { + uint16_t temp = 011064; + if (!peek_only) TRACE("READ-I/O system id: %o", temp); + return temp; + } + + if (a == ADDR_LFC) // line frequency clock and status register + return kw11_l_->read_word(a); + + if (a == ADDR_LP11CSR) { // printer, CSR register, LP11 + uint16_t temp = 0x80; + if (!peek_only) TRACE("READ-I/O LP11 CSR: %o", temp); + return temp; + } + + /// MMU /// + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + return mmu_->read_word(a); + + return mmu_->read_byte(a); + } + /////////// + + if (a >= 0177740 && a <= 0177753) { // cache control register and others + if (!peek_only) TRACE("READ-I/O cache control register/others (%06o): %o", a, 0); + // TODO + return 0; + } + + if (a >= 0170200 && a <= 0170377) { // unibus map + if (!peek_only) TRACE("READ-I/O unibus map (%06o): %o", a, 0); + // TODO + return 0; + } + + if (a >= 0172100 && a <= 0172137) { // MM11-LP parity + if (!peek_only) TRACE("READ-I/O MM11-LP parity (%06o): %o", a, 1); + return 1; + } + + if (word_mode == wm_byte) { + if (a == ADDR_PSW) { // PSW + uint8_t temp = c->getPSW(); + if (!peek_only) TRACE("READ-I/O PSW LSB: %03o", temp); + return temp; + } + + if (a == ADDR_PSW + 1) { + uint8_t temp = c->getPSW() >> 8; + if (!peek_only) TRACE("READ-I/O PSW MSB: %03o", temp); + return temp; + } + if (a == ADDR_STACKLIM) { // stack limit register + uint8_t temp = c->getStackLimitRegister(); + if (!peek_only) TRACE("READ-I/O stack limit register (low): %03o", temp); + return temp; + } + if (a == ADDR_STACKLIM + 1) { // stack limit register + uint8_t temp = c->getStackLimitRegister() >> 8; + if (!peek_only) TRACE("READ-I/O stack limit register (high): %03o", temp); + return temp; + } + + if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register + uint8_t temp = microprogram_break_register; + if (!peek_only) TRACE("READ-I/O microprogram break register (low): %03o", temp); + return temp; + } + if (a == ADDR_MICROPROG_BREAK_REG + 1) { // microprogram break register + uint8_t temp = microprogram_break_register >> 8; + if (!peek_only) TRACE("READ-I/O microprogram break register (high): %03o", temp); + return temp; + } + + if (a == ADDR_MMR0) { + uint8_t temp = mmu_->getMMR0(); + if (!peek_only) TRACE("READ-I/O MMR0 LO: %03o", temp); + return temp; + } + if (a == ADDR_MMR0 + 1) { + uint8_t temp = mmu_->getMMR0() >> 8; + if (!peek_only) TRACE("READ-I/O MMR0 HI: %03o", temp); + return temp; + } + } + else { + if (a == ADDR_MMR0) { + uint16_t temp = mmu_->getMMR0(); + if (!peek_only) TRACE("READ-I/O MMR0: %06o", temp); + return temp; + } + + if (a == ADDR_MMR1) { // MMR1 + uint16_t temp = mmu_->getMMR1(); + if (!peek_only) TRACE("READ-I/O MMR1: %06o", temp); + return temp; + } + + if (a == ADDR_MMR2) { // MMR2 + uint16_t temp = mmu_->getMMR2(); + if (!peek_only) TRACE("READ-I/O MMR2: %06o", temp); + return temp; + } + + if (a == ADDR_MMR3) { // MMR3 + uint16_t temp = mmu_->getMMR3(); + if (!peek_only) TRACE("READ-I/O MMR3: %06o", temp); + return temp; + } + + if (a == ADDR_PSW) { // PSW + uint16_t temp = c->getPSW(); + if (!peek_only) TRACE("READ-I/O PSW: %06o", temp); + return temp; + } + + if (a == ADDR_STACKLIM) { // stack limit register + uint16_t temp = c->getStackLimitRegister(); + if (!peek_only) TRACE("READ-I/O stack limit register: %06o", temp); + return temp; + } + + if (a == ADDR_CPU_ERR) { // cpu error register + uint16_t temp = mmu_->getCPUERR(); + if (!peek_only) TRACE("READ-I/O CPUERR: %06o", temp); + return temp; + } + + if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register + uint16_t temp = microprogram_break_register; + if (!peek_only) TRACE("READ-I/O microprogram break register: %06o", temp); + return temp; + } + } + + if (tm11 && a >= TM_11_BASE && a < TM_11_END && !peek_only) + return word_mode == wm_byte ? tm11->read_byte(a) : tm11->read_word(a); + + if (rk05_ && a >= RK05_BASE && a < RK05_END && !peek_only) + return word_mode == wm_byte ? rk05_->read_byte(a) : rk05_->read_word(a); + + if (rl02_ && a >= RL02_BASE && a < RL02_END && !peek_only) + return word_mode == wm_byte ? rl02_->read_byte(a) : rl02_->read_word(a); + + if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END && !peek_only) + return word_mode == wm_byte ? tty_->read_byte(a) : tty_->read_word(a); + + if (dc11_ && a >= DC11_BASE && a < DC11_END && !peek_only) + return word_mode == wm_byte ? dc11_->read_byte(a) : dc11_->read_word(a); + + if (rp06_ && a >= RP06_BASE && a < RP06_END && !peek_only) + return word_mode == wm_byte ? rp06_->read_byte(a) : rp06_->read_word(a); + + // LO size register field must be all 1s, so subtract 1 + uint32_t system_size = m->get_memory_size() / 64 - 1; + + if (a == ADDR_SYSSIZE + 2) { // system size HI + uint16_t temp = system_size >> 16; + if (!peek_only) TRACE("READ-I/O accessing system size HI: %06o", temp); + return temp; + } + + if (a == ADDR_SYSSIZE) { // system size LO + uint16_t temp = system_size; + if (!peek_only) TRACE("READ-I/O accessing system size LO: %06o", temp); + return temp; + } + + if (!peek_only) { + TRACE("READ-I/O UNHANDLED read %08o (%c), (base: %o)", m_offset, word_mode == wm_byte ? 'B' : ' ', mmu_->get_io_base()); + + c->trap(004); // no such i/o + throw 1; + } + + return -1; + } + + if (peek_only) { + TRACE("READ from %06o - out of range!", addr_in); + return 0; + } + + c->trap(004); // no such RAM + throw 1; + } + + if ((addr_in & 1) && word_mode == wm_word) { + if (peek_only == false) { + TRACE("READ from %06o - odd address!", addr_in); + mmu_->trap_if_odd(addr_in, run_mode, space, false); + throw 2; + return 0; + } + } + + uint16_t temp = 0; + if (word_mode == wm_byte) + temp = m->read_byte(m_offset); + else + temp = m->read_word(m_offset); + + if (!peek_only) TRACE("READ from %06o/%07o %c %c: %06o (%s)", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode == wm_byte ? 'B' : 'W', temp, mode_selection == rm_prev ? "prev" : "cur"); + + return temp; +} + +bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const +{ + auto meta = mmu_->calculate_physical_address(run_mode, addr); + + if (space == d_space && meta.physical_data_is_psw) + return true; + + if (space == i_space && meta.physical_instruction_is_psw) + return true; + + return false; +} + +write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t space) +{ + int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); + + const uint8_t apf = addr_in >> 13; // active page field + + bool is_data = space == d_space; + bool d = is_data && mmu_->get_use_data_space(run_mode); + + if (mmu_->is_enabled() && (addr_in & 1) == 0 /* TODO remove this? */ && addr_in != ADDR_MMR0) + mmu_->set_page_written_to(run_mode, d, apf); + + uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, true, true, space); + + if (m_offset >= m->get_memory_size()) { + uint32_t io_base = mmu_->get_io_base(); + bool is_io = m_offset >= io_base; + + if (is_io) { + uint16_t a = m_offset - io_base + 0160000; // TODO + + if (word_mode == wm_byte) { + if (a == ADDR_PSW || a == ADDR_PSW + 1) { // PSW + TRACE("WRITE-I/O PSW %s: %03o", a & 1 ? "MSB" : "LSB", value); + + uint16_t vtemp = c->getPSW(); + + update_word(&vtemp, a & 1, value); + + vtemp &= ~16; // cannot set T bit via this + + c->setPSW(vtemp, false); + + return { true }; + } + + if (a == ADDR_STACKLIM || a == ADDR_STACKLIM + 1) { // stack limit register + TRACE("WRITE-I/O stack limit register %s: %03o", a & 1 ? "MSB" : "LSB", value); + + uint16_t v = c->getStackLimitRegister(); + + update_word(&v, a & 1, value); + + v |= 0377; + + c->setStackLimitRegister(v); + + return { false }; + } + + if (a == ADDR_MICROPROG_BREAK_REG || a == ADDR_MICROPROG_BREAK_REG + 1) { // microprogram break register + TRACE("WRITE-I/O micropram break register %s: %03o", a & 1 ? "MSB" : "LSB", value); + + update_word(µprogram_break_register, a & 1, value); + + return { false }; + } + + if (a == ADDR_MMR0 || a == ADDR_MMR0 + 1) { // MMR0 + TRACE("WRITE-I/O MMR0 register %s: %03o", a & 1 ? "MSB" : "LSB", value); + + uint16_t temp = mmu_->getMMR0(); + update_word(&temp, a & 1, value); + mmu_->setMMR0(temp); + + return { false }; + } + } + else { + if (a == ADDR_PSW) { // PSW + TRACE("WRITE-I/O PSW: %06o", value); + c->setPSW(value & ~16, false); + return { true }; + } + + if (a == ADDR_STACKLIM) { // stack limit register + TRACE("WRITE-I/O stack limit register: %06o", value); + c->setStackLimitRegister(value & 0xff00); + return { false }; + } + + if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 + int reg = a - ADDR_KERNEL_R; + TRACE("WRITE-I/O kernel R%d: %06o", reg, value); + c->setRegister(reg, value); + return { false }; + } + if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 + int reg = a - ADDR_USER_R; + TRACE("WRITE-I/O user R%d: %06o", reg, value); + c->setRegister(reg, value); + return { false }; + } + if (a == ADDR_KERNEL_SP) { // kernel SP + TRACE("WRITE-I/O kernel SP: %06o", value); + c->setStackPointer(0, value); + return { false }; + } + if (a == ADDR_PC) { // PC + TRACE("WRITE-I/O PC: %06o", value); + c->setPC(value); + return { false }; + } + if (a == ADDR_SV_SP) { // supervisor SP + TRACE("WRITE-I/O supervisor sp: %06o", value); + c->setStackPointer(1, value); + return { false }; + } + if (a == ADDR_USER_SP) { // user SP + TRACE("WRITE-I/O user sp: %06o", value); + c->setStackPointer(3, value); + return { false }; + } + + if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register + TRACE("WRITE-I/O microprogram break register: %06o", value); + microprogram_break_register = value & 0xff; // only 8b on 11/70? + return { false }; + } + } + + if (a == ADDR_CPU_ERR) { // cpu error register + TRACE("WRITE-I/O CPUERR: %06o", value); + mmu_->setCPUERR(0); + return { false }; + } + + if (a == ADDR_MMR3) { // MMR3 + TRACE("WRITE-I/O set MMR3: %06o", value); + mmu_->setMMR3(value); + return { false }; + } + + if (a == ADDR_MMR0) { // MMR0 + TRACE("WRITE-I/O set MMR0: %06o", value); + mmu_->setMMR0(value); + return { false }; + } + + if (a == ADDR_PIR) { // PIR + TRACE("WRITE-I/O set PIR: %06o", value); + + value &= 0177000; + + int bits = value >> 9; + + while(bits) { + value += 042; // bit 1...3 and 5...7 + bits >>= 1; + } + + mmu_->setPIR(value); + + return { false }; + } + + if (a == ADDR_LFC) { // line frequency clock and status register + kw11_l_->write_word(a, value); + + return { false }; + } + + if (tm11 && a >= TM_11_BASE && a < TM_11_END) { + TRACE("WRITE-I/O TM11 register %d: %06o", (a - TM_11_BASE) / 2, value); + word_mode == wm_byte ? tm11->write_byte(a, value) : tm11->write_word(a, value); + return { false }; + } + + if (rk05_ && a >= RK05_BASE && a < RK05_END) { + TRACE("WRITE-I/O RK05 register %d: %06o", (a - RK05_BASE) / 2, value); + word_mode == wm_byte ? rk05_->write_byte(a, value) : rk05_->write_word(a, value); + return { false }; + } + + if (rl02_ && a >= RL02_BASE && a < RL02_END) { + TRACE("WRITE-I/O RL02 register %d: %06o", (a - RL02_BASE) / 2, value); + word_mode == wm_byte ? rl02_->write_byte(a, value) : rl02_->write_word(a, value); + return { false }; + } + + if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END) { + TRACE("WRITE-I/O TTY register %d: %06o", (a - PDP11TTY_BASE) / 2, value); + word_mode == wm_byte ? tty_->write_byte(a, value) : tty_->write_word(a, value); + return { false }; + } + + if (dc11_ && a >= DC11_BASE && a < DC11_END) { + word_mode == wm_byte ? dc11_->write_byte(a, value) : dc11_->write_word(a, value); + return { false }; + } + + if (rp06_ && a >= RP06_BASE && a < RP06_END) { + word_mode == wm_byte ? rp06_->write_byte(a, value) : rp06_->write_word(a, value); + return { false }; + } + + if (a >= 0172100 && a <= 0172137) { // MM11-LP parity + TRACE("WRITE-I/O MM11-LP parity (%06o): %o", a, value); + return { false }; + } + + /// MMU /// + // supervisor + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + mmu_->write_word(a, value); + else + mmu_->write_byte(a, value); + + return { false }; + } + + if (a >= 0177740 && a <= 0177753) { // cache control register and others + // TODO + return { false }; + } + + if (a >= 0170200 && a <= 0170377) { // unibus map + TRACE("writing %06o to unibus map (%06o)", value, a); + // TODO + return { false }; + } + + if (a == ADDR_CONSW) { // switch register + console_leds = value; + return { false }; + } + + if (a == ADDR_SYSSIZE || a == ADDR_SYSSIZE + 2) // system size (is read-only) + return { false }; + + if (a == ADDR_SYSTEM_ID) // is r/o + return { false }; + + /////////// + + TRACE("WRITE-I/O UNHANDLED %08o(%c): %06o (base: %o)", m_offset, word_mode == wm_byte ? 'B' : 'W', value, mmu_->get_io_base()); + + if (word_mode == wm_word && (a & 1)) [[unlikely]] { + TRACE("WRITE-I/O to %08o (value: %06o) - odd address!", m_offset, value); + + mmu_->trap_if_odd(a, run_mode, space, true); + + throw 8; + } + + c->trap(004); // no such i/o + + throw 9; + } + + c->trap(004); // no such RAM + throw 1; + } + + if (word_mode == wm_word && (addr_in & 1)) [[unlikely]] { + TRACE("WRITE to %06o (value: %06o) - odd address!", addr_in, value); + + mmu_->trap_if_odd(addr_in, run_mode, space, true); + + throw 10; + } + + TRACE("WRITE to %06o/%07o %c %c: %06o", addr_in, m_offset, space == d_space ? 'D' : 'I', word_mode == wm_byte ? 'B' : 'W', value); + + if (word_mode == wm_byte) + m->write_byte(m_offset, value); + else + m->write_word(m_offset, value); + + return { false }; +} + +void bus::write_physical(const uint32_t a, const uint16_t value) +{ + TRACE("physicalWRITE %06o to %o", value, a); + + if (a >= m->get_memory_size()) { + TRACE("physicalWRITE to %o: trap 004", a); + c->trap(004); + throw 12; + } + else { + m->write_word(a, value); + } +} + +uint16_t bus::read_physical(const uint32_t a) +{ + if (a >= m->get_memory_size()) { + TRACE("physicalREAD from %o: trap 004", a); + c->trap(004); + throw 13; + } + + uint16_t value = m->read_word(a); + + TRACE("physicalREAD %06o from %o", value, a); + + return value; +} + +uint16_t bus::read_word(const uint16_t a, const d_i_space_t s) +{ + return read(a, wm_word, rm_cur, false, s); +} + +uint16_t bus::peek_word(const uint16_t a) +{ + return read(a, wm_word, rm_cur, true); +} + +void bus::write_word(const uint16_t a, const uint16_t value, const d_i_space_t s) +{ + write(a, wm_word, value, rm_cur, s); +} + +uint8_t bus::read_unibus_byte(const uint32_t a) +{ + uint8_t v = 0; + if (a < m->get_memory_size()) + v = m->read_byte(a); + TRACE("read_unibus_byte[%08o]=%03o", a, v); + return v; +} + +void bus::write_unibus_byte(const uint32_t a, const uint8_t v) +{ + TRACE("write_unibus_byte[%08o]=%03o", a, v); + + if (a < m->get_memory_size()) + m->write_byte(a, v); +} diff --git a/bus.h b/bus.h index 43cb2f3..f744206 100644 --- a/bus.h +++ b/bus.h @@ -122,11 +122,11 @@ public: tm_11 *getTM11() { return tm11; } rp06 *getRP06() { return rp06_; } - 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 d_i_space_t s = i_space); uint8_t read_byte(const uint16_t a) override { return read(a, wm_byte, rm_cur); } uint16_t read_word(const uint16_t a, const d_i_space_t s); uint16_t read_word(const uint16_t a) override { return read_word(a, i_space); } - uint16_t peek_word(const uint16_t a); + uint16_t peek_word(const int run_mode, const uint16_t a); uint8_t read_unibus_byte(const uint32_t a); uint16_t read_physical(const uint32_t a); diff --git a/console_ncurses.cpp b/console_ncurses.cpp index cd6f2cf..c1d59bb 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -148,7 +148,7 @@ void console_ncurses::panel_update_thread() uint16_t current_PC = c->getPC(); memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); - uint16_t current_instr = b->peek_word(current_PC); + uint16_t current_instr = b->peek_word(run_mode, current_PC); auto data = c->disassemble(current_PC); diff --git a/cpu.cpp b/cpu.cpp index c8c76d4..6937e64 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -496,23 +496,23 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo case 1: // (Rn) g.addr = getRegister(reg, mode_selection); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, isR7_space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); break; case 2: // (Rn)+ / #n g.addr = getRegister(reg, mode_selection); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, isR7_space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); addRegister(reg, mode_selection, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1, reg }; break; case 3: // @(Rn)+ / @#a - g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, false, isR7_space); + g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, isR7_space); // might be wrong: the adds should happen when the read is really performed, because of traps addRegister(reg, mode_selection, 2); g.mmr1_update = { 2, reg }; g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, g.space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); break; case 4: // -(Rn) addRegister(reg, mode_selection, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); @@ -520,31 +520,31 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo g.space = d_space; g.addr = getRegister(reg, mode_selection); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, isR7_space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); break; case 5: // @-(Rn) addRegister(reg, mode_selection, -2); g.mmr1_update = { -2, reg }; - g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, false, isR7_space); + g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, isR7_space); g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, g.space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); break; case 6: // x(Rn) / a - next_word = b->read(getPC(), wm_word, mode_selection, false, i_space); + next_word = b->read(getPC(), wm_word, mode_selection, i_space); addRegister(7, mode_selection, + 2); g.addr = getRegister(reg, mode_selection) + next_word; g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, g.space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); break; case 7: // @x(Rn) / @a - next_word = b->read(getPC(), wm_word, mode_selection, false, i_space); + next_word = b->read(getPC(), wm_word, mode_selection, i_space); addRegister(7, mode_selection, + 2); - g.addr = b->read(getRegister(reg, mode_selection) + next_word, wm_word, mode_selection, false, d_space); + g.addr = b->read(getRegister(reg, mode_selection) + next_word, wm_word, mode_selection, d_space); g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, false, g.space); + g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); break; } @@ -1427,7 +1427,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) addToMMR1(a); // read from previous space - v = b->read(a.addr.value(), wm_word, rm_prev, false, word_mode == wm_byte ? d_space : i_space); + v = b->read(a.addr.value(), wm_word, rm_prev, word_mode == wm_byte ? d_space : i_space); } setPSW_flags_nzv(v, wm_word); @@ -1900,10 +1900,9 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c { assert(mode_register < 64); - uint16_t next_word = b->peek_word(pc & 65535); - + int run_mode = getPSW_runmode(); + uint16_t next_word = b->peek_word(run_mode, pc & 65535); int reg = mode_register & 7; - uint16_t mask = word_mode == wm_byte ? 0xff : 0xffff; std::string reg_name; @@ -1919,37 +1918,37 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c return { reg_name, 2, -1, uint16_t(getRegister(reg) & mask) }; case 1: - return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(getRegister(reg)) & mask) }; + return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg)) & mask) }; case 2: if (reg == 7) return { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) }; - return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(getRegister(reg)) & mask) }; + return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg)) & mask) }; case 3: if (reg == 7) - return { format("@#%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(next_word) & mask) }; + return { format("@#%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, next_word) & mask) }; - return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(b->peek_word(getRegister(reg))) & mask) }; + return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg))) & mask) }; case 4: - return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(getRegister(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) }; + return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) }; case 5: - return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(b->peek_word(getRegister(reg) - 2)) & mask) }; + return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) - 2)) & mask) }; case 6: if (reg == 7) - return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(getRegister(reg) + next_word) & mask) }; + return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(run_mode, getRegister(reg) + next_word) & mask) }; - return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(getRegister(reg) + next_word) & mask) }; + return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, getRegister(reg) + next_word) & mask) }; case 7: if (reg == 7) - return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(b->peek_word(getRegister(reg) + next_word)) & mask) }; + return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) + next_word)) & mask) }; - return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(b->peek_word(getRegister(reg) + next_word)) & mask) }; + return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) + next_word)) & mask) }; } return { "??", 0, -1, 0123456 }; @@ -1957,7 +1956,7 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c std::map > cpu::disassemble(const uint16_t addr) const { - uint16_t instruction = b->peek_word(addr); + uint16_t instruction = b->peek_word(getPSW_runmode(), addr); word_mode_t word_mode = instruction & 0x8000 ? wm_byte : wm_word; std::string word_mode_str = word_mode == wm_byte ? "B" : ""; diff --git a/debugger.cpp b/debugger.cpp index 23eb05e..5fd77c2 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -933,7 +933,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto for(int i=0; ipeek_word(cur_addr) : b->read_physical(cur_addr); + int val = parts[2] == "v" ? b->peek_word(c->getPSW_runmode(), cur_addr) : b->read_physical(cur_addr); if (val == -1) { cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr)); From b84359ca4466ff6cf9787d574cd2d2c9eaa5b997 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 21:49:01 +0200 Subject: [PATCH 10/23] micro opt --- bus.cpp | 24 ++++++++++++++++-------- mmu.cpp | 21 +++++++++++---------- mmu.h | 13 +++++++------ 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/bus.cpp b/bus.cpp index 1d30af5..07a96cc 100644 --- a/bus.cpp +++ b/bus.cpp @@ -95,11 +95,14 @@ bus *bus::deserialize(const JsonDocument j, console *const cnsl, std::atomic_uin if (j.containsKey("tty")) b->add_tty(tty::deserialize(j["tty"], b, cnsl)); - if (j.containsKey("mmu")) - b->add_mmu(mmu::deserialize(j["mmu"], m)); + cpu *c = nullptr; + if (j.containsKey("cpu")) { + c = cpu::deserialize(j["cpu"], b, event); + b->add_cpu(c); + } - if (j.containsKey("cpu")) - b->add_cpu(cpu::deserialize(j["cpu"], b, event)); + if (j.containsKey("mmu")) + b->add_mmu(mmu::deserialize(j["mmu"], m, c)); if (j.containsKey("rl02")) b->add_rl02(rl02::deserialize(j["rl02"], b)); @@ -135,7 +138,7 @@ void bus::set_memory_size(const int n_pages) delete m; m = new memory(n_bytes); - mmu_->begin(m); + mmu_->begin(m, c); TRACE("Memory is now %u kB in size", n_bytes / 1024); } @@ -181,19 +184,24 @@ void bus::add_ram(memory *const m) delete this->m; this->m = m; - mmu_->begin(m); + mmu_->begin(m, c); } void bus::add_mmu(mmu *const mmu_) { delete this->mmu_; this->mmu_ = mmu_; + + mmu_->begin(m, c); } void bus::add_cpu(cpu *const c) { delete this->c; this->c = c; + + if (mmu_) + mmu_->begin(m, c); } void bus::add_tm11(tm_11 *const tm11) @@ -242,7 +250,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); - uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, false, space); + uint32_t m_offset = mmu_->calculate_physical_address(run_mode, addr_in, false, space); uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; @@ -552,7 +560,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (mmu_->is_enabled() && (addr_in & 1) == 0 /* TODO remove this? */ && addr_in != ADDR_MMR0) mmu_->set_page_written_to(run_mode, d, apf); - uint32_t m_offset = mmu_->calculate_physical_address(c, run_mode, addr_in, true, space); + uint32_t m_offset = mmu_->calculate_physical_address(run_mode, addr_in, true, space); uint32_t io_base = mmu_->get_io_base(); bool is_io = m_offset >= io_base; diff --git a/mmu.cpp b/mmu.cpp index 88ff8ff..3a758bb 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -17,9 +17,10 @@ mmu::~mmu() { } -void mmu::begin(memory *const m) +void mmu::begin(memory *const m, cpu *const c) { this->m = m; + this->c = c; reset(); } @@ -354,7 +355,7 @@ void mmu::mmudebug(const uint16_t a) } } -void mmu::verify_page_access(cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) +void mmu::verify_page_access(const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) { const auto [ trap_action, access_control ] = get_trap_action(run_mode, d, apf, is_write); if (trap_action == T_PROCEED) @@ -403,7 +404,7 @@ void mmu::verify_page_access(cpu *const c, const uint16_t virt_addr, const int r } } -void mmu::verify_access_valid(cpu *const c, const uint32_t m_offset, const int run_mode, const bool d, const int apf, const bool is_io, const bool is_write) +void mmu::verify_access_valid(const uint32_t m_offset, const int run_mode, const bool d, const int apf, const bool is_io, const bool is_write) { if (m_offset >= m->get_memory_size() && !is_io) [[unlikely]] { TRACE("TRAP(04) (throw 6) on address %08o", m_offset); @@ -432,7 +433,7 @@ void mmu::verify_access_valid(cpu *const c, const uint32_t m_offset, const int r } } -void mmu::verify_page_length(cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) +void mmu::verify_page_length(const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) { uint16_t pdr_len = get_pdr_len(run_mode, d, apf); if (pdr_len == 127) @@ -473,7 +474,7 @@ void mmu::verify_page_length(cpu *const c, const uint16_t virt_addr, const int r } } -uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space) +uint32_t mmu::calculate_physical_address(const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space) { uint32_t m_offset = a; @@ -490,15 +491,15 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const if ((getMMR3() & 16) == 0) // off is 18bit m_offset &= 0x3ffff; - verify_page_access(c, a, run_mode, d, apf, is_write); + verify_page_access(a, run_mode, d, apf, is_write); // e.g. ram or i/o, not unmapped uint32_t io_base = get_io_base(); bool is_io = m_offset >= io_base; - verify_access_valid(c, m_offset, run_mode, d, apf, is_io, is_write); + verify_access_valid(m_offset, run_mode, d, apf, is_io, is_write); - verify_page_length(c, a, run_mode, d, apf, is_write); + verify_page_length(a, run_mode, d, apf, is_write); } return m_offset; @@ -559,10 +560,10 @@ void mmu::set_par_pdr(const JsonVariantConst j_in, const int run_mode, const boo pages[run_mode][is_d][i_pdr++].pdr = v; } -mmu *mmu::deserialize(const JsonVariantConst j, memory *const mem) +mmu *mmu::deserialize(const JsonVariantConst j, memory *const mem, cpu *const c) { mmu *m = new mmu(); - m->begin(mem); + m->begin(mem, c); for(int run_mode=0; run_mode<4; run_mode++) { if (run_mode == 2) diff --git a/mmu.h b/mmu.h index c97987c..f99013e 100644 --- a/mmu.h +++ b/mmu.h @@ -56,22 +56,23 @@ private: uint16_t CSR { 0 }; memory *m { nullptr }; + cpu *c { nullptr }; JsonDocument add_par_pdr(const int run_mode, const bool is_d) const; void set_par_pdr(const JsonVariantConst j_in, const int run_mode, const bool is_d); - void verify_page_access (cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write); - void verify_access_valid(cpu *const c, const uint32_t m_offset, const int run_mode, const bool d, const int apf, const bool is_io, const bool is_write); - void verify_page_length (cpu *const c, const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write); + void verify_page_access (const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write); + void verify_access_valid(const uint32_t m_offset, const int run_mode, const bool d, const int apf, const bool is_io, const bool is_write); + void verify_page_length (const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write); public: mmu(); virtual ~mmu(); - void begin(memory *const m); + void begin(memory *const m, cpu *const c); JsonDocument serialize() const; - static mmu *deserialize(const JsonVariantConst j, memory *const m); + static mmu *deserialize(const JsonVariantConst j, memory *const m, cpu *const c); void mmudebug(const uint16_t a); @@ -94,7 +95,7 @@ public: memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const; std::pair get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write); - uint32_t calculate_physical_address(cpu *const c, const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space); + uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool is_write, const d_i_space_t space); uint16_t getMMR0() const { return MMR0; } uint16_t getMMR1() const { return MMR1; } From 38f19c7e058c166137633cf0bd6368a1f830a3e6 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 23 Jun 2024 22:47:01 +0200 Subject: [PATCH 11/23] turbo mode --- mmu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mmu.cpp b/mmu.cpp index 3a758bb..dca919c 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -348,11 +348,13 @@ std::pair mmu::get_trap_action(const int run_mode, const boo void mmu::mmudebug(const uint16_t a) { +#if !defined(TURBO) for(int rm=0; rm<4; rm++) { auto ma = calculate_physical_address(rm, a); TRACE("RM %d, a: %06o, apf: %d, PI: %08o (PSW: %d), PD: %08o (PSW: %d)", rm, ma.virtual_address, ma.apf, ma.physical_instruction, ma.physical_instruction_is_psw, ma.physical_data, ma.physical_data_is_psw); } +#endif } void mmu::verify_page_access(const uint16_t virt_addr, const int run_mode, const bool d, const int apf, const bool is_write) From 7be8362ed48d81ecf4a18d153909d70b4a31c7ec Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:04:21 +0200 Subject: [PATCH 12/23] micro opt --- bus.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/bus.cpp b/bus.cpp index 07a96cc..05fe7d6 100644 --- a/bus.cpp +++ b/bus.cpp @@ -346,12 +346,9 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } /// MMU /// - if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || - (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || - (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || - (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || - (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || - (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if ((a >= ADDR_PDR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PAR_U_END)) { if (word_mode == wm_word) return mmu_->read_word(a); @@ -749,13 +746,9 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 } /// MMU /// - // supervisor - if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || - (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || - (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || - (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || - (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || - (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if ((a >= ADDR_PDR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PAR_U_END)) { if (word_mode == wm_word) mmu_->write_word(a, value); else @@ -763,6 +756,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 return { false }; } + /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others // TODO From 5bf9f4d7828070af797646726d15a72b04d0d724 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:04:33 +0200 Subject: [PATCH 13/23] micro opt --- mmu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmu.h b/mmu.h index f99013e..6f4e92a 100644 --- a/mmu.h +++ b/mmu.h @@ -82,7 +82,7 @@ public: void show_state(console *const cnsl) const override; bool is_enabled() const { return MMR0 & 1; } - bool is_locked() const { return !!(MMR0 & 0160000); } + bool is_locked() const { return MMR0 & 0160000; } void set_page_trapped (const int run_mode, const bool d, const int apf) { pages[run_mode][d][apf].pdr |= 1 << 7; } void set_page_written_to(const int run_mode, const bool d, const int apf) { pages[run_mode][d][apf].pdr |= 1 << 6; } From ba67467f554df6dda1b37d00f9a1d569bbf3f7a7 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:19:29 +0200 Subject: [PATCH 14/23] clean-up --- cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 6937e64..046b8fa 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -606,7 +606,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) if (word_mode == wm_byte && dst_mode == 0) setRegister(dst_reg, int8_t(g_src.value.value())); // int8_t: sign extension else { - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur, false); + auto g_dst = getGAMAddress(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); set_flags = putGAM(g_dst, g_src.value.value()); @@ -1017,7 +1017,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) set_flags = true; } else { - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur, false); + auto g_dst = getGAMAddress(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); set_flags = putGAM(g_dst, 0); From ae5b269dfa083236c1cd1bfbad8a9f94c21d085c Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:25:39 +0200 Subject: [PATCH 15/23] getGAM is always called with rm_cur --- cpu.cpp | 114 ++++++++++++++++++++++++++++---------------------------- cpu.h | 2 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 046b8fa..2c62a39 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -477,9 +477,9 @@ void cpu::addToMMR1(const gam_rc_t & g) } // GAM = general addressing modes -gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool read_value) +gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const bool read_value) { - gam_rc_t g { word_mode, mode_selection, i_space, mode, { }, { }, { }, { } }; + gam_rc_t g { word_mode, rm_cur, i_space, mode, { }, { }, { }, { } }; d_i_space_t isR7_space = reg == 7 ? i_space : (b->getMMU()->get_use_data_space(getPSW_runmode()) ? d_space : i_space); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ always d_space here? TODO @@ -491,60 +491,60 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo switch(mode) { case 0: // Rn g.reg = reg; - g.value = getRegister(reg, mode_selection) & (word_mode == wm_byte ? 0xff : 0xffff); + g.value = getRegister(reg, rm_cur) & (word_mode == wm_byte ? 0xff : 0xffff); break; case 1: // (Rn) - g.addr = getRegister(reg, mode_selection); + g.addr = getRegister(reg, rm_cur); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 2: // (Rn)+ / #n - g.addr = getRegister(reg, mode_selection); + g.addr = getRegister(reg, rm_cur); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); - addRegister(reg, mode_selection, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); + g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); + addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1, reg }; break; case 3: // @(Rn)+ / @#a - g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, isR7_space); + g.addr = b->read(getRegister(reg, rm_cur), wm_word, rm_cur, isR7_space); // might be wrong: the adds should happen when the read is really performed, because of traps - addRegister(reg, mode_selection, 2); + addRegister(reg, rm_cur, 2); g.mmr1_update = { 2, reg }; g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); break; case 4: // -(Rn) - addRegister(reg, mode_selection, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); + addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1, reg }; g.space = d_space; - g.addr = getRegister(reg, mode_selection); + g.addr = getRegister(reg, rm_cur); if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, isR7_space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 5: // @-(Rn) - addRegister(reg, mode_selection, -2); + addRegister(reg, rm_cur, -2); g.mmr1_update = { -2, reg }; - g.addr = b->read(getRegister(reg, mode_selection), wm_word, mode_selection, isR7_space); + g.addr = b->read(getRegister(reg, rm_cur), wm_word, rm_cur, isR7_space); g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); break; case 6: // x(Rn) / a - next_word = b->read(getPC(), wm_word, mode_selection, i_space); - addRegister(7, mode_selection, + 2); - g.addr = getRegister(reg, mode_selection) + next_word; + next_word = b->read(getPC(), wm_word, rm_cur, i_space); + addRegister(7, rm_cur, + 2); + g.addr = getRegister(reg, rm_cur) + next_word; g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); break; case 7: // @x(Rn) / @a - next_word = b->read(getPC(), wm_word, mode_selection, i_space); - addRegister(7, mode_selection, + 2); - g.addr = b->read(getRegister(reg, mode_selection) + next_word, wm_word, mode_selection, d_space); + next_word = b->read(getPC(), wm_word, rm_cur, i_space); + addRegister(7, rm_cur, + 2); + g.addr = b->read(getRegister(reg, rm_cur) + next_word, wm_word, rm_cur, d_space); g.space = d_space; if (read_value) - g.value = b->read(g.addr.value(), word_mode, mode_selection, g.space); + g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); break; } @@ -570,7 +570,7 @@ bool cpu::putGAM(const gam_rc_t & g, const uint16_t value) gam_rc_t cpu::getGAMAddress(const uint8_t mode, const int reg, const word_mode_t word_mode) { - return getGAM(mode, reg, word_mode, rm_cur, false); + return getGAM(mode, reg, word_mode, false); } bool cpu::double_operand_instructions(const uint16_t instr) @@ -599,7 +599,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) switch(operation) { case 0b001: { // MOV/MOVB Move Word/Byte - gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode, rm_cur); + gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode); bool set_flags = true; @@ -621,9 +621,9 @@ bool cpu::double_operand_instructions(const uint16_t instr) } case 0b010: { // CMP/CMPB Compare Word/Byte - gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode, rm_cur); + gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode); - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); addToMMR1(g_src); @@ -639,9 +639,9 @@ bool cpu::double_operand_instructions(const uint16_t instr) } case 0b011: { // BIT/BITB Bit Test Word/Byte - gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode, rm_cur); + gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode); - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); addToMMR1(g_src); @@ -654,7 +654,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) } case 0b100: { // BIC/BICB Bit Clear Word/Byte - gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode, rm_cur); + gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode); if (dst_mode == 0) { addToMMR1(g_src); // keep here because of order of updates @@ -667,7 +667,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) setPSW_flags_nzv(result, word_mode); } else { - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); addToMMR1(g_src); @@ -682,7 +682,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) } case 0b101: { // BIS/BISB Bit Set Word/Byte - gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode, rm_cur); + gam_rc_t g_src = getGAM(src_mode, src_reg, word_mode); if (dst_mode == 0) { addToMMR1(g_src); // keep here because of order of updates @@ -697,7 +697,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) setPSW_v(false); } else { - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); addToMMR1(g_src); @@ -715,9 +715,9 @@ bool cpu::double_operand_instructions(const uint16_t instr) } case 0b110: { // ADD/SUB Add/Subtract Word - auto g_ssrc = getGAM(src_mode, src_reg, wm_word, rm_cur); + auto g_ssrc = getGAM(src_mode, src_reg, wm_word); - auto g_dst = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); addToMMR1(g_ssrc); @@ -776,7 +776,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) case 0: { // MUL int16_t R1 = getRegister(reg); - auto R2g = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto R2g = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(R2g); int16_t R2 = R2g.value.value(); @@ -793,7 +793,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } case 1: { // DIV - auto R2g = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto R2g = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(R2g); int16_t divider = R2g.value.value(); @@ -840,7 +840,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) case 2: { // ASH uint32_t R = getRegister(reg), oldR = R; - auto g_dst = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); uint16_t shift = g_dst.value.value() & 077; @@ -894,7 +894,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) case 3: { // ASHC uint32_t R0R1 = (uint32_t(getRegister(reg)) << 16) | getRegister(reg | 1); - auto g_dst = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); uint16_t shift = g_dst.value.value() & 077; @@ -950,7 +950,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) case 4: { // XOR (word only) uint16_t reg_v = getRegister(reg); // in case it is R7 - auto g_dst = getGAM(dst_mode, dst_reg, wm_word, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); uint16_t vl = g_dst.value.value() ^ reg_v; @@ -989,7 +989,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) if (word_mode == wm_byte) // handled elsewhere return false; - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); uint16_t v = g_dst.value.value(); @@ -1045,7 +1045,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) set_flags = true; } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); v = a.value.value(); @@ -1080,7 +1080,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); int32_t vl = (a.value.value() + 1) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1112,7 +1112,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); int32_t vl = (a.value.value() - 1) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1144,7 +1144,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); uint16_t v = -a.value.value(); @@ -1179,7 +1179,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); const uint16_t vo = a.value.value(); bool org_c = getPSW_c(); @@ -1216,7 +1216,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); const uint16_t vo = a.value.value(); bool org_c = getPSW_c(); @@ -1235,7 +1235,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) } case 0b000101111: { // TST/TSTB - auto g = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g = getGAM(dst_mode, dst_reg, word_mode); uint16_t v = g.value.value(); addToMMR1(g); @@ -1264,7 +1264,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v(getPSW_c() ^ getPSW_n()); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); uint16_t t = a.value.value(); bool new_carry = t & 1; @@ -1310,7 +1310,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v(getPSW_c() ^ getPSW_n()); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); uint16_t t = a.value.value(); bool new_carry = false; @@ -1357,7 +1357,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v(getPSW_n() ^ getPSW_c()); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); uint16_t v = a.value.value(); @@ -1398,7 +1398,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setRegister(dst_reg, v); } else { - auto a = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto a = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(a); uint16_t vl = a.value.value(); uint16_t v = (vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1467,7 +1467,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) if (word_mode == wm_byte) { // MTPS #if 0 // not in the PDP-11/70 psw &= 0xff00; // only alter lower 8 bits - psw |= getGAM(dst_mode, dst_reg, word_mode, rm_cur).value.value() & 0xef; // can't change bit 4 + psw |= getGAM(dst_mode, dst_reg, word_mode).value.value() & 0xef; // can't change bit 4 #else trap(010); #endif @@ -1484,7 +1484,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000110111: { // MFPS (get PSW to something) / SXT if (word_mode == wm_byte) { // MFPS #if 0 // not in the PDP-11/70 - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); uint16_t temp = psw & 0xff; bool extend_b7 = psw & 128; @@ -1504,7 +1504,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) #endif } else { // SXT - auto g_dst = getGAM(dst_mode, dst_reg, word_mode, rm_cur); + auto g_dst = getGAM(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); uint16_t vl = -getPSW_n(); diff --git a/cpu.h b/cpu.h index deaa2d9..0a10458 100644 --- a/cpu.h +++ b/cpu.h @@ -87,7 +87,7 @@ private: void addToMMR1(const gam_rc_t & g); - gam_rc_t getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool read_value = true); + gam_rc_t getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const bool read_value = true); gam_rc_t getGAMAddress(const uint8_t mode, const int reg, const word_mode_t word_mode); bool putGAM(const gam_rc_t & g, const uint16_t value); // returns false when flag registers should not be updated From bd1228bbf8f56a62786742fe024797f5fae59bfa Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:28:33 +0200 Subject: [PATCH 16/23] camel case get/setRegister --- breakpoint_register.cpp | 2 +- bus.cpp | 8 +- cpu.cpp | 166 ++++++++++++++++++++-------------------- cpu.h | 6 +- debugger.cpp | 2 +- loaders.cpp | 4 +- main.cpp | 6 +- 7 files changed, 97 insertions(+), 97 deletions(-) diff --git a/breakpoint_register.cpp b/breakpoint_register.cpp index 832aef0..698686b 100644 --- a/breakpoint_register.cpp +++ b/breakpoint_register.cpp @@ -42,7 +42,7 @@ std::optional breakpoint_register::is_triggered() const uint16_t v = 0; if (register_nr < 8) - v = c->getRegister(register_nr); // TODO run-mode + v = c->get_register(register_nr); // TODO run-mode else { hwreg_t reg = hwreg_t(register_nr); diff --git a/bus.cpp b/bus.cpp index 05fe7d6..2a3bed6 100644 --- a/bus.cpp +++ b/bus.cpp @@ -260,12 +260,12 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm //// REGISTERS //// if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 - uint16_t temp = c->getRegister(a - ADDR_KERNEL_R) & (word_mode == wm_byte ? 0xff : 0xffff); + uint16_t temp = c->get_register(a - ADDR_KERNEL_R) & (word_mode == wm_byte ? 0xff : 0xffff); TRACE("READ-I/O kernel R%d: %06o", a - ADDR_KERNEL_R, temp); return temp; } if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 - uint16_t temp = c->getRegister(a - ADDR_USER_R) & (word_mode == wm_byte ? 0xff : 0xffff); + uint16_t temp = c->get_register(a - ADDR_USER_R) & (word_mode == wm_byte ? 0xff : 0xffff); TRACE("READ-I/O user R%d: %06o", a - ADDR_USER_R, temp); return temp; } @@ -628,13 +628,13 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 int reg = a - ADDR_KERNEL_R; TRACE("WRITE-I/O kernel R%d: %06o", reg, value); - c->setRegister(reg, value); + c->set_register(reg, value); return { false }; } if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 int reg = a - ADDR_USER_R; TRACE("WRITE-I/O user R%d: %06o", reg, value); - c->setRegister(reg, value); + c->set_register(reg, value); return { false }; } if (a == ADDR_KERNEL_SP) { // kernel SP diff --git a/cpu.cpp b/cpu.cpp index 2c62a39..77618af 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -143,7 +143,7 @@ void cpu::reset() init_interrupt_queue(); } -uint16_t cpu::getRegister(const int nr, const rm_selection_t mode_selection) const +uint16_t cpu::get_register(const int nr, const rm_selection_t mode_selection) const { if (nr < 6) { int set = get_register_set(); @@ -163,7 +163,7 @@ uint16_t cpu::getRegister(const int nr, const rm_selection_t mode_selection) con return pc; } -void cpu::setRegister(const int nr, const uint16_t value, const rm_selection_t mode_selection) +void cpu::set_register(const int nr, const uint16_t value, const rm_selection_t mode_selection) { if (nr < 6) { int set = get_register_set(); @@ -182,27 +182,27 @@ void cpu::setRegister(const int nr, const uint16_t value, const rm_selection_t m } } -void cpu::setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value) +void cpu::set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value) { if (word_mode == wm_byte) { - uint16_t v = getRegister(nr); + uint16_t v = get_register(nr); v &= 0xff00; assert(value < 256); v |= value; - setRegister(nr, v); + set_register(nr, v); } else { - setRegister(nr, value); + set_register(nr, value); } } bool cpu::put_result(const gam_rc_t & g, const uint16_t value) { if (g.addr.has_value() == false) { - setRegisterLowByte(g.reg.value(), g.word_mode, value); + set_registerLowByte(g.reg.value(), g.word_mode, value); return true; } @@ -491,22 +491,22 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo switch(mode) { case 0: // Rn g.reg = reg; - g.value = getRegister(reg, rm_cur) & (word_mode == wm_byte ? 0xff : 0xffff); + g.value = get_register(reg, rm_cur) & (word_mode == wm_byte ? 0xff : 0xffff); break; case 1: // (Rn) - g.addr = getRegister(reg, rm_cur); + g.addr = get_register(reg, rm_cur); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 2: // (Rn)+ / #n - g.addr = getRegister(reg, rm_cur); + g.addr = get_register(reg, rm_cur); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1, reg }; break; case 3: // @(Rn)+ / @#a - g.addr = b->read(getRegister(reg, rm_cur), wm_word, rm_cur, isR7_space); + g.addr = b->read(get_register(reg, rm_cur), wm_word, rm_cur, isR7_space); // might be wrong: the adds should happen when the read is really performed, because of traps addRegister(reg, rm_cur, 2); g.mmr1_update = { 2, reg }; @@ -518,14 +518,14 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1, reg }; g.space = d_space; - g.addr = getRegister(reg, rm_cur); + g.addr = get_register(reg, rm_cur); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 5: // @-(Rn) addRegister(reg, rm_cur, -2); g.mmr1_update = { -2, reg }; - g.addr = b->read(getRegister(reg, rm_cur), wm_word, rm_cur, isR7_space); + g.addr = b->read(get_register(reg, rm_cur), wm_word, rm_cur, isR7_space); g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -533,7 +533,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo case 6: // x(Rn) / a next_word = b->read(getPC(), wm_word, rm_cur, i_space); addRegister(7, rm_cur, + 2); - g.addr = getRegister(reg, rm_cur) + next_word; + g.addr = get_register(reg, rm_cur) + next_word; g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -541,7 +541,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo case 7: // @x(Rn) / @a next_word = b->read(getPC(), wm_word, rm_cur, i_space); addRegister(7, rm_cur, + 2); - g.addr = b->read(getRegister(reg, rm_cur) + next_word, wm_word, rm_cur, d_space); + g.addr = b->read(get_register(reg, rm_cur) + next_word, wm_word, rm_cur, d_space); g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -563,7 +563,7 @@ bool cpu::putGAM(const gam_rc_t & g, const uint16_t value) return rc.is_psw == false; } - setRegister(g.reg.value(), value, g.mode_selection); + set_register(g.reg.value(), value, g.mode_selection); return true; } @@ -604,7 +604,7 @@ bool cpu::double_operand_instructions(const uint16_t instr) bool set_flags = true; if (word_mode == wm_byte && dst_mode == 0) - setRegister(dst_reg, int8_t(g_src.value.value())); // int8_t: sign extension + set_register(dst_reg, int8_t(g_src.value.value())); // int8_t: sign extension else { auto g_dst = getGAMAddress(dst_mode, dst_reg, word_mode); addToMMR1(g_dst); @@ -659,10 +659,10 @@ bool cpu::double_operand_instructions(const uint16_t instr) if (dst_mode == 0) { addToMMR1(g_src); // keep here because of order of updates - uint16_t v = getRegister(dst_reg); // need the full word + uint16_t v = get_register(dst_reg); // need the full word uint16_t result = v & ~g_src.value.value(); - setRegister(dst_reg, result); + set_register(dst_reg, result); setPSW_flags_nzv(result, word_mode); } @@ -687,10 +687,10 @@ bool cpu::double_operand_instructions(const uint16_t instr) if (dst_mode == 0) { addToMMR1(g_src); // keep here because of order of updates - uint16_t v = getRegister(dst_reg); // need the full word + uint16_t v = get_register(dst_reg); // need the full word uint16_t result = v | g_src.value.value(); - setRegister(dst_reg, result); + set_register(dst_reg, result); setPSW_n(SIGN(result, word_mode)); setPSW_z(IS_0(result, word_mode)); @@ -774,7 +774,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) switch(operation) { case 0: { // MUL - int16_t R1 = getRegister(reg); + int16_t R1 = get_register(reg); auto R2g = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(R2g); @@ -782,8 +782,8 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) int32_t result = R1 * R2; - setRegister(reg, result >> 16); - setRegister(reg | 1, result & 65535); + set_register(reg, result >> 16); + set_register(reg | 1, result & 65535); setPSW_n(result < 0); setPSW_z(result == 0); @@ -797,7 +797,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) addToMMR1(R2g); int16_t divider = R2g.value.value(); - int32_t R0R1 = (uint32_t(getRegister(reg)) << 16) | getRegister(reg | 1); + int32_t R0R1 = (uint32_t(get_register(reg)) << 16) | get_register(reg | 1); if (divider == 0) { // divide by zero setPSW_n(false); @@ -829,8 +829,8 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) return true; } - setRegister(reg, quot); - setRegister(reg | 1, rem); + set_register(reg, quot); + set_register(reg | 1, rem); setPSW_v(false); @@ -838,7 +838,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } case 2: { // ASH - uint32_t R = getRegister(reg), oldR = R; + uint32_t R = get_register(reg), oldR = R; auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); @@ -886,13 +886,13 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) setPSW_n(SIGN(R, wm_word)); setPSW_z(R == 0); - setRegister(reg, R); + set_register(reg, R); return true; } case 3: { // ASHC - uint32_t R0R1 = (uint32_t(getRegister(reg)) << 16) | getRegister(reg | 1); + uint32_t R0R1 = (uint32_t(get_register(reg)) << 16) | get_register(reg | 1); auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); @@ -939,8 +939,8 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) bool new_sign = R0R1 & 0x80000000; setPSW_v(sign != new_sign); - setRegister(reg, R0R1 >> 16); - setRegister(reg | 1, R0R1 & 65535); + set_register(reg, R0R1 >> 16); + set_register(reg | 1, R0R1 & 65535); setPSW_n(R0R1 & 0x80000000); setPSW_z(R0R1 == 0); @@ -949,7 +949,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } case 4: { // XOR (word only) - uint16_t reg_v = getRegister(reg); // in case it is R7 + uint16_t reg_v = get_register(reg); // in case it is R7 auto g_dst = getGAM(dst_mode, dst_reg, wm_word); addToMMR1(g_dst); uint16_t vl = g_dst.value.value() ^ reg_v; @@ -1010,9 +1010,9 @@ bool cpu::single_operand_instructions(const uint16_t instr) bool set_flags = false; if (word_mode == wm_byte && dst_mode == 0) { - uint16_t v = getRegister(dst_reg) & 0xff00; + uint16_t v = get_register(dst_reg) & 0xff00; - setRegister(dst_reg, v); + set_register(dst_reg, v); set_flags = true; } @@ -1038,9 +1038,9 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t v = 0; if (word_mode == wm_byte && dst_mode == 0) { - v = getRegister(dst_reg) ^ 0xff; + v = get_register(dst_reg) ^ 0xff; - setRegister(dst_reg, v); + set_register(dst_reg, v); set_flags = true; } @@ -1067,7 +1067,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000101010: { // INC/INCB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; v = (v + 1) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1077,7 +1077,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_z(IS_0(v, word_mode)); setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x80 : v == 0x8000); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1099,7 +1099,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000101011: { // DEC/DECB // TODO unify if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; v = (v - 1) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1109,7 +1109,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_z(IS_0(v, word_mode)); setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x7f : v == 0x7fff); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1130,7 +1130,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000101100: { // NEG/NEGB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; v = (-v) & (word_mode == wm_byte ? 0xff : 0xffff); @@ -1141,7 +1141,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x80 : v == 0x8000); setPSW_c(v); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1163,7 +1163,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000101101: { // ADC/ADCB if (dst_mode == 0) { - const uint16_t vo = getRegister(dst_reg); + const uint16_t vo = get_register(dst_reg); uint16_t v = vo; uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; bool org_c = getPSW_c(); @@ -1176,7 +1176,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v((word_mode == wm_byte ? (vo & 0xff) == 0x7f : vo == 0x7fff) && org_c); setPSW_c((word_mode == wm_byte ? (vo & 0xff) == 0xff : vo == 0xffff) && org_c); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1200,7 +1200,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000101110: { // SBC/SBCB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); const uint16_t vo = v; uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; bool org_c = getPSW_c(); @@ -1213,7 +1213,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_v((word_mode == wm_byte ? (vo & 0xff) == 0x80 : vo == 0x8000) && org_c); setPSW_c(IS_0(vo, word_mode) && org_c); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1247,7 +1247,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000110000: { // ROR/RORB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); bool new_carry = v & 1; uint16_t temp = 0; @@ -1256,7 +1256,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) else temp = (v >> 1) | (getPSW_c() << 15); - setRegister(dst_reg, temp); + set_register(dst_reg, temp); setPSW_c(new_carry); setPSW_n(SIGN(temp, word_mode)); @@ -1289,7 +1289,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000110001: { // ROL/ROLB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); bool new_carry = false; uint16_t temp = 0; @@ -1302,7 +1302,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) temp = (v << 1) | getPSW_c(); } - setRegister(dst_reg, temp); + set_register(dst_reg, temp); setPSW_c(new_carry); setPSW_n(SIGN(temp, word_mode)); @@ -1339,7 +1339,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b000110010: { // ASR/ASRB if (dst_mode == 0) { - uint16_t v = getRegister(dst_reg); + uint16_t v = get_register(dst_reg); uint16_t hb = word_mode == wm_byte ? v & 128 : v & 32768; setPSW_c(v & 1); @@ -1350,7 +1350,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) v >>= 1; v |= hb; - setRegister(dst_reg, v); + set_register(dst_reg, v); setPSW_n(SIGN(v, word_mode)); setPSW_z(IS_0(v, word_mode)); @@ -1384,7 +1384,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) case 0b00110011: { // ASL/ASLB if (dst_mode == 0) { - uint16_t vl = getRegister(dst_reg); + uint16_t vl = get_register(dst_reg); uint16_t v = ((vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff)); if (word_mode == wm_byte) @@ -1395,7 +1395,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) setPSW_c(SIGN(vl, word_mode)); setPSW_v(getPSW_n() ^ getPSW_c()); - setRegister(dst_reg, v); + set_register(dst_reg, v); } else { auto a = getGAM(dst_mode, dst_reg, word_mode); @@ -1420,7 +1420,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t v = 0xffff; if (dst_mode == 0) - v = getRegister(dst_reg, rm_prev); + v = get_register(dst_reg, rm_prev); else { // calculate address in current address space auto a = getGAMAddress(dst_mode, dst_reg, wm_word); @@ -1445,7 +1445,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) bool set_flags = true; if (dst_mode == 0) - setRegister(dst_reg, v, rm_prev); + set_register(dst_reg, v, rm_prev); else { auto a = getGAMAddress(dst_mode, dst_reg, wm_word); addToMMR1(a); @@ -1473,11 +1473,11 @@ bool cpu::single_operand_instructions(const uint16_t instr) #endif } else { - setRegister(6, getPC() + dst * 2); + set_register(6, getPC() + dst * 2); - setPC(getRegister(5)); + setPC(get_register(5)); - setRegister(5, popStack()); + set_register(5, popStack()); } break; @@ -1643,7 +1643,7 @@ bool cpu::condition_code_operations(const uint16_t instr) void cpu::pushStack(const uint16_t v) { - if (getRegister(6) == stackLimitRegister) { + if (get_register(6) == stackLimitRegister) { TRACE("stackLimitRegister reached %06o while pushing %06o", stackLimitRegister, v); trap(04, 7); @@ -1657,7 +1657,7 @@ void cpu::pushStack(const uint16_t v) uint16_t cpu::popStack() { - uint16_t a = getRegister(6); + uint16_t a = get_register(6); uint16_t temp = b->read_word(a, d_space); addRegister(6, rm_cur, 2); @@ -1721,7 +1721,7 @@ bool cpu::misc_operations(const uint16_t instr) return true; case 0b0000000000000111: // MFPT - //setRegister(0, 0); + //set_register(0, 0); trap(010); // does not exist on PDP-11/70 return true; @@ -1774,7 +1774,7 @@ bool cpu::misc_operations(const uint16_t instr) int link_reg = (instr >> 6) & 7; // PUSH link - pushStack(getRegister(link_reg)); + pushStack(get_register(link_reg)); if (!b->getMMU()->isMMR1Locked()) { b->getMMU()->addToMMR1(-2, 6); @@ -1782,7 +1782,7 @@ bool cpu::misc_operations(const uint16_t instr) } // MOVE PC,link - setRegister(link_reg, getPC()); + set_register(link_reg, getPC()); // JMP dst setPC(dst_value); @@ -1797,12 +1797,12 @@ bool cpu::misc_operations(const uint16_t instr) const int link_reg = instr & 7; // MOVE link, PC - setPC(getRegister(link_reg)); + setPC(get_register(link_reg)); // POP link - uint16_t word_on_stack = b->read_word(getRegister(6), d_space); + uint16_t word_on_stack = b->read_word(get_register(6), d_space); - setRegister(link_reg, word_on_stack); + set_register(link_reg, word_on_stack); // do not overwrite SP when it was just set if (link_reg != 6) @@ -1841,7 +1841,7 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) if (kernel_mode) vector = 4; - setRegister(6, 04); + set_register(6, 04); } else { b->getMMU()->clearMMR1(); @@ -1869,16 +1869,16 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) setPSW(new_psw, false); if (processing_trap_depth >= 2 && kernel_mode) - setRegister(6, 04); + set_register(6, 04); - uint16_t prev_sp = getRegister(6); + uint16_t prev_sp = get_register(6); try { pushStack(before_psw); pushStack(before_pc); } catch(const int exception) { // recover stack - setRegister(6, prev_sp); + set_register(6, prev_sp); } processing_trap_depth = 0; @@ -1915,40 +1915,40 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c switch(mode_register >> 3) { case 0: - return { reg_name, 2, -1, uint16_t(getRegister(reg) & mask) }; + return { reg_name, 2, -1, uint16_t(get_register(reg) & mask) }; case 1: - return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg)) & mask) }; + return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) }; case 2: if (reg == 7) return { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) }; - return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg)) & mask) }; + return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) }; case 3: if (reg == 7) return { format("@#%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, next_word) & mask) }; - return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg))) & mask) }; + return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg))) & mask) }; case 4: - return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, getRegister(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) }; + return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) }; case 5: - return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) - 2)) & mask) }; + return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) - 2)) & mask) }; case 6: if (reg == 7) - return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(run_mode, getRegister(reg) + next_word) & mask) }; + return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) }; - return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, getRegister(reg) + next_word) & mask) }; + return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) }; case 7: if (reg == 7) - return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) + next_word)) & mask) }; + return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) }; - return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, getRegister(reg) + next_word)) & mask) }; + return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) }; } return { "??", 0, -1, 0123456 }; @@ -2352,7 +2352,7 @@ std::map > cpu::disassemble(const uint16_t for(int i=0; i<8; i++) { if (i < 6) - registers.push_back(format("%06o", getRegister(i))); + registers.push_back(format("%06o", get_register(i))); else if (i == 6) registers.push_back(format("%06o", sp[psw >> 14])); else diff --git a/cpu.h b/cpu.h index 0a10458..2cabe60 100644 --- a/cpu.h +++ b/cpu.h @@ -181,8 +181,8 @@ public: uint16_t getStackPointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; } uint16_t getPC() const { return pc; } - void setRegister(const int nr, const uint16_t value, const rm_selection_t mode_selection = rm_cur); - void setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value); + void set_register(const int nr, const uint16_t value, const rm_selection_t mode_selection = rm_cur); + void set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value); // used by 'main' for json-validation void lowlevel_register_set(const uint8_t set, const uint8_t reg, const uint16_t value); void lowlevel_register_sp_set(const uint8_t set, const uint16_t value); @@ -193,7 +193,7 @@ public: void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; } void setPC(const uint16_t value) { pc = value; } - uint16_t getRegister(const int nr, const rm_selection_t mode_selection = rm_cur) const; + uint16_t get_register(const int nr, const rm_selection_t mode_selection = rm_cur) const; bool put_result(const gam_rc_t & g, const uint16_t value); }; diff --git a/debugger.cpp b/debugger.cpp index 5fd77c2..189ccbb 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -1310,7 +1310,7 @@ void run_bic(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop { cpu *const c = b->getCpu(); - c->setRegister(7, start_addr); + c->set_register(7, start_addr); *cnsl->get_running_flag() = true; diff --git a/loaders.cpp b/loaders.cpp index 340cebb..dca3fd4 100644 --- a/loaders.cpp +++ b/loaders.cpp @@ -156,7 +156,7 @@ void set_boot_loader(bus *const b, const bootloader_t which) for(uint16_t i=0; iwrite_word(uint16_t(offset + i * 2), bl[i]); - c->setRegister(7, start); + c->set_register(7, start); } std::optional load_tape(bus *const b, const std::string & file) @@ -291,5 +291,5 @@ void load_p11_x11(bus *const b, const std::string & file) fclose(fh); cpu *const c = b->getCpu(); - c->setRegister(7, 0); + c->set_register(7, 0); } diff --git a/main.cpp b/main.cpp index e4be40c..7ed75b7 100644 --- a/main.cpp +++ b/main.cpp @@ -633,13 +633,13 @@ int main(int argc, char *argv[]) if (bic_start.has_value() == false) return 1; // fail - b->getCpu()->setRegister(7, bic_start.value()); + b->getCpu()->set_register(7, bic_start.value()); } if (sa_set) - b->getCpu()->setRegister(7, start_addr); + b->getCpu()->set_register(7, start_addr); - DOLOG(info, true, "Start running at %06o", b->getCpu()->getRegister(7)); + DOLOG(info, true, "Start running at %06o", b->getCpu()->get_register(7)); #if !defined(_WIN32) struct sigaction sa { }; From a4f753915ce8d71ace83530dd823fa54a1996585 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:35:04 +0200 Subject: [PATCH 17/23] removed variable from get/set_register --- cpu.cpp | 58 +++++++++++++++++++++++++++++++-------------------------- cpu.h | 4 ++-- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 77618af..8a5d551 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -143,7 +143,7 @@ void cpu::reset() init_interrupt_queue(); } -uint16_t cpu::get_register(const int nr, const rm_selection_t mode_selection) const +uint16_t cpu::get_register(const int nr) const { if (nr < 6) { int set = get_register_set(); @@ -151,31 +151,23 @@ uint16_t cpu::get_register(const int nr, const rm_selection_t mode_selection) co return regs0_5[set][nr]; } - if (nr == 6) { - if (mode_selection == rm_prev) - return sp[getPSW_prev_runmode()]; - + if (nr == 6) return sp[getPSW_runmode()]; - } assert(nr == 7); return pc; } -void cpu::set_register(const int nr, const uint16_t value, const rm_selection_t mode_selection) +void cpu::set_register(const int nr, const uint16_t value) { if (nr < 6) { int set = get_register_set(); regs0_5[set][nr] = value; } - else if (nr == 6) { - if (mode_selection == rm_prev) - sp[getPSW_prev_runmode()] = value; - else - sp[getPSW_runmode()] = value; - } + else if (nr == 6) + sp[getPSW_runmode()] = value; else { assert(nr == 7); pc = value; @@ -491,22 +483,22 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo switch(mode) { case 0: // Rn g.reg = reg; - g.value = get_register(reg, rm_cur) & (word_mode == wm_byte ? 0xff : 0xffff); + g.value = get_register(reg) & (word_mode == wm_byte ? 0xff : 0xffff); break; case 1: // (Rn) - g.addr = get_register(reg, rm_cur); + g.addr = get_register(reg); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 2: // (Rn)+ / #n - g.addr = get_register(reg, rm_cur); + g.addr = get_register(reg); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1, reg }; break; case 3: // @(Rn)+ / @#a - g.addr = b->read(get_register(reg, rm_cur), wm_word, rm_cur, isR7_space); + g.addr = b->read(get_register(reg), wm_word, rm_cur, isR7_space); // might be wrong: the adds should happen when the read is really performed, because of traps addRegister(reg, rm_cur, 2); g.mmr1_update = { 2, reg }; @@ -518,14 +510,14 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1, reg }; g.space = d_space; - g.addr = get_register(reg, rm_cur); + g.addr = get_register(reg); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 5: // @-(Rn) addRegister(reg, rm_cur, -2); g.mmr1_update = { -2, reg }; - g.addr = b->read(get_register(reg, rm_cur), wm_word, rm_cur, isR7_space); + g.addr = b->read(get_register(reg), wm_word, rm_cur, isR7_space); g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -533,7 +525,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo case 6: // x(Rn) / a next_word = b->read(getPC(), wm_word, rm_cur, i_space); addRegister(7, rm_cur, + 2); - g.addr = get_register(reg, rm_cur) + next_word; + g.addr = get_register(reg) + next_word; g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -541,7 +533,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo case 7: // @x(Rn) / @a next_word = b->read(getPC(), wm_word, rm_cur, i_space); addRegister(7, rm_cur, + 2); - g.addr = b->read(get_register(reg, rm_cur) + next_word, wm_word, rm_cur, d_space); + g.addr = b->read(get_register(reg) + next_word, wm_word, rm_cur, d_space); g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); @@ -563,7 +555,13 @@ bool cpu::putGAM(const gam_rc_t & g, const uint16_t value) return rc.is_psw == false; } - set_register(g.reg.value(), value, g.mode_selection); + if (g.mode_selection == rm_prev) { + assert(g.reg.value() == 6); + sp[getPSW_prev_runmode()] = value; + } + else { + set_register(g.reg.value(), value); + } return true; } @@ -1419,8 +1417,12 @@ bool cpu::single_operand_instructions(const uint16_t instr) // always words: word_mode-bit is to select between MFPI and MFPD uint16_t v = 0xffff; - if (dst_mode == 0) - v = get_register(dst_reg, rm_prev); + if (dst_mode == 0) { + if (dst_reg == 6) + v = sp[getPSW_prev_runmode()]; + else + v = get_register(dst_reg); + } else { // calculate address in current address space auto a = getGAMAddress(dst_mode, dst_reg, wm_word); @@ -1444,8 +1446,12 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t v = popStack(); bool set_flags = true; - if (dst_mode == 0) - set_register(dst_reg, v, rm_prev); + if (dst_mode == 0) { + if (dst_reg == 6) + sp[getPSW_prev_runmode()] = v; + else + set_register(dst_reg, v); + } else { auto a = getGAMAddress(dst_mode, dst_reg, wm_word); addToMMR1(a); diff --git a/cpu.h b/cpu.h index 2cabe60..3f74eb1 100644 --- a/cpu.h +++ b/cpu.h @@ -181,7 +181,7 @@ public: uint16_t getStackPointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; } uint16_t getPC() const { return pc; } - void set_register(const int nr, const uint16_t value, const rm_selection_t mode_selection = rm_cur); + void set_register(const int nr, const uint16_t value); void set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value); // used by 'main' for json-validation void lowlevel_register_set(const uint8_t set, const uint8_t reg, const uint16_t value); @@ -193,7 +193,7 @@ public: void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; } void setPC(const uint16_t value) { pc = value; } - uint16_t get_register(const int nr, const rm_selection_t mode_selection = rm_cur) const; + uint16_t get_register(const int nr) const; bool put_result(const gam_rc_t & g, const uint16_t value); }; From e782dc43ddc9ce14d44bd9ac57ad4c77be6a7dd1 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 09:37:25 +0200 Subject: [PATCH 18/23] removed variable from add_register --- cpu.cpp | 32 ++++++++++++++------------------ cpu.h | 2 +- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 8a5d551..b274adf 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -202,17 +202,13 @@ bool cpu::put_result(const gam_rc_t & g, const uint16_t value) return b->write(g.addr.value(), g.word_mode, value, g.mode_selection, g.space).is_psw == false; } -uint16_t cpu::addRegister(const int nr, const rm_selection_t mode_selection, const uint16_t value) +uint16_t cpu::add_register(const int nr, const uint16_t value) { if (nr < 6) return regs0_5[get_register_set()][nr] += value; - if (nr == 6) { - if (mode_selection == rm_prev) - return sp[getPSW_prev_runmode()] += value; - + if (nr == 6) return sp[getPSW_runmode()] += value; - } assert(nr == 7); @@ -494,20 +490,20 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo g.addr = get_register(reg); if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); - addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); + add_register(reg, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1, reg }; break; case 3: // @(Rn)+ / @#a g.addr = b->read(get_register(reg), wm_word, rm_cur, isR7_space); // might be wrong: the adds should happen when the read is really performed, because of traps - addRegister(reg, rm_cur, 2); + add_register(reg, 2); g.mmr1_update = { 2, reg }; g.space = d_space; if (read_value) g.value = b->read(g.addr.value(), word_mode, rm_cur, g.space); break; case 4: // -(Rn) - addRegister(reg, rm_cur, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); + add_register(reg, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1); g.mmr1_update = { word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1, reg }; g.space = d_space; g.addr = get_register(reg); @@ -515,7 +511,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo g.value = b->read(g.addr.value(), word_mode, rm_cur, isR7_space); break; case 5: // @-(Rn) - addRegister(reg, rm_cur, -2); + add_register(reg, -2); g.mmr1_update = { -2, reg }; g.addr = b->read(get_register(reg), wm_word, rm_cur, isR7_space); g.space = d_space; @@ -524,7 +520,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo break; case 6: // x(Rn) / a next_word = b->read(getPC(), wm_word, rm_cur, i_space); - addRegister(7, rm_cur, + 2); + add_register(7, + 2); g.addr = get_register(reg) + next_word; g.space = d_space; if (read_value) @@ -532,7 +528,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo break; case 7: // @x(Rn) / @a next_word = b->read(getPC(), wm_word, rm_cur, i_space); - addRegister(7, rm_cur, + 2); + add_register(7, + 2); g.addr = b->read(get_register(reg) + next_word, wm_word, rm_cur, d_space); g.space = d_space; if (read_value) @@ -961,7 +957,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } case 7: { // SOB - if (addRegister(reg, rm_cur, -1)) { + if (add_register(reg, -1)) { uint16_t newPC = getPC() - dst * 2; setPC(newPC); @@ -1603,7 +1599,7 @@ bool cpu::conditional_branch_instructions(const uint16_t instr) } if (take) - addRegister(7, rm_cur, offset * 2); + add_register(7, offset * 2); return true; } @@ -1655,7 +1651,7 @@ void cpu::pushStack(const uint16_t v) trap(04, 7); } else { - uint16_t a = addRegister(6, rm_cur, -2); + uint16_t a = add_register(6, -2); b->write_word(a, v, d_space); } @@ -1666,7 +1662,7 @@ uint16_t cpu::popStack() uint16_t a = get_register(6); uint16_t temp = b->read_word(a, d_space); - addRegister(6, rm_cur, 2); + add_register(6, 2); return temp; } @@ -1812,7 +1808,7 @@ bool cpu::misc_operations(const uint16_t instr) // do not overwrite SP when it was just set if (link_reg != 6) - addRegister(6, rm_cur, 2); + add_register(6, 2); return true; } @@ -2416,7 +2412,7 @@ void cpu::step() uint16_t instr = b->read_word(instruction_start); - addRegister(7, rm_cur, 2); + add_register(7, 2); if (double_operand_instructions(instr)) return; diff --git a/cpu.h b/cpu.h index 3f74eb1..bae5032 100644 --- a/cpu.h +++ b/cpu.h @@ -83,7 +83,7 @@ private: bool check_pending_interrupts() const; // needs the 'qi_lock'-lock bool execute_any_pending_interrupt(); - uint16_t addRegister(const int nr, const rm_selection_t mode_selection, const uint16_t value); + uint16_t add_register(const int nr, const uint16_t value); void addToMMR1(const gam_rc_t & g); From d531407d300bbd55ab33bcec139002b05fae0429 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 13:34:55 +0200 Subject: [PATCH 19/23] removed superfluous !! --- mmu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmu.cpp b/mmu.cpp index dca919c..c47ea63 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -140,7 +140,7 @@ bool mmu::get_use_data_space(const int run_mode) const { constexpr const int di_ena_mask[4] = { 4, 2, 0, 1 }; - return !!(MMR3 & di_ena_mask[run_mode]); + return MMR3 & di_ena_mask[run_mode]; } void mmu::clearMMR1() From ddf908027a5f7e247d7c0dad9d3365ea577162b0 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 18:45:01 +0200 Subject: [PATCH 20/23] sanitized peek_word() --- breakpoint_memory.cpp | 12 +++- bus.cpp | 7 +-- bus.h | 2 +- console_ncurses.cpp | 12 +++- cpu.cpp | 135 ++++++++++++++++++++++++++++++++++-------- cpu.h | 2 +- debugger.cpp | 19 ++++-- 7 files changed, 148 insertions(+), 41 deletions(-) diff --git a/breakpoint_memory.cpp b/breakpoint_memory.cpp index 811fcc9..dea0644 100644 --- a/breakpoint_memory.cpp +++ b/breakpoint_memory.cpp @@ -22,10 +22,16 @@ std::optional breakpoint_memory::is_triggered() const { uint16_t v = 0; - if (is_virtual) - v = b->peek_word(rm_cur, addr); // FIXME rm_cur - else + if (is_virtual) { + auto temp = b->peek_word(rm_cur, addr); // FIXME rm_cur + if (temp.has_value() == false) + return { }; + + v = temp.value(); + } + else { v = b->read_physical(addr); + } auto it = values.find(v); if (it == values.end()) diff --git a/bus.cpp b/bus.cpp index 2a3bed6..cedd517 100644 --- a/bus.cpp +++ b/bus.cpp @@ -854,13 +854,13 @@ uint16_t bus::read_word(const uint16_t a, const d_i_space_t s) return read(a, wm_word, rm_cur, s); } -uint16_t bus::peek_word(const int run_mode, const uint16_t a) +std::optional bus::peek_word(const int run_mode, const uint16_t a) { auto meta = mmu_->calculate_physical_address(run_mode, a); uint32_t io_base = mmu_->get_io_base(); - if (meta.physical_instruction >= io_base) // TODO: I/O always returns 0xffff - return 0xffff; + if (meta.physical_instruction >= io_base) + return { }; return m->read_word(meta.physical_instruction); } @@ -882,7 +882,6 @@ uint8_t bus::read_unibus_byte(const uint32_t a) void bus::write_unibus_byte(const uint32_t a, const uint8_t v) { TRACE("write_unibus_byte[%08o]=%03o", a, v); - if (a < m->get_memory_size()) m->write_byte(a, v); } diff --git a/bus.h b/bus.h index f744206..780d70b 100644 --- a/bus.h +++ b/bus.h @@ -126,7 +126,7 @@ public: uint8_t read_byte(const uint16_t a) override { return read(a, wm_byte, rm_cur); } uint16_t read_word(const uint16_t a, const d_i_space_t s); uint16_t read_word(const uint16_t a) override { return read_word(a, i_space); } - uint16_t peek_word(const int run_mode, const uint16_t a); + std::optional peek_word(const int run_mode, const uint16_t a); uint8_t read_unibus_byte(const uint32_t a); uint16_t read_physical(const uint32_t a); diff --git a/console_ncurses.cpp b/console_ncurses.cpp index c1d59bb..4f7ef4b 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -148,7 +148,7 @@ void console_ncurses::panel_update_thread() uint16_t current_PC = c->getPC(); memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); - uint16_t current_instr = b->peek_word(run_mode, current_PC); + auto current_instr = b->peek_word(run_mode, current_PC); auto data = c->disassemble(current_PC); @@ -167,8 +167,14 @@ void console_ncurses::panel_update_thread() for(uint8_t b=0; b<16; b++) mvwprintw(w_panel->win, 1, 1 + 16 - b, "%c", current_PSW & (1 << b) ? '1' : '0'); - for(uint8_t b=0; b<16; b++) - mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "%c", current_instr & (1 << b) ? '1' : '0'); + if (current_instr.has_value()) { + for(uint8_t b=0; b<16; b++) + mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "%c", current_instr.value() & (1 << b) ? '1' : '0'); + } + else { + for(uint8_t b=0; b<16; b++) + mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "-"); + } mvwprintw(w_panel->win, 4, 1, "LEDs:"); diff --git a/cpu.cpp b/cpu.cpp index b274adf..e0ea878 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1898,15 +1898,20 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) while(0); } -cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const +std::optional cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const { assert(mode_register < 64); int run_mode = getPSW_runmode(); - uint16_t next_word = b->peek_word(run_mode, pc & 65535); + auto temp = b->peek_word(run_mode, pc & 65535); + if (temp.has_value() == false) + return { }; + uint16_t next_word = temp.value(); int reg = mode_register & 7; uint16_t mask = word_mode == wm_byte ? 0xff : 0xffff; + std::optional temp2; + std::string reg_name; if (reg == 6) reg_name = "SP"; @@ -1917,49 +1922,111 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c switch(mode_register >> 3) { case 0: - return { reg_name, 2, -1, uint16_t(get_register(reg) & mask) }; + return { { reg_name, 2, -1, uint16_t(get_register(reg) & mask) } }; case 1: - return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) }; + temp2 = b->peek_word(run_mode, get_register(reg)); + if (temp2.has_value() == false) + return { }; + + return { { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } }; case 2: if (reg == 7) - return { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) }; + return { { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) } }; - return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) }; + temp2 = b->peek_word(run_mode, get_register(reg)); + if (temp2.has_value() == false) + return { }; + + return { { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } }; case 3: - if (reg == 7) - return { format("@#%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, next_word) & mask) }; + if (reg == 7) { + temp2 = b->peek_word(run_mode, next_word); + if (temp2.has_value() == false) + return { }; - return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg))) & mask) }; + return { { format("@#%06o", next_word), 4, int(next_word), uint16_t(temp2.value() & mask) } }; + } + + temp2 = b->peek_word(run_mode, get_register(reg)); + if (temp2.has_value() == false) + return { }; + + temp2 = b->peek_word(run_mode, temp2.value()); + if (temp2.has_value() == false) + return { }; + + return { { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } }; case 4: - return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) }; + temp2 = b->peek_word(run_mode, get_register(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)); + if (temp2.has_value() == false) + return { }; + + return { { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } }; case 5: - return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) - 2)) & mask) }; + temp2 = b->peek_word(run_mode, get_register(reg) - 2); + if (temp2.has_value() == false) + return { }; + + temp2 = b->peek_word(run_mode, temp2.value()); + if (temp2.has_value() == false) + return { }; + + return { { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } }; case 6: - if (reg == 7) - return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) }; + if (reg == 7) { + temp2 = b->peek_word(run_mode, get_register(reg) + next_word); + if (temp2.has_value() == false) + return { }; - return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) }; + return { { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(temp2.value() & mask) } }; + } + + temp2 = b->peek_word(run_mode, get_register(reg) + next_word); + if (temp2.has_value() == false) + return { }; + + return { { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(temp2.value() & mask) } }; case 7: - if (reg == 7) - return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) }; + if (reg == 7) { + temp2 = b->peek_word(run_mode, get_register(reg) + next_word); + if (temp2.has_value() == false) + return { }; - return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) }; + temp2 = b->peek_word(run_mode, temp2.value()); + if (temp2.has_value() == false) + return { }; + + return { { format("@%06o", next_word), 4, int(next_word), uint16_t(temp2.value() & mask) } }; + } + + temp2 = b->peek_word(run_mode, get_register(reg) + next_word); + if (temp2.has_value() == false) + return { }; + + temp2 = b->peek_word(run_mode, temp2.value()); + if (temp2.has_value() == false) + return { }; + + return { { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(temp2.value() & mask) } }; } - return { "??", 0, -1, 0123456 }; + return { }; } std::map > cpu::disassemble(const uint16_t addr) const { - uint16_t instruction = b->peek_word(getPSW_runmode(), addr); + auto temp = b->peek_word(getPSW_runmode(), addr); + if (temp.has_value() == false) + return { }; + uint16_t instruction = temp.value(); word_mode_t word_mode = instruction & 0x8000 ? wm_byte : wm_word; std::string word_mode_str = word_mode == wm_byte ? "B" : ""; uint8_t ado_opcode = (instruction >> 9) & 7; // additional double operand @@ -1981,7 +2048,10 @@ std::map > cpu::disassemble(const uint16_t // TODO: 100000011 if (do_opcode == 0b000) { - auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) }; + auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode); + if (addressing.has_value() == false) + return { }; + auto dst_text { addressing.value() }; auto next_word = dst_text.instruction_part; @@ -2074,7 +2144,10 @@ std::map > cpu::disassemble(const uint16_t name = "?"; else { std::string src_text = format("R%d", (instruction >> 6) & 7); - auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) }; + auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode); + if (addressing.has_value() == false) + return { }; + auto dst_text { addressing.value() }; auto next_word = dst_text.instruction_part; @@ -2144,7 +2217,10 @@ std::map > cpu::disassemble(const uint16_t } // source - auto src_text { addressing_to_string(src_register, (addr + 2) & 65535, word_mode) }; + auto addressing_src = addressing_to_string(src_register, (addr + 2) & 65535, word_mode); + if (addressing_src.has_value() == false) + return { }; + auto src_text { addressing_src.value() }; auto next_word_src = src_text.instruction_part; if (next_word_src != -1) @@ -2153,7 +2229,10 @@ std::map > cpu::disassemble(const uint16_t work_values.push_back(src_text.work_value); // destination - auto dst_text { addressing_to_string(dst_register, (addr + src_text.length) & 65535, word_mode) }; + auto addressing_dst = addressing_to_string(dst_register, (addr + src_text.length) & 65535, word_mode); + if (addressing_dst.has_value() == false) + return { }; + auto dst_text { addressing_dst.value() }; auto next_word_dst = dst_text.instruction_part; if (next_word_dst != -1) @@ -2304,7 +2383,10 @@ std::map > cpu::disassemble(const uint16_t text = format("TRAP %o", instruction & 255); if ((instruction & ~0b111111) == 0b0000000001000000) { - auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) }; + auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode); + if (addressing.has_value() == false) + return { }; + auto dst_text { addressing.value() }; auto next_word = dst_text.instruction_part; if (next_word != -1) @@ -2316,7 +2398,10 @@ std::map > cpu::disassemble(const uint16_t } if ((instruction & 0b1111111000000000) == 0b0000100000000000) { - auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) }; + auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode); + if (addressing.has_value() == false) + return { }; + auto dst_text { addressing.value() }; auto next_word = dst_text.instruction_part; if (next_word != -1) diff --git a/cpu.h b/cpu.h index bae5032..1d5ce10 100644 --- a/cpu.h +++ b/cpu.h @@ -105,7 +105,7 @@ private: uint16_t work_value; }; - operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const; + std::optional addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const; void add_to_stack_trace(const uint16_t p); void pop_from_stack_trace(); diff --git a/debugger.cpp b/debugger.cpp index 189ccbb..be9f612 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -431,6 +431,8 @@ void configure_disk(bus *const b, console *const cnsl) int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool instruction_only) { auto data = c->disassemble(pc); + if (data.empty()) + return 2; // problem! auto registers = data["registers"]; auto psw = data["psw"][0]; @@ -933,11 +935,20 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto for(int i=0; ipeek_word(c->getPSW_runmode(), cur_addr) : b->read_physical(cur_addr); + uint16_t val = 0; - if (val == -1) { - cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr)); - break; + if (parts[2] == "v") { + auto v = b->peek_word(c->getPSW_runmode(), cur_addr); + + if (v.has_value() == false) { + cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr)); + break; + } + + val = v.value(); + } + else { + val = b->read_physical(cur_addr); } if (n == 1) From 8294b586b7bf92930c62c7779c94fb89c5c24034 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 24 Jun 2024 22:48:02 +0200 Subject: [PATCH 21/23] bus::write is only returning bool now, no wrapping struct --- bus.cpp | 64 ++++++++++++++++++++++++++++----------------------------- bus.h | 2 +- cpu.cpp | 22 ++++++++++---------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/bus.cpp b/bus.cpp index cedd517..d72f38c 100644 --- a/bus.cpp +++ b/bus.cpp @@ -545,7 +545,7 @@ bool bus::is_psw(const uint16_t addr, const int run_mode, const d_i_space_t spac return false; } -write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t space) +bool bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t space) { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); @@ -577,7 +577,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 c->setPSW(vtemp, false); - return { true }; + return true; } if (a == ADDR_STACKLIM || a == ADDR_STACKLIM + 1) { // stack limit register @@ -591,7 +591,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 c->setStackLimitRegister(v); - return { false }; + return false; } if (a == ADDR_MICROPROG_BREAK_REG || a == ADDR_MICROPROG_BREAK_REG + 1) { // microprogram break register @@ -599,7 +599,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 update_word(µprogram_break_register, a & 1, value); - return { false }; + return false; } if (a == ADDR_MMR0 || a == ADDR_MMR0 + 1) { // MMR0 @@ -609,7 +609,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 update_word(&temp, a & 1, value); mmu_->setMMR0(temp); - return { false }; + return false; } } else { @@ -622,65 +622,65 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (a == ADDR_STACKLIM) { // stack limit register TRACE("WRITE-I/O stack limit register: %06o", value); c->setStackLimitRegister(value & 0xff00); - return { false }; + return false; } if (a >= ADDR_KERNEL_R && a <= ADDR_KERNEL_R + 5) { // kernel R0-R5 int reg = a - ADDR_KERNEL_R; TRACE("WRITE-I/O kernel R%d: %06o", reg, value); c->set_register(reg, value); - return { false }; + return false; } if (a >= ADDR_USER_R && a <= ADDR_USER_R + 5) { // user R0-R5 int reg = a - ADDR_USER_R; TRACE("WRITE-I/O user R%d: %06o", reg, value); c->set_register(reg, value); - return { false }; + return false; } if (a == ADDR_KERNEL_SP) { // kernel SP TRACE("WRITE-I/O kernel SP: %06o", value); c->setStackPointer(0, value); - return { false }; + return false; } if (a == ADDR_PC) { // PC TRACE("WRITE-I/O PC: %06o", value); c->setPC(value); - return { false }; + return false; } if (a == ADDR_SV_SP) { // supervisor SP TRACE("WRITE-I/O supervisor sp: %06o", value); c->setStackPointer(1, value); - return { false }; + return false; } if (a == ADDR_USER_SP) { // user SP TRACE("WRITE-I/O user sp: %06o", value); c->setStackPointer(3, value); - return { false }; + return false; } if (a == ADDR_MICROPROG_BREAK_REG) { // microprogram break register TRACE("WRITE-I/O microprogram break register: %06o", value); microprogram_break_register = value & 0xff; // only 8b on 11/70? - return { false }; + return false; } } if (a == ADDR_CPU_ERR) { // cpu error register TRACE("WRITE-I/O CPUERR: %06o", value); mmu_->setCPUERR(0); - return { false }; + return false; } if (a == ADDR_MMR3) { // MMR3 TRACE("WRITE-I/O set MMR3: %06o", value); mmu_->setMMR3(value); - return { false }; + return false; } if (a == ADDR_MMR0) { // MMR0 TRACE("WRITE-I/O set MMR0: %06o", value); mmu_->setMMR0(value); - return { false }; + return false; } if (a == ADDR_PIR) { // PIR @@ -697,52 +697,52 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 mmu_->setPIR(value); - return { false }; + return false; } if (a == ADDR_LFC) { // line frequency clock and status register kw11_l_->write_word(a, value); - return { false }; + return false; } if (tm11 && a >= TM_11_BASE && a < TM_11_END) { TRACE("WRITE-I/O TM11 register %d: %06o", (a - TM_11_BASE) / 2, value); word_mode == wm_byte ? tm11->write_byte(a, value) : tm11->write_word(a, value); - return { false }; + return false; } if (rk05_ && a >= RK05_BASE && a < RK05_END) { TRACE("WRITE-I/O RK05 register %d: %06o", (a - RK05_BASE) / 2, value); word_mode == wm_byte ? rk05_->write_byte(a, value) : rk05_->write_word(a, value); - return { false }; + return false; } if (rl02_ && a >= RL02_BASE && a < RL02_END) { TRACE("WRITE-I/O RL02 register %d: %06o", (a - RL02_BASE) / 2, value); word_mode == wm_byte ? rl02_->write_byte(a, value) : rl02_->write_word(a, value); - return { false }; + return false; } if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END) { TRACE("WRITE-I/O TTY register %d: %06o", (a - PDP11TTY_BASE) / 2, value); word_mode == wm_byte ? tty_->write_byte(a, value) : tty_->write_word(a, value); - return { false }; + return false; } if (dc11_ && a >= DC11_BASE && a < DC11_END) { word_mode == wm_byte ? dc11_->write_byte(a, value) : dc11_->write_word(a, value); - return { false }; + return false; } if (rp06_ && a >= RP06_BASE && a < RP06_END) { word_mode == wm_byte ? rp06_->write_byte(a, value) : rp06_->write_word(a, value); - return { false }; + return false; } if (a >= 0172100 && a <= 0172137) { // MM11-LP parity TRACE("WRITE-I/O MM11-LP parity (%06o): %o", a, value); - return { false }; + return false; } /// MMU /// @@ -754,31 +754,31 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 else mmu_->write_byte(a, value); - return { false }; + return false; } /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others // TODO - return { false }; + return false; } if (a >= 0170200 && a <= 0170377) { // unibus map TRACE("writing %06o to unibus map (%06o)", value, a); // TODO - return { false }; + return false; } if (a == ADDR_CONSW) { // switch register console_leds = value; - return { false }; + return false; } if (a == ADDR_SYSSIZE || a == ADDR_SYSSIZE + 2) // system size (is read-only) - return { false }; + return false; if (a == ADDR_SYSTEM_ID) // is r/o - return { false }; + return false; /////////// @@ -817,7 +817,7 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 else m->write_word(m_offset, value); - return { false }; + return false; } void bus::write_physical(const uint32_t a, const uint16_t value) diff --git a/bus.h b/bus.h index 780d70b..016aa3a 100644 --- a/bus.h +++ b/bus.h @@ -130,7 +130,7 @@ public: uint8_t read_unibus_byte(const uint32_t a); uint16_t read_physical(const uint32_t a); - write_rc_t write(const uint16_t a, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t s = i_space); + bool write(const uint16_t a, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t s = i_space); void write_unibus_byte(const uint32_t a, const uint8_t value); void write_byte(const uint16_t a, const uint8_t value) override { write(a, wm_byte, value, rm_cur); } void write_word(const uint16_t a, const uint16_t value, const d_i_space_t s); diff --git a/cpu.cpp b/cpu.cpp index e0ea878..1f2a9ca 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -199,7 +199,7 @@ bool cpu::put_result(const gam_rc_t & g, const uint16_t value) return true; } - return b->write(g.addr.value(), g.word_mode, value, g.mode_selection, g.space).is_psw == false; + return b->write(g.addr.value(), g.word_mode, value, g.mode_selection, g.space) == false; } uint16_t cpu::add_register(const int nr, const uint16_t value) @@ -548,7 +548,7 @@ bool cpu::putGAM(const gam_rc_t & g, const uint16_t value) if (g.addr.has_value()) { auto rc = b->write(g.addr.value(), g.word_mode, value, g.mode_selection, g.space); - return rc.is_psw == false; + return rc == false; } if (g.mode_selection == rm_prev) { @@ -1078,7 +1078,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) addToMMR1(a); int32_t vl = (a.value.value() + 1) & (word_mode == wm_byte ? 0xff : 0xffff); - bool set_flags = b->write(a.addr.value(), a.word_mode, vl, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, vl, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(vl, word_mode)); @@ -1110,7 +1110,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) addToMMR1(a); int32_t vl = (a.value.value() - 1) & (word_mode == wm_byte ? 0xff : 0xffff); - bool set_flags = b->write(a.addr.value(), a.word_mode, vl, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, vl, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(vl, word_mode)); @@ -1142,7 +1142,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) addToMMR1(a); uint16_t v = -a.value.value(); - bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1179,7 +1179,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) bool org_c = getPSW_c(); uint16_t v = (vo + org_c) & (word_mode == wm_byte ? 0x00ff : 0xffff); - bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1216,7 +1216,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) bool org_c = getPSW_c(); uint16_t v = (vo - org_c) & (word_mode == wm_byte ? 0xff : 0xffff); - bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1269,7 +1269,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) else temp = (t >> 1) | (getPSW_c() << 15); - bool set_flags = b->write(a.addr.value(), a.word_mode, temp, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, temp, a.mode_selection, a.space) == false; if (set_flags) { setPSW_c(new_carry); @@ -1319,7 +1319,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) temp = (t << 1) | getPSW_c(); } - bool set_flags = b->write(a.addr.value(), a.word_mode, temp, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, temp, a.mode_selection, a.space) == false; if (set_flags) { setPSW_c(new_carry); @@ -1365,7 +1365,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) v >>= 1; v |= hb; - bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(v, word_mode)); @@ -1397,7 +1397,7 @@ bool cpu::single_operand_instructions(const uint16_t instr) uint16_t vl = a.value.value(); uint16_t v = (vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff); - bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space).is_psw == false; + bool set_flags = b->write(a.addr.value(), a.word_mode, v, a.mode_selection, a.space) == false; if (set_flags) { setPSW_n(SIGN(v, word_mode)); From 32f93b4f769bc9657f57457320b8946c7906df17 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 25 Jun 2024 11:29:57 +0200 Subject: [PATCH 22/23] logging --- rp06.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rp06.cpp b/rp06.cpp index 25804e6..f603860 100644 --- a/rp06.cpp +++ b/rp06.cpp @@ -191,7 +191,7 @@ void rp06::write_word(const uint16_t addr, uint16_t v) uint32_t cur_n = std::min(end_offset - cur_offset, SECTOR_SIZE); if (function_code == 070) { - DOLOG(debug, false, "RP06: reading %u bytes from %u (dec) to %06o (oct)", cur_n, offs, addr); + DOLOG(debug, false, "RP06: reading %u bytes from %u (dec) to %06o (oct)", cur_n, cur_offset, addr); if (!fhs.at(0)->read(cur_offset, cur_n, xfer_buffer, SECTOR_SIZE)) { DOLOG(ll_error, true, "RP06 read error %s from %u", strerror(errno), cur_offset); @@ -204,7 +204,7 @@ void rp06::write_word(const uint16_t addr, uint16_t v) b->write_unibus_byte(addr++, xfer_buffer[i]); } else { - DOLOG(debug, false, "RP06: writing %u bytes to %u (dec) from %06o (oct)", cur_n, offs, addr); + DOLOG(debug, false, "RP06: writing %u bytes to %u (dec) from %06o (oct)", cur_n, cur_offset, addr); for(uint32_t i=0; iread_unibus_byte(addr++); From d7bd8d193ac6198afb8c90bb85afc2b206128af4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 25 Jun 2024 19:18:13 +0200 Subject: [PATCH 23/23] compile fix --- ESP32/console_esp32.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ESP32/console_esp32.cpp b/ESP32/console_esp32.cpp index 0d09997..28e70b3 100644 --- a/ESP32/console_esp32.cpp +++ b/ESP32/console_esp32.cpp @@ -121,7 +121,7 @@ void console_esp32::panel_update_thread() if (panel_mode == PM_BITS) { memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC); - uint16_t current_instr = b->peek_word(run_mode, current_PC); + auto current_instr = b->peek_word(run_mode, current_PC); int pixel_offset = 0; @@ -140,8 +140,14 @@ void console_esp32::panel_update_thread() for(uint8_t b=0; b<16; b++) pixels.setPixelColor(pixel_offset++, current_PSW & (1l << b) ? magenta : 0); - for(uint8_t b=0; b<16; b++) - pixels.setPixelColor(pixel_offset++, current_instr & (1l << b) ? red : 0); + if (current_instr.has_value()) { + for(uint8_t b=0; b<16; b++) + pixels.setPixelColor(pixel_offset++, current_instr.value() & (1l << b) ? red : 0); + } + else { + for(uint8_t b=0; b<16; b++) + pixels.setPixelColor(pixel_offset++, 0); + } pixels.setPixelColor(pixel_offset++, running_flag ? white : 0);