Initial Goal Reached - Stretch Goals TBD
My goal for the Retrochallenge 2018/09 was to get a retro CPU core running on my FPGA board.
Mission accomplished - I used:
- The well-respected open-source Arlet 6502 core,
- Verilog code to create 64K of RAM with pre-loaded contents,
- Some other Verilog glue code to put those pieces together, and jump-start the 6502 with a reset pulse.
The pre-loaded contents, specified by a simple HEX file, made the 6502 perform a few easy operations (like load a direct value into the accumulator), then jump to an endless loop padded with NOPs. On start-up, the 6502 jumps to the address specified at $FFFC and $FFFD. I placed the address $0400 at those RAM locations, and the program itself at $0400.
Since I had no I/O, it was a challenge to validate the program was actually running. I was able to do this by watching the contents of the PC (program counter) using the built-in debugging tools of Xilinx Vivado, the development software used to program my FPGA.
Initial challenges, some of which were documented in my earlier blog entries, included the RAM not working right and my HEX file not being properly formatted. I did make it through those challenges, borrowing from work documented on the C64 on an FPGA blog.
However, my stretch goals were to expand that into something that looked like a retro computer. I didn't get very far down that road.
The 6502 chip uses memory-mapped I/O. In order to get data in or out of the 6502, it would be necessary for me to modify the RAM interface so that certain addresses would, instead of storing/loading to actual RAM, would transfer data to/from some other circuitry instead. I did get this working just a little bit - I created a Verilog register and connected it to the 4 LEDs on the Zybo board. Then, I modified the RAM interface so that, if location hex E000 was written to, the output (lower 4 bits) would appear on the LEDs. This was actually pretty awesome, and worked well. But it's not very much I/O :-)
Where From Here
So, for I/O, what I want to do is have two FIFOs, one for 6502 input, the other for output. If you write a byte to whatever I pick for the output memory address on the 6502, it will push that byte to the output FIFO. If you read a corresponding input address on the 6502, it will read the byte from the input FIFO. In both cases, the full or empty indicators of the FIFO would be checked as appropriate.
On the other end of those FIFOs, I'd like to put a RS232 UART. This will enable the 6502 to send and receive via a standard serial connection. Bang, Bob's your uncle, I/O. It will take some Verilog glue logic to hook this all up, but when done, I don't see any reason it wouldn't work.
Even though Retrochallenge is over, I'm going to keep going with this. Now that I have a working 6502, I'm hungry for more.
Thanks for reading! Stay Tuned!