First, I should say that I was slightly surprised because I'd had the idea that a single instruction would be executed after the RTI(*). But, second, I should say that I have a very high degree of confidence in the simulation. If it doesn't match our expectations, we need to think harder!
MichaelM wrote:
The described behavior of that simple code sequence when interrupted just doesn't seem right.
It seems to me that something is not right with the behavior described as it corresponds to the INY instruction. First, I am assuming that the IRQ is asserted before CLI.
I added a couple of NOPs to check that nothing changes - indeed, nothing changes. You can see I've tabulated 'irq'.
Quote:
Second, at the completion of CLI, the interrupt is not immediately taken and the INX instruction is fetched and executed: X += 1. Third, at the completion of the INX, the I mask is not set, IRQ is asserted, so the processor takes the interrupt.
In a sense, I think this is not quite right. I think the processor was already committed to take the interrupt.
Quote:
(I expect that the I bit is cleared in P by CLI not on the falling edge of Phi2 or rising edge of Phi1, but on the rising edge of Phi2. This puts a half cycle delay in the clearing of the I bit, which allows INX to execute.)
Most things change at the fall of phi2/rise of phi1. Indeed, you can see the I bit changes at the beginning of cycle2.
Quote:
The interrupt service routine (ISR) is simply an RTI instruction. To enter the ISR after the INX, the processor does not increment the PC, so it first pushes {PCH, PCL}, which point to INX
In fact, no - this is probably the crux - PC has already been incremented to 3
Quote:
..., and then it pushes P. The processor then updates (sets) the I bit in P and performs a jmp ($FFFE) to get to the RTI instruction of the ISR.
Conceptually it executes a jmp indirect, but (as discussed elsewhere) it's actually executing something rather like a BRK
Quote:
The RTI immediately reverses the process, by pulling P from the stack, pulling PCL for the INX instruction and incrementing it,
Actually no - PC was already pre-incremented
Quote:
... pulling PCH for the INX instruction and incrementing it if a carry occurred (PCL += 1), and then performing a fetch of the INY instruction.
Indeed, we see INY is (re)fetched
Quote:
INY should execute,
But no, it is subsumed by the IR being forced to zero, which causes the BRK-like subsequent behaviour
Quote:
... and at its completion...
Hope this helps somewhat!
Cheers
Ed
(*)In fact, I think what I was misremembering might be the way that the instruction after a CLI will always be executed - precisely because of the pipelining, which means the next instruction is underway as the I bit is cleared.