The Z80 CPU runs from [email protected]~90mA

The original Z80 processor can be driven from DC to 2.5 MHz (the Z80A runs to 4 MHz – the one we are focusing on)

So, in order to get the Z80 to run – we need proper power and a system clock.

To get up and running quickly and to provide some flexibility, I am going to use a PIC10F322 to generate the clock signal and hold the processor in reset after power is applied to allow the power to stabilize before releasing the reset.

A PIC10F322can be programmed to output a reference clock. The values it can output are, 4Mhz, 2Mhz, 1Mhz, 500Khz, 250Khz, 125Khz, or 7.75khz.

For this fun project, I will program a reference clock of 125Khz. The clock will be feed into the Z80 Clock pin (6) with a 330Ohm pull up on the clock line. PORTA.2 is the reference clock out on the PIC10F322.

PORTA.0 from the PIC10F322 will connect to the Z80 Reset Line – Pin26 (Active Low). This line will be tied to ground VIA a 10K pull down. This will keep the Z80 in reset, until the 10F322 pulls the line high – after about 500ms (a lot longer than needed) after power on.

PORTA.3 of the PIC10F322 we will attach a pushbutton – normally open to act as a reset. When triggered will drop PORTA.0 low – resetting the Z80 CPU.

Here is the Circuit Diagram

Project Z80 - Clock and Reset Circuit

Here is it laid out on the breadboard

Project Z80 - Clock and Reset Circuit

And how do we know this is working…. D2 is the M1 line from the Z80 CPU
On the Z80 – The M1 line will be pulled LOW doing the start of a machine cycle – to indicate the fetch of an OP code.

It is trying to load – however there is nothing for it to load. Yet..

Timing Logic showing the M1, Reset, and CPU Clock.

 

Project Z80 - Clock and Reset Circuit 
#include <xc.h>
#include <stdint.h>

//Device Configuration
#pragma config FOSC = INTOSC  // Oscillator Selection 
#pragma config BOREN = ON    // Brown-out Reset
#pragma config WDTE = OFF    // Watchdog Timer
#pragma config PWRTE = ON    // Power-up Timer
#pragma config MCLRE = OFF   // MCLR Pin Function Select bit->MCLR pin function is digital input, MCLR internally tied to VDD
#pragma config CP = OFF      // Code Protection 
#pragma config LVP = OFF     // Low-Voltage Programming 
#pragma config LPBOR = ON    // Brown-out Reset Selection bits
#pragma config BORV = LO    // Brown-out Reset Voltage Selection
#pragma config WRT = OFF    // Flash Memory Self-Write Protection

//Used to calculate the delay time - Change depending on processor Speed
#define _XTAL_FREQ 500000  //500Khz

//Prototypes
void setup(void);
void check_button(void);


void main(void)
{
    setup();
    
    while(1)
    {
        check_button();
    }
}

void setup(void)
{
   
    //Disable analog for A.0, set as Output, Set to Low - This will keep the z80 in reset mode until A.0 goes high. 
    ANSELAbits.ANSA0 = 0;
    TRISAbits.TRISA0 = 0; //A.0 Output
    LATAbits.LATA0 = 0;  //Put A.0 low Z80 in reset
    
    //Set the System Clock - You can change this to match the setting you are looking for
    OSCCONbits.IRCF = 0b010;  //Set System Clock to 500Khz FOSC/4 = 125Khz
    CLKRCONbits.CLKROE = 1; //Enable Clock Reference out on RA.2
    
    //Setup the reset sitch    
    WPUAbits.WPUA3 = 1; //Enable Weakpull up on A.3   
    OPTION_REGbits.nWPUEN = 0; //Requires being enabled in option reg as well
    
    __delay_ms(50); //50ms delay
     LATAbits.LATA0 = 1; //Take A.0 high and Z80 out of reset
    
}

void check_button(void)
{
    //Keep in mind a pullup keeps the pin logic high. TO test for button press - the button when pressed with bring the pin to logic 0 or low.
    if (PORTAbits.RA3 == 0)
    {
        __delay_ms(50); //50ms delay checking for button bonce
        
        if (PORTAbits.RA3 == 0)
        {
            LATAbits.LATA0 = 0;  //Put A.0 high Z80 in reset
            
            while (PORTAbits.RA3 == 0){} //Going to wait here if the button is still being pressed button needs to be released before moving on            
             
            __delay_ms(100); //100ms delay
             LATAbits.LATA0 = 1; //Take A.0 high and Z80 out of reset           
        }
        
        
    }
}

–FUTURE PLANS

The PIC10F322 is limited by the number of output pins (4). I will need to use a larger PIC processor to start with.

To expand on this – Add single instruction stepping.

The idea is to use the M1 and Wait lines.

As we know – M1 goes LOW at the beginning of every instruction fetch cycle. Ml signifies that the computer has completed one instruction and is starting on the next.

We would stop the CPU before it executes the next instruction.

And the WAIT line does just that. A LOW signal on WAIT holds the CPU as long as you want in the M1 cycle. When WAIT is back HIGH, the CPU will resume.

Will need to add a switch and button to the PIC. The switch to change run modes and the button to single step.

Maybe, I will even add some interface to the PIC allowing for changing of the CPU clock. That is what I like about this stuff. Whatever you can dream up – you can create.

 

Something You Might Be Intrested In


 

10F32X Rapid Prototype Board

Make The PIC10F322 and other PIC10F Processors Breadboard Friendly for Quick and Easy Prototyping.

{Click to learn more}

Project Z80 - Clock and Reset Circuit