Py65 0.1: Introducing Py65Mon
-
Py65 0.1, a 6502 microprocessor simulator written in Python, has been released and is available on the Python Package Index (PyPI). You can now easy_install it:
$ easy_install py65
Py65Mon
Since my initial announcement of Py65, there have been many bug fixes and unit tests added. The most noticeable addition is a new machine language monitor. It will be installed automatically and is started with the
py65moncommand:$ py65mon Py65 Monitor <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> .
At the prompt, type
helpfor a list of commands orhelp commandfor help on a specific command. The monitor commands are very similar to the excellent VICE Monitor, so VICE users should feel right at home.The biggest difference from VICE is that the
loadcommand requires a load address as the second argument and starts reading the binary data from byte 0. It does not expect byte 0 and 1 of the file to contain a Commodore-style load address. Also, assembling and disassembling from the monitor are not yet implemented but are planned.Hello World
Just like Michal Kowalski’s 6502 Macroassembler & Simulator for Windows, Py65Mon will trap writes to
$E001and echo the bytes toSTDOUT.This is enough to get us to our first “Hello World” program running under Py65. First, we’ll write a short assembly language program to print the message. Save it as
hello.asm.*=$C000 CHAROUT=$F001 ;Originally $E001, now $F001 since Py65 0.2 HELLO: LDX #$00 LOOP: LDA MESSAGE,X BEQ DONE STA CHAROUT INX JMP LOOP DONE: RTS MESSAGE = * !text "Hello, World!" !byte 0
We then assemble the program into a binary, using Marco Baye’s Acme Cross-Assembler:
src$ acme --format plain --outfile hello.bin hello.asm
The
--format plainswitch instructs Acme not to prepend the Commodore-style load address in the binary. If you’d like to get going quickly, you can also download hello.bin.With the binary ready, we can start the monitor and load it in:
src$ py65mon Py65 Monitor <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> .add_label c000 hello <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> .load "hello.bin" hello Wrote +29 bytes from $c000 to $c01c
Py65Mon supports symbolic addressing in most commands. The first command,
add_label, defineshelloas a label for address$C000. The second command loads the binary into that address.We can now set the program counter with the
registerscommand, and execute the code up toRTSwith thereturncommand.<6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> .registers pc=hello <6502: A=00, X=0d, Y=00, Flags=20, SP=ff, PC=c000> .return Hello, World! <6502: A=00, X=0d, Y=00, Flags=20, SP=ff, PC=c00e> .
Now we have run the program, printed “Hello, World!”, and returned to the prompt. We can see the program counter is left at
$C00E.You can also use the
stepcommand to step through the program. Just set the program counter to the start address again ($C000orhello) and repeatedly enterstep. As you are stepping repeatedly, you can simply hit ENTER to repeat the last command.From here you can also explore other commands, e.g.
mem c000:c003to display the memory in that address range. The default radix is hexadecimal. You can also prefix with$for hexadecimal or+for decimal, likemem +49152:+49155.Next Steps
Py65 and its monitor are now complete enough to run most simple 6502 programs, including many from the 6502.org Source Code Repository. The next versions will include more I/O devices and monitor commands, with the goal of running a sophisticated 6502 program like Lee’s Davisons’ Enhanced 6502 BASIC.
