Wednesday 31 August 2011

19. The Ups and Downs of an Astable 555 Timer (How fast will it go?)

Well not that fast really. OK its faster than the refresh rate on your TV, but in the grand scheme of the computer world, its not that fast at all. Now I did get it to clock up 250KHz but the problem is that the peak voltage was not high enough and the low voltage not low enough. Its seems the faster I tried to get it to go the smaller the voltage difference.

Measuring the signal with the Xprotolab Oscilloscope is not easy either. It has a minimum resolution of 500 nano seconds per pixel, which if you do the sum 1/0.0000005 = 2MHz, means a 250KHz signal is 8 pixels wide. At higher frequencies the signal starts to become a blur on the screen.

Another aspect of the astable 555 timer is the Duty Cycle. Ideally, you probably want the time the voltage is high to be the same as when it is low, e.g. 50% each. The main external components used are 2 resistors (R1 & R2) and a capacitor (C1). Using 2 identical resistors gives you a Duty Cycle of 66%. To achive a Duty Cycle of 50% R2 needs to be roughly 10x that of R1. So with 2x 1K resistors and a 1nF capacitor we get about 250KHz with a 66% Duty Cycle, but changing R2 for a 10K resistor gets a 52% Duty Cycle and a much reduced clock speed of 57KHz. However, the low volatge is 0.000V and the peak is 4.480V using a 5V supply, much more usable. The Z80 Datasheet says that the input voltage for CLK should be Vcc-0.6 minimum, which with a 5V supply is 4.4V, so 4.480V should be OK to drive the clock signal.

Here are a few screenshots to show what I am talking about:
R1=1K R2=1K C1=1nF ~ Vmax=4.160V Vmin=1.600V Freq=250KHz Duty=66%
R1=1K R2=1K C1=10nF ~ Vmax=4.480V Vmin=0.000V Freq=42.55KHz Duty=66%
R1=1K R2=10K C1=1nF ~ Vmax=4.480V Vmin=0.000V Freq=58.82KHz Duty=52%

If I want to run this faster I am going to have to buy a quartz crystal. For this standard Z80 it needs to be 2.5MHz. (The Z80A will go at 4MHz).

18. Pinups! Oops! I mean Pinouts :)

I was trying to visualise the connections between the main ICs for my little project. Specifically the address bus pins(A0 to A15) and the data bus (D0 to D7). Looking at 3 .pdf datasheets did not help and what I really wanted was a side by side picture. So I started up Microsoft Paint and started making some of my own images, and here they are:
The Z80, the 128k SRAM and the 8K EEPROM.

Friday 26 August 2011

17. Old Timer

Thinking about what to use as a clock source to tick over the Z80, I remembered I had a couple of 555 timers. These have been around since 1971 and not much has changed. There are several modes you can operate these 555s but I am going to get it to generate a squarish pulse using the 'astable' confuration. You can read up about how to do that elsewhere on the web. Suffice to say I'm using 2x 1k resistors and a 10nF capacitor. Hook these up to the 555 and you get a pusle from pin 3. Yay!

Here a pic of the setup:

Now to measure the pulse we have produced. The Xprotolab Oscilloscope comes into it own here. I connect pin3 from the 555 to the CH1 input. It seems we have a pulse operating at 42.55KHz. Ok its not the speediest rate to run a Z80 at but it'll do to start with.

Here's the output from the oscilloscope:

There is formula for working out what combination of resistors and capacitor give a particular frequency, however, as I found out using resistors of too low a value gave a very weak pulse, ie the high voltage was not enough to trigger a response on the CLK input to the Z80. However, just changing the capacitor and keeping the 1K resistors, does allow you to adjust the frequency. Changing it to a 470uF almost gets you a 1 seconds pulse. Its slightly over, and it does also depend on the tolerance of the resistors, but its close enough. This lead me to ponder if there was such a thing as a variable capacitor, and then I remembered from my Denshi Block days that is what was inside the tuner. With something like that we could have a variable speed computer. Something to look at later.

16. Serial Killer App.

I got the USB to UART device yesterday. Works a treat. I'm glad I didn't decide to make my own, the CP2102 is so small the soldering would have been a nightmare. Although it did come with drivers for Windows, I don't have any File Transfer over Serial Port Software, but Linux does.

I downloaded the capture.sh script from www.gabotronics.com and installed the following package:
sudo apt-get install -y lrzsz

I then ran capture.sh and it transfered a screenshot of the Xprotolab Oscilloscope:

It comes out black on white, so a little bit of image conversion:
convert -negate a.bmp b.bmp
and hey presto:

Now there is an interface that is in development for the PC using the same Serial connection. it still needs a bit of work, but so far its looking good. Check it out at http://www.gabotronics.com/product-info/xprotolab-pc-interface.htm

However for now, I'm happy with the screenshots from the oscilloscope. :D

Tuesday 23 August 2011

15. USB connector for the XProtolab

The micro USB port on the Xprotolab is actually a serial port with a USB connector. Connecting it up to the USB port on the PC gives power, but thats it. In order to use the serial port capabilities you need to have some hardware in between so that when you plug into the USB on the PC it thinks its a COM port.

Now in America, you can buy a cable from Gabotronics, however their distributor in the UK doesn't stock it. However Gabotronics do tell you how to connect one up... to a CP2102. Its a small chip. Fiddly soldering. But wait, there is something I can buy that will get me most of the way: TRIXES USB 2.0 To TTL Serial Converter from Play.com For £4.24 including shipping, I cant refuse. A CP2102 chip from Farnells cost £4.44+VAT.

All I need now is an old micro USB cable to dissect to connect to the Serial Converter.

Why do I want to do this anyway? Well they are designing an interface for the PC to communicate with the Xprotolab and you can also get screenshots (aparently). We'll see.

Another parcel coming then, its Christmas again :)

14. Goodies Received.

I got the oscilloscope and the Ardunio board yesterday. I should have gotten them Saturday but I was out when the postman came so had to wait for the Post Office depot to open at 7am Monday.

Not much to say about the Arduino except, its bigger, has more pins and will allow me to connect up the whole of the Z80, the SRAM and EEPROM chips.

The oscilloscope is amazing! It's so small but full of features, and despite the small display is actually very readable.

Heres a pic of them both:


Friday 19 August 2011

1101. Retail Therapy.

I bought some goodies from Cool Components.

The Arduino Mega 2560 and the XMega XProtolab Oscilloscope.

The bigger Arduino gives me more connections for communicating with the Z80, the SRAM and the EEPROM. The oscilloscope means I can test and check my circuits are working such as a clock circuit running at 1MHz.

Its like Christmas :)

Tuesday 16 August 2011

12. Resistance Is Futile.

I have a whole stash of resistors from a kit. They're on strips and none of them are labelled. Well of course they are labelled but with 5 coloured lines around them. Great, now I can work out what they are, or so I thought. Even with an online resistor calculator I can't tell for sure. Some of the colours are a bit vague, or maybe its just my eyesight going. Is that a brown or a gold, is that red a shade of blue?

Anyway, I found a better way of identifying them. I just used an Ohmmeter to measure their resistance. Simples.

Now for a little chant: Ohm, Ohm, Ohm, Ohm....

Sunday 14 August 2011

11. Fried chips? Well just an LED so far...

Well it was bound to happen sooner or later. I fried an LED.

Maplin is open on Sundays, so I popped over to get some of those components to make a 5 volt power supply.

It worked. I put a red LED on the +5v coming from the circuit and connected the other end to ground. It lit up, for a while. I noticed this smell of hot electronics then the LED faded away. The bulb was hot, the voltage regulator (78L05) was hot. Not good!

So I rememeber reading somewhere, always use a resistor with an LED. So I put a 1K resistor in front and then found another LED and it was fine. Not hot anywhere.

Here is a diagram I made using CircuitMaker Student Edition which was free to download:

Saturday 13 August 2011

10. Oh! The Power...

A thought occurred to me. So far I've been using the Arduino to supply power to the Z80 and other ICs (Integrated Circuits aka chips). This can't be the case in the long run. I either need to use a battery or a some mains power adapter.

Now a battery would be good, but what to use. I need 5 volts. If I use 3 AA or AAA batteries, they are 1.5 volts each and thats only 4.5 volts altogether. Add a fourth and I get 6 volts. Too much. So I search the web and find I need something called a Voltage Regulator, but which one? Further reading says I could use a 7805. This will convert much higher voltages to 5v the (the 05 in the 7805 gives us a clue here it seems). Reading further tells me ideally a voltage 2-3 volts higher on the input would be preferable so an 8 volt battery? Hmm, lets go with a 9 volt PPV battery.

The 7805 comes in a few flavours, such as 78L05, 78M05 and 78S05. The L model give 0.1 Amps of current output, the M 0.5 Amps and the S 2.0 Amps. There are others, but its important to choose one that has enough power to drive the circuitry. At this stage I'm not sure. I need to look at the datasheets for ICs I already have to see what range current is expected. I expect it will be either L or M. Anything higher and I think higher and I think I'd fry the circuits.

There is also the implementation of the Voltage Regulator in the circuit that need some thought. It seems we need to put capacitors either side of the voltage regulator to stop it fluctuating too much and for safety a diode to stop us from blowing things up by connecting the battery up the wrong way. This article has a diagram on how to connect it up: http://stuff.nekhbet.ro/2006/06/18/how-to-build-a-5v-regulator-using-78l05-7805.html

I need some more components!

9. The Memory LOW down.

One thing to watch out for when connecting the Arduino to things like memory chips is that by default all the Arduino pins are LOW. Now considering that connections on the memory chips like WE (write enable) and CE (chip enable) are "active Low", then they will be active when a new program is loaded into the Arduino. This means you could overwrite your memory inadvertently. Most likely you will write the value 0 to the address 0 since all the data and address lines will probably be low.

Of course I am talking from experience here as this is exactly what happended to me when I was playing with the SRAM chip. I wrote 2 programs, one called SRAM_Writer and one called SRAM_Reader. I initially ran the Writer and then the Reader. Everything read back OK except memory address 0 which was 0 and my Writer program had written a value of 3 to it.

For safety, best to use some inverters like the 7404s on the critial connections so that they will be HIGH when the Arduino starts up.

Friday 12 August 2011

8. SRAM Working.

I managed to get the SRAM chip working. I only have a limited number of pins on the Arduino and I needed 4 just to control the chip. I decided to use 3 pins for the address lines and 3 more pins for the data lines. All other pins on the chip I connected to ground effectively making them low or 0. With this configuration I can read/write the values 0 to 7 to the memory addresses 0 to 7 because 7 is the biggest value you can make with 3 binary digits 111 = 1x4 + 1x2 + 1x1 = 7.

There are 17 address lines on this SRAM chip I'm using labelled A0 through to A16 and that allows 217 memory addresses which is 131072 or 128K. In today's world this is an insignificant amount of RAM, but to put it into perspective, the Sinclair ZX80 had 1K of RAM and a 4K ROM, the ZX81 had 1K RAM and an 8K ROM, the Spectrum had 48K of RAM and a 16K ROM.

Wednesday 10 August 2011

7. Writing machine code.

It would be fair to say that you can't talk to the Z80 in English, or any other language come to that.  It will however accept an 8 bit byte with a value in the range from 0 to 255 or 00 to FF in hexidecimal ( I wont explain how to convert decimal into hex or visa versa, suffice to say your PC's calculator program should be able to do it if you're interested).

If I put 00 on the data lines (basically I grounded them all for now so they are always set at 00) when the Z80 fetches the next instruction, it will read 00 and execute the NOP (No Operation) instruction, and do nothing.  This is a valid instruction for the Z80.  As each instruction byte takes 4 clock tics to process, a processor running at 1MHz will take 4us (4 micro seconds) to do nothing.  This is very useful for timing, because like in the real world when you're waiting for something to happen, you might just sit there and do nothing.

Anyway,  it not easy knowing all the values of all the commands, its much easier to know an instruction by name such as NOP.

Consider the following Z80 program:
LD A,1   ; Load A with 1
LD B,2   ; Load B with 2
ADD A,B  ; Add B to A
HALT     ; Stop

This converts into the following values in hex machine code:
3E 01  ; Load A with 1
06 02  ; Load B with 2
80     ; Add B to A
76     ; Stop
Now as you can see the program was easier to understand than the 6 bytes that the Z80 needs to receive to make it happen. What we need is something that will assemble the bytes from the written commands. As it happens there is a Z80 Assembler program called z80asm which will do it for you.  So this is what I am going to use to create the bytes that I will store in the EEPROM to instruct the Z80 what to do.

6. Memories

Well a CPU is not much good unless you can send instructions to it. They have to be stored somewhere, so you need memory. Now there are various types of memory chip and the most common types are RAM (Random Access Memory) which is fast, but forgets everything once power is switched off, and ROM (Read Only Memory) which keeps it contents after power down.

RAM is good for storing all things that change such as calculation results, the current colour of a pixel on the screen, the location of your pieces in a chess game. There are many uses. ROM on the other hand is fixed. The BIOS which is the program that initially starts your PC is stored on a ROM. It never changes. It can't change, and this makes it difficult to use in an experimental way because like CDs, once written at the factory, they can't be overwritten. We could use a PROM (Programmable Read Only Memory), but this is like a CD-R once you've finished writing to it, you can't overwrite or erase it either. There are EPROMS (Erasble Programmable Read Only Memories) but tend to need ultraviolet light to shine on them to erase them, hardly convenient. There is a better solution EEPROMS (Electrically Erasable Programmable Read Only Memories)

There is also a kind of half way house with SRAM (Static Random Access Memory) which is like RAM but will remember everything if you keep a low voltage applied as used by the BIOS to store settings and backed up with something like a CR2032 battery for when the power is switched off. They last for several years.

For my computer I am going to use an SRAM and EEPROM , which will effectively be my RAM and ROM.

The Z80 has 16 lines for addressing memories and 8 lines for the data. Back in the 80s, memories with similar pins were abundant but these days you have to go and hunt for them. I found some at Farnell's, it came to about £10 but I couldn't order with a credit card unless I bought £20 (pre VAT) worth of good, so I got 35 of each Red, Green and Yellow LEDs. The order arrived today - yay.

I got the ALLIANCE MEMORY AS6C1008-55PCN - SRAM and the ATMEL - AT28C64B-15PU - EEPROM.  Need to read the data sheets and understand how they work so it'll be a while before I get going with these yet.  The Arduino will help.

5. Here's one I made earlier...

I bought a breadboard from Maplin and some jump wires and put the ICs (intergrated circuits, that'll be the computer chips then), and some LEDs to the address pins of the Z80 and a bright blue LED on the clock. I did try initially putting the blue LED in-line but for some reason it wouldn't light up so I assumed it didnt have enough power to drive it (it was a HIGH line state before going into the inverter) , so I took a feed off the 'active low' state of the CLK signal from the 74LS04 and fed it back in and inverted the signal again and then connected the blue LED to that and it lit up like a dream. The hex inverters also have their own power supply and can boost a signal coming in. I think they're also known as 'buffers'.

Anyway, here it is all wired up ready to go:



This is the Arduino program I wrote to talk to the Z80:
/*
Zilog Z80 Controller
*/

const int CPU = 0;
const int PIN = 1;
const int DIR = 2;
const int STS = 3;


/* low states = true */
int CLK[4]    = {06,13,OUTPUT,LOW}; // in
int INT[4]    = {16,0,OUTPUT,LOW}; // in
int NMI[4]    = {17,0,OUTPUT,LOW}; // in
int HALT[4]   = {18,12,INPUT,LOW};  // out
int MREQ[4]   = {19,11,INPUT,LOW};  // out
int IORQ[4]   = {20,10,INPUT,LOW};  // out
int RD[4]     = {21,9,INPUT,LOW};  // out
int WR[4]     = {22,8,INPUT,LOW};  // out
int BUSACK[4] = {23,7,INPUT,LOW};  // out
int WAIT[4]   = {24,0,OUTPUT,LOW}; // in
int BUSRQ[4]  = {25,0,OUTPUT,LOW}; // in
int RESET[4]  = {26,6,OUTPUT,LOW}; // in
int M1[4]     = {27,5,INPUT,LOW};  // out
int RFSH[4]   = {28,4,INPUT,LOW};  // out

int OLDM1[4]  = {27,5,INPUT,LOW};

int T = 0;

void setup() {                

  // Define Pins
  pinMode(CLK[PIN],   CLK[DIR]);
  pinMode(M1[PIN],    M1[DIR]);
  pinMode(RESET[PIN], RESET[DIR]);
  pinMode(HALT[PIN],  HALT[DIR]);
  pinMode(MREQ[PIN],  MREQ[DIR]);
  pinMode(IORQ[PIN],  IORQ[DIR]);
  pinMode(RD[PIN],    RD[DIR]);
  pinMode(WR[PIN],    WR[DIR]);
  pinMode(BUSACK[PIN],  BUSACK[DIR]);
  pinMode(RFSH[PIN],  RFSH[DIR]);
  
  // Setup Serial Port
  Serial.begin(9600);

  // Reset CPU
  Serial.println("CPU Reset");
  delay(500);
  RESET[STS]=HIGH;
  digitalWrite(RESET[PIN],RESET[STS]);
  delay(2000);
  RESET[STS]=LOW;
  digitalWrite(RESET[PIN],RESET[STS]);
}

void loop() {

  //Start Clock Period T

  digitalWrite(CLK[PIN],CLK[STS]);
  
  delay(500);
 
  // Read Machine Cycle Status M  Clock High
  M1[STS]=digitalRead(M1[PIN]);
  HALT[STS]=digitalRead(HALT[PIN]);
  MREQ[STS]=digitalRead(MREQ[PIN]);
  IORQ[STS]=digitalRead(IORQ[PIN]);
  RD[STS]=digitalRead(RD[PIN]);
  WR[STS]=digitalRead(WR[PIN]);
  BUSACK[STS]=digitalRead(BUSACK[PIN]);
  RFSH[STS]=digitalRead(RFSH[PIN]);
  

  Serial.print(T);
  Serial.print("=");
  Serial.print(CLK[STS]);
  Serial.print(" M1=");
  Serial.print(M1[STS]);
  Serial.print(" HALT=");
  Serial.print(HALT[STS]);
  Serial.print(" MREQ=");
  Serial.print(MREQ[STS]);
  Serial.print(" IORQ=");
  Serial.print(IORQ[STS]);
  Serial.print(" RD=");
  Serial.print(RD[STS]);
  Serial.print(" WR=");
  Serial.print(WR[STS]);
  Serial.print(" RFSH=");
  Serial.print(RFSH[STS]);
  Serial.print(" BUSACK=");
  Serial.print(BUSACK[STS]);
  Serial.println();

  if(M1[STS]==HIGH && OLDM1[STS]==LOW) {
    Serial.println("----M1 Starts----");
  }
  OLDM1[STS]=M1[STS];

  CLK[STS]=!CLK[STS];
  T=T+CLK[STS];
} 

Tuesday 9 August 2011

4. The Decoupling Capacitor.

Now stuff that I tell you on this blog is what I am learning as I go. This is no exception. I had no idea what a Decoupling Capacitor was. I kind of knew what a capacitor was. Its similar to the hot water tank in the loft in its function. As you use hot water, it refills the hot water boiler, then it in turn is refilled from the mains water supply. Similarly if you connect a capacitor between the +5V and GND pins on the Z80 CPU it will fill with charge so that when the CPU starts to drain the battery by turning pins on and off the capacitor can take up the slack and keep the CPU with voltage. I used a 0.1uF (microfarad) capacitor. It needs to be as close to the CPU as possible so I just straddled the capacitor directly over the CPU.

Ideally you'll have one on every logic chip, but I opted to just put one on the whole circuit so just decoupled the main +5V supply and ground.

3. What NOT?

Now it kind of goes against the grain coming from a software angle that something is ON when it is OFF and visa versa. I like 0 to represent OFF and 1 for ON. However all the control pins on the Z80 are 'Active Low' which means from a software point of view I have to turn a pin on the Arduino OFF to turn something ON on the Z80. Yes I know very confusing. Fortunately there are logic chips that can switch that around for you. I used some 74LS04 Hex Inverters. Basically on each chip you can stick in a high voltage and get a low voltage out and visa versa. One pin goes in, one comes out and there are 6 pairs (hence the Hex). Now the Z80 has 13 control pins and so I opted to get 2 Hex Inverters. Ok so that lets me control 12 pins on the Z80, so I will just hook up any pins I don't really need to use at this stage to the +5V supply (remember high voltage means OFF).

At this point I would like to thank Hackman's Realm for a description of how to get a Z80 working. After several attempts at wiring the Z80 to the Arduino I am surprised I didn't blow one of them up by connecting thing up the wrong way, and Hackman's document put me on the right path (I did say I didnt know what I was doing at the start :) ).

So now I can tell the Arduino to set a pin HIGH i.e. ON and via the 74LS04 chip the Z80 gets a LOW signal turning the pin ON.

So what I send to the CPU is NOT what I sent but satisfies the 'active Low' requirements and everyone is happy!

2. Arduino hook up.


Last Christmas, I got my wife to buy me an Arduino UNO. I'd had a passing interest in electronics from an early age when my father gave me his Denshi Block electronics set to play with. I just had to open the book of projects and place the components exactly as in the picture, connect up the battery and annoy my mother playing the electronic cat sound all day. So I knew from an early age, what the components were, but not necessarily what they did. This probably lead to me blowing up my ZX Spectrum by adding a reset switch and kind of put me off wiring up anything else and breaking it and instead I entered the world of software.

For £20, the Arduino has all the electronics, all I need to do is program it on the PC to turn a pin on and light up an LED and my interest in electronics is rekindled. If I break it, well I could fork out another £20.

I had a brief play with the UNO at Christmas but don't get much time to play with it until about 8 months later i.e. now. Having tamed the electronic beast and even got it to drive a 16x2 LCD display from Maplin, I start to look for a project. So I buy the Z80 CPU. Fortunately it was the better choice for a project as it can be easily hand cranked, compared to other processors of the same era e.g. the MOS 6502.

All CPUs need a pulse to come alive. Pin 6 on the Z80 the Clock Input and this expects to see a voltage go low then high, then low then high etc. Each time the voltage goes low, the processor moves on a step. For the Z80 it takes at least 4 clock tics to process an instruction. Ultimately the Z80 should be able to jog along at 1 million tics per second or 1 MegaHertz (MHz). I want to understand how the Z80 ticks (no pun intended) and to do this I want to see changes happen visibly (such as an LED going on and off) so I want to control the frequency of the tics.

I begin to wire up the Z80 to the Arduino...

1. Journey begins... well continues.

Back in the 80's, when I was a teenager I had a Sinclair ZX80 (which evolved into a ZX81 via an 8K ROM replacement) and a Sinclair ZX Spectrum. Apart from the obvious Sinclair brand attachment, they all were underpinned by the Zilog Z80 Processor. After getting to grips with the BASIC programming language I discovered the world of machine code programming, writing code that spoke directly to the core of the machine, and so my journey began.

Luckily for me the Z80 was all wrapped up in a nice hardware parcel courtesy of Sinclair Research Ltd with memory, a keyboard and able to hook up to a TV via an aerial input (how quaint!). I didn't have to know about electronics, all I needed to know was how to store bytes representing the Z80 instruction code into memory via the old POKE command and then executing it to do whatever I had dreamed up that day.

My affair with the Z80 came to an end after I tried to wire up a reset switch directly to the chip. It never worked again after that and my Sinclair ZX Spectrum became a door stop.

By this time, the Personal Computer had arrived on the scene and my attention was drawn to this new and shiny world.

25 years later, and after a conversation reminiscing about the good old days of the Z80 and 6502 processors I end up buying a Z80 chip for £5 off of eBay and my journey continues...