Tuesday, 21 February 2017

My Z80 Computer Version 2

My Z80 Computer


Continuing on from the last project. I have modified the circuit. Now ridding the system of the (E)EPROM and introducing a AVR microcontroller. Before going into detail, the AVR essentially halts the Z80 CPU and writes a bootloader into the first block of RAM, it then releases the control of the bus to the Z80 CPU and starts executing from $0000. The AVR microcontroller then becomes an I/O decoder, I2C bus and USB I/O.

The start of the schematic, showing the Z80, AVR and SRAM. Not yet complete

To start, the AVR will hold the Z80 in a tri-state bus and in Reset, during this time it will load a small 'bootloader' program into the first 512-bytes of RAM. Once this is done, The Z80 will be brought out of reset and the AVR will start generating Clock pulses on the Clock line though a timer on the AVR (which can be halted upon request). During this time now, the Z80 will essentially think it's the Bus Master, with 32k of RAM, a small bootloader program and a collection of I/O through Serial and I2C bus to start with, it will then begin "loading" via an I/O port and filling up the RAM with what ever O/S or programming the initial boot loader is designed to load.
The AVR can also serve as a non-volatile storage (via it's EEPROM) and serve as a permanent program space with a seperate area for the 'ROM' to be loaded into RAM.
Latest schematic. 

The Serial port can be used for communication with the computer, the I2C bus can be used for added permanent storage as well as adpating to a preprogrammed FPGA Gameduino device for video and sound output.

Sunday, 12 February 2017

My Z80 Computer (Ongoing)

One thing I have learnt when breadboarding digital electronics is to create little templates (in reverse) for the underside of the board. This allows easier wiring to various chips on the board.
This particular project I have opted to put the data lines on top through hole, and run the address lines from underneath. Much less mess that way.
I print them so that there is an approx gap between the printed pins of 0.1 inch as standard.

Z80 CPU, 64kB EEPROM (using only 32kB), and 32kB SRAM underside templates I use on veroboard to aide in the soldering of the underside.

After searching through all my TTL logic devices and finding everything but the required 7432 OR gate I started entertaining other ideas (It would be at least 2 weeks before I could continue with this project otherwise and the options open to me had much more possibilities down the line.) I decided on using an ATMega328 device running at 16MHz to perform, to start with, memory and IO decoding. The Atmel uController will also, upon power up, provide a Reset signal for a second to reset the Z80s state.

The below is the intended Input and corresponding outputs to the 7404 TTL inverters

x = don't care of input, since A15 line status is irrelavant to how the IO is done. Even though in an IO state the A15 pin would represent a 0
I found later that the uController doesn't handle well due to program latency etc as a decoder more than about 0.5MHz clock cycle for Z80.
Due to the latency on the ATMega328 (which I had a feeling it would be in simulation) I have reverted back to a 74hc32 as the IO and Mem decoder, However I have kept the ATMega in circuit as a very reliable adjustable clock source and boot reset. I have also provisioned for the next expansion (IO), using headers for A0-A6, D0-D7, *IORD, *IOWR and other a few other pins broken out from the main board.
I am hoping to complete on my couple days off this weekend. Once done, I will just run another program which will write and read to RAM and monitor the process at a slower clock speed (hence advantage of reprogrammable uController on the board. :geek: )
The schematic is a bit of a mess of wires but it was done late at night and only a reference for the build.

This is version 2. Replacing with the 74hc32 or gate for memory decoding and seitching to atmega for clock and reset for the moment.
The first code for the 328 is listed below. Sets up a 2MHz timer and the main program runs the reset cycle for the Z80.
const int freqOutputPin = 3;
const int ocr2aval  = 3;

void setup()
   pinMode(freqOutputPin, OUTPUT);
   TCCR2A = ((1 << WGM21) | (1 << COM2B0));
   TCCR2B = (1 << CS20);
   TIMSK2 = 0;
   OCR2A = ocr2aval;

int led = 13;
int res = 8;
int count = 1;

void loop(){

   // Start Reset Process

digitalWrite (res, HIGH);

while (count < 10) {
  digitalWrite (led, HIGH);
  digitalWrite (led,LOW);
  count = count +1;

   // Turn pin 14 to '0' to bring CPU out of reset
   // Flash LED on pin 19 signifying out of reset and normal operation

digitalWrite (res,LOW);

while (count < 20) {
  digitalWrite (led, HIGH);
  digitalWrite (led,LOW);



The picture below shows the frequency output and duty cycle % of clock from Timer on ATMega

ATMEga328 was programmed with my program, plugged into the z80 main board and powered up. The LED flashing is just a late addition to get a feedback from uController.

Video is located here showing the power up and cycle from Reset hold to Regular operation and clock pulse. The LED is run from two steps of program just to indicate the point of the program running. I had my frequency counter attached to pin 6 of Z80 socket to check the clock pulse out from my uController. Next to add OR Gate, Z80, Memory and hopefully get my EEPROM programmer working on another machine to create a short program to test the mainboard operation.
I will get the video up and running, it is on my youtube channel at the moment, but am currently redesigning for a larger ATMega and only SRAM and load ROM image in via AVR ;)
A quick run down, without going into technical details of what is to come... I will be holding the Z80 in a reset state and load contents of 'ROM' from the AVR Flash to the SRAM and then allow the Z80 to run.. The AVR will take care of I/O. When an IO request happens, the AVR will Halt the Z80, to process the IO request, before continuing. This is due to the fact that the AVR will take a bit longer to respond to the Z80 requests than hard-logic. This was realised when I originally tried to use the original ATMega328 past about 500kHz and it could no longer keep up with the requests from the IO and MEM lines


Copyright (c)2014-2017 Wolf Technologies - Shane van Ingen