CLI latency now...

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

CLI latency now...

Post by Zepper »

- Here, I'm really unsure about this. I'm getting error 10) CLI RTI should not allow any IRQs. If I delay the I flag clearing by 1 instruction, so it gives error 4) Exactly one instruction after CLI should execute before IRQ is taken.

- Could you clarify the CLI behaviour? Should I latch the pending IRQs and restore them after the 'one instruction latency' ???
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

IRQs aren't latched, so the CPU will only vector an IRQ if the IRQ line is asserted when the CPU is checking it. CLI clears the I flag after the next-to-last clock, so the IRQ line won't get checked until late in the next instruction, thus the interrupt can't occur immediately. Unlike CLI, RTI restores the I flag early enough that it takes effect immediately. So if you have the IRQ line asserted continuously, the I flag set, and a value with bit 2 set on top byte of the stack (i.e. $04), executing CLI then RTI will not result in an interrupt.

Unlike the corresponding delayed effect of SEI, one of those obscure things Quietust referred to elsewhere, the delayed effect of CLI could easily be an important detail that some things rely on.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

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: Select all


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
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

Here:

Code: Select all

CLI (cyc 0)   -   opcode fetch                              (I=1)
              <----  I flag examined here                   (I=1)  <--+ 
The I flag examined here means check for any pending IRQs and trigger it..?

By the way, is the NMI triggered before the last cycle too?
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Fx3 wrote:The I flag examined here means check for any pending IRQs and trigger it..?

Not really.

The IRQ does not happen before the last cycle. The IRQ happens 'between' instructions like you'd expect.


However! The status of the I flag between instructions does not matter as the CPU has already decided whether or not an IRQ will trip before the last cycle of the previous instruction occured.

Code: Select all

<-+  if I is set here...
  |
<-+  ...IRQ will not trip here
By the way, is the NMI triggered before the last cycle too?
Well again -- an NMI will only happen 'between' instructions.

However, yes, there is that 1 cycle delay between when an NMI is "tripped" and when it actually happens. For the same reason that delay exists for IRQs.
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Disch wrote:EDIT -- bah, blargg is too fast! or my reply was too long. Either way XD
Your diagram was better. It's nice to not be the only one who can explain these things here. Thanks.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

Fixed.

Code: Select all

    (cyc 4)   -   pull PC low                               (I=1)
              <----  I flag examined here                   (I=1)  <--+ 

- I just had to insert the IRQ flag examination in the RTI code... boom!
Post Reply