It is almost a year since I touched my 6502 systems. I decided to step away as reliability problems were frustrating me greatly. In particular programs didn't run reliably with the 1 MHz clock and I suffered repeated loose connections. God knows how Ben Eater copes with his bread board circuits, I guess he must be so meticulous that all his connections are reliable.
Options
I considered various options to make my system more "permanent" and less error-prone:
* Design a PCB for my components and get it made up
- this is too complicated for a first PCB creation, very difficult to be 100% accurate
* Buy a PCB designed for these components
- I did find one that looked promising by Jeff Tranter but opted to try the W65C02SXB instead
* Buy a W65C02SXB which contains all the components I need
- I did buy a board, and it is wonderful, but it is somewhat different to use
* Use stripboard to create a permanent version of my working breadboard circuit.
- This is the most reasonable way forward and one I have put a lot of effort into.
Stripboard
Stripboard generally comes in boards upto 38 columns wide with long tracks. This isn't very convenient for soldering ICs as all the tracks have to be cut under each chip. There are a few stripboards available (I only really looked on eBay) in breadboard style format.and I have purchased some of each type. The main requirement is to have at least two holes, preferably three, on either side of the larger chips to solder connections.
Layout
In theory I could just copy my existing breadboard chips and connections to stripboard. In practice the first boards I found were not as wide as breadboard (which has 63 holes across) so I needed a different arrangement. In addition the existing breadboard components weren't necessarily in the best positions so there were some potential improvements I could make.
As ROM and RAM share address and data bus connections and I have previously had problems with them I decided to create a ROM-RAM memory board with a NAND chip for control logic and off-board bus and control connections to the 6502. As an Arduino Mega is used for testing and to program ROMs it is best connected to the memory board. Offboard connections will be made using dupont connectors terminated in male posts on the board.
It was a hard days work to draw a board diagram with chip locations and all necessary connections. In particular I needed to make sure that all 6502 pins required both for memory chips and those used by the Mega were available. Clearly any errors preventing the board working would be difficult to correct once it had been soldered.
Build
As an amateur at this business it was obvious that I should build the board in stages. The first stage is to solder EEPROM and Arduino Mega connections. The Mega is used to write code to ROM and the ROM can work in isolation from NAND, RAM and CPU. I inserted a ROM chip (AT28C256) with known code onto the board and checked I could read it from the Mega and then wrote some new code to the ROM and read it back.
We can now solder remaining board connections.
The NAND chip is used to select either RAM or ROM. Our simplified memory map is:
$0000-$3FFF RAM
$8000-$FFFF ROM
so we use the address wires A15 and A14 in the NAND gates to enable/disable ROM and RAM.
A sketch is used to check that NAND inputs provide the correct control signals to ROM and RAM. Another sketch, which is very similar to the ROM read sketch can then test reading and writing RAM.
We are now confident our memory works and it is time to add the W65C02 CPU to the circuit. We are not yet ready for a soldered version so the CPU and reset button are put onto a breadboard. The CPU needs a clock, for which the trusty Ben Eater Clock circuit is used.
At this stage we are not using RAM, program instructions are loaded from ROM and executed by the CPU.
A monitor sketch is devised, running on the Mega, which displays address and data bus values after each clock cycle.
The 6502 datasheet explains that when Reset is pressed the CPU uses 6 clock cycles to initialise and then loads a reset vector from address $FFFC and $FFFD. On the right you can see that cycles 6 and 7 load an address $8000 from these addresses and executes the (non-existent) program starting at $8000.
In fact, we previously used a Mega sketch to store data in the reset vector $FFFC=0x00 and $FFFD=0x80. The 6502 uses "little-endian" addresses, which means that the low order address byte is stored first. and the high order byte second so these values are correctly interpreted as address $8000.
Program Execution
We now write a simple assembly program to write some data in a loop and load it into ROM starting at address $8000 using the Mega. The address values $6000 and $6002 shown below don't exist but that doesn't matter; using the Mega monitor we can watch each instruction being loaded and executed.
The picture below shows the source program and the hex machine code which it translates to - it is only 17 bytes in length.
On the monitor line #8 shows the first instruction being loaded/executed from address $8000. The loop instruction "jmp loop" at address $800E-$8010 is executed in lines #26 to #28 and execution continues at address $800A.
Conclusion
This is great we have built a simple 6502 system with RAM and ROM on stripboard. We have the CPU connected and a working monitor to show instructions being executed. It is a big step forward in complexity and more more successful than previous efforts. I have done this before following the inimitable Ben Eater videos but I have learned enough to put things together myself.
This is only a brief breathing space along the journey to make a useable system but it is the culmination of some solid work and I am happy with the results so far.
The next step, which I can document shortly is to provide input / output capability and in particular to incorporate an ACIA serial terminal interface.