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
py65mon
command:$ py65mon Py65 Monitor <6502: A=00, X=00, Y=00, Flags=20, SP=ff, PC=0000> .
At the prompt, type
help
for a list of commands orhelp command
for 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
load
command 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
$E001
and 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 plain
switch 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
, defineshello
as a label for address$C000
. The second command loads the binary into that address.We can now set the program counter with the
registers
command, and execute the code up toRTS
with thereturn
command.<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
step
command to step through the program. Just set the program counter to the start address again ($C000
orhello
) 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:c003
to 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.