Skip to content

Commit 8b46d49

Browse files
committed
Fix "mov1 cy,sfr.bit" instructions clobbering PSW
1 parent 6a93f04 commit 8b46d49

3 files changed

Lines changed: 38 additions & 1 deletion

File tree

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
- Added cycle counting for all instructions.
55

6+
- Fixed a bug where the "mov1 cy,sfr.bit" instructions would
7+
overwrite the PSW with register A.
8+
69
1.0.0 (2020-02-15)
710
------------------
811

k0emu/processor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1746,7 +1746,7 @@ def _opcode_0x71_0x0c_to_0x7c_mov1(self, opcode2):
17461746
bit = _bit(opcode2)
17471747
address = self._consume_sfr()
17481748
src = self._bus_read(address)
1749-
dest = self.read_gp_reg(Registers.A)
1749+
dest = self.read_psw()
17501750
result = self._operation_mov1(src, bit, dest, 0)
17511751
self.write_psw(result)
17521752
self._inst_cycles +=2

k0emu/tests/test_processor.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,40 @@ def test_71_7c_mov1_cy_sfr_bit7(self):
36083608
self.assertEqual(proc.pc, len(code))
36093609
self.assertEqual(proc.read_psw(), Flags.CY)
36103610

3611+
# mov1 cy,sfr.bit preserves other PSW bits
3612+
def test_71_0c_mov1_cy_sfr_preserves_psw(self):
3613+
proc, _ = _make_processor()
3614+
code = [0x71, 0x2c, 0xfe] # mov1 cy,0fffeh.2
3615+
proc.write_memory_bytes(0, code)
3616+
proc.write_memory(0xfffe, 0x04) # bit 2 set
3617+
proc.write_psw(Flags.IE | Flags.Z) # set IE and Z
3618+
proc.write_gp_reg(Registers.A, 0x00) # A=0 (different from PSW)
3619+
proc.step()
3620+
# CY should be set, IE and Z should be preserved
3621+
self.assertEqual(proc.read_psw(), Flags.IE | Flags.Z | Flags.CY)
3622+
3623+
def test_71_0c_mov1_cy_sfr_clears_cy(self):
3624+
proc, _ = _make_processor()
3625+
code = [0x71, 0x2c, 0xfe] # mov1 cy,0fffeh.2
3626+
proc.write_memory_bytes(0, code)
3627+
proc.write_memory(0xfffe, 0x00) # bit 2 clear
3628+
proc.write_psw(Flags.IE | Flags.CY) # IE set, CY set
3629+
proc.write_gp_reg(Registers.A, 0xFF) # A=FF (different from PSW)
3630+
proc.step()
3631+
# CY should be cleared, IE should be preserved, A should not affect PSW
3632+
self.assertEqual(proc.read_psw(), Flags.IE)
3633+
3634+
def test_71_0c_mov1_cy_sfr_does_not_use_register_a(self):
3635+
proc, _ = _make_processor()
3636+
code = [0x71, 0x0c, 0xfe] # mov1 cy,0fffeh.0
3637+
proc.write_memory_bytes(0, code)
3638+
proc.write_memory(0xfffe, 0x01) # bit 0 set
3639+
proc.write_psw(Flags.IE) # PSW = 0x80
3640+
proc.write_gp_reg(Registers.A, 0x20) # A = 0x20 (RBS1 bit)
3641+
proc.step()
3642+
# Should set CY and preserve IE. Must NOT set RBS1 from A.
3643+
self.assertEqual(proc.read_psw(), Flags.IE | Flags.CY)
3644+
36113645
# mov1 0fffeh.0,cy ;71 09 fe sfr
36123646
def test_71_09_mov1_sfr_bit_0_cy(self):
36133647
proc, _ = _make_processor()

0 commit comments

Comments
 (0)