So, you think you’re smart and use this code pattern to restore the interrupt state after disabling it:
ld a,i di ; do stuff that does not modify p/v flag ret po ei ret
Bad idea! Because, quote Z80 user manual:
LD A,I
P/V contains contents of IFF2
If an interrupt occurs during execution of this instruction, the Parity flag contains a 0.
In other words, if an interrupt occurs in the wrong place, the interrupt status will be restored incorrectly.
This caused a rare random hang in VGMPlay, which recently became much more reproducible because I now generate a lot more interrupts in my development version. Fortunately this behaviour is also emulated well, so I was able to find the cause relatively quickly.
Even the MSX2 BIOS developers used this pattern for CALSLT / CALLF, and as a result also introduced this rare interrupt restoration status bug. Thus, you must also not rely on CALSLT / CALLF preserving the interrupt state, despite it saying so (on MSX1, I believe it always disables them anyway).
I’m left with asking myself: why, Zilog, why!
Anyone know of a way to reliably determine the interrupt state? I can’t think of any.