6

I'm trying to emulate an Amstrad CPC 464. Currently, I'm working on interrupt handling and I'm wondering: Some Z80 instructions, like EI or decoding multiple consecutive 0xdd prefixes don't accept interrupts occurring directly after them.

Are interrupt requests remembered until when they can next be accepted or could they be lost? The second option seems problematic for me, but I can't find any explicit documentation.

In the case of the EI instruction it seems the Z80 can just ignore the interrupt request outright, because interrupts are currently not enabled, but what happens in the case of the prefix? Is the interrupt acknowledged after the next instruction has been executed? The reason why I'm confused about this is that I read that the interrupt request signal generated by the gate array only lasts about 1.4 microseconds, which even is shorter than some instructions.

For reference, here is where I got the 1.4 microseconds from.

2
  • 4
    I had the belief that the CPC holds the interrupt line until it sees an interrupt acknowledgement cycle, but cannot find a reference. I'll see whether I can dig anything out. – Tommy May 24 at 14:11
  • 3
    Agree with Tommy in that it's generally the peripheral that controls an interrupt line, not the CPU. i.e IRQ is an input. – Brian H May 24 at 14:16
8

According to this CPCTech entry:

In the CPC the Gate Array generates maskable interrupts, to do this it uses the HSYNC and VSYNC signals from the CRTC, a 6-bit internal counter and monitors the interrupt acknowledge from the Z80.

...

When [counter conditions are met] the Gate-Array will issue a interrupt request to the Z80, the interrupt request remains active until the Z80 acknowledges it.

...

When the interrupt is acknowledged, this is sensed by the Gate-Array. The [counter is suitably manipulated] and the interrupt request is cleared.

So, the process is:

  1. the gate array starts signalling the interrupt;
  2. the Z80 does whatever it does (see Raffzahn's excellent-as-always answer for more on that);
  3. upon the Z80 acknowledging the interrupt — which it'll do only when it's actually acting upon it — the gate array will stop signalling the interrupt.

So to answer your question directly: the interrupt request may last indefinitely, continuing until the Z80 acknowledges an interrupt.

2
  • 2
    I'm accepting this answer, because it answers my question directly. But I learned something valuable from the other excellent answers as well. – mdm May 25 at 14:21
  • 1
    @mdm That's the evidence that you asked a truly good question. So, thank you! – Brian H May 25 at 14:34
9

but I can't find any explicit documentation.

The documentation for the Z80 behaviour is in its manual. For the way the CPC hardware handles it, you may need to see these circuits. It may, for example hold an IRQ until it is accepted.

but what happens in the case of the prefix? Is the interrupt acknowledged after the next instruction has been executed?

The same way as when an interrupt occurs half way through an instruction.

The reason why I'm confused about this is that I read that the interrupt request signal generated by the Gate Array only lasts about 1.4 microseconds, which even is shorter than some instructions.

The linked page does not really show if that is linked to any kind of CPU response or not. It would be unusual to assert INT only for a time that short. To me this rather seems like a single shot recorded where the CPU simply reacted to the Interrupt within 1.4 µs. Without further clarification, I'd be a bit sceptical about this being valid in general.

Then again, the CPC timing is kind of complicated. For one thing, instructions are synchronized to video execution, and timer handling does include a correction factor, so the answer to this case may be less Z80-related and more due to the way the CPC operates.


Z80 Interrupt Initiation

The Z80 Technical Manual does describe the interrupt signals and their behaviour already in full on page 8:

enter image description here

(Taken from Z80-CPU Technical Manual of 1976)

As described, the IRQ is level sensitive, so any request must be held low until it is recognized - any circuit design should hold it low at least until acknowledged (IORQ active while M1 is active), or better until service started. It will only be recognized at the beginning (raising clock) of the last T-State of the last instruction and only if there is no higher priority issue - such as NMI or BUSRQ. To do so it must be low for at least 80 ns before the rising clock edge.

NMI in contrast is edge triggered. An occurrence at any time during processing will be recorded (minimum needed pulse width is 80 ns), but handling is postponed until the end of the actual instruction (*1).

For more information, there is a high quality 'rewrite' of the May 1978 The Z80 Family Program Interrupt Structure.


*1 - In fact, the detailed description of NMI on page 17/18 seems to hold a copy/paste error - that got corrected in later manuals.

2
  • "any circuit design should hold it low at least until acknowledged or better until service started" -- then ZX Spectrum is definitely NOT an ANY circuit. :) It has fixed INT pulse length. – lvd May 24 at 19:08
  • @lvd Erm, there will always be that one different design ... just, why do I have the feeling that the name Sinclair more often creeps up than any other names? (A bit) More serious, AFAIR, the INT signal is held down for 32 clock cycles. that's way longer than any Z80 instruction, so technically it is held down until acknowledged - as withing 32 clocks the Z80 (in a basic Spectrum) will always have issued an ACK, wouldn't it? – Raffzahn May 24 at 19:53
5

As far as I know, no /INT is remembered as it is purely level-triggered, as @Raffzahn noted. So losing interrupts in your conditions is just expected.

Same design is in ZX Spectrum, with probably a longer pulse. Some ZX clones are even capable of catching interrupt several times when the interrupt routine is as simple as EI:RET.

EI disables interrupt recognition in itself, so interrupt can't follow EI execution. Prefixes are disabling interrupt recognition for themselves until valid non-prefixed opcode is executed, so that the full prefixed command, no matter how many prefixes it had, can execute interrupt after itself.

2
  • EI enables interrupts, but I think it affects internal state too late for an interrupt to be recognised immediately afterwards. Apologies if I’ve misunderstood your answer. – Tommy May 24 at 22:05
  • 1
    No, effectively enabling interrupts after next insn is by design. The reason for that is to allow every interrupt handler to return (EI:RET) before entering next handler. Otherwise there will be stack overflow during heavy interrupting conditions. – lvd May 25 at 6:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.