Author Topic: CPC Z80 timing  (Read 3031 times)

0 Members and 1 Guest are viewing this topic.

Offline Executioner

  • Supporter
  • 6128 Plus
  • *
  • Posts: 790
  • Country: au
  • WinAPE Developer
    • WinAPE
  • Liked: 374
CPC Z80 timing
« on: 11:28, 27 November 09 »
After many years, I think I've finally worked it out properly! After looking at implementing an accurate emulation of the Z80 at the instruction sub-cycle level in order to get ZX memory contention timing working properly, I thought it would be nice to actually work out how the Z80 timing really gets adjusted by the CPC hardware, and I think I've finally worked it out. Seems to work by aligning memory read and write instructions to every fourth cycle. I've applied this to the full instruction set and it appears to work fine, except for the OUT (C),r instruction, so there's something weird going on with the timing there so the CPC may be modifying the OUT timing in another way, but it doesn't appear to affect OUT (n),A the same way.

Did one of the CPC variants actually had the Gate Array implemented in logic? Does anyone actually have one or better still a circuit schematic or similar?

Offline arnoldemu

  • Supporter
  • 6128 Plus
  • *
  • Posts: 4.959
  • Country: gb
    • Unofficial Amstrad WWW Resource
  • Liked: 1894
Re: CPC Z80 timing
« Reply #1 on: 16:08, 27 November 09 »
After many years, I think I've finally worked it out properly! After looking at implementing an accurate emulation of the Z80 at the instruction sub-cycle level in order to get ZX memory contention timing working properly, I thought it would be nice to actually work out how the Z80 timing really gets adjusted by the CPC hardware, and I think I've finally worked it out. Seems to work by aligning memory read and write instructions to every fourth cycle. I've applied this to the full instruction set and it appears to work fine, except for the OUT (C),r instruction, so there's something weird going on with the timing there so the CPC may be modifying the OUT timing in another way, but it doesn't appear to affect OUT (n),A the same way.

Did one of the CPC variants actually had the Gate Array implemented in logic? Does anyone actually have one or better still a circuit schematic or similar?
"The processor is a Z80A running at a clock frequency of 4.00 MHz (±0.1%). There is logic
that stretches /MREQ and /IORQ using the CPU WAIT facility so that the processor can
only make one access to memory each microsecond." So access to I/O is subject to extra wait states.

It is worth noting to clean up some confusion: The CRTC generates addresses HSYNC, VSYNC and DISPTMG only.

The Gate-Array uses the generated addresses to read 2 bytes to generate pixels for display. At the same time it is also refreshing the RAM (so bad use of the CRTC can make the ram forget it's contents especially on CPC+!), generate final HSYNC, VSYNC for display and also generate WAIT to force the CPU to keep of the RAM when it needs it.

Some people think the CRTC reads pixels for the display, but this is incorrect.

Back to timing:

I also looked at the "internal" timings of each instruction recently when i was fixing the timings in Arnold.

I made a spreadsheet of the opcodes and the actions they were doing, order is based on order defined in zilog documents so not completely confirmed.

I also figured out why the timings are different for some instructions with interrupt acknowledge:
e.g.
INC ss - 6 T states

If executed one after each other:

INC ss
INC ss

This effectively becomes:
4, 2, delay, 4, 2, delay, 4, 2, delay
The delay being the timing being adjusted by the gate-array to give priority to the display.

But if an interrupt comes during this instruction, there are effectively 2 cycles after it  which the interrupt acknowledge can use. After this an opcode fetch is effectively made during the interrupt execution.

So this instruction is shorter when an interrupt is acknowledge immediately after it.

The prototype cpc had the gate array implemented in logic, but finding a schematic or somebody willing to take a picture of it is going to be almost impossible.

timings for out (c),r according to zilog:

4,4,4

4 t for reading first opcode, 4 t for reading second opcode, 4t for i/o write.

but effectively with the added wait this is something like this:

4,4,1,4

because of extra WAIT inserted by cpc hardware. And this is then effectively stretched to 4,4,4,4.

timings for out (n),a according to zilog:

4,3,4

4t for first opcode read, 3t for second opcode read, 4t for i/o write.

if an extra wait is inserted here we are ok it is soaked up by the 3 and effectively becomes 4,4,4.
« Last Edit: 16:15, 27 November 09 by arnoldemu »
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource