1
0
mirror of https://github.com/mnaberez/py65.git synced 2024-06-06 20:29:34 +00:00

Add support for 65C02 opcode 0x7C: JMP (abs,X)

This commit is contained in:
Mike Naberezny 2012-11-22 15:23:28 -08:00
parent e48058e7c1
commit 65389218f4
7 changed files with 52 additions and 4 deletions

View File

@ -11,7 +11,9 @@
- Fixed a bug where the MPU status display would wrap unexpectedly
on some terminals.
- Added support for 65C02 opcode 0x89 (BIT immediate).
- Added support for 65C02 opcode 0x89: BIT #.
- Added support for 65C02 opcode 0x7C: JMP (abs,x).
0.13 (2012-11-15)

View File

@ -19,6 +19,8 @@ class Assembler:
re.compile(r'^\$00([0-9A-F]{2})$')],
['inx', # "($0012,X)
re.compile(r'^\(\$00([0-9A-F]{2}),X\)$')],
['iax', # "($1234,X)
re.compile(r'^\(\$([0-9A-F]{2})([0-9A-F]{2}),X\)$')],
['iny', # "($0012),Y"
re.compile(r'^\(\$00([0-9A-F]{2})\),Y$')],
['ind', # "($1234)"

View File

@ -29,6 +29,9 @@ class MPU(mpu6502.MPU):
def ZeroPageIndirectAddr(self):
return self.WordAt(255 & (self.ByteAt(self.pc)))
def IndirectAbsXAddr(self):
return (self.WordAt(self.pc) + self.x) & self.addrMask
def AccumulatorAddr(self):
return self.a
@ -261,6 +264,10 @@ class MPU(mpu6502.MPU):
def inst_0x3a(self):
self.opDECR(None)
@instruction(name="JMP", mode="iax", cycles=6)
def inst_0x7c(self):
self.pc = self.WordAt(self.IndirectAbsXAddr())
@instruction(name="BRA", mode="rel", cycles=1, extracycles=1)
def inst_0x80(self):
self.BranchRelAddr()

View File

@ -78,6 +78,13 @@ class Disassembler:
disasm += ' (%s,X)' % address_or_label
length = 2
elif addressing == 'iax':
address = self._mpu.WordAt(pc + 1)
address_or_label = self._address_parser.label_for(
address, '$' + self.addrFmt % address)
disasm += ' (%s,X)' % address_or_label
length = 3
elif addressing == 'rel':
opv = self._mpu.ByteAt(pc + 1)
targ = pc + 2

View File

@ -463,6 +463,19 @@ class MPUTests(unittest.TestCase, Common6502Tests):
self.assertEqual(mpu.NEGATIVE, mpu.p & mpu.NEGATIVE)
self.assertEqual(0, mpu.p & mpu.ZERO)
# JMP Indirect Absolute X-Indexed
def test_jmp_iax_jumps_to_address(self):
mpu = self._make_mpu()
mpu.x = 2
# $0000 JMP ($ABCD,X)
# $ABCF Vector to $1234
self._write(mpu.memory, 0x0000, (0x7C, 0xCD, 0xAB))
self._write(mpu.memory, 0xABCF, (0x34, 0x12))
mpu.step()
self.assertEqual(0x1234, mpu.pc)
self.assertEqual(6, mpu.processorCycles)
# LDA Zero Page, Indirect
def test_lda_zp_ind_loads_a_sets_n_flag(self):

View File

@ -470,8 +470,19 @@ class AssemblerTests(unittest.TestCase):
def dont_test_assembles_7b(self):
pass
def dont_test_assembles_7c(self):
pass
def test_assembles_7c_6502(self):
self.assertRaises(SyntaxError,
self.assemble, "JMP ($1234,X)")
def test_assembles_7c_65c02(self):
mpu = MPU65C02()
self.assertEqual([0x7c, 0x34, 0x12],
self.assemble('JMP ($1234,X)', 0x0000, mpu))
def test_assembles_07_65c02(self):
mpu = MPU65C02()
self.assertEqual([0x07, 0x42],
self.assemble('RMB0 $42', 0x0000, mpu))
def test_assembles_7d(self):
self.assertEqual([0x7d, 0x00, 0x44],

View File

@ -633,11 +633,17 @@ class DisassemblerTests(unittest.TestCase):
self.assertEqual(1, length)
self.assertEqual('???', disasm)
def test_disassembles_7c(self):
def test_disassembles_7c_6502(self):
length, disasm = self.disassemble([0x7c])
self.assertEqual(1, length)
self.assertEqual('???', disasm)
def test_disassembles_7c_65c02(self):
mpu = MPU65C02()
length, disasm = self.disassemble([0x7c, 0x34, 0x12], 0x0000, mpu)
self.assertEqual(3, length)
self.assertEqual('JMP ($1234,X)', disasm)
def test_disassembles_7d(self):
length, disasm = self.disassemble([0x7d, 0x00, 0x44])
self.assertEqual(3, length)