It is currently Tue Sep 18, 2018 1:15 pm

 All times are UTC - 7 hours

 Page 1 of 1 [ 8 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: 8-step duty cycle (attn: blargg)Posted: Sun Jul 24, 2005 9:35 pm

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
Blargg's APU doc mentions that the square programmable timer clocks the duty cycle every OTHER clock (effectively dividing the frequency by 2). And that the duty cycle takes 8 steps rather than 16.

This reminds me of BT's section on the noise channel. It have higher frequency values for the noise lookup table but said that the RNG unit is updated every OTHER clock.

Anyway -- I've since been thinking about it... and does this make ANY difference at all when emulating? I mean it's good to know the exact hardware behavior... but doing a 16-step duty cycle would have the exact same effect as a divided by 2 8-step duty cycle, wouldn't it?

As brought up in that savestate thread you said we should save the duty cycle as 0-7 -- but then wouldn't we have to save ANOTHER byte (or just a bit) to signal whether this is the first or second clock in the 2-step divider? Couldn't we just say that the low bit of the duty cycle counter is the step of the divider?

I don't know how much sense I'm making (it's pretty late and I'm tired) -- but my question is simple: Does emulating a 16-bit duty cycle have ANY effect on the generated wave? Or does it yeild the exact same result as emulating a divided-by-2 8-step duty cycle. Because I can't see how it would be different (and it sure is loads simpler to do 16-steps).

Top

 Post subject: Posted: Sun Jul 24, 2005 11:04 pm

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1428
As I understand, the main difference is that updating the period while the channel is playing will result in slightly different behaviour between the two methods.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

Top

 Post subject: Posted: Mon Jul 25, 2005 2:20 am

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Maybe I'll get an award for the most rewrites of this post.

My APU reference is incorrect regarding the timer with divde-by-two on the output. I was thinking of the Wiki where it has been corrected. Apologies for that and any other remaining errors.

Yes, a 16-step duty sequence is equivalent to using an 8-step duty sequence with a divide-by-two on its input. And yes, it would be a mess to try to explicitly code the divide-by-two and save this state. I thought the question was whether the divide-by-two was before or after the timer, which does make a difference. If before, the timer is only reloaded 8 times per wave, otherwise it's reloaded 16 times per wave.

I've written several tests to verify that the divide-by-two is before the timer (link to test ROM below). That should be just as simple to implement as having it after (reload timer with raw * 2 + 2, use 8-step duty sequence).

In the simplest test, I ran the square with \$4002 = 8 (i.e. highest pitch). Then I executed

Code:
lda #255
sta \$4002
pha       ; 21 delay
pla
pha
pla
pha
pla
lda #8
sta \$4002

which would cause the timer to be reloaded one time with whatever 255 gives. Looking in a sound editor, the flat section in the middle of the high pitch was 512 clocks (divider before timer) rather than 256 clocks (divider after timer).

In a more complex test I run a cycle-timed loop that changes \$4003 momentarily (for 4 clocks) every fourth timer reload. This produces two different results depending on where the divider is. I verified both by putting the divider before and after in an emulator. The NES matches with the divider before. Here's the NES ROM, main asm code, and recordings for before and after:

square_timer_div2.zip

Top

 Post subject: Posted: Mon Jul 25, 2005 9:48 am
 Formerly Fx3

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3153
Location: Brazil
Well, I didn't get the idea... >_< but the result in my emulator was the sound played in "correct.wav". However, there are "clicks" during the playback; minor, but audible. I use 8 steps - if I switch to 16 steps, then I hear "after.wav".

_________________
Zepper
RockNES developer

Top

 Post subject: Posted: Mon Jul 25, 2005 11:58 am

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Quote:
Well, I didn't get the idea

Same here . I rewrote the loop last night (almost three hours on this topic, ugh) and put some diagrams in the asm source, but they still don't make it completely clear.

Your emulator probably works right. Changing the timer to the other way and verifying the test failed was a good idea to do.

The test plays three tones. The first one's pitch depends on how the timer is implemented, the second with the pitch it should be, and the third the pitch it would be if the divider is put after the timer. There will probably sometimes be a slight click between the tones (I actually wanted to re-run it on a NES until it did click, so I didn't make it seem as if it should be seamless).

Top

 Post subject: Posted: Mon Jul 25, 2005 12:03 pm
 Formerly Fx3

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3153
Location: Brazil
Nice test, blargg. I forgot to say this... ^_^;;

_________________
Zepper
RockNES developer

Top

 Post subject: Posted: Mon Jul 25, 2005 12:42 pm

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20552
Location: NE Indiana, USA (NTSC)
blargg wrote:
The test plays three tones. [...] There will probably sometimes be a slight click between the tones (I actually wanted to re-run it on a NES until it did click, so I didn't make it seem as if it should be seamless).

Or you could insert clicks manually with CPU\$4011. Do you plan on making an updated version of the test case?

Top

 Post subject: Posted: Mon Jul 25, 2005 3:13 pm

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
As a reminder, the square duty handling isn't something that is detectable from the 6502 CPU, so instead of having a nice pass/fail result code printed on screen, the test has to cause a large audible difference when there is a problem. Every test of this sort requires a unique strategy for magnifying differences in behavior, and the pass/fail result will of course be different. I need to better document what is relevant to the test result, and what can be ignored.

I'm working on a set of kick-ass validation ROMs to verify both the documented operation of the APU and emulator implementations of it. The few tests I've released are just a preview of what's to come. I'm thrilled to be working on these because they are so useful for validating an emulator, especially when you make big changes to it. I hope to get around to writing tests for the CPU, memory, and PPU subtleties too. I love being able to shine a spotlight into obscure corners of software so it can be improved.

Disch's recent distinction between APU behavior that affects long-term emulation accuracy (things that code running on the CPU can detect) and that which only affects audio output was useful in helping me focus on finishing the ROMs that validate CPU-detectable APU errors. It's been very difficult figuring out a strategy of what to test, how to test it, how to package the tests, etc.

I'm sure everyone will enjoy implementing the new complex APU frame counter behavior once I get it documented and finish the test ROMs (not!). I haven't even implemented it yet.

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 8 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: Google [Bot], koitsu and 1 guest

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki