⭅ Previous (Expanding IO) | Next (Flashing the Bootloader) ⭆ |
Now that we can read the full address bus from the 6502, we have enough visibility to try to run a program on the 6502.
We’ll update our control program on the atmega, and write a program that talks to the atmega via serial to feed in the appropriate data from an emulated ROM chip.
There are two goals for this next experiment. First, we’d like to make sure we can feed in a program to the 6502. Though the 6502 is extremely well documented and understood, many similar chips are not. With a technique to watch a program execute on a mostly unknown chip, we’ll be able to better understand its behavior.
Additionally, we havent yet seen a zero on the read-vs-write pin. To check that this is working, we’ll ensure our test program writes to memory at least once. To make the write interesting, our program will write a unique value each time. This will also check that the reading of the data pins is working.
A very simple program to accomplish the above looks like:
In 6502 assembly, it looks something like:
.reset:
ldx #$1
.loop:
stx $dead
inx
jmp .loop
The program should start at .reset, and start our counter with 1. Since the program isn’t doing much else, we can keep the counter in the accumulator register.
Most 6502 based systems, like the NES, map peripherals into memory. This program is doing nothing more than executing from memory. When assembling, the resulting binary can fill the entire address space (2 ** 16 bytes = 65536 bytes).
Full source and build scripts available here.
Like before, we want to step the 6502 along. To emulate an attached program ROM, we need to check each cycle whether the 6502 is reading or writing.
Since our assembled program is the size of the entire address space, step 1 is as simple as looking up the nth byte from the assembled binary.
Full sourcecode for the host program is available on github.
Our old sketch just performed a reset and logged the state of the 6502 busses each cycle. To allow control from our linux machine, we’ll have the atmega program listen for commands over serial. These commands will be:
reset\n
Toggle the clock while holding the device in reset in order to initialize the 6502.
step\n
Toggle the clock and read the busses afterwards.
d=VALUE\n
Set the data bus to a given value. The host will be expected to send a step afterwards.
The atmenga will respond with a newline terminated string after each command, so the host program knows when the microcontroller is finished.
Full sourcecode for this “driver” program is available here.
With these three pieces in place, lets run our program and check that it works!
After a bit of debugging, I was able to capture the following log. Here’s a snippet of the beginning. A “full” trace corresponding to the first 200 cycles is also available here. the first 200 cycles of execution:
The arrows < and > indicate the direction of the message. < is to the atmega and then the 6502, and > is from the atmega.
> a=0xFFFC r=1
< d0 ok
> d=0x0
< step ok
> a=0xFFFD r=1
< d128 ok
> d=0x80
< step ok
> a=0x8000 r=1
< d162 ok
> d=0xA2
< step ok
> a=0x8001 r=1
< d1 ok
> d=0x1
< step ok
> a=0x8002 r=1
< d142 ok
> d=0x8E
< step ok
> a=0x8003 r=1
< d173 ok
> d=0xAD
< step ok
> a=0x8004 r=1
< d222 ok
> d=0xDE
< step ok
> a=0xDEAD r=0 d=0x1
6502 wrote 0x1 at 0xDEAD
< step ok
> a=0x8005 r=1
< d232 ok
> d=0xE8
< step ok
> a=0x8006 r=1
< d76 ok
> d=0x4C
< step ok
> a=0x8006 r=1
< d76 ok
> d=0x4C
< step ok
> a=0x8007 r=1
< d2 ok
> d=0x2
< step ok
> a=0x8008 r=1
< d128 ok
> d=0x80
< step ok
> a=0x8002 r=1
< d142 ok
> d=0x8E
< step ok
> a=0x8003 r=1
< d173 ok
> d=0xAD
< step ok
> a=0x8004 r=1
< d222 ok
> d=0xDE
< step ok
> a=0xDEAD r=0 d=0x2
6502 wrote 0x2 at 0xDEAD
The reset works as before, and we can see that r=0 when the 6502 needs to write. Additionally, we see writes are occuring at 0xDEAD as expected, and the value written increases sequentially.
With that, all the key pieces of this basic chiplab are working. All that remains is to build a web interface, to allow anyone to submit programs and observe results.
A simple version of the Chiplab is now online, so you can follow along with this program and any others you write for the 6502.
Here is the full assembled program used in the above example, which you can try out at the 6502 chiplab.
⭅ Previous (Expanding IO) | Next (Flashing the Bootloader) ⭆ |