improved implementation of indirect bug across page boundaries including indexed indirects as well
This commit is contained in:
parent
044c86325c
commit
44099ae4f2
16
applepy.py
16
applepy.py
|
@ -39,6 +39,12 @@ class Memory:
|
|||
def read_word(self, address):
|
||||
return self.read_byte(address) + (self.read_byte(address + 1) << 8)
|
||||
|
||||
def read_word_bug(self, address):
|
||||
if address % 0x100 == 0xFF:
|
||||
return self.read_byte(address) + (self.read_byte(address & 0xFF00) << 8)
|
||||
else:
|
||||
return self.read_word(address)
|
||||
|
||||
def write_screen(self, address, value):
|
||||
base = address - 0x400
|
||||
hi, lo = divmod(base, 0x80)
|
||||
|
@ -366,17 +372,13 @@ class CPU:
|
|||
return (self.zero_page_mode() + signed(self.y_index)) % 0x100
|
||||
|
||||
def indirect_mode(self):
|
||||
address = self.absolute_mode()
|
||||
hi = address + 1
|
||||
# emulate a known bug in 6502
|
||||
hi = (address & 0xFF00) + (((address & 0xFF) + 1) & 0xFF)
|
||||
return self.memory.read_byte(address) + (self.memory.read_byte(hi) << 8)
|
||||
return self.memory.read_word_bug(self.absolute_mode())
|
||||
|
||||
def indirect_x_mode(self):
|
||||
return self.memory.read_word((self.read_pc_byte() + signed(self.x_index)) % 0x100)
|
||||
return self.memory.read_word_bug((self.read_pc_byte() + signed(self.x_index)) % 0x100)
|
||||
|
||||
def indirect_y_mode(self):
|
||||
return self.memory.read_word(self.read_pc_byte()) + signed(self.y_index)
|
||||
return self.memory.read_word_bug(self.read_pc_byte()) + signed(self.y_index)
|
||||
|
||||
def relative_mode(self):
|
||||
pc = self.get_pc()
|
||||
|
|
49
tests.py
49
tests.py
|
@ -949,5 +949,54 @@ class TestSystemFunctionOperations(unittest.TestCase):
|
|||
self.cpu.NOP()
|
||||
|
||||
|
||||
class Test6502Bugs(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.memory = Memory(0x10000)
|
||||
self.cpu = CPU(self.memory)
|
||||
|
||||
def test_zero_page_x(self):
|
||||
self.cpu.x_index = 0x01
|
||||
self.memory.load(0x1000, [0x00, 0x7F, 0xFF])
|
||||
self.cpu.program_counter = 0x1000
|
||||
self.assertEqual(self.cpu.zero_page_x_mode(), 0x01)
|
||||
self.assertEqual(self.cpu.zero_page_x_mode(), 0x80)
|
||||
self.assertEqual(self.cpu.zero_page_x_mode(), 0x00)
|
||||
|
||||
def test_indirect(self):
|
||||
self.memory.load(0x20, [0x00, 0x20])
|
||||
self.memory.load(0x00, [0x12])
|
||||
self.memory.load(0xFF, [0x34])
|
||||
self.memory.load(0x100, [0x56])
|
||||
self.memory.load(0x1000, [0x20, 0x20, 0xFF, 0xFF, 0x00, 0x45, 0x23])
|
||||
self.memory.load(0x2000, [0x05])
|
||||
self.memory.load(0x1234, [0x05])
|
||||
self.memory.load(0x2345, [0x00, 0xF0])
|
||||
|
||||
self.cpu.program_counter = 0x1000
|
||||
|
||||
self.cpu.x_index = 0x00
|
||||
self.cpu.LDA(self.cpu.indirect_x_mode())
|
||||
self.assertEqual(self.cpu.accumulator, 0x05)
|
||||
|
||||
self.cpu.y_index = 0x00
|
||||
self.cpu.LDA(self.cpu.indirect_y_mode())
|
||||
self.assertEqual(self.cpu.accumulator, 0x05)
|
||||
|
||||
self.cpu.y_index = 0x00
|
||||
self.cpu.LDA(self.cpu.indirect_y_mode())
|
||||
self.assertEqual(self.cpu.accumulator, 0x05)
|
||||
|
||||
self.cpu.x_index = 0x00
|
||||
self.cpu.LDA(self.cpu.indirect_x_mode())
|
||||
self.assertEqual(self.cpu.accumulator, 0x05)
|
||||
|
||||
self.cpu.x_index = 0xFF
|
||||
self.cpu.LDA(self.cpu.indirect_x_mode())
|
||||
self.assertEqual(self.cpu.accumulator, 0x05)
|
||||
|
||||
self.assertEqual(self.cpu.indirect_mode(), 0xF000)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue