diff --git a/src/py65/devices/mpu65c02.py b/src/py65/devices/mpu65c02.py index f847fad..59dfac9 100644 --- a/src/py65/devices/mpu65c02.py +++ b/src/py65/devices/mpu65c02.py @@ -24,6 +24,10 @@ class MPU(NMOS6502): # operations + def opRMB(self, x, mask): + address = x() + self.memory[address] &= mask + def opSTZ(self, x): self.memory[x()] = 0x00 @@ -46,12 +50,27 @@ class MPU(NMOS6502): self.memory[address] = m & ~self.a # instructions + + @instruction(name="RMB0", mode="zpg", cycles=5) + def inst_0x07(self): + self.opRMB(self.ZeroPageAddr, 0xFE) + self.pc += 1 @instruction(name="ORA", mode="zpi", cycles=5) def inst_0x12(self): self.opORA(self.ZeroPageIndirectAddr) self.pc += 1 + @instruction(name="RMB1", mode="zpg", cycles=5) + def inst_0x17(self): + self.opRMB(self.ZeroPageAddr, 0xFD) + self.pc += 1 + + @instruction(name="RMB2", mode="zpg", cycles=5) + def inst_0x27(self): + self.opRMB(self.ZeroPageAddr, 0xFB) + self.pc += 1 + @instruction(name="AND", mode="zpi", cycles=5) def inst_0x32(self): self.opAND(self.ZeroPageIndirectAddr) @@ -62,11 +81,26 @@ class MPU(NMOS6502): self.opBIT(self.ZeroPageXAddr) self.pc += 1 + @instruction(name="RMB3", mode="zpg", cycles=5) + def inst_0x37(self): + self.opRMB(self.ZeroPageAddr, 0xF7) + self.pc += 1 + + @instruction(name="RMB4", mode="zpg", cycles=5) + def inst_0x47(self): + self.opRMB(self.ZeroPageAddr, 0xEF) + self.pc += 1 + @instruction(name="EOR", mode="zpi", cycles=5) def inst_0x52(self): self.opEOR(self.ZeroPageIndirectAddr) self.pc += 1 + @instruction(name="RMB5", mode="zpg", cycles=5) + def inst_0x57(self): + self.opRMB(self.ZeroPageAddr, 0xDF) + self.pc += 1 + @instruction(name="PHY", mode="imp", cycles=3) def inst_0x5a(self): self.stPush(self.y) @@ -76,6 +110,11 @@ class MPU(NMOS6502): self.opSTZ(self.ZeroPageAddr) self.pc += 1 + @instruction(name="RMB6", mode="zpg", cycles=5) + def inst_0x67(self): + self.opRMB(self.ZeroPageAddr, 0xBF) + self.pc += 1 + @instruction(name="ADC", mode="zpi", cycles=5) def inst_0x72(self): self.opADC(self.ZeroPageIndirectAddr) @@ -91,6 +130,11 @@ class MPU(NMOS6502): self.y = self.stPop() self.FlagsNZ(self.y) + @instruction(name="RMB7", mode="zpg", cycles=5) + def inst_0x77(self): + self.opRMB(self.ZeroPageAddr, 0x7F) + self.pc += 1 + @instruction(name="STA", mode="zpi", cycles=5) def inst_0x92(self): self.opSTA(self.ZeroPageIndirectAddr) diff --git a/src/py65/tests/devices/test_mpu65c02.py b/src/py65/tests/devices/test_mpu65c02.py index ed6c52c..5e3707c 100644 --- a/src/py65/tests/devices/test_mpu65c02.py +++ b/src/py65/tests/devices/test_mpu65c02.py @@ -343,6 +343,102 @@ class MPUTests(unittest.TestCase, Common6502Tests): self.assertEquals(0xFF, mpu.sp) self.assertEquals(4, mpu.processorCycles) + # RMB0 + + def test_rmb0_clears_bit_0_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x07, 0x43)) #=> RMB0 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11111110', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB1 + + def test_rmb1_clears_bit_1_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x17, 0x43)) #=> RMB1 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11111101', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB2 + + def test_rmb2_clears_bit_2_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x27, 0x43)) #=> RMB2 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11111011', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB3 + + def test_rmb3_clears_bit_3_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x37, 0x43)) #=> RMB3 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11110111', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB4 + + def test_rmb4_clears_bit_4_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x47, 0x43)) #=> RMB4 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11101111', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB5 + + def test_rmb5_clears_bit_5_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x57, 0x43)) #=> RMB5 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('11011111', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB6 + + def test_rmb6_clears_bit_6_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x67, 0x43)) #=> RMB6 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('10111111', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + + # RMB7 + + def test_rmb7_clears_bit_7_without_affecting_other_bits(self): + mpu = self._make_mpu() + mpu.memory[0x0043] = int('11111111',2) + self._write(mpu.memory, 0x0000, (0x77, 0x43)) #=> RMB7 $43 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(5, mpu.processorCycles) + expected = int('01111111', 2) + self.assertEquals(expected, mpu.memory[0x0043]) + # STA Zero Page, Indirect def test_sta_zp_indirect_stores_a_leaves_a_and_n_flag_unchanged(self):