It is currently Sun Jul 15, 2018 6:21 pm

 All times are UTC - 7 hours

 Page 1 of 1 [ 8 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Square duty cycle vs apu_mixer/square testPosted: Tue Dec 20, 2016 7:51 pm

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 445
(This is pretty much a follow up of the conversation in Mesen's main thread, but I figured this might be better off as a thread of its own at this point)

So I've been taking another look at Mesen's square channel code, and looking at the "apu_mixer/square" test's code..

And there's something that I just can't make sense of.
In the test, square 2's duty cycle is set to 50%.
The code writes to \$4007 to reset square 2's sequencer and sets the timer to 111 (i.e clock every 224 cpu cycles)
Then, it loops and writes 127 to \$4011, 160 times in a row (each 896 cycles apart), before finally writing 123 on the 161th write.

The sequence looks like this, right after the \$4007 write that causes the sequencer to reset to 0 (thus outputting 0 for the next 4 square cycles)
Code:
DMC Value:         127 #1          127 #2          127 #3  ... (156 more writes) ...    127 #160        123             127            [...]
Square Output:     0   0   0   0   1   1   1   1   0      ...                   ...     1   1   1   1   0   0   0   0   1   1   1   1  [...]

So odd writes (1, 3, #161) match with a "0" for the duty cycle and even writes (#2, #4, #160) match with a "1".
This means that the 161th write (value = 123) falls on a falling edge for the duty cycle (1 -> 0), which makes BOTH channels drop at the same time.
Considering the test is attempting to cancel both channels by applying the opposite change, that doesn't make sense. I would expect the exact opposite.

What am I not understanding?

Current problems I had with my code vs the wiki:
1- Writes to \$4003/7 were resetting the sequencer AND the timer (instead of just the sequencer).
2- The sequencer was counting upwards instead of downwards.
(It looks like both of these might be "fixes" I took from puNES' code while attempting to make the apu_mixer tests work, but they both contradict the wiki)

After fixing these to match the wiki, I get a perfect match up (cycle-wise) between the square duty changes and the DMC writes, but the value of the square channel is always opposite of what it would need to be for it to cancel out the DMC's output.
At this point, if I invert the duty cycle so that the sequence after a \$4007 write is 11110000 instead of 00001111, everything falls into place and the sound output is (to my ears) even closer to the apu_mixer/square recording than my older code.

Picture below is the (what I assume to be) NES recording that was bundled with the tests, Mesen's 0.5.3 output (bottom), and Mesen's current output if I fix both bugs, and invert the duty cycle like I said (middle).
Clearly the middle one is the closest to the recording - so what am I not getting?

 Attachments: ApuMixerSquare.png [ 10.69 KiB | Viewed 1555 times ]
Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Tue Dec 20, 2016 7:57 pm

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20248
Location: NE Indiana, USA (NTSC)
Inverting the duty is on the right track. Because the waveform position counter is a down counter, it counts in the order 07654321, producing the waveform 01111000.

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Tue Dec 20, 2016 8:04 pm

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 445
Yes, it counts 07654321, but that produces 00001111 (according to the wiki), which is what I used in the sequence above (repeated 161 times).
But then that doesn't produce noise cancellation, it doubles up the sound's volume instead. (DMC goes 127 -> 123 when square goes 1 -> 0, and then 123 -> 127 happens when square does 0 -> 1)

To get the square channel to produce the opposite of the DMC channel, I need to count backwards (07654321) and invert the duty cycle values (0<->1) so that it becomes 11110000.

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Wed Dec 21, 2016 5:38 am

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1418
Sour wrote:
Yes, it counts 07654321, but that produces 00001111 (according to the wiki)

The wiki is wrong, then - the hardware definitely outputs 01111000 for that duty cycle, and I'm pretty sure it's been confirmed against visual2a03 (it effectively outputs D2 of the counter).

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

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Wed Dec 21, 2016 6:32 am

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 445
Ah, now I see my mistake. Thanks for clearing this up! I always looked at the wiki's data thinking it was the internal representation of the duty cycle from indexes 0 to 7. But it does actually says that this is the actual sequence that is output, so it's actually listed as 07654321.

So I wasn't counting backwards as I originally thought.
That still leaves a 1 duty cycle gap though. Does writing to 4003/7 change the output instantly because it resets the sequencer? Or is that delayed until the next time the timer expires? I.e, when you write does it reset to index 0 and then goes to index 7 on the next time the timer is up?

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Wed Dec 21, 2016 3:19 pm

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 445
I took a look at Nintendulator's code, and it implies any write to \$4000-4007 can instantly alter the channel's output - I'm not sure if this is actually written anywhere on the wiki though.

So the write to \$4007 instantly resets the sequencer, and ends up setting the volume to 0.
The sequence is then 0 (on \$4007 write) 1 (on next timer) 1 1 1 0 0 0 (like the wiki), with the first DMC write occurring at the same time as the first "1", this matches up perfectly with the DMC channel's output. The end result is an almost silent tone, all while keeping in line with everything that's written in the wiki.

Problem solved, I think. Thanks for the help!

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Wed Dec 21, 2016 5:48 pm

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1418
Sour wrote:
I took a look at Nintendulator's code, and it implies any write to \$4000-4007 can instantly alter the channel's output - I'm not sure if this is actually written anywhere on the wiki though.

It's only for \$4003 and \$4007, and the APU Pulse page states that "The sequencer is restarted at the first value of the current sequence."

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

Top

 Post subject: Re: Square duty cycle vs apu_mixer/square testPosted: Wed Dec 21, 2016 9:22 pm

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 445
Quietust wrote:
the APU Pulse page states that "The sequencer is restarted at the first value of the current sequence."
Yea, but I always had interpreted that as "the next time the timer expires and the duty cycle moves to the next step, it'll have been reset to the start of the sequence instead".
Now that I know the actual behavior, and thinking about it from a hardware point of view (which is something I know relatively little about), it does make more sense that it would be applied immediately, though.

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: No registered users and 4 guests

 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