Introduction: 6502 Minimal Computer (with Arduino MEGA) Part 3

Moving on still further, I have now added an Octal Latch, 8 rectangular LEDs and a 220 Ohm resistor array to the main board. There is also a jumper between the array's common pin and ground, so that the LEDs can be turned off. The 74HC00 NAND gate has been replaced with a 78LS08 AND gate, the wiring to the gate has also been altered. The AND gate means that the 6522 is now located at $6000 instead of $E000.

There is also a pin for the connection of an external clock to drive the 6502. With this connection, there is no need for the MEGA to provide a clock signal. The MEGA still monitors what is going on with the processor as before.

I used a 20 pin 74HC373 for the latch because I had some. This was OK when on the breadboard, but a 74HC573 is bus compatible and would have saved loads of wiring. The UCN5801A which is a 22 pin IC might also be considered in the circuit, but the wiring will be slightly different.

The top, single orange LED is a power indicator and the the lower left red one indicates when a write is taking place. The latter will be insignificant if the board is run at higher speeds.

The modified circuit is above (with the 74HC573).

Step 1: Demonstration Programs

Two simple demonstration programs are included in the 6502 monitor and their disassembled code is here.

This program loads 1 into the 6502 A register and stores it in the latch. It then adds 1 to the A register and stores that in the latch. Then it jumps back to $1005 and the process repeats for ever.

* = 1000
1000   A9 01      LDA #$01
1002   8D 00 41   STA $4100
1005   69 01      ADC #$01
1007   8D 00 41   STA $4100
100A   4C 05 10   JMP $1005
100D              .END

This program first sets the DDR of the 6522 port B to output. It then stores $55 (B01010101) in the port as well as the latch. The A register then rotates 1 step right and now holds $AA (B10101010). This is again stored in port B and the latch. The program jumps back to $1005 and continues for ever.

* = 1000
1000   A9 FF      LDA #$FF
1002   8D 02 60   STA $6002
1005   A9 55      LDA #$55
1007   38         SEC
1008   8D 00 60   STA $6000
100B   8D 00 41   STA $4100
100E   6A         ROR A
100F   8D 00 60   STA $6000
1012   8D 00 41   STA $4100
1015   4C 05 10   JMP $1005
1018              .END

The sharp eyed among you may notice that the coloured LEDs are showing a different pattern than the green ones. This is because the common lead is connected to 5v on the coloured ones and the common on the green ones is connected to ground.

Change this line of code to program2 or program3.

setDataPins(program3[offset]);

A 6502 Assembler and Disassembler are useful tools to help encode your programs.

Step 2: Adding an EEPROM

For the EEPROM board, I used a 950 x 650 mm strip board and 19mm male header pins to enable the board to clear the one underneath. This board plugs into the 6502 board below. The EEPROM is an ATMEL 28C256 which has 28 pins and contains 32k x 8 bits of memory. This is more than adequate for the small programs being used at present.

I haven't done a circuit diagram for this board, but its is fairly straight forward how it connects to the 6502 board below. These EEPROM chips are not bus friendly so have to be wired to the individual pins, hence all the "green and white spaghetti". I have solved the bridging issue on the earlier board by wiring the data lines together on the underside of the board.

The EEPROM's 14 address pins connect to the appropriate pins on the left hand side (green wires) and the I/O pins to the data pins on the right (white wires). Pin 27 (WE) is connected to pin 28 (5v), pin 22 (OE) is connected to ground and pin 20 (CE) is connected to a NAND gate.The 2 inputs of of the NAND gate are connected to A15 on the main board. This means that when this pin goes high, the NAND gate gives a low signal to the CE pin of the EEPROM which makes it active. With this set up it means that the EEPROM can only be read by the 6502.

As the EEPROM lives in the top 32k on the memory map, it means that $FFFC and $FFFD can hold the start address for the 6502 after it has been reset. With the 6522 having its addresses between $6000 and $600F and the latch is at $4100, it stops any memory conflicts.

The NMI vector ($FFFA and $FFFB) and BRK / IRQ vector ($FFFE anf $FFFF) could also be written in the same way.

Step 3: Programming the EEPROM

To store a program on the EEPROM, it needs a programmer. I made one from a strip board, an Arduino Pro Mini, a couple of 74HC595's and and a ZIF socket. Originally, the programmer was made for an AT28C16 which has fewer address lines than the AT28C256 so had to be modified.

The circuit diagram shows how to wire both of these EEPROMs. It is not clear from the photo that the two 595 chips are upside down and not as shown on the diagram. Pins 1 to 7 of 595/1 line up with A1 to A7 of the EEPROM regardless of which is used. This saves 7 connecting wires. The board now looks a bit tight and this is because originally I used a 24 pin DIL socket which has now been replaced by the much larger 28 pin ZIF socket.

A program is included that works with my board. The program will work with any Arduino and 595s in a circuit as shown. I chose a 5v Pro Mini because it is compact and cheap enough to leave in the set up.

Step 4: The EEPROM Programs

There are three simple programs in EEPROM programmer. To use them, just uncomment the line you want to use.

// Read from port A of 6522
//const byte data[] = {0xA9,0x00,0x8D,0x03,0x60,0xAD,0x01,0x60,0x4C,0x05,0x90,0x00};

The program shows a memory dump when it has finished. The part of the program below gives you full control of what you want to write or erase, sets $FFFC & $FFFD and then displays the contents of a given range. Just uncomment or alter the parameters as you require. The addresses can also be entered in decimal format.

  // eraseEEPROM(422,930,0x41); // Use to erase whole or part of EEPROM - start, end, byte
  Serial.println("Programming EEPROM");
  amount = program_numeric_data(0x1000);  
 
  writeEEPROM(0x7ffc,0x00);  // Set $FFFC for 6502
  writeEEPROM(0x7ffd,0x90);  // Set $FFFD for 6502
  //writeEEPROM(0x1000,0xA9);  // Write 1 byte of data
  Serial.println(" done");
  String outline = " Written " + (String)amount + " bytes";
  Serial.println(outline);
  Serial.println("Reading EEPROM");
  printContents(0x0000,0x112f);  // Set range to display
  printContents(0x7ff0,0x7fff);  // Reads last 16 bytes on EEPROM

An abridged output from the program is above.

Step 5: Running the 6502 From the EEPROM

The programmed EEPROM can now be inserted into its board and this piggy backs on to the main 6502 board which piggy backs on to the MEGA. The side and top view photos above show how it all fits together.

The 6502 can now read the start vector from $FFFC and $FFFD (which is $9000) and then jump to the program that is stored there. The MEGA is still providing the clock signal and its program needs to be altered to provide just the clock signal and monitor the 6502. A modified program is provided to do this.

The running photo shows this program running.

9000        LDA #$00        A9 00
9002        STA $6003       8D 03 60
9005        LDA #$FF        A9 FF
9007        STA $6002       8D 02 60
900A        LDA $6001       AD 01 60
900D        STA $6000       8D 00 60
9010        EOR #$FF        49 FF
9012        STA $4100       8D 00 41
9015        JMP $900A       4C 0A 90

The switches are plugged into port A and the program displays the value it is reading on port B and the 74HC373 (which is obscured at present). the switches are connected to ground and the LEDs are connected to 5v. The EOR #$FF corrects the problem of the latch and port B displaying different patterns by flipping the bits before writing to the latch.

Step 6: External Time Signal

If a clock signal is applied to the pin at the top of the board, the 6502 can now run independently of the MEGA. Of course it also needs a power supply. I have experimented with different clocks and even run the 6502 at 1MHz with a crystal oscillator. The MEGA cannot keep up with faster speeds, so has to be removed.

I also tried the output from a 555 timer but that does not work. I think it might be because it is not a square wave? When connected to one of the CD4017 outputs, it did drive the 6502. I patched into one of the kits above to try and get a clock signal.

I am still looking at different methods to get a clock signal.

Step 7: Conclusion

I have shown how to build some complex circuits and get a very simple "computer" to work with a minimal amount of parts. Granted, the computer cannot do a great deal at present or is likely to do so in future.

Back in the early 80's, with my VIC20, I used to wonder at the awesome machine and not have the first idea of how to start putting one together. Times have moved on and so has technology, but it is still nice to get back to basics and be proud of something you have built from scratch.

To further develop this computer, I intend to put 2k of SRAM at $0000 to $2047 and add a 1 MHz oscillator. Will probably add something like a CD4040 (12-Stage Binary Ripple Counter / Divider) so that I can tap into different clock speeds.

Might even add an LCD display to give text outputs rather than just flashing lights. The EEPROM programmer will also need to be modified to deal with the larger programs needed to run an LCD display.

Even though the MEGA is becoming unnecessary for the running of the 6502, it still comes in handy for debugging the machine code. As anyone knows, machine code always contains bugs!