Sprite OAM and Frame IRQ timing issues

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Sprite OAM and Frame IRQ timing issues
by on (#89751)
Hello everyone!

I'm new here, and I'm developing a NES emulator as a personal project/for fun.

It's getting to be quite accurate, but now I've hit a snag that I can't seem to overcome by myself.

No matter what I try, I can't pass the cpu_interrupts_v2 test #4. (IRQ and Sprite DMA test). It's always off by one instruction at some point.

I've tried fiddling with both Sprite DMA and frame IRQ timings, but to no avail.

So, how many CPU cycles do frame irq/sprite dma take?

- For frame IRQ, I'm counting 29833 cycles if $4017 is set to $00 at an even cycle, and 29834 if it's set at an odd cycle;
- For sprite DMA, I'm counting (after the initial 4 STA cycles), 514 cycles if $4014 is written at an even cycle, or 513 if $4014 is written at an odd cycle. If the IRQ triggers during sprite DMA, I delay it by one instruction;

Is this correct? I've tried many things to no avail, it always fails somewhere, so I must be doing something wrong.

With the timings I described above, this is the result I get:

Image

Thanks in advance for all the help!

by on (#89766)
I seem to have figured out what the problem, there was a bug in a way I was calculating the IRQ when there was a new frame between the $4017 write and the IRQ hitting.

I now (finally) pass the IRQ tests, after a very puzzling week!

I hope the timings are trully correct, though :) If anyone can confirm the timing values I wrote in the previous post, I would be very thankful!

by on (#89776)
crudelios wrote:
I seem to have figured out what the problem, there was a bug in a way I was calculating the IRQ when there was a new frame between the $4017 write and the IRQ hitting.


Do you use timestamp in your emulator?

by on (#89789)
Yes, I precalculate the CPU cycle at which the irq should happen, and then compare it with the current cycle. Seems to be working fine now, incidentally I now also pass the apu even/odd jitter test, which I wasn't passing before.

EDIT: When dealing with frame irqs, after you write to $4017 and the counter reaches 0, it is reset. But in that case, for how many clocks does the CPU run before the next irq? Specifically, should I count the extra even/odd cycle when the counter resets after the irq?

Thanks!

by on (#89794)
As far as I can tell you, the test fails in my emu and in Nintendulator and Nestopia. Mind you to post the correct output screen, plz?

EDIT: quote from my notes...

Quote:
When writing to $4017, the frame counter reset
and the quarter/half frame triggers happen simultaneously,
but only on "odd" cycles (and only after the first "even" cycle
after the write occurs) - thus, it happens either 2 or 3 cycles
after the write (i.e. on the 2nd or 3rd cycle of the next instruction).

After 2 or 3 clock cycles (depending on when the write is performed),
the timer is reset.

If the mode flag is set, then both "quarter frame" and "half frame"
signals are also generated.

by on (#89801)
This is my current output screen:

Image

I'm now struggling with the last test, which is barely working at all (it either hangs or displays completely bogus values), so this is still a work in progress.

Edit: After a whole lot of work, I'm passing all five tests. I'm not sure I'm correctly implementing the delay between APU frame IRQs when $4017 isn't written to, though.