NMI & IRQ
Moderator: Moderators
-
- Posts: 4
- Joined: Sun Dec 30, 2007 4:42 am
It seems like the print functions (print_x, print_y etc.) leaves the PPU rendering ON, causing it to go into its +0/-1 odd-frame-cycle mode. Won't this cause a problem for the sync_nmi routine (it says the rendering should be OFF)? If I disable it manually before sync_nmi is executed, the test passes, but otherwise not since the NMI will then occur a few PPU clocks too early (before LDA) on the 2nd run.
I'm having the same trouble as FentonCole. I get the following when I run the demo:
It's not totally wrong -- it's just shifted down; there's an extra $23 $00 in there and it's as if the first NMI is occuring 1 clock earlier than it should. But when I take out my skip-odd-cycle implimentation, I get a pass.
I'll have to look at this more later
Code: Select all
$23 $00
$23 $00
$21 $00
$21 $00
$20 $00
$20 $00
$20 $00
$20 $00
$20 $00
$20 $00
$20 $00
$24 $20
I'll have to look at this more later
New, improved, properly tested on my NES at reset time, ca65 source that can be built on anyone's machine, lots of nifty reusable library routines and scrolling text console, and some description of the code organization and philosophy: nmi_during_irq2.zip
At this point I'm not sure how to interpret the result (what's actually happening at each clock), but at least you have something you can compare your emulator to a NES with. And if I've still screwed up like before, don't hesitate to call me on it. Testing on a NES using a more normal devcart would be appreciated.
At this point I'm not sure how to interpret the result (what's actually happening at each clock), but at least you have something you can compare your emulator to a NES with. And if I've still screwed up like before, don't hesitate to call me on it. Testing on a NES using a more normal devcart would be appreciated.
Can't you upload into another server? I'm unable to downl... oh, I already said that, right? 
EDIT: ...got it.

EDIT: ...got it.
Code: Select all
http://www.proxyhustle.com/
Zepper
RockNES author
RockNES author
Thanks for all the excellent work blargg! It's definately appreciated.
I'm having some trouble though. I get the right sequence of numbers... but it still says I failed.
Similar problem with the new BRK test. I get the same results as before (except there's an extra 27 36 00 line in front) but it's saying I'm failing, whereas I pass the old test.
Did the correct output change? Is my checksum wrong? If so, what problem does that indicate?
I'm having some trouble though. I get the right sequence of numbers... but it still says I failed.
Code: Select all
23 00
21 00
21 00
20 00
20 00
20 00
20 00
20 00
20 00
20 00
24 20
24 20
30BFCFCA
FAILED: 2
Similar problem with the new BRK test. I get the same results as before (except there's an extra 27 36 00 line in front) but it's saying I'm failing, whereas I pass the old test.
Did the correct output change? Is my checksum wrong? If so, what problem does that indicate?
-
- Posts: 4
- Joined: Sun Dec 30, 2007 4:42 am
Disch, the last two lines of the nmi_during_irq test should have 25 for the NMI flag, so carry is set, indicating that for these two the NMI is occurring after the SEC at the beginning of the IRQ handler, not before as is apparently happening for yours. What really seems to be going on (to me) internally is that NMI will replace the IRQ if it is asserted during the first five clocks of the IRQ handling; if it occurs during the last two, it will occur after the first instruction of the IRQ handler (fitting in with the usual behavior of NMI). This would mean that the first two "20 00" lines are where the NMI is being asserted during the first and second clocks of the CLC, not the IRQ handling itself.
Rather than trying to understand why this is so (it doesn't really make any logical sense to me), I'll just accept that that's how it works.blargg wrote:What really seems to be going on (to me) internally is that NMI will replace the IRQ if it is asserted during the first five clocks of the IRQ handling; if it occurs during the last two, it will occur after the first instruction of the IRQ handler (fitting in with the usual behavior of NMI).
Anyway I have both working now, and since correct numbers for the new tests have not yet been posted, here they are:
Code: Select all
nmi_during_brk:
27 30 00
26 36 00
26 36 00
36 00 00
36 00 00
36 00 00
36 00 00
36 00 00
27 36 00
27 36 00
nmi_during_irq:
23 00
21 00
21 00
20 00
20 00
20 00
20 00
20 00
20 00
20 00
25 20
25 20
And a recap of behavior for good measure:
-) if an NMI occurs during the first 5 cycles of BRK or IRQ, status is pushed to stack as if it were a BRK/IRQ, but the NMI vector is jumped to instead. IRQ/BRK is effectively supressed. Though an IRQ would still be pending and will occur after RTI unless acknowledged -- but the BRK is completely skipped over.
-) if an NMI occurs during the last 2 cycles of BRK or IRQ, BRK/IRQ proceeds as normal, and NMI occurs after the first instruction following the BRK/IRQ.
I have no clues what's happening here, I got:
- Could you help me?
Code: Select all
23 00
21 00
21 00
25 21
25 21
25 21
...
Zepper
RockNES author
RockNES author
The first column is the flags on entry to the NMI, the second IRQ, or 00 if that handler wasn't executed. The time the IRQ (would) occur is fixed, while the time for the NMI is one clock later on each successive row. This is the code section where the interrupts occur:
The first result row you got was 23 00, so the NMI is firing when the C and Z flags are set, and it's before the LDA #1. Then the next two lines, it's firing when just the C flag is set, so you can see that it must be just after the LDA #1 which clears the Z flag. Then you have 25 21, so the NMI is firing when the I and C flags are set, and the IRQ is firing with just the C flag set. So apparently your IRQ is firing before the CLC, and before the NMI as well (since the NMI occurs when the I flag is set, as it would be inside the IRQ handler). The source code includes similar commentary on the correct sequence for comparison.
Code: Select all
clv
sec
; Z and C set, others clear
; NMI occurs here first,
lda #1 ; clear Z flag
; then here for two clocks,
clc ; clear C flag
; then here.
; IRQ should occur here, but yours seems to be occurring before the clc
nop
@blargg
- You're using frameIRQs. My emulator passes in all APU (and NMI) test ROMs, with no hacks. During the sequence #4 (line 5, or "20 00"), the IRQs start firing (making a request to trigger) before the CLC instruction. This way, a 7-cycles IRQ is started, but a NMI is requested during the 1st of those 7 cycles.
- Is my IRQ timing off even if it passes the APU test ROMs???
EDIT: I fixed my code and it passes. There's an exception though: I cannot figure why a NMI is being requested during a LDX #$01 instruction (2nd byte fetch to be exact), making to trigger right in the end of the instruction, instead of triggering in the next one. I added an hack to acknowledge the NMI request during such instruction. This issue happens on nmi_timing test ROM.
- You're using frameIRQs. My emulator passes in all APU (and NMI) test ROMs, with no hacks. During the sequence #4 (line 5, or "20 00"), the IRQs start firing (making a request to trigger) before the CLC instruction. This way, a 7-cycles IRQ is started, but a NMI is requested during the 1st of those 7 cycles.
- Is my IRQ timing off even if it passes the APU test ROMs???
Code: Select all
23 00
21 00
21 00
20 00
25 21 <- here
25 20
25 21
25 20
25 21
25 20
25 21
25 20
Zepper
RockNES author
RockNES author