In the comments for http://atariage.com/forums/blog/148/entry-13844-blast-off/there was some discussion on whether the TIA could be used to generate speech.
Previously I'd done some programming which tried to brute-force fit the TIA waveforms to music. The results were less than impressive, but speech might be simple enough to achieve better results.
The waveforms were based on what I'd learned about the TIA Audio Noise Generator circuit, and documented in several blog posts (sorry about the formatting), from working thought the logic in the TIA schematics. But doing back through those blogs, I wasn't 100% confident in my analysis of the AUDC logic. So I decided to start from scratch.
The first step was figuring out the wired logic. Was it an AND, OR, or NOR? My Google-fu wasn't able to find anything solid, although the Wikipedia article on wired logic showed wired ANDs had the resistor tied to Vcc while the wired ORs were tied to ground. Other parts of the schematic clearly used wired AND logic, with the connection to +5 clearly indicated and no arrow. Given these differences, they probably weren't wired ANDs.
If I assumed the AUDC[0] output is positive logic, then they are wired NORs as this means any high (1) will force the output low (0), so only AUDC = %0000 will cause the leftmost vertical wired NOR to be high, which then force the input to the 4 stage LFSR (after the inverter) to be high. This would match the AUDC = 0 result of "always high". Wired NOR also makes sense for the connections which prevent the LFSR from getting locked into the "don't change state'. (Although this could have been eliminated by using AUDC = 0 as a reset.)
That then let's me determine the following (where c? is the AUDC bits, x[] is the 5 stage LFSR and y[] is the 4 stage LSFR, both clocked on a rising edge):
x[t] = NOR1 + !( x[t-5] ^ L1 ) + NOR7
y[t] = NOR1 + NOR2 + NOR3 + NOR4 + NOR5
yclk = !xclk + !( NOR6 + !c1 + !( !c1 + !c0 + !x[t-5] ) )
NOR1 = !( c3 + c2 + c1 + c0 )
NOR2 = !( c3 + c2 + !( NOR8 + ( y[t-3] ^ y[t-4] ) ) )
NOR3 = !(!c3 +!c2 + !( NOR9 + !y[t-3] )
NOR4 = !( c3 +!c2 + y[t-1] )
NOR5 = !(!c3 + c2 + !x[t-5] )
NOR6 = !(!c1 + c0 + x[t-1] + x[t-2] + x[t-3] + !x[t-4] )
NOR7 = !( !(c1 + c0 + NOR8) + x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
NOR8 = !( y[t-1] + y[t-2] + y[t-3] + y[t-4] )
NOR9 = !(!y[t-1] + y[t-2] +!y[t-3])
L1 = !( !( !(c1 + c0) + !x[t-3] ) + ( !(c1 + c0) * y[t-4] ) )
Reducing for the various AUDC values:
AUDC = 0 = %0000
x[t] = 1
y[t] = 1
yclk = !xclk
AUDC = 1 = %0001
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = ( y[t-3] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] )
yclk = !xclk
AUDC = 2 = %0010
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = ( y[t-3] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] )
yclk = !xclk + x[t-1] + x[t-2] + x[t-3] + !x[t-4]
AUDC = 3 = %0011
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = ( y[t-3] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] )
yclk = !xclk + !x[t-5]
AUDC = 4 = %0100
x[t] = ( x[t-5] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] + x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !y[t-1]
yclk = !xclk
AUDC = 5 = %0101
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !y[t-1]
yclk = !xclk
AUDC = 6 = %0110
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !y[t-1]
yclk = !xclk + x[t-1] + x[t-2] + x[t-3] + !x[t-4]
AUDC = 7 = %0111
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !y[t-1]
yclk = !xclk + !x[t-5]
AUDC = 8 = %1000
x[t] = ( x[t-5] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] + x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = x[t-5]
yclk = !xclk
AUDC = 9 = %1001
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = x[t-5]
yclk = !xclk
AUDC = 10 = %1010
x[t] = ( x[t-5] ^ x[t-3] ) + !( + x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = x[t-5]
yclk = !xclk + x[t-1] + x[t-2] + x[t-3] + !x[t-4]
AUDC = 11 = %1011
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = x[t-5]
yclk = !xclk + !x[t-5]
AUDC = 12 = %1100
x[t] = ( x[t-5] ^ y[t-4] ) + !( y[t-1] + y[t-2] + y[t-3] + y[t-4] + x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !(!y[t-1] + y[t-2] +!y[t-3]) + !y[t-3]
yclk = !xclk
AUDC = 13 = %1101
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !(!y[t-1] + y[t-2] +!y[t-3]) + !y[t-3]
yclk = !xclk
AUDC = 14 = %1110
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !(!y[t-1] + y[t-2] +!y[t-3]) + !y[t-3]
yclk = !xclk + x[t-1] + x[t-2] + x[t-3] + !x[t-4]
AUDC = 15 = %1111
x[t] = ( x[t-5] ^ x[t-3] ) + !( x[t-1] + x[t-2] + x[t-3] + x[t-4] + x[t-5] )
y[t] = !(!y[t-1] + y[t-2] +!y[t-3]) + !y[t-3]
yclk = !xclk + !x[t-5]
Now to rewrite the programs to generate the waveforms and do the brute-force companding.
]]>