NOP interrupt polling

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

JonteP
Posts: 10
Joined: Tue Aug 14, 2018 5:32 am

NOP interrupt polling

Post by JonteP » Thu Sep 06, 2018 10:54 pm

I'm sorry if this is something obvious, but I couldn't find any information about this.

I was failing Blargg's ppu_vbl_nmi test suite #8: nmi_off_timing.
(here nmi is disabled right before vblank and the test checks whether NMI triggers)

I noticed that I could pass this by not polling for interrupts during the last NOP cycle.

But fixing this instead breaks another test from cpu_interrupts_v2, #5: branch_delays_irq
(this one checks the conditions under which branches polls for interrupts)

So, obviously both can't be right, but which one is? Does int. polling occur during a NOP or not?

Thanks!
J

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

Re: NOP interrupt polling

Post by Zepper » Fri Sep 07, 2018 7:27 am

(INTs = NMI and IRQ acknowledgement)

1. There are different NOPs due to the different addressing modes. You're (probably) taking opcode $EA as NOP. The quick answer here is YES - you should poll INTs normally.

2. If branch is taken, the 3rd cycle is executed without polling INTs. If the page was crossed, an extra read is performed - yes, you poll INTs normally.

3. About the PPU timing, set a temp_flag=true 1 PPU cycle before the VBlank *and* request an NMI if enabled. On $2002 read, if temp_flag == true, clear the flag and the requested NMI. On VBlank cycle, set $2002:$80 only if temp_flag remains true.

JonteP
Posts: 10
Joined: Tue Aug 14, 2018 5:32 am

Re: NOP interrupt polling

Post by JonteP » Fri Sep 07, 2018 11:42 am

Zepper wrote:(INTs = NMI and IRQ acknowledgement)

1. There are different NOPs due to the different addressing modes. You're (probably) taking opcode $EA as NOP. The quick answer here is YES - you should poll INTs normally.

2. If branch is taken, the 3rd cycle is executed without polling INTs. If the page was crossed, an extra read is performed - yes, you poll INTs normally.

3. About the PPU timing, set a temp_flag=true 1 PPU cycle before the VBlank *and* request an NMI if enabled. On $2002 read, if temp_flag == true, clear the flag and the requested NMI. On VBlank cycle, set $2002:$80 only if temp_flag remains true.
Thanks for a very helpful answer!

Yes, I forgot to mention that it's the $ea NOP I'm talking about. So, is this dependent on the NOP opcode?

I'll be sure to try out your suggestion!

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

Re: NOP interrupt polling

Post by Zepper » Fri Sep 07, 2018 2:50 pm

JonteP wrote:Yes, I forgot to mention that it's the $ea NOP I'm talking about. So, is this dependent on the NOP opcode?
For some reason, this is the NOP opcode used for the test. Nothing more.

User avatar
rainwarrior
Posts: 7814
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NOP interrupt polling

Post by rainwarrior » Fri Sep 07, 2018 3:51 pm

I'm just curious what is meant by "polling" here? Doesn't an IRQ just occur after any instruction concludes? What does it mean if "the 3rd cycle is executed without polling INTs"?

In the case of the NMI cancelling read, yes it would matter there which cycle the read occurs, but for an IRQ why would you have to check it in the middle of any instruction?

User avatar
koitsu
Posts: 4217
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: NOP interrupt polling

Post by koitsu » Fri Sep 07, 2018 4:14 pm

^ I'm wondering this myself too.

And no, I haven't yet read the wizard's tome that is http://wilsonminesco.com/6502interrupts/ (and I'd say 75% of that page is talking about interfacing with other ICs that induce hardware IRQ), but the diagram in section 1.3 indicates exactly the above (which also correlates with everything else I've read in books and otherwise).

So what exactly is meant by:

1. "the 3rd cycle is executed without polling INTs" (yes I know nop is a 3-cycle instruction),
2. "the NMI cancelling reading"

For #1, is this because nop is actually handled differently (internal to the CPU) than other instructions, given that it "does nothing"? My gut feeling is that that's the case, but some better phrasing/clarification would be beneficial.

As for branch instructions -- I really don't understand/get this (see: interrupts should only fire after the instruction is executed; I don't even understand how/why the +1 cycle addition for page crossing would matter).

I'd love for Garth to chime in here on this too, if at all possible.

Questions questions questions!

Sour
Posts: 813
Joined: Sun Feb 07, 2016 6:16 pm

Re: NOP interrupt polling

Post by Sour » Fri Sep 07, 2018 4:23 pm

IIRC, the IRQ signal is checked/polled on the 2nd-to-last cycle of all instructions (I feel like there is a small exception to this, might be the bit about page crossing branches). So it's possible for another instruction to execute before the IRQ handler is called if the IRQ signal is set too late during the current instruction.

There is nothing different about NOP vs other instructions in terms of the IRQ timing, afaik, though.

User avatar
rainwarrior
Posts: 7814
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NOP interrupt polling

Post by rainwarrior » Fri Sep 07, 2018 4:35 pm

Ah, so you're saying there is effectively a 1 cycle delay between when an IRQ happens and when it applies (in most cases)? That is interesting.

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

Re: NOP interrupt polling

Post by Zepper » Fri Sep 07, 2018 8:39 pm

Quote from the sources...

Code: Select all

; A taken non-page-crossing branch ignores IRQ during
; its last clock, so that next instruction executes
; before the IRQ. Other instructions would execute the
; NMI before the next instruction.
That means the 3rd cycle.
rainwarrior wrote:I'm just curious what is meant by "polling" here? Doesn't an IRQ just occur after any instruction concludes?
And what could it possibly BE? Well, IRQ and NMI acknowledgement during the last cycle of an instruction. Again, "acknowledge" means triggering an IRQ/NMI after the current instruction *IF* previously requested.

Again if not clear enough... A taken non-page-crossing branch ignores IRQ during its last clock.
Last edited by Zepper on Fri Sep 07, 2018 8:46 pm, edited 2 times in total.

User avatar
koitsu
Posts: 4217
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: NOP interrupt polling

Post by koitsu » Fri Sep 07, 2018 8:43 pm

Wow, this is the first I've heard of IRQ and NMI differing in behaviour, particularly tied to specific opcodes (re: how the underlying opcodes are implemented in silicon). Yikes.

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

Re: NOP interrupt polling

Post by Zepper » Fri Sep 07, 2018 8:47 pm

Sour wrote:There is nothing different about NOP vs other instructions in terms of the IRQ timing, afaik, though.
You're right.

User avatar
koitsu
Posts: 4217
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: NOP interrupt polling

Post by koitsu » Fri Sep 07, 2018 8:54 pm

Would it help folks if I asked Blargg to chime in here (unlikely), or if I asked him to read this thread + posted a verbatim answer/reply on his behalf?

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

Re: NOP interrupt polling

Post by Zepper » Fri Sep 07, 2018 9:07 pm

koitsu wrote:Would it help folks if I asked Blargg to chime in here (unlikely), or if I asked him to read this thread + posted a verbatim answer/reply on his behalf?
He left the forums a long time ago for reasons of his own, and we should respect him.

The test file is 5-branch_delays_irq, from cpu_interrupts_v2 package.

Sour
Posts: 813
Joined: Sun Feb 07, 2016 6:16 pm

Re: NOP interrupt polling

Post by Sour » Fri Sep 07, 2018 9:30 pm

I was starting to think I might be remembering some details wrong, but it looks like all of this is properly documented on the wiki already: http://wiki.nesdev.com/w/index.php/CPU_interrupts

User avatar
rainwarrior
Posts: 7814
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NOP interrupt polling

Post by rainwarrior » Fri Sep 07, 2018 10:56 pm

koitsu wrote:what exactly is meant by "the NMI cancelling reading"
If you read status from $2002 on the same cycle that the NMI hits, the NMI flag is cleared before the interrupt happens and it's "cancelled", and the read also returns a 0 for vblank status.

It's the reason why you can't really use a bit $2002 polling loop to time a frame, it will only reliably wait "at least" one frame, but if you're unlucky it'll be more.
Wow, I hadn't even heard of interrupt hijacking. That looks like quite a problem :S though I guess the NMI shines through to the top which is the most important, and an IRQ will still be pending once it returns anyway... but weird to think though that a BRK coinciding with an NMI could fail to trigger the IRQ handler, didn't know about that possibility.

Post Reply