From 9a18221229322bd7d298ea0d6d9b20f0de94e687 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 31 Mar 2022 23:46:43 +0200 Subject: [PATCH] RTI/RTT cannot set all PSW bits (the upper 5) --- CMakeLists.txt | 4 ++-- bus.cpp | 4 ++-- cpu.cpp | 18 +++++++++++++----- cpu.h | 2 +- tests.cpp | 18 +++++++++--------- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 439003a..c01ead7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ add_executable( include(CheckIPOSupported) check_ipo_supported(RESULT supported) -#set(CMAKE_BUILD_TYPE RelWithDebInfo) -set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_BUILD_TYPE RelWithDebInfo) +#set(CMAKE_BUILD_TYPE Debug) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) diff --git a/bus.cpp b/bus.cpp index 25a7ed7..1fa56b3 100644 --- a/bus.cpp +++ b/bus.cpp @@ -375,7 +375,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons else vtemp = (vtemp & 0xff00) | value; - c -> setPSW(vtemp); + c -> setPSW(vtemp, false); return value; } @@ -396,7 +396,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons else { if (a == 0177776) { // PSW D(fprintf(stderr, "write PSW %o\n", value);) - c -> setPSW(value); + c -> setPSW(value, false); return value; } diff --git a/cpu.cpp b/cpu.cpp index 9a36081..75e3dcc 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -187,9 +187,17 @@ int cpu::getPSW_spl() const return (psw >> 5) & 7; } -void cpu::setPSW(const uint16_t v) +void cpu::setPSW(const uint16_t v, const bool limited) { - psw = v; + if (limited) { + psw |= v & 0174000; // current & previous mode can only be increased, 11 can only be set + + psw = 0174000; // retain upper 5 bit + psw |= v & ~0174000; + } + else { + psw = v; + } } void cpu::check_queued_interrupts() @@ -1298,7 +1306,7 @@ bool cpu::misc_operations(const uint16_t instr) case 0b0000000000000010: // RTI setPC(popStack()); - setPSW(popStack()); + setPSW(popStack(), !!(getPSW() >> 12)); return true; case 0b0000000000000011: // BPT @@ -1311,7 +1319,7 @@ bool cpu::misc_operations(const uint16_t instr) case 0b0000000000000110: // RTT setPC(popStack()); - setPSW(popStack()); + setPSW(popStack(), !!(getPSW() >> 12)); return true; case 0b0000000000000111: // MFPT @@ -1411,7 +1419,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl) if (new_ipl != -1) new_psw = (new_psw & ~0xe0) | (new_ipl << 5); new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode' - setPSW(new_psw); + setPSW(new_psw, false); pushStack(before_psw); pushStack(before_pc); diff --git a/cpu.h b/cpu.h index ec89a7a..9cf8493 100644 --- a/cpu.h +++ b/cpu.h @@ -95,7 +95,7 @@ public: void setBitPSW(const int bit, const bool v); uint16_t getPSW() const { return psw; } - void setPSW(const uint16_t v); + void setPSW(const uint16_t v, const bool limited); uint16_t getStackLimitRegister() { return stackLimitRegister; } void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; } diff --git a/tests.cpp b/tests.cpp index f2142a6..1f2d071 100644 --- a/tests.cpp +++ b/tests.cpp @@ -60,11 +60,11 @@ void test__registers(cpu *const c) assert(c -> getStackPointer(0) == 3); assert(c -> getStackPointer(1) == 4); assert(c -> getStackPointer(3) == 5); - c -> setPSW(0); + c -> setPSW(0, false); assert(c -> getRegister(6) == 3); - c -> setPSW(0b0100000000000000); + c -> setPSW(0b0100000000000000, false); assert(c -> getRegister(6) == 4); - c -> setPSW(0b1100000000000000); + c -> setPSW(0b1100000000000000, false); assert(c -> getRegister(6) == 5); // PSW @@ -1112,7 +1112,7 @@ void test_bic(cpu *const c) c -> reset(); c -> setRegister(0, 01234); c -> setRegister(1, 01111); - c -> setPSW(15); + c -> setPSW(15, false); b -> writeWord(0, 0040001); // bic r0,r1 do_test(c, 1); @@ -2013,17 +2013,17 @@ void test_mfp(cpu *const c) fprintf(stderr, "---\n"); b -> write(0100, false, 07711, false); b -> writeWord(0177640, 0); // setup memory kernel - c -> setPSW(3 << 14); + c -> setPSW(3 << 14, false); // write a word 0123 to 0100 in current mode which is user fprintf(stderr, "===\n"); b -> write(0100, false, 0123, false); // go back to kernel mode - c -> setPSW(0 << 14); + c -> setPSW(0 << 14, false); fprintf(stderr, "+++\n"); c -> setRegister(0, 0100); c -> setRegister(6, 02000); - c -> setPSW((0 << 14) | (3 << 12)); + c -> setPSW((0 << 14) | (3 << 12), false); b -> writeWord(0, 006510); // MFPD (R0) do_test(c, 1); @@ -2031,11 +2031,11 @@ void test_mfp(cpu *const c) assert(c -> getRegister(6) == 01776); // FIXME flags - c -> setPSW(3 << 14); + c -> setPSW(3 << 14, false); //fprintf(stderr, "%o == 07711\n", b -> read(0100, false, false)); fflush(NULL); assert(b -> read(0100, false, false) == 0123); - c -> setPSW(0 << 14); + c -> setPSW(0 << 14, false); fprintf(stderr, "%o == 0123\n", b -> read(0100, false, false)); fflush(NULL); assert(b -> read(0100, false, false) == 07711); }