Methods for (re)starting of DMC playback?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

Methods for (re)starting of DMC playback?

Post by jwdonal »

So I've been working on my DMC implementation. I think it is fairly complete and seems to be working pretty well, but I have this nasty little bug that I can't figure out.

When I play bomberman I hear the explosions. When I play Kung Fu I hear the grunts/laughs. But when I play Duck Hunt I hear 1 "arf!" and that's it - no more. When you first start the game the dog actually barks 3 times in a row, but I only ever hear 1 bark.

On the very first bark, if I watch registers $4010-$4013 and $4015, I see the DMC Enable flag (bit 4 of $4015) get set to 1. This causes the DMC to start playback as the the Wiki says it should. But after this initial bit set the DMC Enable is never cleared and set again to cause playback to (re)start.

The only DMC-related registers which are written to following the first bark are $4012 (sample address) and the $4010 frequency index bits. Is writing different values to these registers supposed to (re)start playback somehow? If so, there is no mention of it in any DMC RE'ing documents that I could find. I think I must be missing some critical information about the DCM.... :(

Also, I can see in register $4010 that the DMC Loop flag and DMC Interrupt Enable flag are _not_ set. So this is not a looping problem and its not an interrupt problem.

The only way I know of that the DMC can be manually (re)started (from looking at the documentation I have) is by changing bit 4 of $4015 from 0 to 1. Is there some other way?

Also, if anyone knows if the 3 barks is actually a single "track" of 3 barks or if it is simply 1 bark repeated 3 times that might help me a little bit in my debugging... I am currently assuming it is the same bark "data" repeated 3 times (since it would require the least memory space) but that might be a bad assumption.

Thanks in advance!

Jonathon :)
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

I can't say for sure because I didn't actually check, so take this with a grain of salt.

If you've ruled out looping the only other thing I can think of is that you're not stopping the DMC at the end of the sample.

The DMC stops itself (ie: it clears $4015.4) when the sample is finished (specifically, iirc it's actually when the last byte of data is fetched). The game can restart the sample by writing 1 to $4015.4 again. It does not have to write zero to $4015.4 if the sample has already stopped.
User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

oh man

Post by jwdonal »

The DMC stops itself (ie: it clears $4015.4) when the sample is finished...
Oh my gosh, I am totally not doing this!! Will fix now and get back to you!

THANKS SO MUCH!!
User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

clarification

Post by jwdonal »

I haven't finished implemented the fix yet, but can you tell me if I'm still supposed to clear the DMC enable bit in $4015 if the Loop flag in $4010 is set?

The reason I ask is because, according to the Wiki and Blargg's apu_ref.txt doc, the interrupt flag should not be asserted when playback completes if the loop flag is set. So I'm wondering if there is a similar condition for clearing the DMC enable bit when playback completes.

Thanks!!
User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

Post by jwdonal »

Disch is the man! That fixed it! I hear barks and quacks like I should now! :)

In my own defense I rechecked the DMC documentation and I still don't see anywhere that tells you to clear bit 4 of $4015 when playback is done. If someone can point me to someplace that states this I'll be happy to eat my words. :) Actually I'll be very happy since it must be some DMC documentation that I don't currently have that I would like to get my hands on. :) Hopefully, someone doesn't point me to a document that I already have...that would be funny.

I'd still like to know (from my previous post) if I should still clear $4015.4 if the Loop flag is set. Right now I am clearing the bit regardless of the loop flag's value.

Thanks again Disch! :)
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

It's covered in the APU status register page. You might keep in mind that $4015 is really two separate registers. There's the control register, which does things when written to. There's the status register, which gives you the current values of things when read. In neither case is there an 8-bit byte that you can write to and read from.

On that page, it states that reading bit 4 reflects whether the DMC's bytes remaining counter is non-zero. A write of 0 to bit 4 sets the bytes remaining to 0, and a write of 1 to bit 4 when bytes remaining is 0 restarts the DMC sample. If I read that correctly, a write of 1 to bit 4 when the bytes remaining is non-zero has no effect. Don't assume anything beyond what you read, like that there's an internal "last value written to bit 4" which is compared with the current value to see whether it's different, or anything like this.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

blargg's apu ref also says the same thing:

Code: Select all

    ---d nt21   DMC, noise, triangle, square 2, square 1

If d is set and the DMC's DMA reader has no more sample bytes to fetch, the DMC
sample is restarted. If d is clear then the DMA reader's sample bytes remaining
is set to 0.
So yeah I worded it incorrectly in my previous post. It has to do with how many bytes are remaining in the sample.

So therefore, if it's looping, the bytes remaining is never zero because:

Code: Select all

The bytes counter is decremented;
if it becomes zero and the loop flag is set, the sample is restarted (see
above), otherwise if the bytes counter becomes zero and the interrupt enabled
flag is set, the interrupt flag is set.
User avatar
jwdonal
Posts: 719
Joined: Sat Jun 27, 2009 11:05 pm
Location: New Mexico, USA
Contact:

haha

Post by jwdonal »

Haha, you know, as I was falling asleep last night I was thinking, "hmmm, I wonder if the answer is on the APU status register page instead of the DMC module page." And yep, there it is just like you said. LOL.

Thanks so much for your help guys! You answered all my questions!! :-D

I will be posting some new video clips on my site soon to demonstrate my DMC working.

Pz!

Jonathon
Post Reply