RTI/RTT cannot set all PSW bits (the upper 5)

This commit is contained in:
folkert van heusden 2022-03-31 23:46:43 +02:00
parent 2dbab12373
commit 9a18221229
5 changed files with 27 additions and 19 deletions

View file

@ -28,8 +28,8 @@ add_executable(
include(CheckIPOSupported) include(CheckIPOSupported)
check_ipo_supported(RESULT supported) check_ipo_supported(RESULT supported)
#set(CMAKE_BUILD_TYPE RelWithDebInfo) set(CMAKE_BUILD_TYPE RelWithDebInfo)
set(CMAKE_BUILD_TYPE Debug) #set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE)

View file

@ -375,7 +375,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons
else else
vtemp = (vtemp & 0xff00) | value; vtemp = (vtemp & 0xff00) | value;
c -> setPSW(vtemp); c -> setPSW(vtemp, false);
return value; return value;
} }
@ -396,7 +396,7 @@ uint16_t bus::write(const uint16_t a, const bool word_mode, uint16_t value, cons
else { else {
if (a == 0177776) { // PSW if (a == 0177776) { // PSW
D(fprintf(stderr, "write PSW %o\n", value);) D(fprintf(stderr, "write PSW %o\n", value);)
c -> setPSW(value); c -> setPSW(value, false);
return value; return value;
} }

16
cpu.cpp
View file

@ -187,10 +187,18 @@ int cpu::getPSW_spl() const
return (psw >> 5) & 7; return (psw >> 5) & 7;
} }
void cpu::setPSW(const uint16_t v) void cpu::setPSW(const uint16_t v, const bool limited)
{ {
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; psw = v;
} }
}
void cpu::check_queued_interrupts() void cpu::check_queued_interrupts()
{ {
@ -1298,7 +1306,7 @@ bool cpu::misc_operations(const uint16_t instr)
case 0b0000000000000010: // RTI case 0b0000000000000010: // RTI
setPC(popStack()); setPC(popStack());
setPSW(popStack()); setPSW(popStack(), !!(getPSW() >> 12));
return true; return true;
case 0b0000000000000011: // BPT case 0b0000000000000011: // BPT
@ -1311,7 +1319,7 @@ bool cpu::misc_operations(const uint16_t instr)
case 0b0000000000000110: // RTT case 0b0000000000000110: // RTT
setPC(popStack()); setPC(popStack());
setPSW(popStack()); setPSW(popStack(), !!(getPSW() >> 12));
return true; return true;
case 0b0000000000000111: // MFPT case 0b0000000000000111: // MFPT
@ -1411,7 +1419,7 @@ void cpu::trap(const uint16_t vector, const int new_ipl)
if (new_ipl != -1) if (new_ipl != -1)
new_psw = (new_psw & ~0xe0) | (new_ipl << 5); new_psw = (new_psw & ~0xe0) | (new_ipl << 5);
new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode' new_psw |= (before_psw >> 2) & 030000; // apply new 'previous mode'
setPSW(new_psw); setPSW(new_psw, false);
pushStack(before_psw); pushStack(before_psw);
pushStack(before_pc); pushStack(before_pc);

2
cpu.h
View file

@ -95,7 +95,7 @@ public:
void setBitPSW(const int bit, const bool v); void setBitPSW(const int bit, const bool v);
uint16_t getPSW() const { return psw; } 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; } uint16_t getStackLimitRegister() { return stackLimitRegister; }
void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; } void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; }

View file

@ -60,11 +60,11 @@ void test__registers(cpu *const c)
assert(c -> getStackPointer(0) == 3); assert(c -> getStackPointer(0) == 3);
assert(c -> getStackPointer(1) == 4); assert(c -> getStackPointer(1) == 4);
assert(c -> getStackPointer(3) == 5); assert(c -> getStackPointer(3) == 5);
c -> setPSW(0); c -> setPSW(0, false);
assert(c -> getRegister(6) == 3); assert(c -> getRegister(6) == 3);
c -> setPSW(0b0100000000000000); c -> setPSW(0b0100000000000000, false);
assert(c -> getRegister(6) == 4); assert(c -> getRegister(6) == 4);
c -> setPSW(0b1100000000000000); c -> setPSW(0b1100000000000000, false);
assert(c -> getRegister(6) == 5); assert(c -> getRegister(6) == 5);
// PSW // PSW
@ -1112,7 +1112,7 @@ void test_bic(cpu *const c)
c -> reset(); c -> reset();
c -> setRegister(0, 01234); c -> setRegister(0, 01234);
c -> setRegister(1, 01111); c -> setRegister(1, 01111);
c -> setPSW(15); c -> setPSW(15, false);
b -> writeWord(0, 0040001); // bic r0,r1 b -> writeWord(0, 0040001); // bic r0,r1
do_test(c, 1); do_test(c, 1);
@ -2013,17 +2013,17 @@ void test_mfp(cpu *const c)
fprintf(stderr, "---\n"); fprintf(stderr, "---\n");
b -> write(0100, false, 07711, false); b -> write(0100, false, 07711, false);
b -> writeWord(0177640, 0); // setup memory kernel 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 // write a word 0123 to 0100 in current mode which is user
fprintf(stderr, "===\n"); fprintf(stderr, "===\n");
b -> write(0100, false, 0123, false); b -> write(0100, false, 0123, false);
// go back to kernel mode // go back to kernel mode
c -> setPSW(0 << 14); c -> setPSW(0 << 14, false);
fprintf(stderr, "+++\n"); fprintf(stderr, "+++\n");
c -> setRegister(0, 0100); c -> setRegister(0, 0100);
c -> setRegister(6, 02000); c -> setRegister(6, 02000);
c -> setPSW((0 << 14) | (3 << 12)); c -> setPSW((0 << 14) | (3 << 12), false);
b -> writeWord(0, 006510); // MFPD (R0) b -> writeWord(0, 006510); // MFPD (R0)
do_test(c, 1); do_test(c, 1);
@ -2031,11 +2031,11 @@ void test_mfp(cpu *const c)
assert(c -> getRegister(6) == 01776); assert(c -> getRegister(6) == 01776);
// FIXME flags // FIXME flags
c -> setPSW(3 << 14); c -> setPSW(3 << 14, false);
//fprintf(stderr, "%o == 07711\n", b -> read(0100, false, false)); fflush(NULL); //fprintf(stderr, "%o == 07711\n", b -> read(0100, false, false)); fflush(NULL);
assert(b -> read(0100, false, false) == 0123); 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); fprintf(stderr, "%o == 0123\n", b -> read(0100, false, false)); fflush(NULL);
assert(b -> read(0100, false, false) == 07711); assert(b -> read(0100, false, false) == 07711);
} }