The Atari Keyboard Speaks Out

Walter M. Lee

How to use the console speaker — Atari's fifth voice. Here's an explanation of the Atari built-in loudspeaker and a user-controllable BASIC program to play music without using the TV speaker.

One of the frequently unused features of the Atari computer is the keyboard loudspeaker. Many of the sound effects created on the Apple II + keyboard loudspeaker can also be generated on the Atari. The four-voice audio output of the Atari to the television is more flexible than the keyboard speaker. However, if your display is a monitor instead of a television set, it may not support the four-voice audio output. The keyboard loudspeaker is then a practical means for audio output or feedback. In addition, the keyboard loudspeaker allows the television or monitor to be turned off while the Atari is executing a long program. The loudspeaker can then signal when the job is finished.

The Atari keyboard loudspeaker is accessible from the BASIC cartridge. A simple PRINT statement will create a buzzer.

10 PRINT "{BELL}";

This buzzer has a fixed tone and duration. To create a variable duration, one must POKE zero into the speaker register, CONSOL, at location 53279 decimal. The duration is set by the number of times CONSOL is set to zero.

10 INPUT N
20 FOR I = 0 TO N : POKE 53279, 0 : NEXT I
30 GOTO 10

Creating pure pitches on the Atari keyboard loudspeaker requires more work. A loudspeaker produces sound by creating waves of alternating high and low pressure in the air. The loudspeaker does this by moving a diaphragm (the loudspeaker's cone) forward and backward. As the diaphragm moves forward it squeezes the air in front of it, causing a region of high pressure. As the diaphragm moves backward, the air rushes in to fill the space left behind the moving diaphragm and creates a region of low pressure. These pressure waves radiate out from the loudspeaker in the direction of propagation; i.e., sound waves are longitudinal waves. Storing 8 into CONSOL pushes the diaphragm one way, and storing 0 into CONSOL pushes the diaphragm the other way.

The time delay between switching CONSOL from 8 to 0 constitutes the period of the sound wave; therefore, it designates the frequency generated by the sound wave. The shorter the time delay, the higher the frequency. The Vertical Blank Interrupt stores an 8 into CONSOL every 1/60 of a second. This is why Program 1 works. However, this also prevents the keyboard loudspeaker from generating any pitch other than 60 hertz (hertz = cycles/second). Fortunately, we do not have to disable the entire Vertical Blank Interrupt to create variable pitches on the loudspeaker. The Vertical Blank Interrupt is broken into two stages. During critical code sections (e.g., I/O routines), the Atari Operating System will defer the second stage of the Vertical Blank Interrupt. This is done by setting the CRITIC flag, at location 66 decimal, to a nonzero value. The second stage stores 8 into CONSOL. The first stage updates the real-time clock, the ATTRACT mode, and the system countdown timer 1. The shadow registers, the game controllers, and the system countdown timers two through five are disabled with the second stage. To regain the second stage, we set CRITIC = 0, which is its normal state.

The time delay for the Atari has an intrinsic pitch distortion. This is due to the Atari Display processor, ANTIC, which "steals" machine cycles from the 6502 in order to generate the display on the television and to refresh memory. This is called Direct Memory Access (DMA). The DMA cannot be accounted for in the delay loop and causes the pitch to get out of synchronization. The accuracy of the pitch generated must be sacrificed if we are to maintain a display. Graphics mode 3 through 6 (BASIC) seem to have the least effect on pitch distortion. To create the purest tone possible, the screen must be turned off. This is achieved by storing zero into DMACTL, at location 54272 decimal, after disabling the shadow registers by setting CRITIC = 1. Program 1 creates various low tones on the keyboard loudspeaker.

In machine language, the frequency range is extended. The upper frequencies are increased by a much greater extent than the lower frequencies. The lower frequencies degrade into "clicks," which is normal for square wave sound synthesis.

Most users will want to use this technique in BASIC. I have written an Atari BASIC USR function to control the keyboard loudspeaker. Program 2 puts this USR function in memory locations 1536 to 1600 decimal. The USR function

DUMMY = USR(1536, I, J)

sets I = pitch and J = duration. The pitch can be from 1 (the highest) to 255 (the lowest). Setting I = 0 is equivalent to setting I = 256. The variable J has a range from 0 to 65,535. The longest duration is when J = 65, 535. The pitch distortion should be around 10% when the screen is off. Program 2 does a frequency range test and then plays a perceptible version of the ABC song. A table of pitch values for musical notes is also included in the program. To create other tunes, I have included a table of corresponding musical notes and their approximate pitch numbers. These values were calculated from a CRC Handbook of Chemistry and Physics and may not be correct. My checking was hampered by the fact that I do not have a musical ear. The Pitch number is the reciprocal of the product

pitch = 1/musical note frequency * cycle speed * 5 cycles

The cycle speed is .8517 microseconds per machine cycle, which is much slower than the official speed of .56 microseconds per machine cycle. The Atari's 6502B main processor has an effective speed of 1.17Mhz in Graphics Mode 0 (BASIC). I calculated this speed by dividing the execution time of A = USR(1536, 255, 8191) by the number of cycles the 6502 must execute.

These programs present the fifth audio voice to Atari users. For users without a television or monitor audio output, these programs give the user a limited audio output without additional hardware. For the less ambitious programmer, lines 29100 to 30002 in Program 2 and the pitch table to musical notes are all you need.

PROGRAM 1. The Atari Keyboard Speaks Out

100 C = 53279
101 S1 = 8 : S2 = 0 : A = 24 : B = 2 : D = 48
102 CRITIC = 66 : DMACTL = 54272
200 POKE CRITIC, 66 : POKE DMACTL, 0
222 FOR J = 0 TO A STEP B : FOR K = 0 TO D : POKE C, S1 : FOR I = 0 TO J : NEXT I : POKE C, S2 : NEXT K : NEXT J
240 POKE CRITIC, 0

PROGRAM 2. The Atari Keyboard Speaks Out

90 DIM PITCH(32, 2)
99 GRAPHICS 2 + 16 : ? #6; "FREQUENCY RANGE TEST"
100 GOSUB 29100 : REM MAKE SUBROUTINE
101 RESTORE 110
102 REM PITCH# = 1 / (FREQ * .85^-07 + 5)
103 REM EQUAL TEMPERED CHROMATIC
104 REM SCALE : A(4) = 440hz
105 REM FROM A#(5) = 932hz to
106 REM C(8) = 4186hz.see CRC Handbook
107 REM of Chem.and Physics 58th ed.
108 REM page E - 48
110 DATA 252, 238, 224, 212, 200, 189, 178, 168, 159, 150, 141, 133, 126, 119, 112, 106, 100, 94, 89, 84, 79, 75, 71, 67, 63, 59, 56, 53
200 FOR I = 1 TO 28 : READ A
210 PITCH(I, 1) = A : PITCH(I, 2) = 1024 + (I - 1) * 127 : NEXT I
290 REM FREQUENCY RANGE TEST
300 FOR I = 1 TO 28 : A = USR(1536, PITCH(I, 1), PITCH(I, 2)) : NEXT I
390 REM SING A. B. C.
400 RESTORE 410
401 POSITION 0, 3 : ? #6; "ABC"
410 DATA 3, 3, 10, 10, 12, 12, 10, 8, 8, 7, 7, 5, 5, 5, 5, 3, 10, 10, 8, 8, 7, 7, 5, 10, 10, 8, 8, 7, 7, 5, 5, 3
420 FOR I = 1 TO 44 : READ A : A = USR(1536, PITCH(A, 1), PITCH(A, 2)) : NEXT I
29099 END
29100 RESTORE 30000
29101 FOR I = 1536 TO 1600 : READ A : POKE I, A : NEXT I : POKE I + 1, 0 : RETURN
30000 DATA 133, 203, 104, 104, 133, 205, 104, 133, 204, 104, 133, 207, 104, 133, 206, 165, 203, 72, 138, 72, 152, 72
30001 DATA 169, 1, 133, 66, 166, 206, 169, 8, 141, 31, 208, 164, 204, 136, 208, 253, 140, 31, 208, 202, 208, 240
30002 DATA 169, 0, 197, 207, 240, 5, 198, 207, 76, 26, 6, 104, 168, 104, 170, 104, 169, 0, 133, 66, 96

Return to Table of Contents | Previous Section | Next Section