According to multiple documentation sources, non-maskable interrupts (NMIs) can be nested (or reentrant) in a Z80 microprocessor.
This is, upon a
/NMI signal pulse, the CPU will interrupt the current program by resetting
IFF1 to disable maskable interrupts, pushing the program counter in the stack and jumping to address 0x0066 to execute the interrupt service routine there.
The point is that a new
/NMI signal pulse can interrupt the ongoing ISR before it ends with a
RETN instruction. This is documented in The Undocumented Z80 Documented and confirmed in other StackExchange questions. When this happens, there is an odd case that, if permitted, would derive in an abnormal situation.
If maskable interrupts were enabled before the NMI was accepted, the first invocation of the ISR will execute with
IFF1 reset and
IFF2 set. This is the well-known mechanism to restore
RETN instruction when ISR terminates, so the user-defined interruption config is honored.
When the second
/NMI pulse is detected before
RETN takes place, a new NMI is accepted by the CPU. It will perform exactly the same procedure as the outer ISR: reset
PC in the stack and jump to 0x0066.
Now let's say the inner ISR ends with a
RETN instruction without any further NMI reentrance. This will copy
IFF1, pop the
PC from the stack, and continue with the execution of the ISR of the outer NMI. As maskable interrupts were enabled since the very beginning, this will effectively enable those interrupts. And the ISR of the outer NMI will execute such that it can be interrupted again by a maskable interrupt.
In other words, nested or reentrant NMIs can derive in situations where maskable interrupts are enabled, and a
/INT signal can interrupt the execution of a NMI. This is equivalent to putting a
EI instruction in the code of the NMI service routine.
After this, I am not sure if there is something I am not considering, or just that this is a flaw of the original design of the CPU. I checked the source code of a few Z80 emulators (MAME included), and all them operate as I am assuming. If that's how the things work, is
/NMI something that have to be used very carefully? Do designers have to consider this and ensure
/NMI cannot have multiple pulses? Or perhaps it is totally OK to have maskable interrupts interrupting NMIs? Am I exaggerating the situation then?