Triangle channel length/linear counter confusion

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Triangle channel length/linear counter confusion
by on (#111626)
Another one of these. :P

The description of the triangle channel on the wiki confuses the heck out of me. For example:

Quote:
The linear counter control will silence the channel after a specified time with a resolution of 240Hz in NTSC (see frame counter below). It shares a control bit with the length counter in $4008, which means that they are always enabled at the same time, and whichever is longer is redundant. See APU Triangle for more linear counter details.


Does this mean that if C ("length counter disable/linear counter control") is clear, then both the length counter and the linear counter will be counting down, while C being set means they're both halted? (In that case, calling it something like "length counter halt/linear counter halt" might be clearer.)

Also, http://wiki.nesdev.com/w/index.php/APU_Triangle mentions a "halt" flag (which I assume is different from the length counter halt flag). Is the only purpose of this (possibly abstract) flag to determine when the linear counter gets reloaded, or does it affect output as well? If it's the former, then "halt" seems like a confusing name.

(I guess internally it might be some set-to-0-then-wrap-around-to-reload-value thing instead of a "halt" flag...)
Re: Triangle channel length/linear counter confusion
by on (#111630)
Yes, they're either both on or both off, more or less.

The halt flag represents a delay of action until the next sequencer clock. It corresponds to a real hardware function of some sort, but I have no idea how it's actually implemented. I dunno what the best name for these things is, I've just left it as is when making revisions to the wiki. Control seems an okay name for the bit, especially since there's that layer of indirection (represented by the internal "halt" flag).
Re: Triangle channel length/linear counter confusion
by on (#111634)
rainwarrior wrote:
Yes, they're either both on or both off, more or less.


Do they both have the same behavior re. halting and unhalting as well, with e.g. the following behavior when setting and clearing the C flag?

8, 7, 6, *halt flag set*, 5, 5, 5, 5, 5, *halt flag cleared*, 4, 3, 2, 1, 0, *channel silenced*
Re: Triangle channel length/linear counter confusion
by on (#111635)
Quote:
Does this mean that if C ("length counter disable/linear counter control") is clear, then both the length counter and the linear counter will be counting down, while C being set means they're both halted? (In that case, calling it something like "length counter halt/linear counter halt" might be clearer.)

No. The control flag being clear clears the halt flag, but the control flag being set doesn't affect the halt flag. It doesn't directly affect linear counter operation, only the halt flag.

The halt flag in the linear counter stops the counter from decrementing when it's set. And yes, it also affects when the linear counter is reloaded.

I probably chose the name "halt" because it's one word. It's really a mode flag, telling whether the linear counter is reloaded or decremented on linear clocks. We could call it a mode flag, with the two modes named:

* linear mode can be in one of two states: reloading or counting.
* Writing to $400B sets linear mode to reloading.
* When the frame counter generates a linear counter clock, the following actions occur in order:
1. If linear mode = reloading, linear counter is reloaded with counter reload value from $4008.
If linear mode = counting and linear counter > 0, linear counter is decremented.
2. If bit 7 of $4008 is clear, linear mode is set to counting.

Bring on critique round two and let's refine this more!
Re: Triangle channel length/linear counter confusion
by on (#111640)
blargg wrote:
I probably chose the name "halt" because it's one word. It's really a mode flag, telling whether the linear counter is reloaded or decremented on linear clocks.


I might still be a bit confused, but maybe it could be called something like "linear counter initialization flag" (or "linear counter reload flag"), since it indicates whether the linear counter should be initialized on the next linear clock. It's a bit more verbose, but "halt" is easy to confuse with the length counter halt flag, and might also give you the idea that it halts the waveform generator.

Edit: "linear counter setup flag" or "linear counter load flag" might be even better.
Re: Triangle channel length/linear counter confusion
by on (#111641)
Excuse the mind dump, but just so I don't forget before tomorrow :P:

Maybe the "control flag" could be renamed to the "halt flag" and stuff put in terms of the halt flag (i.e., the old "control flag") affecting the length counter and the linear counter differently. For the length counter, it determines when the counter counts down, while for the linear counter, it determines when the counter starts to count down (i.e., there's no way to stop the linear counter once it has begun counting down).

(I know that the control flag doesn't control those directly btw. Only its status at the length/linear frame counter clocks matters.)
Re: Triangle channel length/linear counter confusion
by on (#111647)
Quote:
maybe it could be called something like "linear counter initialization flag" (or "linear counter reload flag"), since it indicates whether the linear counter should be initialized on the next linear clock.

It keeps reinitializing the counter though, not just one time.

Quote:
Maybe the "control flag" could be renamed to the "halt flag"

Though it being set isn't an indication as to whether the linear counter is running, ugh.

"Note hold flag" came to mind, since it's descriptive without context. "It holds the note playing on this channel". Or "indefinite duration". All of these still imply that setting it in the middle of a note holds it, which fails for the linear counter.

$4008 bit 7: note hold flag

$400B write: switches linear counter to reload mode

linear clock:
Reload mode: copy $4008 low 7 bits to linear counter
Count mode: if linear counter > 0, decrement

Then, if note hold flag is clear, switch to count mode.

So if I do $4008=$C0, then $400B write, I'm saying "start a held note" then later do $4008=$40, I'm saying "unhold note and let it finish".

If I do $4008=$40, then a $400B write, I'm saying "start a note of linear duration $40". If I then do $4008=$C0, I'm confused :)

I have to assume that the convoluted nature of the linear counter was just a transistor-efficient way of implementing a second counter to aid with short bursts of the triangle for sound effects, or maybe just filling unused space on the die.
Re: Triangle channel length/linear counter confusion
by on (#111650)
If it was unused space on the die, then why wasn't it used for 3/8 duty pulse waves, or tighter period control in noise/DMC?
Re: Triangle channel length/linear counter confusion
by on (#111651)
It could just be that the APU was poorly/hastily designed and undertested. It seems that about half of its features are of such minimal use they were just ignored by most developers.
Re: Triangle channel length/linear counter confusion
by on (#111654)
Quote:
If it was unused space on the die, then why wasn't it used for 3/8 duty pulse waves, or tighter period control in noise/DMC?

SO - TRUE

Not only a counter is almost useless since it can be simply implemented in software, but having two of them for the same channel is twice more useless. Seriously, wtf ?
Re: Triangle channel length/linear counter confusion
by on (#111655)
So when "halt" is set, the linear counter is held at "reset", and when "halt" is clear, the linear counter proceeds as usual?

That'd explain why $4008 needed to be > $80 to create continuous sound; if the reload value is 0, then the value would continually be 0, as opposed to where I thought "halt" just turned the linear counter off. :P
Re: Triangle channel length/linear counter confusion
by on (#111656)
I don't know what set of terms you're using since we've shuffled them up in this thread :)
Re: Triangle channel length/linear counter confusion
by on (#111687)
Forgetting the control flag for the moment, my main gripe is that there are two "halt" flags. I think renaming the one unique to the triangle channel to "linear counter reload flag" would be a good first step. (As blargg says you could also put it in terms of the linear counter being in either "reload" or "counting" mode.)

For example, the following reads pretty naturally:

  1. If the linear counter reload flag is set, the linear counter is reloaded with the counter reload value, otherwise if the linear counter is non-zero, it is decremented.
  2. If the control flag is clear, the linear counter reload flag is cleared.

I'll go ahead with that edit unless I see someone protest in a while. :)
Re: Triangle channel length/linear counter confusion
by on (#111697)
I've renamed the linear counter halt flag on http://wiki.nesdev.com/w/index.php/APU_Triangle now.

blargg wrote:
Quote:
Maybe the "control flag" could be renamed to the "halt flag"

Though it being set isn't an indication as to whether the linear counter is running, ugh.

"Note hold flag" came to mind, since it's descriptive without context. "It holds the note playing on this channel". Or "indefinite duration". All of these still imply that setting it in the middle of a note holds it, which fails for the linear counter.


How about "linear counter start flag/length counter halt flag"? "Start" makes it sound like it starts counting down when it's set at a linear clock though, while it's actually the other way around... :evil:

Could just call it the "halt" flag for symmetry with the pulse channels and explain that it acts a bit weirdly for the linear counter too for simplicity, even if the name isn't ideal...
Re: Triangle channel length/linear counter confusion
by on (#111706)
Linear counter is what the triangle channel has instead of envelope, and I've noticed that some game (was it Hatris?) plays shorter notes on triangle during music fadeouts. So it'd be wise to pick a name that could apply to both, like "envelope halt" or "linear counter halt".