diff --git a/src/py65/assembler.py b/src/py65/assembler.py index 1390d19..2398bcc 100644 --- a/src/py65/assembler.py +++ b/src/py65/assembler.py @@ -8,6 +8,7 @@ class Assembler: r'[,xXyY\s]*)$') Addressing = [ + ['zpi', re.compile(r'^\(\$00([0-9A-F]{2})\)$')], # "($0012)" ['zpx', re.compile(r'^\$00([0-9A-F]{2}),X$')], # "$0012,X" ['zpy', re.compile(r'^\$00([0-9A-F]{2}),Y$')], # "$0012,Y" ['zpg', re.compile(r'^\$00([0-9A-F]{2})$')], # "$0012" diff --git a/src/py65/devices/mpu65c02.py b/src/py65/devices/mpu65c02.py index 868b247..6ef2e5c 100644 --- a/src/py65/devices/mpu65c02.py +++ b/src/py65/devices/mpu65c02.py @@ -14,6 +14,11 @@ class MPU(NMOS6502): instruction = make_instruction_decorator(instruct, disassemble, cycletime, extracycles) + # addressing modes + + def ZeroPageIndirectAddr(self): + return self.WordAt( 255 & (self.ByteAt(self.pc))) + # operations def opSTZ(self, x): @@ -66,7 +71,12 @@ class MPU(NMOS6502): @instruction(name="STZ", mode="abx", cycles=5) def i9e(self): self.opSTZ(self.AbsoluteXAddr) - self.pc+=2 + self.pc += 2 + + @instruction(name="LDA", mode="zpi", cycles=5) + def ib2(self): + self.opLDA(self.ZeroPageIndirectAddr) + self.pc += 1 @instruction(name="PHX", mode="imp", cycles=3) def ida(self): diff --git a/src/py65/disassembler.py b/src/py65/disassembler.py index 79e670e..b894f07 100644 --- a/src/py65/disassembler.py +++ b/src/py65/disassembler.py @@ -79,6 +79,13 @@ class Disassembler: disasm += ' ' + address_or_label length = 2 + elif addressing == 'zpi': + zp_address = self._mpu.ByteAt(pc + 1) + address_or_label = self._address_parser.label_for(zp_address, + '($%02x)' % zp_address) + disasm += ' %s' % address_or_label + length = 2 + elif addressing == 'zpg': zp_address = self._mpu.ByteAt(pc + 1) address_or_label = self._address_parser.label_for(zp_address, diff --git a/src/py65/monitor.py b/src/py65/monitor.py index eab2970..2e43042 100644 --- a/src/py65/monitor.py +++ b/src/py65/monitor.py @@ -6,7 +6,7 @@ import re import shlex import asyncore import sys -from py65.devices.mpu6502 import MPU +from py65.devices.mpu65c02 import MPU from py65.disassembler import Disassembler from py65.assembler import Assembler from py65.utils.addressing import AddressParser diff --git a/src/py65/tests/devices/test_mpu65c02.py b/src/py65/tests/devices/test_mpu65c02.py index b964950..9138aab 100644 --- a/src/py65/tests/devices/test_mpu65c02.py +++ b/src/py65/tests/devices/test_mpu65c02.py @@ -12,6 +12,32 @@ class MPUTests(unittest.TestCase, Common6502Tests): self.assertEquals('<65C02: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000>', repr(mpu)) + # LDA Zero Page, Indirect + + def test_lda_zp_indirect_loads_a_sets_n_flag(self): + mpu = self._make_mpu() + mpu.a = 0x00 + self._write(mpu.memory, 0x0000, (0xB2, 0x10)) #=> LDA ($0010) + self._write(mpu.memory, 0x0010, (0xCD, 0xAB)) #=> Vector to $ABCD + mpu.memory[0xABCD] = 0x80 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(0x80, mpu.a) + self.assertEquals(mpu.NEGATIVE, mpu.flags & mpu.NEGATIVE) + self.assertEquals(0, mpu.flags & mpu.ZERO) + + def test_lda_zp_indirect_loads_a_sets_z_flag(self): + mpu = self._make_mpu() + mpu.a = 0x00 + self._write(mpu.memory, 0x0000, (0xB2, 0x10)) #=> LDA ($0010) + self._write(mpu.memory, 0x0010, (0xCD, 0xAB)) #=> Vector to $ABCD + mpu.memory[0xABCD] = 0x00 + mpu.step() + self.assertEquals(0x0002, mpu.pc) + self.assertEquals(0x00, mpu.a) + self.assertEquals(mpu.ZERO, mpu.flags & mpu.ZERO) + self.assertEquals(0, mpu.flags & mpu.NEGATIVE) + # PHX def test_phx_pushes_x_and_updates_sp(self):