1
0
mirror of https://github.com/mnaberez/py65.git synced 2025-01-16 18:33:00 +00:00

Remove page wrap bug from indexed indirect (X) on 65C02

This commit is contained in:
Mike Naberezny 2014-01-23 17:27:41 -08:00
parent ec311c879e
commit 3c6c631945
3 changed files with 293 additions and 38 deletions

View File

@ -26,11 +26,14 @@ class MPU(mpu6502.MPU):
# addressing modes
def IndirectXAddr(self):
return self.WordAt(self.ByteAt(self.pc) + self.x)
def ZeroPageIndirectAddr(self):
return self.WordAt(255 & (self.ByteAt(self.pc)))
return self.WordAt(self.ByteAt(self.pc))
def IndirectAbsXAddr(self):
return (self.WordAt(self.pc) + self.x) & self.addrMask
return self.addrMask & (self.WordAt(self.pc) + self.x)
def AccumulatorAddr(self):
return self.a

View File

@ -5636,17 +5636,38 @@ class MPUTests(unittest.TestCase, Common6502Tests):
mpu = self._make_mpu()
self.assertTrue("6502" in repr(mpu))
# LDA Zero Page, X-Indexed
# ADC Indirect, Indexed (X)
def test_lda_zp_x_indexed_page_wraps(self):
def test_adc_ind_indexed_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x00
mpu.a = 0x01
mpu.x = 0xFF
# $0000 LDA $80,X
self._write(mpu.memory, 0x0000, (0xB5, 0x80))
mpu.memory[0x007F] = 0x42
# $0000 ADC ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x61, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x01
mpu.memory[0xBBBB] = 0x02
mpu.step()
self.assertEqual(0x03, mpu.a)
# AND Indirect, Indexed (X)
def test_and_ind_indexed_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x42
mpu.x = 0xFF
# $0000 AND ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x21, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0
mpu.memory[0xBBBB] = 0xFF
mpu.step()
self.assertEqual(0x0002, mpu.pc)
self.assertEqual(0x42, mpu.a)
# BRK
@ -5671,9 +5692,75 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(mpu.BREAK, mpu.p & mpu.BREAK)
self.assertEqual(0, mpu.p & mpu.DECIMAL)
# CMP Indirect, Indexed (X)
def test_cmp_ind_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = 0
mpu.a = 0x42
mpu.x = 0xFF
# $0000 CMP ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xC1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x00
mpu.memory[0xBBBB] = 0x42
mpu.step()
self.assertEqual(mpu.ZERO, mpu.p & mpu.ZERO)
# EOR Indirect, Indexed (X)
def test_eor_ind_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = 0
mpu.a = 0xAA
mpu.x = 0xFF
# $0000 EOR ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x41, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x00
mpu.memory[0xBBBB] = 0xFF
mpu.step()
self.assertEqual(0x55, mpu.a)
# LDA Indirect, Indexed (X)
def test_lda_ind_indexed_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x00
mpu.x = 0xff
# $0000 LDA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xA1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x42
mpu.memory[0xBBBB] = 0xEF
mpu.step()
self.assertEqual(0xEF, mpu.a)
# LDA Zero Page, X-Indexed
def test_lda_zp_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x00
mpu.x = 0xFF
# $0000 LDA $80,X
self._write(mpu.memory, 0x0000, (0xB5, 0x80))
mpu.memory[0x007F] = 0x42
mpu.step()
self.assertEqual(0x0002, mpu.pc)
self.assertEqual(0x42, mpu.a)
# JMP Indirect
def test_jmp_jumps_to_address_with_page_wrap_bug(self):
def test_jmp_indirect_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.memory[0x00ff] = 0
# $0000 JMP ($00)
@ -5682,6 +5769,59 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(0x6c00, mpu.pc)
self.assertEqual(5, mpu.processorCycles)
# ORA Indirect, Indexed (X)
def test_ora_ind_indexed_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0
mpu.x = 0xFF
# $0000 ORA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x01, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0
mpu.memory[0xBBBB] = 0x42
mpu.step()
self.assertEqual(0x42, mpu.a)
# SBC Indirect, Indexed (X)
def test_sbc_ind_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = mpu.CARRY
mpu.a = 0x03
mpu.x = 0xFF
# $0000 SBC ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xE1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x01
mpu.memory[0xBBBB] = 0x02
mpu.step()
self.assertEqual(0x01, mpu.a)
# STA Indirect, Indexed (X)
def test_sta_ind_indexed_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x42
mpu.x = 0xFF
# $0000 STA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x81, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0
mpu.memory[0xBBBB] = 0
mpu.step()
self.assertEqual(0x00, mpu.memory[0xABCD])
self.assertEqual(0x42, mpu.memory[0xBBBB])
# Test page wrapping
def test_zeropage_indexed_ind_wrap(self):
@ -5694,34 +5834,6 @@ class MPUTests(unittest.TestCase, Common6502Tests):
mpu.step()
self.assertEqual(0x31, mpu.a)
def test_zeropage_indexed_wrap(self):
mpu = self._make_mpu()
mpu.x = 1
# $0000 LDA $FF,X
self._write(mpu.memory, 0, (0xb5, 0xff))
mpu.step()
self.assertEqual(0xb5, mpu.a)
def test_zeropage_ind_indexed_wrap(self):
mpu = self._make_mpu()
mpu.x = 0
mpu.memory[0xa100] = 0x31
mpu.memory[0xff] = 0
# $0000 LDA ($FF,X)
self._write(mpu.memory, 0, (0xa1, 0xff))
mpu.step()
self.assertEqual(0x31, mpu.a)
def test_zeropage_ind_indexed_index_wrap(self):
mpu = self._make_mpu()
mpu.x = 0xff
mpu.memory[0xa100] = 0x31
mpu.memory[0x00ff] = 0
# $0000 LDA ($00,X)
self._write(mpu.memory, 0, (0xa1, 0))
mpu.step()
self.assertEqual(0x31, mpu.a)
def _get_target_class(self):
return py65.devices.mpu6502.MPU

View File

@ -11,6 +11,23 @@ class MPUTests(unittest.TestCase, Common6502Tests):
mpu = self._make_mpu()
self.assertTrue('65C02' in repr(mpu))
# ADC Indirect, Indexed (X)
def test_adc_ind_indexed_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x01
mpu.x = 0xFF
# $0000 ADC ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x61, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x01
mpu.memory[0xBBBB] = 0x02
mpu.step()
self.assertEqual(0x02, mpu.a)
# ADC Zero Page, Indirect
def test_adc_bcd_off_zp_ind_carry_clear_in_accumulator_zeroes(self):
@ -149,6 +166,23 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(mpu.OVERFLOW, mpu.p & mpu.OVERFLOW)
self.assertEqual(0, mpu.p & mpu.ZERO)
# AND Indirect, Indexed (X)
def test_and_ind_indexed_x_does_not_have_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x42
mpu.x = 0xFF
# $0000 AND ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x21, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0xFF
mpu.memory[0xBBBB] = 0
mpu.step()
self.assertEqual(0x42, mpu.a)
# AND Zero Page, Indirect
def test_and_zp_ind_all_zeros_setting_zero_flag(self):
@ -442,6 +476,42 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(mpu.BREAK, mpu.p & mpu.BREAK)
self.assertEqual(0, mpu.p & mpu.DECIMAL)
# CMP Indirect, Indexed (X)
def test_cmp_ind_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = 0
mpu.a = 0x42
mpu.x = 0xFF
# $0000 CMP ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xC1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x42
mpu.memory[0xBBBB] = 0x00
mpu.step()
self.assertEqual(mpu.ZERO, mpu.p & mpu.ZERO)
# EOR Indirect, Indexed (X)
def test_eor_ind_x_does_not_have_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = 0
mpu.a = 0xAA
mpu.x = 0xFF
# $0000 EOR ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x41, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0xFF
mpu.memory[0xBBBB] = 0x00
mpu.step()
self.assertEqual(0x55, mpu.a)
# EOR Zero Page, Indirect
def test_eor_zp_ind_flips_bits_over_setting_z_flag(self):
@ -499,6 +569,23 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(0x1234, mpu.pc)
self.assertEqual(6, mpu.processorCycles)
# LDA Indirect, Indexed (X)
def test_lda_ind_indexed_x_does_not_have_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x00
mpu.x = 0xff
# $0000 LDA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xA1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x42
mpu.memory[0xBBBB] = 0xFF
mpu.step()
self.assertEqual(0x42, mpu.a)
# LDA Zero Page, Indirect
def test_lda_zp_ind_loads_a_sets_n_flag(self):
@ -531,6 +618,23 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(mpu.ZERO, mpu.p & mpu.ZERO)
self.assertEqual(0, mpu.p & mpu.NEGATIVE)
# ORA Indirect, Indexed (X)
def test_ora_ind_indexed_x_does_not_have_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0
mpu.x = 0xFF
# $0000 ORA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x01, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x42
mpu.memory[0xBBBB] = 0
mpu.step()
self.assertEqual(0x42, mpu.a)
# ORA Zero Page, Indirect
def test_ora_zp_ind_zeroes_or_zeros_sets_z_flag(self):
@ -806,6 +910,42 @@ class MPUTests(unittest.TestCase, Common6502Tests):
mpu.step()
self.assertEqual(expected, mpu.p)
# SBC Indirect, Indexed (X)
def test_sbc_ind_x_has_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.p = mpu.CARRY
mpu.a = 0x03
mpu.x = 0xFF
# $0000 SBC ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0xE1, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0x01
mpu.memory[0xBBBB] = 0x02
mpu.step()
self.assertEqual(0x02, mpu.a)
# STA Indirect, Indexed (X)
def test_sta_ind_indexed_x_does_not_have_page_wrap_bug(self):
mpu = self._make_mpu()
mpu.a = 0x42
mpu.x = 0xFF
# $0000 STA ($80,X)
# $007f Vector to $BBBB (read if page wrapped)
# $017f Vector to $ABCD (read if no page wrap)
self._write(mpu.memory, 0x0000, (0x81, 0x80))
self._write(mpu.memory, 0x007f, (0xBB, 0xBB))
self._write(mpu.memory, 0x017f, (0xCD, 0xAB))
mpu.memory[0xABCD] = 0
mpu.memory[0xBBBB] = 0
mpu.step()
self.assertEqual(0x42, mpu.memory[0xABCD])
self.assertEqual(0x00, mpu.memory[0xBBBB])
# STA Zero Page, Indirect
def test_sta_zp_ind_stores_a_leaves_a_and_n_flag_unchanged(self):