Watching a Z80 from an RP2350

ibobev1 pts0 comments

Watching a Z80 from an RP2350 – Kevin's Blog

Skip to content

I’m messing around with the Raspberry Pi Pico RP2350 and PIO and at some point want to see if I can hook it up to a Z80.

As a starter, I’ve been experimenting with seeing if I can get an RP2350 to see the Z80 address and data bus in any manner.

I’m using a Pimoroni PGA2350 in my own custom breakout PCB.

The Z80 Bus

There is a lot of detail out there about the Z80 and Z80 bus, so I’m not going to go over that again here, but here are some key references:

http://www.z80.info/ – the home of everything Z80!

The RC2014 bus specification and description.

Electronic Circuits – interfacing with a Z80 microprocessor v3 (data and address buses).

Z80 User Manual – Chapter on "Timing".

Build Your Own Z80 Computer – Steve Ciarcia

The key features relevant to me are:

16-bit address bus (A0-A15).

8-bit data bus (D0-D7).

A number of OUTPUT control lines.

A number of INPUT control lines (including RESET and CLOCK).

The original Z80 was an NMOS device and ran at 2.5MHz (Z80), but there were 4MHz (Z80A) and 6MHz (Z80B) versions soon afterwards. Then the CMOS versions appeared with a whole range of clock speeds, typically 8MHz (Z84C0008) and 10MHz (Z84C0010), and even up to 20MHz (Z84C0020). They were made by a whole host of different manufacturers – Zilog, SGS, ST, NEC, Mostek, etc (more here), but they don’t all seem to have had the same numbering schemes that I could find.

It was discontinued in 2024, although some overseas marketplaces assure me that they can provide brand new 20MHz Zilog Z84C0020’s at less than a few £s each 😉

A Z80 CPU Tester will give an idea of the type and speed of any unknown Z80 found "in the wild" though (I had fun testing a batch of said "20MHz" devices myself).

The Z80 Clock

Of particular interest to me is the clock speed. In particular, what is the minimum clock speed possible? There are some (modern, apparently) versions of the Z80 that are fully static – i.e. they will retain state between clock pulses, including a complete stop. But I’m not clear if most are. But seeing as someone managed to create a hand-cranked, clocked Z80 based computer, I suspect a really slow clock is unlikely to be an issue. There is a note here that it is best to hold the clock HIGH when not being cycled.

Going back to the original Z80A datasheet, we find:

The max clock period is defined in note [12] as:

So basically adding those values together. The max pulse width for LOW has a given value of 2000nS, and the rise and fall times are fixed at 30nS, so key to determining the longest period accepted is the max pulse width for HIGH. That is provided in note [E]:

So the implication is that clock LOWs should be no longer than 2uS, but clock HIGHs in principle can be anything, with guaranteed functionality up to 200uS. This gives a total clock period of at least around 203uS which equates to a clock frequency of just under 5KHz.

This explains the previous noted comment about holding clocks HIGH.

One issue could be that some signals need several clock cycles. In particular, RESET is expected to be held for 3 clock cycles to ensure a proper reset occurs, so that will naturally have to be longer for longer clock pulses.

It is worth noting at this point that the Z80 has two concepts of a cycle: machine (M) cycles and clock (T) cycles (sometimes called states). Machine cycles are multiples of clock cycles (typically 3 to 6 T cycles per M cycle). Many Z80 instruction references will list the number of cycles (M) and states (T) that an instruction will take to execute.

There is also the option for an external peripheral (e.g. memory) to get the Z80 CPU to wait. This involves asserting the /WAIT signal until the peripheral is ready to continue. This allows synchronisation between the CPU and slower memory.

Part of the consequence of all this is that a single-clock-cycling option isn’t particularly useful, as it will need several steps of the single-cycle clock to execute a single Z80 instruction.

For interest, there is an instruction-aware single-stepper circuit in the Build Your Own Z80 Computer book (figure 4.5), which can monitor /M1 and use /WAIT to pause the CPU until the next step.

RP2350 GPIO

I’m using the Arduino Pico core from here: https://github.com/earlephilhower/arduino-pico

Which makes it easy to build and download code to the RP2350, but I’m trying to stick to Pico C/C++ SDK functions rather than using the Arduino environment overlays.

To initialse GPIO on an RP2040/RP2350 requires the following:

gpio_init(pin);<br>gpio_set_dir(pin, dir);<br>gpio_put(pin, value);<br>value = gpio_get(pin);

But this is too slow for a bus read. But there is an option to act on several GPIO pins at the same time, for example:

gpio_init_mask(gpiobitmap);<br>gpio_set_dir_in_masked(gpiobitmap);<br>gpio_clr_mask(gpio_bitmap);<br>gpio_set_mask(gpio_bitmap);<br>uint32_t value = gpio_get_all();

But these APIs were designed with the RP2040 in mind, and so only...

clock cycles rp2350 pico value instruction

Related Articles