It is currently Sun Sep 23, 2018 4:00 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: NOP interrupt polling
PostPosted: Thu Sep 06, 2018 10:54 pm 
Offline

Joined: Tue Aug 14, 2018 5:32 am
Posts: 8
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


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 7:27 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3154
Location: Brazil
(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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 11:42 am 
Offline

Joined: Tue Aug 14, 2018 5:32 am
Posts: 8
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!


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 2:50 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3154
Location: Brazil
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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 3:51 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6818
Location: Canada
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?


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 4:14 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3606
Location: Mountain View, CA
^ 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!


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 4:23 pm 
Offline

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 516
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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 4:35 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6818
Location: Canada
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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 8:39 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3154
Location: Brazil
Quote from the sources...
Code:
; 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.

Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 8:43 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3606
Location: Mountain View, CA
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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 8:47 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3154
Location: Brazil
Sour wrote:
There is nothing different about NOP vs other instructions in terms of the IRQ timing, afaik, though.

You're right.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 8:54 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3606
Location: Mountain View, CA
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?


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 9:07 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3154
Location: Brazil
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.


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 9:30 pm 
Offline

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 516
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


Top
 Profile  
 
PostPosted: Fri Sep 07, 2018 10:56 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6818
Location: Canada
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.

Sour wrote:
http://wiki.nesdev.com/w/index.php/CPU_interrupts

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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group