2A03 triangle channel counters

2A03 triangle channel counters
by on (#65480)
Would this be a correct (high-level) way of handling the triangle channel's counters?

$4008.7 clear:
The length counter is decreased at 60 Hz (for NTSC) as long as it's non-zero.
The linear counter is halted.

$4008.7 set:
The length counter is halted.
The linear counter is decreased at 240 Hz (for NTSC) as long as it's non-zero.

Writing to $400B sets the length counter, but at the same time sets $4008.7 and thus enables linear counter mode and reloads the linear counter value from $4008.

Output is effectively stopped when either the linear counter or the length counter is zero, regardless of which of them is active.

by on (#65492)
Any reason to not just implement what is described in the Wiki? Any simplification will alter its behavior.

by on (#65495)
The APU section at the wiki isn't the clearest piece of documentation ever written, and the simplified version is of no use for my purposes since it ignores the counters. So I wanted to ask if my interpretation was correct.
Re: 2A03 triangle channel counters
by on (#65510)
Your simplification doesn't look correct.

You need the following state, with indicated number of bits:

1 Flag
8 Shadow
7 Linear counter

And the following behaviors:
Code:
$4008 write:
    Shadow = value written

$400B write:
    Flag = 1

Linear clock:
    If Flag = 1
        Linear counter = low 7 bits of Shadow
    else if Linear counter > 0
        Linear counter = Linear counter - 1
   
    If bit 7 of Shadow = 0
        Flag = 0

Frequency timer output clock:
    If length counter and linear counter are both non-zero
        go to next step in triangle wave

by on (#65511)
Ah, that's much clearer. Thanks.

I'm just curious about what the purpose then is for the length counter on the triangle channel? If the linear counter always is active and runs at a higher frequency, then the linear counter will often expire before the length counter - making the length counter pointless.

by on (#65513)
mic_ wrote:
I'm just curious about what the purpose then is for the length counter on the triangle channel?

To allow music engines based on the length counter to run the same code for all four PSG channels, using logic like STA $4003,x for x in [0, 4, 8, 12].

by on (#65514)
So then the question is, what is the purpose of the linear counter? Maybe they felt the triangle didn't have enough features, or foresaw the need to have more precise control over its timing, as many games do when combining triangle and noise for a drum sound.

by on (#65515)
Quote:
To allow music engines based on the length counter to run the same code for all four PSG channels, using logic like STA $4003,x for x in [0, 4, 8, 12].


But then it would still have to do something like LDA #$FF / STA $4008 every 30 (video) frames or so to make sure the linear counter doesn't expire (and then LDA #$7F / STA $4008 to un-halt the length counter again) ?

by on (#65516)
I always saw the linear counter as the counterpart to the volume envelope generator.

by on (#65518)
The envelope generator has an auto-reload feature, though.