Atari's Sound System
John Scarborough, Novato, CA
If you're interested in the improvements to Atari sound and music possible via machine language — this will get you started. These simple demonstrations might convince you to abandon the SOUND command entirely.
Many programmers who decide to make the jump from BASIC programming to machine language programming find frustration in their attempt to print to the screen or produce sound. The problem is that there are now no print or sound statements. Machine language deals entirely with retrieving, manipulating, and storing data.
But even after the programmer discovers this it won't do him much good unless he knows where and what to store to produce results. Furthermore, this information is often not provided in the manuals that come with the computer. So how does he obtain this information? He must turn to other methods. Four common ones are:
- The trial and error method (very inefficient, but sometimes necessary).
- Advanced user's manuals.
- Information obtained from a human source, such as from friends or teachers.
- A magazine.
This article is in category four. After studying this article, you will have more control over the four voices provided by the Atari. The article will also briefly cover the built-in speaker.
Look at the following sound command:
SOUND 0, 121, X, X
This instructs the computer to store a value of 121, which will produce a middle C note, into Audio Frequency Control register 0. This register is located at memory location 53760 ($D200 hex). Thus, the following two commands will function identically:
SOUND 0, 121, X, X POKE 53760, 121
The three remaining Audio Frequency Control registers are located at 53762 ($D202), 53764 ($D204), and 53766 ($D206). A POKE 53764, 128 would store a value of 128 (a B note) into the Voice 2 Audio Frequency Control register. SOUND 2, 128, X, X will do the same. (See Figure 1 for a clearer representation of the four Audio Frequency Control registers.)
Now you can store a given frequency (note) into any of the four Audio Frequency Control registers. But what about distortion and volume? Look at the following sound command:
SOUND 0, X, 10, 12
This tells the computer to produce a pure tone (10) and a volume level of 12. Upon execution, the computer will convert the number 10 to 160 (160 is the actual pure tone code. See Figure 2 to find the corresponding distortion codes for the eight additional distortion levels), add 12 to it, and then store the result into Audio Control register 0. This register is located at memory location 53761 ($D201 hex). Thus, the next two commands will perform the same task:
SOUND 0, X, 10, 12 POKE 53761, 160 + 12
The three remaining Audio Control registers are located at 53763 ($D203), 53765 ($D205), and 53767 ($D207). A POKE 53767, 160 + 7 would store a pure tone and volume level of 7 into Audio Control register 3. SOUND 3, X, 160,7 will do the same. (See Figure 1 for a clearer representation of the four Audio Control registers.)
You should now know how to store any given note, tone and volume level into any of the four voices provided by the Atari (and without using sound statements). The following two BASIC programs function identically:
10 SOUND 0, 121, 10, 12 20 GOTO 20 10 POKE 53760, 121 20 POKE 53761, 160 + 12 30 GOTO 30
The Built-in Speaker
That is an overview of the sound that is channeled to the television speaker, but what about the built-in speaker? The built-in speaker is controlled via location 53279 ($D01F).
Program 1 will make the built-in speaker randomly click. (Not a very spectacular sound effect, to be sure, but that's not to be expected from BASIC statements.) Program 2A and 2B (which function identically) will also make the built-in speaker randomly click, but they do not use BASIC statements to produce the sound and will therefore click the speaker much faster than will Program 1. compare the two for yourself. The comparison will give you some idea of the speed available to you from machine language programming.
If you compared Programs 1 and 2, you might have thought: "If machine language can do that much for that little built-in speaker...." Yes, by using machine language you can greatly increase the quality of the sound that comes out of your television speaker.
I leave you with a simple machine language program that will demonstrate this increase in quality. The program is written in both assembly language (3A) and BASIC (3B). This is a simple program; it would have been half as long without the delay routine. However, the sound would not be audible if there were no delay built into the machine language program!
The Four Voices Provided By The Atari
Examples Of The Eight Distortion Levels Using Random Voices
SOUND 0, X, 0, V = POKE 53761, 0 + V SOUND 0, X, 2, V = POKE 53761, 32 + V SOUND 3, X, 4, V = POKE 53767, 64 + V SOUND 1, X, 6, V = POKE 53763, 96 + V SOUND 0, X, 8, V = POKE 53761, 128 + V SOUND 1, X, 10, V = POKE 53763, 160 + V SOUND 2, X, 12, V = POKE 53765, 192 + V SOUND 0, X, 14, V = POKE 53761, 224 + V
5 REM -THIS PROGRAM UTILIZES THE BUILT-IN SPEAKER USING BASIC STATEMENTS 10 A = INT (256 * RND(1)) : REM -LOAD A WITH A RANDOM NUMBER FROM 0 TO 255 20 POKE 53279, A : REM -STORE A AT 53279 30 GOTO 10 : REM -START OVER
5 ; THIS PROGRAM UTILIZES THE BUILT-IN SPEAKER FROM MACHINE LANGUAGE USING THE ASSEMBLER-EDITOR CARTRIDGE 10 * = $600 20 LOOP LDA $D20A ; LOAD A WITH A RANDOM NUMBER FROM 0 TO 255 30 STA 53279 ; STORE A AT 53279 40 JMP LOOP ; START OVER
5 REM -THIS PROGRAM UTILIZES THE BUILT-IN SPEAKER FROM MACHINE LANGUAGE USING THE BASIC CARTRIDGE 10 FOR LOOP = 1536 TO 1544 20 READ DATA 30 POKE LOOP, DATA 40 NEXT LOOP 50 X = USR (1536) 60 DATA 173, 10, 210, 141, 31, 208, 76, 0, 6
5 ; THIS PROGRAM UTILIZES THE TELEVISION SPEAKER FROM MACHINE LANGUAGE USING THE ASSEMBLER-EDITOR CARTRIDGE 10 * = $600 20 FREQ = $660 30 ; STORE A PURE TONE (160) AND A VOLUME LEVEL OF 15 (160 + 15) INTO VOICE 0 40 LDA #175 50 STA $D201 60 ; STORE CURRENT FREQUENCY INTO VOICE 0 70 START LDX FREQ 80 STX $D200 90 INX ; INCREMENT FREQUENCY LEVEL 100 STX FREQ 110 ; DELAY PROGRAM EXECUTION 120 DELAY LDX #15 130 LOOP1 LDY #15 140 LOOP2 DEY 150 BNE LOOP2 160 DEX 170 BNE LOOP1 180 JMP START ; CONTINUE
5 REM -THIS PROGRAM UTILIZES THE TELEVISION SPEAKER FROM MACHINE LANGUAGE USING THE BASIC CARTRIDGE 10 FOR LOOP = 1536 TO 1563 20 READ DATA 30 POKE LOOP, DATA 40 NEXT LOOP 50 X = USR (1536) 60 DATA 169, 175, 141, 1, 210, 174, 96, 6, 142, 0, 210, 232, 142, 96, 6, 162, 15, 160, 15, 136, 208, 253, 202, 208, 248, 76, 5, 6