TMS9919 Sound chip

Pinout
Internal structure
Timing diagram
Electrical characteristics

Programming the sound generators
Playing notes
Direct sound

Introduction

The TMS9919 sound chip contains three independent tone generators and a noise generator that can emit either white noise (i.e. all frequency have identical energy) or periodic noise. I don't have the data manual for this chip, but I have one for the SN76489 and SN76496, very similar chips manufactured by TI. The only difference I noted was that the AUDIOIN pin is not connected on the SN76489AN. If anybody happens to have a copy of the actual TMS9919 manual please let me know.

Pinout

         +----+--+----+ 
D2 |1 o T 16| Vcc
D1 |2 M 15| CLK
D0 |3 S 14| D3
READY |4 13| D4
WE* |5 9 12| D5
CS* |6 9 11| D6
AUDIOOUT |7 1 10| D7
Vss |8 9 9| AUDIOIN
+------------+

Power supply
Vcc +5V, (via a 6.8 uH inductor in the TI-99/4A)
Vss Ground


CPU interface
D0-D7 These input pins accept commands from the CPU.

CS* Chip select. When this pin is active (low) the TMS9919 will input data from the data bus. For proper operation, the device should be initialized by pulling both CS* and WE* high.

WE* Write enable. When active (low) this pin signals a write operation. As far as I know, all operations dealing with the TMS9919 are write operations. I'm not aware that there is anything to read. Anyone?

READY This pin goes low to put the CPU on hold until the TMS9919 is ready: it takes approximately 32 CLOCK cycles for the chip to load data into a register.

CS* WE* READY
L L L
L H L
H L H
H H H


Sound pins
CLK Clock pin. Receives the basic clock signal used to generate sounds. The acceptable frequency ranges from 0 to 4MHz. On the TI-99/4A, this pin receives a 3.58 MHz signal from the VDP CPUCLK pin.

AUDIOIN This input pin receives preformed sound signals and transmits them to the AUDIOOUT pin. It is an analog input. In the TI-99/4A is is connected to pin #44 of the side port via a 330 Ohm resistor, for sound input from the speech synthesizer. It is also connected in parallel to the cassette input port which allow us to ear that funny noise when reading a program from tape. Finally, the TMS9901 also controls this line via a transistor, which could be used by application programs to directly generate sounds via the CRU. This pin is marked n.c. on the SN76489.

AUDIOOUT This pin carries the sound data to the monitor's speaker (pin 3 of the connector). It is connected to an internal analog audio amplifier.

--+
#7|--------+----||---+--uuu---+----< pin 3 monitor port
| | 100uF | ?uH |
| 0.1uF = 10nF = = 10nF
| | | |
| +--www---Gnd Gnd
--+ 10 Ohm


Internal structure

The signal received from the CLOCK pin is divided by 16 to provide the internal signal frequency. This means that the CLOCK signal can be as high as 4 MHz and yet produce audible sounds. Note that there exists a chip, SN76494N, that is exactly similar to the SN76489 except that the CLOCK signal is only divided by 2. It allows to use a clock signal in the 500 kHz range.

The chip contains three tone generators and a noise generator. Each tone generator consists in: a programmable frequency divider that divides the CLOCK frequency by a user-definable value to generate the appropriate tone, a fixed 1/2 frequency divider and a programmable attenuator that allows to control the volume in increments of 2 dB.

The noise generator comprises: a fixed 1/16 divider, a programmable divider (1/2, 1/4 or 1/8), a noise source and an attenuator identical to that of the tone generators. The programmable divider can also accept the output of tone generator number 3 as an input. The noise source is a shift register with a XOR feed-back to prevent lockup in zero state. It is possible to control this feedback circuit to toggle between a "white" noise and a periodic noise. The shift register is cleared each time the divider is loaded, then it shifts at the frequency determined by the divider output.

The four signals are combined by an analog summer, whose output drives an audio amplifier, typically with a current from 0 to -160 uA. The audio output can generate upto 10 mA.

                       ______      _____     __________
,--| 1/N |----| 1/2 |---|Attenuator|---, +1.5V
______ | ______ _____ __________ | | |\
CLOCK >--| 1/16 |--+--| 1/N |----| 1/2 |---|Attenuator|-, '-|\ '--|+\
| ______ _____ __________ '---| \ | \_ _ AUDIOOUT
,-----------+--| 1/N |----| 1/2 |-+-|Attenuator|-----| \_ _| / |
| ,---------------' | / | |-/ |
| ______ | _____ __________ ,--| / | |/ |
'--| 1/16 |----| 1/n |----|shift|---|Attenuator|--' |/ '--WWW-'
Summer 17K

The four attenuators and the four programmable dividers can be accessed from the data bus, as 8 dedicated registers. The tone dividers are 10-bit wide and thus require two bytes of data.

Tone frequency dividers

1 R0 R1 R2 F6 F7 F8 F9
0 x F0 F1 F2 F3 F4 F5

R0-R2: Register address (see below)
F0-F9: Number by which to divide the frequency (>01-3F)

NB The register address is latched on-chip when the first byte is passed. This means that the second byte can be sent repeatedly, as it is identified by a 0 in the most significant bit. In this way, you can very rapidly sweep frequencies, by changing only the 6 most significant bits (F0-F5) with a single byte transfer.


Noise frequency divider

1 R0 R1 R2 x FB F0 F1

R0-R2: Register address (see below)
FB: Feed-back option 0 = periodic, 1 = white noise
F0-F1: Number by which to divide the frequency: 00 = 512, 01 = 1024, 10 = 2048, 11 = use generator #3


Attenuators

1 R0 R1 R2 A0 A1 A2 A3

R0-R2: Register address (see below)
A0-A3: Attenuation. A0 = 16 dB, A1 = 8 dB, A2 = 4dB, A3 = 2 dB. 1111 = sound off
The attenuation accuracy is quite poor: +/- 1 dB


Register address

R0 R1 R2 Register
0 0 0 Tone 1 frequency divider
0 0 1 Tone 1 attenuator
0 1 0 Tone 2 frequency divider
0 1 1 Tone 2 attenuator
1 0 0 Tone 3 frequency divider
1 0 1 Tone 3 attenuator
1 1 0 Noise frequency divider
1 1 1 Noise attenuator


Timing diagram

______               _________               _______     
\_____________/ \_____________/ CE*
_____|_a_| 90-150 ns
| \___________/ >0 | |a \ / READY
| >0 | | |
\_____________/ | \_______ / WE*
|>0| |
X first byte X second byte X D0-D7
a) 90-150 ns    


Electrical characteristics

Absolute maximum ratings

Supply voltage: Vcc               7V
Input voltage: AUDIOIN 0.9V
All others 7V
Output current on AUDIOOUT 10 mA
Continuous power dissipation 1150 mW
Free air temperature: 0 to 70 `C
Storage temperature: -55 to 150 `C



Recommended operating conditions

Parameter Min Nom Max Unit
Supply voltage, Vcc 4.5 5 5.5 V
High-level input voltage 2 . . V
Low-level input voltage . . 0.8 V
AUDIOIN input current 0 . 1.8 mA
High-level output voltage (READY) . . 5.5 V
Low-level output current (READY) . . 2 mA
Input clock frequency . . 4 MHz
Free-air temperature 0 . 70 `C


Electrical characteristics under recommended conditions

Parameter Test conditions Min Typ Max Unit
High-level output current (READY) Vo = +5.5V . . 10 uA
High-level input current (all digital pins) Vi = Vcc . . 10 uA
Low-level input current CE* pin
D0-D7, WE*, CLK pins
Vi = 0 . -25
-10
-175
-70
uA
Input bias voltage (AUDIOIN) R = 4.7 KOhm to Vcc 0.5 0.7 0.9 V
High-level output voltage (AUDIOOUT) . . . 5.5 V
Low-level output voltage (READY) I = 2 mA . 0.25 0.4 V
Peak-to-peak output voltage (AUDIOOUT) Vcc = +5V Attenuation = 0 dB
(other generators -30 dB)
260 . . mV
Supply current Outputs open . 30 50 mA
Input capacitance . . . 15 pF
 


Programming the sound generators

The four generators (3 tone and 1 noise) can be accessed independently by the data bus. The first byte of data contains the address of the desired generator and the parameter to change (frequency or volume). In some cases, a second byte of data may follow, that will be sent to the same generator as the previous one. In the TI-99/4A the sound chip data port is mapped at >8400, but the address is incompletely decoded: only A0-A5, A15 and MEMEN* are taken into account. Thus, the chip will respond to any even address in the range >8400->85FE.

Generator Frequency Volume
Tone 1 >8z >xy >9v
Tone 2 >Az >yx >Bv
Tone 2 >Cz >yx >Dv
Noise >En >Fv
Frequency = 111860.8 Hz              Volume v:  +1 = -2 dB (>F = off)
xyz

Tones

Two bytes are required to set the frequency of a tone generator. The first nibble of the first byte contains the address of the generator (>8, >A or >C). The second nibble should be appended to the end of the second byte to generate a 3-nibble number xyz. The output frequency can be calculated by dividing 111,860.8Hz by xyz. The value 111,860.8 is due to the fact that the 3.58 MHz clock signal is divided by 32 to produce the base frequency used by the generators.

Once the first byte is passed, the second byte can be modified as often as needed, as long as no other command is passed. This allows for rapid frequency changes, as only one byte needs to be passed (although only the 6 most-significant bits will be changed).

Noises

For the noise generator, only one byte is needed. The first nibble should contain the address (>E) and the second 3 command bits that decide whether the generator will emit white noise or periodic noise (bit 6) and select the basal frequency from a list of three. It is also possible to instruct the noise generator to adopt the same frequency as tone generator 3, even if the latter is currently silent (i.e. volume = >F).

1 1 1 0 0 w r r 
>E | | |
| 0 0 : 6991 Hz
| 0 1 : 3496 Hz
| 1 0 : 1748 Hz
| 1 1 : freq of generator 3
|
0 : Periodic noise
1 : White noise

Volume

Strictly speaking, one does not set the volume for a generator, but rather its attenuation. That is, higher values result in lower volumes. Zero is the maximum volume, any increment by one reduces the volume by 2 dB (i.e. 100 times less sound energy), and >F turns the generator completely off.


Playing notes

Here is a table that you can use to program the frequencies of a "well-tempered keyboard". Just replace the dot with the code of the desired generator (>8, >A or >C) and pass the result as two bytes at >8400.

C               
- .735 .C1A .60D .B06 .503 .B01
############ - .732 .419 .A0C .506 .203 .901
D
- .A2F .D17 .E0B .F05 .003 .801
############ - .F2C .816 .40B .A05 .D02 .601
E
- .72A .315 .A0A .505 .A02 .501
F
- .128 .014 .00A .005 .802 .401
############ - .D25 .E12 .709 .C04 .602 -
G
- .B23 .D11 .F08 .704 .402 -
############ - .B21 .D10 .708 .304 .202 -
A
.93F .C1F .E0F .F07 .004 .002 -
############ .03C .01E .00F .807 .C03 .E01 -
B
.A38 .51C .20E .107 .903 .C01 -

Notes
The underlined .E0F corresponds to the middle A at 440 Hz. Note that many orchestra nowadays tend to tune their middle A at a higher pitch: at 441, 442 or even upto 444 Hz. I'll leave you with the task to correct this table accordingly..

You may have noted that the calculated frequency follows a log scale, dobbling from one column to another (taking rounding mistakes into account). That's because of the way our ear is designed: octaves, subjectively "equal" intervals of 12 half-tones correspond to a dobbling of the frequency. This allow us to ear a wide range of frequencies.

One last remark: this table works well to emulate keyboard instruments (piano, harpsichord, organ) that are "tempered", i.e. on which an A sharp is the same as a B flat. This is not the case for other instruments like the violin or the cello: on these the A sharp is a tad (a "coma" in french, a "microtone" in english?) higher than the B flat. Most people won't notice the difference, unless the same note is played on a piano and a violin together: it gives the impression that the violinist does not play in tune. He does! It's the piano that's wrong.


Examples

* Let's play a note 
LI R0,>8400 Sound port address on the TI-99/4A
LI R1,>8E0F Middle A on generator 1
MOVB R1,*R0
SWPB R1
MOVB R1,*R0
LI R2,>9200 Volume: 4 dB below maximum
MOVB R2,*R0 Play it
... Wait

* Now let's make a noise (the note is still playing)
LI R1,>DF00 Make sure generator 3 is off
MOVB R1,*R0
LI R1,>CC1A C on generator 3
MOVB R1,*R0
SWPB R1
MOVB R1,*R0
LI R1,>E300 Periodic noise, picking frequency from gen 3
MOVB R1,*R0
LI R1,>F000 Volume: full blast
... Wait

* Turn all sounds off
LI R1,>9F00 Start with generator 1
LP1 MOVB R1,*R0 Turn it off
AI R1,>2000 Next generator
JNC LP1 Carry set when >EF becomes >00
B *R11

This example is deceptively simple: programming music is a fairly complicated task. First you must decide how to encode your music: do you want a separate list for each generator or a common list?

Then you must time each note. A good way is to place a sound list in the VDP memory and to let the ISR play it, but according to your needs you may want to do it yourself, for instance with the TMS9901 timer. You must also remember that each note should be followed by a small silence, unless you're playing legato (although to repeat a note in legato, you still need a small silence). Conversely, to play staccato or pizzicatti you must reduce the duration of a note and increase the silence accordingly.

And then, there is the problem of the volume: progressive changes in volume (crescendo, decrescendo) can be tricky to program as they must be integrated into your sound list. Finally for some instruments to sound natural, the sound of each note should be slowly fading over time. That's the case with the piano for instance (but not with the flute: as long as the musician is blowing steadily, the volume remains unchanged).



Direct sound

We can send sound directly to the speaker via the sound chip, without using the generators. This is achieved with CRU bit 24 in the console: it is normally used to control whether the input from a cassette tape recorder will be audible, but thanks to a pull-up resistor it can also be used to generate sound even if no recorder is installed.

* Tentative routine to program direct sound via the CRU
* R1 contains a pointer to a list of sound bits
* R2 is the size of the list, in words
* R3 is the delay between two bits (i.e. depends on the sampling rate)
* In addition, the routine makes use of R4, R10 and R12.
BITSND MOV R11,R10
CLR R12 CRU base of the TMS9901
LP2 MOV *R1+,R4 Get one word from the list
LI R0,16 16 bits per word
LP1 SLA R4,1 Test next bit
JNC SK1
SBO 24 Send 1 to sound gate
JMP SK2
SK1 SBZ 24 Send 0 to sound gate
SK2 BL @DELAY Delay between two bits
DEC R0
JNE LP1 Next bit
DEC R2
JNE LP2 Next word
B *R10

* Delay routine
DELAY MOV R3,R12 Get delay value (in R12, to save a register)
LP3 DEC R12
JNE LP3 Keep waiting
B *R11 R12 is now >0000, which is the correct CRU value
* NB: for short delays, we should account for the longer time between two
* words, due to the 4 extra instructions needed to load a new word.
* Main program
START LI R1,BUFFER Buffer address
LI R2,>0800 Buffer size
LI R3,>AAAA Test pattern: highest possible pitch (1010 1010)
L0 MOV R3,*R1+ Fill buffer with test pattern
DEC R2
JNE L0
      LI   R1,BUFFER   Buffer address
LI R2,>0800 Buffer size
LI R3,>0040 Delay value
BL @BITSND Play buffer content
... Return when done (this may take time)

Here, the tricky part is to determine the list of bits to be passed. I wonder if PC .RAW files could be used?

Also, I don't think there is any way to control the volume. Any suggestions?


SoundFX

A different method was used by Barry Boone in his excellent SoundFX program. He sets the maximum frequency (>001) on the three sound generators and then modulates the volume (identically for all three). Obviously, this implies carefully controlled timing loops so as to generate the required frequency.

Barry made the SoundFX source available on his website, so I encourage you to have a look at it. Here is an excerpt, containing only the sound generation routines and the routines that translate other sound files in SoundFX format..

Revision 1. 2/19/99. OK for release
Revision 2. 3/30/99. Polishing
Revision 3. 5/30/99. Tested & debugged examples
Revision 4. 6/16/00. Added SoundFX info
Revision 5. 7/2/00. Got the SN76489 manual. Added structure, timing, electricals.
Revision 6. 7/12/00. Got the SN76494 manual. Changes electricals.


Back to the TI-99/4A Tech Pages