I’ve started a new Python project called Py65. It aims to provide building blocks for modeling 65xx microcomputer systems in software, with a focus on homebuilt hardware. Using simulation, embedded systems software can be developed and tested much faster.

In its current form, Py65 supports the original NMOS 6502 microprocessor from MOS Technology. The venerable 6502 and variants of it powered such famous microcomputers as the Commodore 64, game systems like the Atari 2600 and Nintendo Entertainment System (NES), as well as thousands of consumer and embedded devices today.

I haven’t released a package for Py65 yet but I’ll be doing this after some organizational changes are complete. For now, you can get it from its Subversion repository linked from the Py65 page on Ohloh.

The Python interactive interpreter itself can be used as a monitor:

>>> from py65.mpu6502 import MPU >>> mpu = MPU() >>> mpu <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> >>> mpu.memory[0x0000:0x0001] = (0x69, 0x16) #=> $0000 ADC #$16 >>> mpu.step() <6502: A=16, X=00, Y=00, Flags=20, SP=ff, PC=0002> >>> from py65.mpu6502 import MPU >>> mpu = MPU() >>> mpu <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> >>> mpu.memory[0x0000:0x0001] = (0x69, 0x16) #=> $0000 ADC #$16 >>> mpu.step() <6502: A=16, X=00, Y=00, Flags=20, SP=ff, PC=0002>

The simulator currently supports all legal NMOS 6502 opcodes and I have written a large unit test suite to verify its core. Most of its tests look like this one:

def test_bne_zero_set_does_not_branch(self): mpu = MPU() mpu.flags |= cpu.ZERO mpu.memory[0x0000:0x0001] = (0xD0, 0x06) #=> BNE +6 mpu.step() self.assertEquals(0x0002, mpu.pc) def test_bne_zero_set_does_not_branch(self): mpu = MPU() mpu.flags |= cpu.ZERO mpu.memory[0x0000:0x0001] = (0xD0, 0x06) #=> BNE +6 mpu.step() self.assertEquals(0x0002, mpu.pc)

Py65’s own unit tests hint at what tests for your own assembly language programs could look like. I am especially interested in unit testing my own embedded software and I will be working on an assertion vocabulary and test helpers for this.

There are a lot of possibilities for what could be done with Py65. For now, I plan to include a system for mapping virtual devices into the microprocessor’s address space, add more hooks into the simulator, and include support for additional 65xx family hardware.

Py65 does not include an assembler. If you need one, I recommend André Fachat‘s excellent xa assembler which is currently maintained by Cameron Kaiser.