it's not 1 instruction latency... it's 1
cycle latency. The status of the I flag is looked at at the start of the last cycle in the instruction -- therefore for an IRQ to trip after an instruction, the I flag must be clear BEFORE the final cycle of the instruction..
Since CLI clears I on the last cycle, an IRQ will be pushed back 1 instruction. Same goes for PLP.
However, RTI changes the I flag
BEFORE the final cycle -- so an IRQ can occur after it.
Basically:
CLI/SEI/PLP: delay by 1 instruction
RTI: no delay
However, it might not always be that simple. See: CLI RTI might not allow any IRQs because in both cases, the I flag can be set before the final cycle. If you look at each instruction at each cycle:
Code:
CLI - 2 cycles
RTI - 6 cycles
CLI (cyc 0) - opcode fetch (I=1)
<---- I flag examined here (I=1) <--+
(cyc 1) - clear I flag, fetch byte, throw away (I=0) |
<---- Do NOT IRQ, I flag was set before last cycle <--+
RTI (cyc 0) - fetch opcode (I=0)
(cyc 1) - fetch next byte, throw away (I=0)
(cyc 2) - inc SP (I=0)
(cyc 3) - pull status (I flag set) (I=1)
(cyc 4) - pull PC low (I=1)
<---- I flag examined here (I=1) <--+
(cyc 5) - pull PC high (I=1) |
<---- Do NOT IRQ, I flag was set! <--+
This is probably why you were getting that error 10
EDIT -- bah, blargg is too fast! or my reply was too long. Either way XD