From 0f32d9fca9ee58127461ac72b2669318c20156f7 Mon Sep 17 00:00:00 2001 From: outofmbufs Date: Wed, 9 Apr 2025 22:16:56 -0500 Subject: [PATCH 1/2] Make @property psw use pswfields/dict methods --- machine.py | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/machine.py b/machine.py index 492fce6..fff042c 100644 --- a/machine.py +++ b/machine.py @@ -921,28 +921,14 @@ class PDP1170(PDP11): @property def psw(self): - # NOTE: to simplify/accelerate condition code handling during - # instructions, the NZVC bits are broken out into individual - # attributes, and are stored as truthy/falsey not necessarily - # 1/0 or True/False. - - # so, to reconstitute NZVC bits ... - NZVC = 0 - if self.psw_n: - NZVC |= 0o10 - if self.psw_z: - NZVC |= 0o04 - if self.psw_v: - NZVC |= 0o02 - if self.psw_c: - NZVC |= 0o01 - - return (((self.psw_curmode & 3) << 14) | - ((self.psw_prevmode & 3) << 12) | - ((self.psw_regset & 1) << 11) | - ((self.psw_pri & 7) << 5) | - ((self.psw_trap & 1) << 4) | - NZVC) + pswd = {attr: getattr(self, 'psw_' + attr) + for attr in self._pswfields} + # the various 1-bit attributes are stored as "truthy/falsy" + # in the psw_foo attributes but need to be normalized to 1/0 here + for a, v in pswd.items(): + if self._pswfields[a][1] == 1: + pswd[a] = bool(v) + return self._dict2psw(pswd) # Write the ENTIRE processor word, without any privilege enforcement. # The lack of privilege enforcement is necessary because, e.g., that's From 0ad6fec19b6f3615d8d6fb9b8299bca9bea967a7 Mon Sep 17 00:00:00 2001 From: outofmbufs Date: Thu, 10 Apr 2025 12:44:25 -0500 Subject: [PATCH 2/2] test_psw --- pdptests.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/pdptests.py b/pdptests.py index 9753e96..03c886d 100644 --- a/pdptests.py +++ b/pdptests.py @@ -356,6 +356,69 @@ class TestMethods(unittest.TestCase): self.check16(p) self.assertEqual(p.r[0], r0result) + def test_psw(self): + p = self.make_pdp() + + # the test is assembled from: + # .org 4000 + # halt = 0 + # mov $20000,sp / establish a stack on general principles + # clr r0 / clears all PSW bits except Z + # inc r0 / clears Z + # sen + # bmi 1f + # mov $66610,r2 + # halt + # 1: cln + # bpl 1f + # mov $66650,r2 + # halt + # 1: clr r0 + # inc r0 + # sez + # beq 1f + # mov $66604,r2 + # halt + # 1: clz + # bne 1f + # mov $66644,r2 + # halt + # 1: clr r0 + # inc r0 + # sev + # bvs 1f + # mov $66602,r2 + # halt + # 1: clv + # bvc 1f + # mov $66642,r2 + # halt + # 1: clr r0 + # inc r0 + # sec + # bcs 1f + # mov $66601,r2 + # halt + # 1: clc + # bcc 1f + # mov $66641,r2 + # halt + # 1: mov $77, r2 + # halt + + insts = [0o12706, 0o20000, 0o5000, 0o5200, 0o270, 0o100403, 0o12702, + 0o66610, 0o0, 0o250, 0o100003, 0o12702, 0o66650, 0o0, + 0o5000, 0o5200, 0o264, 0o1403, 0o12702, 0o66604, 0o0, + 0o244, 0o1003, 0o12702, 0o66644, 0o0, 0o5000, 0o5200, 0o262, + 0o102403, 0o12702, 0o66602, 0o0, 0o242, 0o102003, 0o12702, + 0o66642, 0o0, 0o5000, 0o5200, 0o261, 0o103403, 0o12702, + 0o66601, 0o0, 0o241, 0o103003, 0o12702, 0o66641, 0o0, + 0o12702, 0o77, 0o0] + + self.loadphysmem(p, insts, 0o4000) + p.run(pc=0o4000) + self.assertEqual(p.r[2], 0o77) + def test_add_sub(self): p = self.make_pdp()