Merge pull request #60 from irmen/master

Added irq() and nmi() to the MPU
This commit is contained in:
Mike Naberezny 2020-10-22 18:41:51 -07:00 committed by GitHub
commit eaa2398cec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 0 deletions

View File

@ -9,6 +9,10 @@
Py65 now requires Python 3.4 or later. On Python 2, Py65 now requires
Python 2.7.
- added ``irq()`` and ``nmi()`` methods to the ``MPU`` class, so that
interrupts can be simulated. Patch by Irmen de Jong.
1.1.0 (2018-07-01)
------------------

View File

@ -74,6 +74,28 @@ class MPU:
self.p = self.BREAK | self.UNUSED
self.processorCycles = 0
def irq(self):
# triggers a normal IRQ
# this is very similar to the BRK instruction
if self.p & self.INTERRUPT:
return
self.stPushWord(self.pc)
self.p &= ~self.BREAK
self.stPush(self.p | self.UNUSED)
self.p |= self.INTERRUPT
self.pc = self.WordAt(self.IRQ)
self.processorCycles += 7
def nmi(self):
# triggers a NMI IRQ in the processor
# this is very similar to the BRK instruction
self.stPushWord(self.pc)
self.p &= ~self.BREAK
self.stPush(self.p | self.UNUSED)
self.p |= self.INTERRUPT
self.pc = self.WordAt(self.NMI)
self.processorCycles += 7
# Helpers for addressing modes
def ByteAt(self, addr):

View File

@ -1905,6 +1905,38 @@ class Common6502Tests:
self.assertEqual(mpu.BREAK | mpu.UNUSED | mpu.INTERRUPT, mpu.p)
# IRQ and NMI handling (very similar to BRK)
def test_irq_pushes_pc_and_correct_status_then_sets_pc_to_irq_vector(self):
mpu = self._make_mpu()
mpu.p = mpu.UNUSED
self._write(mpu.memory, 0xFFFA, (0x88, 0x77))
self._write(mpu.memory, 0xFFFE, (0xCD, 0xAB))
mpu.pc = 0xC123
mpu.irq()
self.assertEqual(0xABCD, mpu.pc)
self.assertEqual(0xC1, mpu.memory[0x1FF]) # PCH
self.assertEqual(0x23, mpu.memory[0x1FE]) # PCL
self.assertEqual(mpu.UNUSED, mpu.memory[0x1FD]) # Status
self.assertEqual(0xFC, mpu.sp)
self.assertEqual(mpu.UNUSED | mpu.INTERRUPT, mpu.p)
self.assertEqual(7, mpu.processorCycles)
def test_nmi_pushes_pc_and_correct_status_then_sets_pc_to_nmi_vector(self):
mpu = self._make_mpu()
mpu.p = mpu.UNUSED
self._write(mpu.memory, 0xFFFA, (0x88, 0x77))
self._write(mpu.memory, 0xFFFE, (0xCD, 0xAB))
mpu.pc = 0xC123
mpu.nmi()
self.assertEqual(0x7788, mpu.pc)
self.assertEqual(0xC1, mpu.memory[0x1FF]) # PCH
self.assertEqual(0x23, mpu.memory[0x1FE]) # PCL
self.assertEqual(mpu.UNUSED, mpu.memory[0x1FD]) # Status
self.assertEqual(0xFC, mpu.sp)
self.assertEqual(mpu.UNUSED | mpu.INTERRUPT, mpu.p)
self.assertEqual(7, mpu.processorCycles)
# BVC
def test_bvc_overflow_clear_branches_relative_forward(self):