DMA operation in APU

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Wed Jun 09, 2010 7:41 pm

ReaperSMS wrote:If your APU isn't running on a per cycle basis, how could it possibly be doing the DMA cycle stealing correctly?
Yes my APU isn't cycle accurate yet but my sprite DMA is accounted for, so I was expecting numbers for the sprite DMA portion that somewhat matched. I didn't realize the sprite/DMC DMA were used to test each other. I thought it was testing whether or not the # of DMA cycles was correct for *either*.

I also noticed there's only a couple of ROM bytes different between the .nes file and the _512.nes file. What is different about the two variants? I get the same results for both...

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Jun 09, 2010 8:09 pm

Yeah, it's kind of crazy: it's using the DMC to count the number of cycles the sequence of code takes, while at the same time having DMC DMA occur at a particular point in the code.

The _512 variant just has the DMC DMA occur 512 clocks later in the test code, so you add $200 to the time column to see the real offset. The only difference in the ROM would be a couple of delay values, and the CRC.

EDIT: newer APU tests on the wiki.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sat Jun 26, 2010 9:49 pm

blargg wrote:It relies on DMC timing and operation being correct. I'll have to finish updating my APU tests and releasing them. This DMC DMA during sprite DMA is one of the hardest-core tests I've written, depending on many other things being perfect.
Image
Okay I've rearchitected my CPU/APU to be cycle-accurate and in sync with each other [run 3 PPU cycles, one CPU cycle, one APU cycle, lather, rinse, repeat]. I'm nearly there, just for some reason I can't get the logic right to have DMC DMA take only two cycles on the write-cycle (5 in screenshot above) of the STA $4014!

I pass both sets (PAL/NTSC) of old APU tests, only failing the IRQ timing test by one CPU cycle...[still scratching head on this one as indicated in a prior post!]. The new tests all pass individually (running the rom_singles) but for some reason I get failure code 16 on test 7 (dmc_basics) if I run the "all-in-one" test ROM. Apparently there's some condition in my APU that is cleared by a ROM reset that causes the tests to individually give a passing result but not when combined and mapper-switched in and run from a non-reset state.

Curiously I was failing the dmc_rates test both in rom_singles and in the "all-in-one" until I changed my timer divider from a "count up from zero to period then reset to zero" to a "count down from period to zero then reset to period" implementation. With the count up approach I pass everything but the dmc_rates test (either as rom_singles or in the "all-in-one"). I believe this has to do with the way the DMC is being "filled" and started by the rate test so that the whole length of the actual tested period can be measured. In the count up approach it takes too long to get to the newly set period, which causes a "rate too long" error.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun Jun 27, 2010 1:54 am

So you have sprite DMA taking 513/514 cycles, depending on whether the $4014 write is on an even or odd cycle? Have you tried having DMA take two cycles if the write cycle occurs one cycle before DMA?, or something like that?

I have no way of running the multi-test ROMs, as my devcart only has 32K PRG. I provide those only because I know many people don't want to write any automated testing support into their emulator, and would thus find the singles tedious. I'd much rather just provide the singles, and not deal with building the multi-ROMs. It's possible that a multi-test won't pass on a NES. If you pass the singles, you're good, period. Before releasing I test all the singles by loading them and powering the NES off then back on, to be sure they are solid. Maybe we can find someone to verify my multi-tests with a PowerPak whenever I need to release them.
Curiously I was failing the dmc_rates test both in rom_singles and in the "all-in-one" until I changed my timer divider from a "count up from zero to period then reset to zero" to a "count down from period to zero then reset to period" implementation.
I'll have to add a specific test for this, since as far as I know none of the APU counters count up; the only time the period for a timer is examined is when it's being reloaded, not every time it's clocked. It's good at least one caught this.

BTW, your screenshots would be less imposing if you just took it of the NES screen and nothing more. BTW, it looks like your NES window is stretched vertically by about 5 or 6 pixels, judging by the frequency of stretched characters.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun Jun 27, 2010 7:15 am

blargg wrote:So you have sprite DMA taking 513/514 cycles, depending on whether the $4014 write is on an even or odd cycle?
Yes.
blargg wrote:Have you tried having DMA take two cycles if the write cycle occurs one cycle before DMA?, or something like that?
Yes that's what my logic does but I'm still tracing through to see why it doesn't do that on the write cycle.
blargg wrote:I have no way of running the multi-test ROMs, as my devcart only has 32K PRG. ... It's possible that a multi-test won't pass on a NES. If you pass the singles, you're good, period.
That's good to hear but it'd be even better to see the results of the "all-in-one" on a real NES! Perhaps I'll remove the "all-in-one"'s from my test ROM status.
blargg wrote:Before releasing I test all the singles by loading them and powering the NES off then back on, to be sure they are solid. Maybe we can find someone to verify my multi-tests with a PowerPak whenever I need to release them.
I need to get me one of them PowerPak's. :D
blargg wrote:I'll have to add a specific test for this, since as far as I know none of the APU counters count up; the only time the period for a timer is examined is when it's being reloaded, not every time it's clocked. It's good at least one caught this.
The only time I examine the period is when I am checking to see if I need to emit a clock (and hence reload the counter). Not sure why count-up/count-down made a difference yet, but I'll keep thinking on it.
blargg wrote:BTW, your screenshots would be less imposing if you just took it of the NES screen and nothing more. BTW, it looks like your NES window is stretched vertically by about 5 or 6 pixels, judging by the frequency of stretched characters.


Yes, essial put in some logic to stretch the emulation window that doesn't quite work right at minimal. I haven't bothered to figure that part out yet. I was kind of hoping someone with more OpenGL knowledge than myself could step in and help get it right. 8) [/url]

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun Jun 27, 2010 7:23 am

Maybe I'm not understanding what you mean by count-up/count-down. There are two basic ways to do a timer: decrement count until it reaches zero, then emit clock and reload with period -or- increment counter from zero and compare with period; once it is >= period, emit clock and reset to 0. The latter is not how any of the APU timers work, and is what I took you to mean by count-up. I can't think of what else you could have meant...

tepples
Posts: 22013
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Jun 27, 2010 7:24 am

blargg wrote:I have no way of running the multi-test ROMs, as my devcart only has 32K PRG. I provide those only because I know many people don't want to write any automated testing support into their emulator, and would thus find the singles tedious.
As I understand it, the support for automated testing wouldn't be too much harder than the support for a Famicombox or a PlayChoice 10.
Before releasing I test all the singles by loading them and powering the NES off then back on, to be sure they are solid. Maybe we can find someone to verify my multi-tests with a PowerPak whenever I need to release them.
I could run a multi-test on an NTSC NES-001 for you.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun Jun 27, 2010 7:35 am

blargg wrote:Maybe I'm not understanding what you mean by count-up/count-down. There are two basic ways to do a timer: decrement count until it reaches zero, then emit clock and reload with period -or- increment counter from zero and compare with period; once it is >= period, emit clock and reset to 0. The latter is not how any of the APU timers work, and is what I took you to mean by count-up. I can't think of what else you could have meant...
Your definition of count-up/count-down is equivalent to mine. The latter was my implementation that was failing the dmc_rates test. The former is the implementation that I switched to that started passing the dmc_rates test, but then I stopped passing the "all-in-one" test with that implementation.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun Jun 27, 2010 7:36 am

tepples wrote: I could run a multi-test on an NTSC NES-001 for you.
Really? It'd be nice to know the pass/fail status of the all-in-one. If it passes, then there's still work to do for me. :D

tepples
Posts: 22013
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Jun 27, 2010 8:14 am

Pardon my incompetence, but I can't find exactly to which ROMs you're referring.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun Jun 27, 2010 8:27 am

tepples wrote:Pardon my incompetence, but I can't find exactly to which ROMs you're referring.
http://wiki.nesdev.com/w/index.php/Emulator_tests#APU

The first one.

tepples
Posts: 22013
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Jun 27, 2010 8:32 am

apu_test tests many aspects of the APU that are visible to the CPU.
"All 8 tests passed" on NES+PowerPak and Nestopia 1.40.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun Jun 27, 2010 8:39 am

NESICIDE wrote:The only time I examine the period is when I am checking to see if I need to emit a clock (and hence reload the counter). Not sure why count-up/count-down made a difference yet, but I'll keep thinking on it.
Imagine the following situation with both implementations: period of some timer is 100, and timer has just emitted a clock. Then period is changed to 50. With count-down, the next clock will be 100 input clocks later. With count-up, it will only be 50 clocks later.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun Jun 27, 2010 6:21 pm

tepples wrote:
apu_test tests many aspects of the APU that are visible to the CPU.
"All 8 tests passed" on NES+PowerPak and Nestopia 1.40.
Thanks tepples! I had Nestopia stuck in PAL mode, so I was getting failures there but didn't spend time trying to figure out why until you pointed out the above.

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Mon Jun 28, 2010 6:56 pm

tepples wrote:
apu_test tests many aspects of the APU that are visible to the CPU.
"All 8 tests passed" on NES+PowerPak and Nestopia 1.40.
And now NESICIDE. Yay!

I took a closer look at my execution trace and noticed that with the sprdma_and_dmc_dma.nes test ROM, the DMA was occurring in the wrong place relative to the CPU cycle. I do an APU cycle on each CPU memory access [read, write, DMA]. If I run the APU cycle *after* the memory access then I get a failure both in the apu_tests.nes and in sprdma_and_dmc_dma.nes. If I run the APU cycle *before* the memory access then I pass both.

Image

Blargg, I removed the chaff from the image...just for you! :shock:

I still fail the second (+512) sprdma_and_dmc_dma.nes test though. I take it this is supposed to show the effect of DMC DMA on the opposite end of the sprite DMA event (ie. the last 16 or so sprite DMA cycles?) It seems to be failing on the first 16 cycles though so I'm not sure.

105 test ROMs down [passing], 31 more to go [failing to some degree].

<completely aside>Does anyone know if Chris Covell's RasterDemo3*.nes (*=,a,b,c,...) work on a real NES?

Post Reply