Sunday 11 September 2022

6502 Terminal

ACIA Serial Chip

My working 6502 system needs some input / output capability.  Ben Eater added a VIA (Versatile Interface Adapter) and attached an LCD display to his system.  I prefer to start with an ACIA (Asynchronous Communication Interface Adapter).  This provides me with a serial interface running at 19200 baud.

An ACIA chip was added to the breadboard and connected using an FTDI chip to a PC USB COM port.  The hardware allows me to use a Windows Terminal or Putty session providing a screen and keyboard interface.  I could attach a physical terminal, but they don't really exist anymore and a PC terminal session works just fine.  I did build a physical terminal using an LCD screen a while ago but I don't need it here.

Arduino Testing

My inspiration for the ACIA connection is Dirk Grappendorf who provides an excellent description and code to terminal I/O.  

To check my breadboard connections I designed a sketch which ran on the Mega without the need to use my CPU.  In fact I did have trouble getting the ACIA to work as an extra capacitor is required which Herr Grappendorf mentioned but I omitted as it wasn't shown on the datasheet.

The ACIA is controlled in a very simple manner.  Two bytes are written to the command and control registers specifying communication parameters.  Subsequently bytes which are inserted in the transmission register are sent to the FTDI and onwards to the PC terminal session.

6502 Machine Code


Once I was happy that wires and the ACIA were working I could write a very simple assembly program which writes the command register (address $4002) the control register (address $4003) and then loops to output a character (0x34, the digit 4) in the data register (address $4000).






The result is a 17 byte program which puts a steady stream of characters out on the terminal.  There isn't any synchronisation by the program to ensure that the terminal is ready for the next character before transmitting it, we simply send characters as fast as we can.


Add RAM

We dont actually require RAM for this version of the program to work.  RAM is required for the 6502 stack, which is used by the subroutine mechanism to store return addresses.  Adding a subroutine to the program allows us to check that RAM is still working.

Clock Speed

Initial testing is carried out using the Ben Eater clock, which is a 555 timer based solution which runs at speeds upto about 200Hz.  Previously I have built an Arduino nano-based clock which allows me to choose between a number of speeds 5 Hz, 50 Hz, 500 Hz and 5000 Hz.  When I substituted the nano clock into the system I found that it worked.  However, as expected, the system didn't work when the full-speed 1 MHz clock chip was connected.

Summary  

We have added a terminal to our 6502 system so that we can do input / output.  We wrote a very simple machine code program as a first test that output to the terminal works.  Normally the "terminal driver" would synchronise transmission and receiving but we had good results with a 5 KHz clock sending characters as fast as we could.
What we really need is a software environment to assemble and load programs so that we can better, more extensive programs - this will come next.




Saturday 10 September 2022

6502 stripboard circuit

 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.