From 3f5f1d91d15758f9502b2500135ea2a4eaff997b Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 20 Apr 2024 18:40:05 +0200 Subject: [PATCH 01/25] set loglevel from debugger --- debugger.cpp | 13 +++++++++++++ log.cpp | 8 +++++++- log.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/debugger.cpp b/debugger.cpp index 49f5255..153d328 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -1049,6 +1049,18 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } + else if (parts[0] == "setll" && parts.size() == 2) { + auto ll_parts = split(parts[1], ","); + + if (ll_parts.size() != 2) + cnsl->put_string_lf("Loglevel for either screen or file missing"); + else { + log_level_t ll_screen = parse_ll(ll_parts[0]); + log_level_t ll_file = parse_ll(ll_parts[1]); + + setll(ll_screen, ll_file); + } + } else if (cmd == "qi") { show_queued_interrupts(cnsl, c); @@ -1087,6 +1099,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto " follows v/p (virtual/physical), all octal values, mmr0-3 and psw are", " registers", "trace/t - toggle tracing", + "setll - set loglevel: terminal,file", "turbo - toggle turbo mode (cannot be interrupted)", "debug - enable CPU debug mode", "bt - show backtrace - need to enable debug first", diff --git a/log.cpp b/log.cpp index a1ca6ce..1eb2b8c 100644 --- a/log.cpp +++ b/log.cpp @@ -39,7 +39,7 @@ void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_scre logfile = lf ? strdup(lf) : nullptr; - log_level_file = ll_file; + log_level_file = ll_file; log_level_screen = ll_screen; l_timestamp = timestamp; @@ -47,6 +47,12 @@ void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_scre atexit(closelog); } +void setll(const log_level_t ll_file, const log_level_t ll_screen) +{ + log_level_file = ll_file; + log_level_screen = ll_screen; +} + void setloguid(const int uid, const int gid) { lf_uid = uid; diff --git a/log.h b/log.h index 1f4003e..2cfce16 100644 --- a/log.h +++ b/log.h @@ -12,6 +12,7 @@ typedef enum { debug, info, warning, ll_error, none } log_level_t; // TODO ll_ log_level_t parse_ll(const std::string & str); void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); +void setll(const log_level_t ll_file, const log_level_t ll_screen); void setloguid(const int uid, const int gid); void closelog(); void dolog(const log_level_t ll, const char *fmt, ...); From 5df0b6f70f8cde6e317b081f9e00bff8477a7e92 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 20 Apr 2024 22:22:28 +0200 Subject: [PATCH 02/25] show wait state in debugger --- cpu.h | 4 ++-- debugger.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cpu.h b/cpu.h index e5010f2..a6028cf 100644 --- a/cpu.h +++ b/cpu.h @@ -126,8 +126,6 @@ public: uint64_t get_wait_time() const { return wait_time; } std::tuple get_mips_rel_speed(const std::optional & instruction_count, const std::optional & t_diff_1s) const; - std::map > get_queued_interrupts() const { return queued_interrupts; } - bool get_debug() const { return debug_mode; } void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); } std::vector > get_stack_trace() const; @@ -141,6 +139,8 @@ public: void init_interrupt_queue(); void queue_interrupt(const uint8_t level, const uint8_t vector); + std::map > get_queued_interrupts() const { return queued_interrupts; } + std::optional get_interrupt_delay_left() const { return trap_delay; } void trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); bool is_it_a_trap() const { return it_is_a_trap; } diff --git a/debugger.cpp b/debugger.cpp index 153d328..114dfa3 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -720,6 +720,12 @@ void show_queued_interrupts(console *const cnsl, cpu *const c) { cnsl->put_string_lf(format("Current level: %d", c->getPSW_spl())); + auto delay = c->get_interrupt_delay_left(); + if (delay.has_value()) + cnsl->put_string_lf(format("Current delay left: %d", delay.value())); + else + cnsl->put_string_lf("No delay"); + auto queued_interrupts = c->get_queued_interrupts(); for(auto & level: queued_interrupts) { From b0df42ad5eb816b7078563c54f0e25a5b21a5644 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 20 Apr 2024 22:51:41 +0200 Subject: [PATCH 03/25] sanity checks --- cpu.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index a714569..68382ab 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -127,9 +127,9 @@ std::vector > cpu::get_stack_trace() const void cpu::reset() { memset(regs0_5, 0x00, sizeof regs0_5); - memset(sp, 0x00, sizeof sp); - pc = 0; - psw = 0; // 7 << 5; + memset(sp, 0x00, sizeof sp); + pc = 0; + psw = 0; // 7 << 5; fpsr = 0; init_interrupt_queue(); } @@ -149,6 +149,8 @@ uint16_t cpu::getRegister(const int nr, const rm_selection_t mode_selection) con return sp[getPSW_runmode()]; } + assert(nr == 7); + return pc; } @@ -166,6 +168,7 @@ void cpu::setRegister(const int nr, const uint16_t value, const rm_selection_t m sp[getPSW_runmode()] = value; } else { + assert(nr == 7); pc = value; } } @@ -210,6 +213,8 @@ uint16_t cpu::addRegister(const int nr, const rm_selection_t mode_selection, con return sp[getPSW_runmode()] += value; } + assert(nr == 7); + return pc += value; } @@ -222,8 +227,10 @@ void cpu::lowlevel_register_set(const uint8_t set, const uint8_t reg, const uint regs0_5[set][reg] = value; else if (reg == 6) sp[set == 0 ? 0 : 3] = value; - else + else { + assert(reg == 7); pc = value; + } } uint16_t cpu::lowlevel_register_get(const uint8_t set, const uint8_t reg) @@ -237,6 +244,8 @@ uint16_t cpu::lowlevel_register_get(const uint8_t set, const uint8_t reg) if (reg == 6) return sp[set == 0 ? 0 : 3]; + assert(reg == 7); + return pc; } From dd474ce40dd605773cdcb681df31b5c837cf57ad Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sat, 20 Apr 2024 23:27:48 +0200 Subject: [PATCH 04/25] logging --- bus.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bus.cpp b/bus.cpp index 604651a..1670647 100644 --- a/bus.cpp +++ b/bus.cpp @@ -652,14 +652,14 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, false, "MMR0: %06o", MMR0); if (trap_action == T_TRAP_250) { - DOLOG(debug, false, "Page access %d: trap 0250", access_control); + DOLOG(debug, false, "Page access %d (for virtual address %06o): trap 0250", access_control, a); c->trap(0250); // trap throw 5; } else { // T_ABORT_4 - DOLOG(debug, false, "Page access %d: trap 004", access_control); + DOLOG(debug, false, "Page access %d (for virtual address %06o): trap 004", access_control, a); c->trap(004); // abort From fe68ef913461e8a1d27d073d0e974ef6a3fe9eca Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 11:12:16 +0200 Subject: [PATCH 05/25] bus address shall always have bit 0 set to 0 --- rl02.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/rl02.cpp b/rl02.cpp index 14aa89a..8d814dd 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -13,11 +13,12 @@ #include "utils.h" +bool flag = false; static const char * const regnames[] = { "control status", - "bus address ", - "disk address ", - "multipurpose " + "bus address", + "disk address", + "multipurpose" }; static const char * const commands[] = { @@ -112,7 +113,7 @@ void rl02::writeByte(const uint16_t addr, const uint8_t v) uint32_t rl02::get_bus_address() const { - return registers[(RL02_BAR - RL02_BASE) / 2] | (uint32_t((registers[(RL02_CSR - RL02_BASE) / 2] >> 4) & 3) << 16); + return (registers[(RL02_BAR - RL02_BASE) / 2] | (uint32_t((registers[(RL02_CSR - RL02_BASE) / 2] >> 4) & 3) << 16)) & ~1; } void rl02::update_bus_address(const uint32_t a) @@ -155,7 +156,8 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) *disk_read_acitivity = true; if (command == 2) { // get status - registers[(RL02_MPR - RL02_BASE) / 2] = 0; + mpr[0] = 5 /* lock on */ | (1 << 3) /* brush home */ | (1 << 4) /* heads over disk */ | (head << 6) | (1 << 7) /* RL02 */; + mpr[1] = mpr[0]; } else if (command == 3) { // seek uint16_t temp = registers[(RL02_DAR - RL02_BASE) / 2]; @@ -172,12 +174,15 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) DOLOG(debug, false, "RL02: seek from cylinder %d to %d (distance: %d, DAR: %06o)", track, new_track, cylinder_count, temp); track = new_track; - update_dar(); +// update_dar(); do_int = true; } else if (command == 4) { // read header mpr[0] = (sector & 63) | (head << 6) | (track << 7); + DOLOG(ll_error, true, "GREP3 %06o", mpr[0]); + if (mpr[0] == 032606) + flag = true; mpr[1] = 0; // zero mpr[2] = 0; // TODO: CRC @@ -193,6 +198,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) count = 0; uint16_t temp = registers[(RL02_DAR - RL02_BASE) / 2]; + DOLOG(ll_error, true, "GREP2 %06o", temp); sector = temp & 63; head = (temp >> 6) & 1; @@ -200,6 +206,11 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) uint32_t temp_disk_offset = calc_offset(); + DOLOG(ll_error, true, "GREP1 %02x", b->getMMR3() & 0x20); + + if (flag) + printf("%06o\n", b->getCpu()->getPC()); + DOLOG(debug, false, "RL02 read %d bytes (dec) from %d (dec) to %06o (oct) [cylinder: %d, head: %d, sector: %d]", count, temp_disk_offset, memory_address, track, head, sector); // update_dar(); @@ -218,6 +229,8 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) b->writeUnibusByte(memory_address++, xfer_buffer[i++]); // update_bus_address(memory_address); + + mpr[0]++; } temp_disk_offset += cur; @@ -249,7 +262,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) if (registers[(RL02_CSR - RL02_BASE) / 2] & 64) { // interrupt enable? DOLOG(debug, false, "RL02 triggering interrupt"); - b->getCpu()->queue_interrupt(4, 0160); + b->getCpu()->queue_interrupt(5, 0160); } } From bccf8c69cf6998f4438af7217608f29042b63e27 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 11:49:13 +0200 Subject: [PATCH 06/25] Syslog logging when file i/o is not available (ESP32) --- debugger.cpp | 20 ++++++++++++++++++++ log.cpp | 47 +++++++++++++++++++++++++++++++++++++++-------- log.h | 7 ++++--- main.cpp | 2 +- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 114dfa3..1a9e921 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -1067,6 +1067,25 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto setll(ll_screen, ll_file); } } + else if (parts[0] == "setll" && parts.size() == 2) { + auto ll_parts = split(parts[1], ","); + + if (ll_parts.size() != 2) + cnsl->put_string_lf("Loglevel for either screen or file missing"); + else { + log_level_t ll_screen = parse_ll(ll_parts[0]); + log_level_t ll_file = parse_ll(ll_parts[1]); + + setll(ll_screen, ll_file); + } + + continue; + } + else if (parts[0] == "setsl" && parts.size() == 3) { + setloghost(parts.at(1).c_str(), parse_ll(parts[2])); + + continue; + } else if (cmd == "qi") { show_queued_interrupts(cnsl, c); @@ -1106,6 +1125,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto " registers", "trace/t - toggle tracing", "setll - set loglevel: terminal,file", + "setsl - set syslog target: requires a hostname and a loglevel", "turbo - toggle turbo mode (cannot be interrupted)", "debug - enable CPU debug mode", "bt - show backtrace - need to enable debug first", diff --git a/log.cpp b/log.cpp index 1eb2b8c..c9986cc 100644 --- a/log.cpp +++ b/log.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include "error.h" @@ -16,9 +19,11 @@ static const char *logfile = strdup("/tmp/kek.log"); +static sockaddr_in syslog_ip_addr = { }; +static bool is_file = true; log_level_t log_level_file = warning; log_level_t log_level_screen = warning; -FILE *lfh = nullptr; +FILE *lfh = nullptr; static int lf_uid = -1; static int lf_gid = -1; static bool l_timestamp = true; @@ -30,23 +35,37 @@ int gettid() } #endif -void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_screen, const bool timestamp) +void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool timestamp) { if (lfh) fclose(lfh); free((void *)logfile); + is_file = true; + logfile = lf ? strdup(lf) : nullptr; log_level_file = ll_file; log_level_screen = ll_screen; - l_timestamp = timestamp; + l_timestamp = timestamp; atexit(closelog); } +void setloghost(const char *const host, const log_level_t ll) +{ + inet_aton(host, &syslog_ip_addr.sin_addr); + syslog_ip_addr.sin_port = htons(514); + + is_file = false; + + log_level_file = ll; + + l_timestamp = false; +} + void setll(const log_level_t ll_file, const log_level_t ll_screen) { log_level_file = ll_file; @@ -59,6 +78,15 @@ void setloguid(const int uid, const int gid) lf_gid = gid; } +void send_syslog(const int ll, const std::string & what) +{ + std::string msg = format("<%d>%s", 16 * 8 + ll, what.c_str()); + + int s = socket(AF_INET, SOCK_DGRAM, 0); + (void)sendto(s, msg.c_str(), msg.size(), 0, reinterpret_cast(&syslog_ip_addr), sizeof syslog_ip_addr); + close(s); +} + void closelog() { if (lfh) { @@ -76,7 +104,6 @@ void dolog(const log_level_t ll, const char *fmt, ...) lfh = fopen(logfile, "a+"); if (!lfh) error_exit(true, "Cannot access log-file %s", logfile); - #if !defined(_WIN32) if (lf_uid != -1 && fchown(fileno(lfh), lf_uid, lf_gid) == -1) error_exit(true, "Cannot change logfile (%s) ownership", logfile); @@ -113,23 +140,27 @@ void dolog(const log_level_t ll, const char *fmt, ...) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(now % 1000000), ll_names[ll]); + if (ll <= log_level_file && is_file == false) + send_syslog(ll, str); #if !defined(ESP32) - if (ll >= log_level_file && lfh != nullptr) + if (ll <= log_level_file && lfh != nullptr) fprintf(lfh, "%s%s\n", ts_str, str); #endif - if (ll >= log_level_screen) + if (ll <= log_level_screen) printf("%s%s\r\n", ts_str, str); free(ts_str); } else { + if (ll <= log_level_file && is_file == false) + send_syslog(ll, str); #if !defined(ESP32) - if (ll >= log_level_file && lfh != nullptr) + if (ll <= log_level_file && lfh != nullptr) fprintf(lfh, "%s\n", str); #endif - if (ll >= log_level_screen) + if (ll <= log_level_screen) printf("%s\r\n", str); } diff --git a/log.h b/log.h index 2cfce16..88172c0 100644 --- a/log.h +++ b/log.h @@ -8,10 +8,11 @@ #include "config.h" -typedef enum { debug, info, warning, ll_error, none } log_level_t; // TODO ll_ prefix +typedef enum { ll_emerg = 0, ll_alert, ll_critical, ll_error, warning, notice, info, debug, none } log_level_t; // TODO ll_ prefix log_level_t parse_ll(const std::string & str); -void setlog(const char *lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); +void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); +void setloghost(const char *const host, const log_level_t ll); void setll(const log_level_t ll_file, const log_level_t ll_screen); void setloguid(const int uid, const int gid); void closelog(); @@ -23,7 +24,7 @@ void dolog(const log_level_t ll, const char *fmt, ...); #define DOLOG(ll, always, fmt, ...) do { \ extern log_level_t log_level_file, log_level_screen; \ \ - if (always || ll >= log_level_file || ll >= log_level_screen) \ + if (always || ll <= log_level_file || ll <= log_level_screen) \ dolog(ll, fmt, ##__VA_ARGS__); \ } while(0) #endif diff --git a/main.cpp b/main.cpp index 98198fa..d2161aa 100644 --- a/main.cpp +++ b/main.cpp @@ -493,7 +493,7 @@ int main(int argc, char *argv[]) console *cnsl = nullptr; - setlog(logfile, ll_file, ll_screen, timestamp); + setlogfile(logfile, ll_file, ll_screen, timestamp); if (validate_json.empty() == false) return run_cpu_validation(validate_json); From 1c03260f37b7ba2b114a3ef7099fe72ffe4558fc Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 21:06:44 +0200 Subject: [PATCH 07/25] coverity suggestions; nbd disk-backend garbage output fix --- breakpoint_register.cpp | 2 +- cpu.cpp | 4 +++- disk_backend_nbd.cpp | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/breakpoint_register.cpp b/breakpoint_register.cpp index d0f893a..20b2cc2 100644 --- a/breakpoint_register.cpp +++ b/breakpoint_register.cpp @@ -79,7 +79,7 @@ std::pair > breakpoint_registe return { nullptr, "register: key or value missing" }; auto values_in = parts.at(1); - auto v_parts = split(values_in, ","); + auto v_parts = split(std::move(values_in), ","); std::set values; for(auto & v: v_parts) values.insert(std::stoi(v, nullptr, 8)); diff --git a/cpu.cpp b/cpu.cpp index 68382ab..5fef699 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -346,6 +346,8 @@ bool cpu::check_pending_interrupts() const for(uint8_t i=start_level; i < 8; i++) { auto interrupts = queued_interrupts.find(i); + assert(interrupts != queued_interrupts.end()); + if (interrupts->second.empty() == false) return true; } @@ -2316,7 +2318,7 @@ std::map > cpu::disassemble(const uint16_t // PSW std::string psw_str = format("%d%d|%d|%d|%c%c%c%c%c", psw >> 14, (psw >> 12) & 3, (psw >> 11) & 1, (psw >> 5) & 7, psw & 16?'t':'-', psw & 8?'n':'-', psw & 4?'z':'-', psw & 2 ? 'v':'-', psw & 1 ? 'c':'-'); - out.insert({ "psw", { psw_str } }); + out.insert({ "psw", { std::move(psw_str) } }); out.insert({ "psw-value", { format("%06o", psw) } }); // values worked with diff --git a/disk_backend_nbd.cpp b/disk_backend_nbd.cpp index 3067bc7..7e3c7fd 100644 --- a/disk_backend_nbd.cpp +++ b/disk_backend_nbd.cpp @@ -119,13 +119,14 @@ bool disk_backend_nbd::connect(const bool retry) } } - if (memcmp(nbd_hello.magic1, "NBDMAGIC", 8) != 0) { + if (fd != -1 && memcmp(nbd_hello.magic1, "NBDMAGIC", 8) != 0) { close(fd); fd = -1; DOLOG(warning, true, "disk_backend_nbd::connect: magic invalid"); } - DOLOG(info, false, "NBD size: %u", NTOHLL(nbd_hello.size)); + if (fd != -1) + DOLOG(info, false, "NBD size: %u", NTOHLL(nbd_hello.size)); } while(fd == -1 && retry); From 056681e32fc299fe1f38b4bf423856bd44833798 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:04:41 +0200 Subject: [PATCH 08/25] dummy core-memory parity --- bus.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bus.cpp b/bus.cpp index 1670647..63cb4f6 100644 --- a/bus.cpp +++ b/bus.cpp @@ -287,6 +287,11 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return 0; } + if (a >= 0172100 && a <= 0172137) { // MM11-LP parity + if (!peek_only) DOLOG(debug, false, "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(); @@ -988,6 +993,11 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 return { false }; } + if (a >= 0172100 && a <= 0172137) { // MM11-LP parity + DOLOG(debug, false, "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) { From 9c75d94d70688fae45aa2009ce1db29a9c200eb6 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:05:27 +0200 Subject: [PATCH 09/25] write rl02 (required for unix 7 to boot) --- rl02.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/rl02.cpp b/rl02.cpp index 8d814dd..8aa8f6d 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -13,7 +13,6 @@ #include "utils.h" -bool flag = false; static const char * const regnames[] = { "control status", "bus address", @@ -180,9 +179,6 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) } else if (command == 4) { // read header mpr[0] = (sector & 63) | (head << 6) | (track << 7); - DOLOG(ll_error, true, "GREP3 %06o", mpr[0]); - if (mpr[0] == 032606) - flag = true; mpr[1] = 0; // zero mpr[2] = 0; // TODO: CRC @@ -190,6 +186,52 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) do_int = true; } + else if (command == 5) { // write data + uint32_t memory_address = get_bus_address(); + + uint32_t count = (65536l - registers[(RL02_MPR - RL02_BASE) / 2]) * 2; + if (count == 65536) + count = 0; + + uint16_t temp = registers[(RL02_DAR - RL02_BASE) / 2]; + + sector = temp & 63; + head = (temp >> 6) & 1; + track = temp >> 7; + + uint32_t temp_disk_offset = calc_offset(); + + DOLOG(debug, false, "RL02 write %d bytes (dec) to %d (dec) from %06o (oct) [cylinder: %d, head: %d, sector: %d]", count, temp_disk_offset, memory_address, track, head, sector); + + while(count > 0) { + uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); + + if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer)) { + DOLOG(ll_error, true, "RL02 write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); + break; + } + + mpr[0] += count / 2; + + temp_disk_offset += cur; + + count -= cur; + + sector++; + if (sector >= rl02_sectors_per_track) { + sector = 0; + + head++; + if (head >= 2) { + head = 0; + + track++; + } + } + } + + do_int = true; + } else if (command == 6 || command == 7) { // read data / read data without header check uint32_t memory_address = get_bus_address(); @@ -198,7 +240,6 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) count = 0; uint16_t temp = registers[(RL02_DAR - RL02_BASE) / 2]; - DOLOG(ll_error, true, "GREP2 %06o", temp); sector = temp & 63; head = (temp >> 6) & 1; @@ -206,11 +247,6 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) uint32_t temp_disk_offset = calc_offset(); - DOLOG(ll_error, true, "GREP1 %02x", b->getMMR3() & 0x20); - - if (flag) - printf("%06o\n", b->getCpu()->getPC()); - DOLOG(debug, false, "RL02 read %d bytes (dec) from %d (dec) to %06o (oct) [cylinder: %d, head: %d, sector: %d]", count, temp_disk_offset, memory_address, track, head, sector); // update_dar(); From 31fcf27c5aadba3064ab78f405096d392d209690 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:18:57 +0200 Subject: [PATCH 10/25] handle new log levels logging output --- log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log.cpp b/log.cpp index c9986cc..38bc47c 100644 --- a/log.cpp +++ b/log.cpp @@ -134,7 +134,7 @@ void dolog(const log_level_t ll, const char *fmt, ...) #endif char *ts_str = nullptr; - const char *const ll_names[] = { "debug ", "info ", "warning", "error " }; + const char *const ll_names[] = { "emerg ", "alert ", "crit ", "error ", "warning", "notice ", "info ", "debug ", "none " }; asprintf(&ts_str, "%04d-%02d-%02d %02d:%02d:%02d.%06d] %s ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(now % 1000000), From 2216589a3fdf0b8a1733daf19be3d40a30331cac Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:29:47 +0200 Subject: [PATCH 11/25] schedule next interrupt --- cpu.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu.cpp b/cpu.cpp index 5fef699..3425057 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -410,6 +410,9 @@ bool cpu::execute_any_pending_interrupt() trap(v, i, true); + // when there are more interrupts scheduled, invoke them asap + trap_delay = initial_trap_delay; + #if defined(BUILD_FOR_RP2040) xSemaphoreGive(qi_lock); #endif From 86a788fd3f45ca7c594a7618ad9bcffc48e9715d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:48:52 +0200 Subject: [PATCH 12/25] interrupt scheduling debugging --- cpu.cpp | 2 +- cpu.h | 1 + debugger.cpp | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cpu.cpp b/cpu.cpp index 3425057..9a362d1 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -392,7 +392,7 @@ bool cpu::execute_any_pending_interrupt() if (interrupts->second.empty() == false) { any_queued_interrupts = true; - if (i < start_level) + if (i < start_level) // at leas we know now that there's an interrupt scheduled continue; if (can_trigger == false) { diff --git a/cpu.h b/cpu.h index a6028cf..c968ca2 100644 --- a/cpu.h +++ b/cpu.h @@ -141,6 +141,7 @@ public: void queue_interrupt(const uint8_t level, const uint8_t vector); std::map > get_queued_interrupts() const { return queued_interrupts; } std::optional get_interrupt_delay_left() const { return trap_delay; } + bool check_if_interrupts_pending() const { return any_queued_interrupts; } void trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); bool is_it_a_trap() const { return it_is_a_trap; } diff --git a/debugger.cpp b/debugger.cpp index 1a9e921..3cac428 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -726,6 +726,8 @@ void show_queued_interrupts(console *const cnsl, cpu *const c) else cnsl->put_string_lf("No delay"); + cnsl->put_string_lf(format("Interrupt pending flag: %d", c->check_if_interrupts_pending())); + auto queued_interrupts = c->get_queued_interrupts(); for(auto & level: queued_interrupts) { From ae00c956796d3b4589ab645508ca05d9ab3f666d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:51:58 +0200 Subject: [PATCH 13/25] SPL only in kernel mode --- cpu.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 9a362d1..7827463 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1569,8 +1569,11 @@ bool cpu::condition_code_operations(const uint16_t instr) } if ((instr & ~7) == 0000230) { // SPLx - int level = instr & 7; - setPSW_spl(level); + if (getPSW_runmode() == 0) { // only in kernel mode + int level = instr & 7; + + setPSW_spl(level); + } // // trap via vector 010 only(?) on an 11/60 and not(?) on an 11/70 // trap(010); From 5251cde04c3306e1439584c37caf3f0fd9a56e41 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:54:05 +0200 Subject: [PATCH 14/25] HALT and RESET only in kernel mode --- cpu.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 7827463..287951a 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1627,7 +1627,10 @@ bool cpu::misc_operations(const uint16_t instr) { switch(instr) { case 0b0000000000000000: // HALT - *event = EVENT_HALT; + if (getPSW_runmode() == 0) // only in kernel mode + *event = EVENT_HALT; + else + trap(4); return true; case 0b0000000000000001: // WAIT @@ -1681,8 +1684,11 @@ bool cpu::misc_operations(const uint16_t instr) return true; case 0b0000000000000101: // RESET - b->init(); - init_interrupt_queue(); + if (getPSW_runmode() == 0) { // only in kernel mode + b->init(); + + init_interrupt_queue(); + } return true; } From cb4017f22be4ac1c9b9a7a3da8488b29374057fb Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 22:56:15 +0200 Subject: [PATCH 15/25] priority --- cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 287951a..4d7f603 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -383,8 +383,8 @@ bool cpu::execute_any_pending_interrupt() uint8_t current_level = getPSW_spl(); // uint8_t start_level = current_level <= 3 ? 0 : current_level + 1; - // uint8_t start_level = current_level + 1; - uint8_t start_level = current_level; + // PDP-11_70_Handbook_1977-78.pdf page 1-5, "processor priority" + uint8_t start_level = current_level + 1; for(uint8_t i=0; i < 8; i++) { auto interrupts = queued_interrupts.find(i); From 3892e752c583f871e8dc1ca66e21dbaff5390760 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Sun, 21 Apr 2024 23:02:46 +0200 Subject: [PATCH 16/25] if there are more interrupts waiting, set the trap delay to something sane --- cpu.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu.cpp b/cpu.cpp index 4d7f603..e7800f3 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -421,6 +421,9 @@ bool cpu::execute_any_pending_interrupt() } } + if (any_queued_interrupts && trap_delay.has_value() == false) + trap_delay = initial_trap_delay; + #if defined(BUILD_FOR_RP2040) xSemaphoreGive(qi_lock); #endif From 6b05fc87c2abcd40c67345093343376b8a514722 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 00:03:35 +0200 Subject: [PATCH 17/25] logging & handle(?) accessing of a non-connected disk device --- rl02.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/rl02.cpp b/rl02.cpp index 8aa8f6d..a11a03e 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -89,7 +89,7 @@ uint16_t rl02::readWord(const uint16_t addr) value = registers[reg]; } - DOLOG(debug, false, "RL02 read \"%s\"/%o: %06o", regnames[reg], addr, value); + DOLOG(debug, false, "RL02: read \"%s\"/%o: %06o", regnames[reg], addr, value); return value; } @@ -137,7 +137,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) { const int reg = (addr - RL02_BASE) / 2; - DOLOG(debug, false, "RL02 write \"%s\"/%06o: %06o", regnames[reg], addr, v); + DOLOG(debug, false, "RL02: write \"%s\"/%06o: %06o", regnames[reg], addr, v); registers[reg] = v; @@ -146,15 +146,22 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) const bool do_exec = !(v & 128); - DOLOG(debug, false, "RL02 set command %d, exec: %d (%s)", command, do_exec, commands[command]); - int device = (v >> 8) & 3; + DOLOG(debug, false, "RL02: device %d, set command %d, exec: %d (%s)", device, command, do_exec, commands[command]); + bool do_int = false; *disk_read_acitivity = true; - if (command == 2) { // get status + if (size_t(device) >= fhs.size()) { + DOLOG(info, false, "RL02: PDP11/70 is accessing a not-attached virtual disk %d", device); + + registers[(RL02_CSR - RL02_BASE) / 2] |= (1 << 10) | (1 << 15); + + do_int = true; + } + else if (command == 2) { // get status mpr[0] = 5 /* lock on */ | (1 << 3) /* brush home */ | (1 << 4) /* heads over disk */ | (head << 6) | (1 << 7) /* RL02 */; mpr[1] = mpr[0]; } @@ -170,7 +177,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) else if (new_track >= rl02_track_count) new_track = rl02_track_count - 1; - DOLOG(debug, false, "RL02: seek from cylinder %d to %d (distance: %d, DAR: %06o)", track, new_track, cylinder_count, temp); + DOLOG(debug, false, "RL02: device %d, seek from cylinder %d to %d (distance: %d, DAR: %06o)", device, track, new_track, cylinder_count, temp); track = new_track; // update_dar(); @@ -182,7 +189,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) mpr[1] = 0; // zero mpr[2] = 0; // TODO: CRC - DOLOG(debug, false, "RL02 read header [cylinder: %d, head: %d, sector: %d] %06o", track, head, sector, mpr[0]); + DOLOG(debug, false, "RL02: device %d, read header [cylinder: %d, head: %d, sector: %d] %06o", device, track, head, sector, mpr[0]); do_int = true; } @@ -201,13 +208,13 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) uint32_t temp_disk_offset = calc_offset(); - DOLOG(debug, false, "RL02 write %d bytes (dec) to %d (dec) from %06o (oct) [cylinder: %d, head: %d, sector: %d]", count, temp_disk_offset, memory_address, track, head, sector); + DOLOG(debug, false, "RL02: device %d, write %d bytes (dec) to %d (dec) from %06o (oct) [cylinder: %d, head: %d, sector: %d]", device, count, temp_disk_offset, memory_address, track, head, sector); while(count > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer)) { - DOLOG(ll_error, true, "RL02 write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); + DOLOG(ll_error, true, "RL02: write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } @@ -247,7 +254,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) uint32_t temp_disk_offset = calc_offset(); - DOLOG(debug, false, "RL02 read %d bytes (dec) from %d (dec) to %06o (oct) [cylinder: %d, head: %d, sector: %d]", count, temp_disk_offset, memory_address, track, head, sector); + DOLOG(debug, false, "RL02: device %d, read %d bytes (dec) from %d (dec) to %06o (oct) [cylinder: %d, head: %d, sector: %d]", device, count, temp_disk_offset, memory_address, track, head, sector); // update_dar(); @@ -255,7 +262,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); if (!fhs.at(device)->read(temp_disk_offset, cur, xfer_buffer)) { - DOLOG(ll_error, true, "RL02 read error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); + DOLOG(ll_error, true, "RL02: read error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; } @@ -296,7 +303,7 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) if (do_int) { if (registers[(RL02_CSR - RL02_BASE) / 2] & 64) { // interrupt enable? - DOLOG(debug, false, "RL02 triggering interrupt"); + DOLOG(debug, false, "RL02: triggering interrupt"); b->getCpu()->queue_interrupt(5, 0160); } From cf9a19e49dd687ea0366f5b40e42299b9e433336 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 08:50:29 +0200 Subject: [PATCH 18/25] termination clean-up --- main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index d2161aa..56ca2fd 100644 --- a/main.cpp +++ b/main.cpp @@ -622,11 +622,11 @@ int main(int argc, char *argv[]) delete metrics_thread; } + delete lf; + delete cnsl; delete b; - delete lf; - return 0; } From acb1e286425bb07f43bc236980411ca98a544125 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 09:19:29 +0200 Subject: [PATCH 19/25] ASH clean-up --- cpu.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index e7800f3..207e6b7 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -830,15 +830,13 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } else { int shift_n = 64 - shift; - uint32_t sign_extend = sign ? 0x8000 : 0; + uint64_t value = (0xffffffff00000000ll | R) >> shift_n; - for(int i=0; i>= 1; - R |= sign_extend; - } + setPSW_c(R >> (shift_n - 1)); setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word)); + + R = value; } R &= 0xffff; From b7a1edec8137c6ff92f987b93e59faec3d53cc3f Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 09:30:12 +0200 Subject: [PATCH 20/25] date --- log.cpp | 2 +- log.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/log.cpp b/log.cpp index 38bc47c..a8053a5 100644 --- a/log.cpp +++ b/log.cpp @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #include diff --git a/log.h b/log.h index 88172c0..b211aa3 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #pragma once From cbe5eaca18d0477d26e363325c420c0b683f9567 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 09:32:50 +0200 Subject: [PATCH 21/25] [[unlikely]] --- ESP32/platformio.ini | 8 ++++---- bus.cpp | 2 ++ log.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ESP32/platformio.ini b/ESP32/platformio.ini index 3cb932b..3d868e6 100644 --- a/ESP32/platformio.ini +++ b/ESP32/platformio.ini @@ -17,8 +17,8 @@ board_build.filesystem = littlefs lib_deps = greiman/SdFat@^2.1.2 adafruit/Adafruit NeoPixel bblanchon/ArduinoJson@^6.19.4 -build_flags = -std=gnu++17 -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 -build_unflags = -std=gnu++11 +build_flags = -std=gnu++2a -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 +build_unflags = -std=gnu++11 -std=gnu++17 extra_scripts = pre:prepare.py [env:SHA2017-badge] @@ -32,6 +32,6 @@ board_build.filesystem = littlefs lib_deps = greiman/SdFat@^2.1.2 adafruit/Adafruit NeoPixel bblanchon/ArduinoJson@^6.19.4 -build_flags = -std=gnu++17 -DESP32=1 -DSHA2017 -ggdb3 -D_GLIBCXX_USE_C99 -ISHAdisplay/Arduino/libraries/epd2in9-badge -ISHAdisplay/Arduino/libraries/epdpaint -ISHAdisplay/components/epaper-29-dke -build_unflags = -std=gnu++11 +build_flags = -std=gnu++2a -DESP32=1 -DSHA2017 -ggdb3 -D_GLIBCXX_USE_C99 -ISHAdisplay/Arduino/libraries/epd2in9-badge -ISHAdisplay/Arduino/libraries/epdpaint -ISHAdisplay/components/epaper-29-dke +build_unflags = -std=gnu++11 -std=gnu++17 upload_protocol = esptool diff --git a/bus.cpp b/bus.cpp index 63cb4f6..ef194a2 100644 --- a/bus.cpp +++ b/bus.cpp @@ -626,6 +626,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c uint32_t io_base = get_io_base(); bool is_io = m_offset >= io_base; + [[unlikely]] if (trap_on_failure) { { auto rc = get_trap_action(run_mode, d, apf, is_write); @@ -673,6 +674,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c } } + [[unlikely]] if (m_offset >= n_pages * 8192l && !is_io) { DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192l); DOLOG(debug, false, "TRAP(04) (throw 6) on address %06o", a); diff --git a/log.h b/log.h index b211aa3..c58e9f5 100644 --- a/log.h +++ b/log.h @@ -24,6 +24,7 @@ void dolog(const log_level_t ll, const char *fmt, ...); #define DOLOG(ll, always, fmt, ...) do { \ extern log_level_t log_level_file, log_level_screen; \ \ + [[unlikely]] \ if (always || ll <= log_level_file || ll <= log_level_screen) \ dolog(ll, fmt, ##__VA_ARGS__); \ } while(0) From 423a2cd43444b889cfca6dddf23b2cc5f6ed18a7 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 13:52:40 +0200 Subject: [PATCH 22/25] comment --- cpu.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 207e6b7..e37477f 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -806,6 +806,8 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) addToMMR1(g_dst); uint16_t shift = g_dst.value.value() & 077; + DOLOG(debug, true, "shift %06o with %d", R, shift); + bool sign = SIGN(R, wm_word); if (shift == 0) { @@ -830,13 +832,14 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } else { int shift_n = 64 - shift; - uint64_t value = (0xffffffff00000000ll | R) >> shift_n; + uint16_t new_value = (uint64_t(0xffffffff0000) | R) >> (shift_n - 1); - setPSW_c(R >> (shift_n - 1)); + setPSW_c(new_value & 1); + new_value >>= 1; + + R = new_value; setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word)); - - R = value; } R &= 0xffff; @@ -2065,7 +2068,7 @@ std::map > cpu::disassemble(const uint16_t } if (text.empty() && name.empty() == false) - text = name + space + src_text + comma + dst_text.operand; + text = name + space + src_text + comma + dst_text.operand; // TODO: swap for ASH, ASHC if (text.empty() == false && next_word != -1) instruction_words.push_back(next_word); From f0bb29fed39c4629ee4db51e44d70ccd0146c9d8 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 14:08:13 +0200 Subject: [PATCH 23/25] ASH --- cpu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index e37477f..5c632d2 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -832,8 +832,9 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) } else { int shift_n = 64 - shift; - uint16_t new_value = (uint64_t(0xffffffff0000) | R) >> (shift_n - 1); + uint16_t new_value = (sign ? uint64_t(0xffffffff0000) : 0) | R; + new_value >>= shift_n - 1; setPSW_c(new_value & 1); new_value >>= 1; @@ -881,8 +882,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) int shift_n = (64 - shift) - 1; // extend sign-bit - if (sign) // convert to unsigned 64b int & extend sign - { + if (sign) { // convert to unsigned 64b int & extend sign R0R1 = (uint64_t(R0R1) | 0xffffffff00000000ll) >> shift_n; setPSW_c(R0R1 & 1); From 046dc7d5791b42aa4bd84988dccd357a83a4f0c4 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 15:45:07 +0200 Subject: [PATCH 24/25] ASH --- cpu.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cpu.cpp b/cpu.cpp index 5c632d2..1a1da2c 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -831,6 +831,15 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word)); } else { + int shift_n = 64 - shift; + uint32_t sign_extend = sign ? 0x8000 : 0; + + for(int i=0; i>= 1; + R |= sign_extend; + } +/* int shift_n = 64 - shift; uint16_t new_value = (sign ? uint64_t(0xffffffff0000) : 0) | R; @@ -839,7 +848,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) new_value >>= 1; R = new_value; - +*/ setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word)); } From 967136108526e4e71f372cce5f2a706fce2f2cff Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 20:29:28 +0200 Subject: [PATCH 25/25] does not work --- cpu.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 1a1da2c..8ae9891 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -839,16 +839,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr) R >>= 1; R |= sign_extend; } -/* - int shift_n = 64 - shift; - uint16_t new_value = (sign ? uint64_t(0xffffffff0000) : 0) | R; - new_value >>= shift_n - 1; - setPSW_c(new_value & 1); - new_value >>= 1; - - R = new_value; -*/ setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word)); }