Skip to content

Interrupts

Manuel Sainz de Baranda y Goñi edited this page Dec 31, 2025 · 15 revisions

Apart from the special reset, which can be considered a pseudo interrupt, the Z80 provides two types of interrupts.

Non-maskable interrupt (NMI)

The non-maskable interrupt takes priority over the maskable interrupt and cannot be disabled under software control. Its usual function is to provide immediate response to important signals.

The Z80 CPU responds to an NMI request by pushing PC onto the stack and jumping to the ISR located at address 0066h. The interrupt enable flip-flop #1 (IFF1) is reset to prevent any maskable interrupt from being accepted during the execution of this routine, which is usually exited by using a reti or retn instruction to restore the original state of IFF1.

The Z80 CPU does not accept a second NMI during the NMI response. Therefore, it is not possible to chain two NMI responses in a row without executing at least one instruction between them.

M-cycle Type T-states
1 NMIA 5
2 Memory Write 3
3 Memory Write 3

Maskable interrupt (INT)

The maskable interrupt is enabled and disabled by using, respectively, the instructions ei and di, which control the state of the interrupt enable flip-flops (IFF1 and IFF2). The Z80 CPU does not accept this kind of interrupt during an ei instruction. This allows ISRs to return without the danger of being interrupted immediately after re-enabling interrupts if the /INT line is still active, which could cause a stack overflow.

The instructions reti and retn do not accept the maskable interrupt if IFF1 and IFF2 do not have the same state prior to the execution of the instruction, which can only be caused by an earlier NMI response.

Once accepted, the Z80 CPU responds to the INT request by producing an INT acknowledge M-cycle (INTA), which indicates that the interrupting I/O device can write to the data bus. The CPU adds 2 wait T-states to this M-cycle, allowing sufficient time to identify which device must insert the interrupt response data (IRD). The first and possibly sole byte of the IRD is read from the data bus during this special M1 cycle.

This interrupt has three operation modes, which are selected through the im instruction:

Mode 0

An instruction supplied via the data bus is executed. Its first byte is read during the INTA M-cycle and, if it is an opcode prefix, additional M-cycles of this kind are produced until the final opcode of the instruction is fetched. Each INTA M-cycle takes as many T-states as its normal M1 counterpart (the opcode fetch M-cycle) plus 2 wait T-states. Subsequent bytes of the instruction are fetched by using normal memory read M-cycles during which the interrupting I/O device must still supply the data. The PC register, however, remains at its pre-interrupt state, not being incremented as a result of the instruction fetch.

Mode 1

An internal rst 38h is executed. The interrupt response data (IRD) read from the data bus during the INT acknowledge cycle is ignored.

M-cycle Type T-states
1 INTA 7
2 Memory Write 3
3 Memory Write 3

Mode 2

An indirect call is executed. The pointer to the ISR is loaded from the memory address formed by taking the I register as the most significant byte, and the interrupt response vector (IRD) read from the data bus as the least significant byte.

Note

Zilog's official documentation states that the least significant bit of the interrupt response vector "must be a zero", since the address formed "is used to get two adjacent bytes to form a complete 16-bit service routine starting address and the addresses must always start in even locations". However, Sean Young's confirmed that there is no such limitation; the CPU fetches the ISR pointer from the specified location regardless of the value of bit 0 of the IRD.

M-cycle Type T-states
1 INTA 7
2 Memory Write 3
3 Memory Write 3
4 Memory Read 3
5 Memory Read 3

Wiki Home

Library usage

Hardware topics

Accompanying material

Clone this wiki locally