APU Test ROM Questions

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
APU Test ROM Questions
by on (#62672)
So I found blargg_apu_2005.07.30 test ROM package yesterday. Hopefully this is the latest. I went from passing no tests [I expected this...my APU had been PPU-frame-based!]

I now pass tests 01, 02, 03, 04, 05, 06, 07, and 09.

I believe I have a clear path toward passing the other three, I just haven't completely got there yet.

I'm curious about a couple of things.

1. Does the APU still run if the CPU is being consumed by PPU sprite DMA fetches? Or does it get held off also? Seeing as the APU is internal and doesn't need to do memory fetches unless it is doing DMA itself, I believe it should be operational throughout a PPU sprite DMA. Either way I could put together a pretty simple test ROM to test this...I just don't know which way it goes.

2. The test.txt document notes for test 08 suggest "IRQ handler is invoked at minimum 29833 clocks after writing $00 to $4017." But the readme.txt shows IRQ being *generated* by the APU on cycles 29830, 29831, and 29832. Given an IRQ takes *at least* 7 CPU cyles to get into, how is it possible? Looking at the test source it *is* expecting the IRQ to fire.

by on (#62674)
APU runs all the time.

I'd ignore the descriptions of how things operate and focus on passing the tests. Descriptions aren't directly testable and are sometimes wrong. The timing tests usually say whether something is too soon or too late, so you can just adjust until you pass.
Re: APU Test ROM Questions
by on (#62676)
1) The APU keeps running.

The CPU stalls because it performs memory accesses every cycle... and it can't access memory at the same time the DMA is, therefore it has to wait. The APU does not access memory and therefore does not need to wait.


2)

I'm not sure what the significance of 29833 is. In fact I actually recommend you ignore that blurb, as you get proper behavior just triggering IRQs at the same time you set the flag in $4015 (provided you emulate IRQs properly).

The probable reason for the discrepancy is because an IRQ needs to wait for the current instruction to complete before it can happen, whereas the flag can be read as high immediately.

The time the IRQ flag (read by $4015) goes high, and the time the IRQ actually happens is one and the same. The only thing to note is the above mentioned latency caused by IRQ having to fall between instructions.

Because of the way the CPU is pipelined, the IRQ has to happen before the last cycle of an instruction, otherwise it gets delayed until after the next instruction.

Confusing, I know. Here's some example code to illustrate:

Code:
LDA $4015  ; 4 cycles
INX  ; 2 cycles


LDA $4015 is 4 cycles:

cyc 0) fetch the opcode
cyc 1) fetch low address byte
cyc 2) fetch high address byte
cyc 3) perform the read (fecth from $4015)

For the IRQ to occur between the LDA and INX instructions, the IRQ would have to happen on or before cyc 2. If it happens on cyc 3, then INX will have already started, and the IRQ won't happen until after INX finishes.

On the other hand, the IRQ bit in $4015 can go high and still be read even if it happens on cyc 3.

So let's look at some edge cases. Let's say the above code happens on cycle 29829 (cyc 0 of LDA = cycle 29829)

Code:
29829:  LDA - fetch opcode
29830:  LDA - fetch low byte  <-  !29830!
29831:  LDA - fetch high byte  <-- "point of no return" for IRQ
29832:  LDA - fetch $4015     <-- IRQ flag is read as 'set'
; <- IRQ happened before "point of no return", so IRQ here


Now let's look again from 29828:
Code:
29828:  LDA - fetch opcode
29829:  LDA - fetch low byte
29830:  LDA - fetch high byte  <-  !29830!
29831:  LDA - fetch $4015     <-- IRQ flag is read as 'set'
; <- IRQ here (IRQ happened before point of no return)


And now from 29827.. which is where it gets tricky:
Code:
29827:  LDA - fetch opcode
29828:  LDA - fetch low byte
29829:  LDA - fetch high byte
29830:  LDA - fetch $4015     <-- !29830!  IRQ flag is read as 'set'
; <- no IRQ here, as the IRQ happened after the point of no return
;   wait until after the next instruction (INX) to actually interrupt.

by on (#62678)
blargg wrote:
APU runs all the time.

I'd ignore the descriptions of how things operate and focus on passing the tests. Descriptions aren't directly testable and are sometimes wrong. The timing tests usually say whether something is too soon or too late, so you can just adjust until you pass.


I forgot one more...thanks Blargg/Disch for the info!

3. In test 10 and 11 I assume the same rules apply to the other length clocking time as well as the one mentioned?
Re: APU Test ROM Questions
by on (#62680)
NESICIDE wrote:
I believe it should be operational throughout a PPU sprite DMA. Either way I could put together a pretty simple test ROM to test this...I just don't know which way it goes.

If you ever figure out if the APU's DMC DMA operation "interrupts" the CPU sprite DMA operation (or if it has to wait for sprite DMA to finish) would you _please_ let me know?? I have posed this question on NesDev (both on the forums and in PMs), the Nestopia forums, and other NES emu sites and no one can give me an answer. One person told me that in their emu they "cheat" and actually perform both DMA operations simultaneously. I'm starting to think that this is what all software-based emus do. Unfortunately, I do not have that luxury in hardware. I haven't had a chance to make up a test ROM.

But seriously, if you figure this out please drop me a PM or email or anything. :)

I originally posed the question quite a while back in this post. It's question #1. Blargg suggested one solution, which I'm sure would be trivial for him, but I am not even remotely close to Blargg's programming skills. And, in all honesty, I didn't completely understand what he meant. Haha. I figured I would come back to it later....maybe now is the time? ;)