MediaWiki:Sitenotice:
2024-03-02: The wiki ran out of disk space, so things were not working. This has been resolved by adding another 5GB of quota ;-) Thanks to Tim Lindner for reporting the issues. 2020-05-17: If a page gives you an error about some revision not being found, just EDIT the page and the old page should appear in the editor. If it does, just SAVE that and the page should be restored. OS-9 Al (talk) 12:22, 17 May 2020 (CDT)

A Real-Time Talking Clock, Dennis Kitsz, page 5: Difference between revisions

From CoCopedia - The Tandy/Radio Shack Color Computer Wiki
Jump to navigation Jump to search
(Added program listing 2)
Line 175: Line 175:
  22 PRINT INT(A/4)  '* A JOYSTICK
  22 PRINT INT(A/4)  '* A JOYSTICK
  23 GOTO 7          '* & DO AGAIN
  23 GOTO 7          '* & DO AGAIN
</pre>
==PROGRAM LISTING 2==
Machine code version of a joystick input routine, using a binary search.
<pre>
00270        LDA        #$34
00280        STA        $FF01
00290        LDA        #$37
00300        STA        $FF03
00310 *
00320 NEXTIN  LDA        #$06
00330        STA        <TEMP1
00340        LDA        #$80
00350        STA        <TEMP2
00360 *
00370 AGAIN  STA        DAC
00380        ROL        ADC
00390        BCC        BIGGER
00400 LESSER  LSR        <TEMP2
00410        ADDA        <TEMP2
00420        BRA        JUMP
00430 BIGGER  LSR        <TEMP2
00440        SUBA        <TEMP2
00450        BRA        JUMP
00460 JUMP    DEC        <TEMP1
00470        BNE        AGAIN
00480        STA        ,X+
00490 *
</pre>
</pre>

Revision as of 20:58, 14 December 2004

A Real-Time Talking Clock

by DENNIS KITSZ

Part I

A real-time clock with voice synthesis!

What would you like? A real-time clock? A voice synthesizer? Info on using joysticks? Software without added hardware? A couple of hardware projects to dig into? Okay, get ready: I've got a something-for-everyone series beginning this month that includes two ways of producing voice from the Color Computer and two ways of adding a real-time clock. Depending on how you fold them together, you can have BASIC programs that speak or a clock that talks.

This month I'll be describing how to do voice synthesis - actually, voice recording" - in software, using your joystick input and cassette output ports. In the process, you will learn how the joystick input works, what sampling and timing mean, how the sound output works, and how you can force the high-speed POKE to work in RAM.

After you've had a chance to play with the vocal input/output, I'll create a purely software real-time clock. Since real time anything has to be totally independent of the vagaries of software, you'll learn about interrupts and video synchronization.

In the second part of this series I'll discuss interfacing and using the General Instrument vocal tract synthesizer (sold inexpensively by Radio Shack), and feeding it through the cartridge SND input. That will open the door to combining the vocal hardware with the interrupt-based realtime clock to create a talking timekeeper.

Finally, part three will offer an allophone (speech sound) vocal tract synthesizer that will give you an unlimited vocabulary. I'll provide it with inflection, too, and throw in one more twist to the plot - a battery-powered real-time clock. That will inevitably lead to a rewarding combination: a talking clock that keeps time even when the computer is off. It, too, will be interrupt-driven and completely transparent to other computer operations.

DIGITAL RECORDING

The basic principles of digital recording were explained in my article on Color Quaver (TCCM, November and December, 1983). Here's a review.

Sound is transmitted by variations in air pressure. Pressure variations are transformed by microphones into proportional electrical voltages. In analog recording (such as a phonograph record) the voltages are stored as wiggles in a record groove; in tape recording, .the voltages become variations In magnetic intensity. By reversing the process and forcing voltages through a loudspeaker, air pressure variations can be reproduced; sound results. At all of its stages, analog recording "looks" like the original sound in some respect.

Digital recording also transforms the air pressure changes into electrical variations, at least to start. From that point, though, the process differs dramatically. The electrical variations are measured at regular intervals, and the voltage that has been measured is stored in computer memory, or on disk or tape. To play the sound, the stored numbers are converted back to voltages at exactly the same rate that they were originally measured.

The process of measuring the changes in incoming voltage is called sampling, and the frequency of this process is called the sampling rate. The accuracy of the measurement is called its resolution. Sampling rate is expressed in kilohertz (thousands of cycles per second, abbreviated KHz), and resolution is provided by the number of bits used to sample and store the incoming voltage. The sampling rate affects the fidelity of the sound (faster sampling means a wider frequency range), and the resolution affects the level of sound intensity and noise (higher resolution means wider dynamic range and a better signal-tonoise ratio).

In the demonstration I've got for you, the sampling rate is about 3.6 KHz (7.2 KHz on a 64K computer using the high-speed RAM mode), and the resolution is six bits. The resulting frequency range ends at 1.8 KHz (3.6 KHz on a high-speed 64K computer), and the signal-to-noise ratio is a poor but quite intelligible 36 dB. High fidelity it ain't. Again, you'll find details in the articles on Color Quaver.

The Color Computer has all the means to record and play back voice or music. You won't get much of it - 4.5 seconds is as long as it will last in 16K of memory - but it will start you on adding voice to your Basic programs or doing experiments with digital sound recording.

THE JOYSTICK

The key to digital sampling is joystick input. Unlike simple Atari-style joysticks, which are made up of just four switches, Color Computer joysticks are variable resistors like stereo volume controls. A voltage (actually + 5 volts) is placeD on one side of the resistor, and ground is hooked to the other side. The variable resistor's "wiper" sweeps from the ground side to the + 5 volt side as you move the joystick, producing a variable voltage at the wiper contact. If the distance from ground to the wiper is labeled A and the distance from + 5 volts to the wiper is called B, then the voltage at the wiper is 5*(A/ A+B).

The Basic command PRINT JOYSTK(O) causes the computer to sample the voltage at the joystick wiper. The number displayed is 0 to 63, representing a range from 1/64ths of five volts (zero volts) to 63/64ths of five volts (4.92 volts). Try it; enter these lines:

 10 CLS : A$="#.## VOLTS"
 20 A=JOYSTK(O)
 30 PRINT @ 269, USING A$; 5*A/64;
 40 GOTO 20

As you move the joystick, the voltage being sampled (within 1/2 bit, or 1/128 volt) will be displayed.

The significant question is how the joysticks work. The voltage values don't just jump into the computer. And if you're looking for a sophisticated analog-to-digital converter chip, you won't find it.

The answer lies in Radio Shack's desire for a low-cost solution, and their cleverness in finding it. Converting a number to a voltage turns out to be an easier task than going the other way 'round. Converting a number to a proportional voltage goes this way: The binary value is fed through a group of resistors; each resistor contributes twice the previous amount of voltage (each bit to the right is twice the value of its neighbor to the left). Binary arithmetic prevails (I'm rushing here), and the resulting voltage ends up proportional to the original binary number. Figure 1 is the schematic of the digital-to-analog output stage of the Color Computer (the Color Computer 2 uses a custom integrated circuit for this).

If you can output a known voltage cheaply and easily, then you can measure any unknown voltage by comparing the two until you get a match. The known voltage feeds into one side of a commonplace electronic device known as a comparator; the unknown voltage feeds into the other side. The comparator flips from 0 to 1 when the unknown input equals or exceeds the known input. By reading the state of the comparator, the precise moment of match can be discovered. Figure 2 is the schematic of the joystick input section of the Color Computer.

Look at Listing 1, a Basic version of what Color Basic does when it checks the joystick. The digital-to-analog converter is found at address $FF20; the comparator bit is found at $FF00. The technique shown here is a binary search, also called successive approximation.

Control information is sent to the computer's ports (Lines 5 and 6) to get things set up and ready to read a joystick input. Variable A starts at the midway point (Line 7) and its value is sent to the binary-to-voltage converter (Line 10). Variable B receives the information from the comparator byte; bit 7 is the actual comparator result, and bits 0 through 6 contain other computer information. By ANDing value B with $80 (binary 10000000, Line 12), all but bit 7 are masked out, leaving the comparator information alone. Figure 3 shows that bit going into a 6821 peripheral interface adaptor, marked JOYIN.

If the comparator shows that the known outgoing value is less than the unknown incoming value, the binary search continues with a higher outgoing test value (Lines 14 - 16). Otherwise, it uses a lesser outgoing test value (Lines 17 - 18). The counter is decremented (Line 19), and the loop repeats until the process homes in on the unknown value. The result is divided by four to put it in the range 0 to 63, and then displayed.

Run the program. You'll see that - without ever using a JOYSTK command - the joystick value is printed correctly on the screen. Granted, the process is slow in Basic, but it demonstrates that analog-to-digital conversion is not mysterious.

If it works in Basic, it zips along in machine code. Look at Listing 2. The same values are sent to locations $FF01 and $FF03 to perform the set-up. The values 6 and $80 are stored in memory locations TEMP1 and TEMP2 as variable information. The value in the A accumulator goes to location DAC ($FF20).

The process varies just slightly, since a rotate command is available in 6809 commands, but not in Basic. Bit 7 of ADC ($FF00) is rotated into the carry flag; a branch-oncarry follows. The variable TEMP2 is divided by two (using a logical shift right, LSR). The rest of the listing is patterned after the Basic program. Here's an interesting comparison.

The Basic listing can do about three samples per second; using the JOYSTK command increases the sample to about 40 per second; the machine code routine can make over three and a half thousand samples each second.

DIGITAL RECORDER

So how does knowing how the joystick input works help you make a digital recording of your voice? Remember that the first stage of digital recording is the transformation of air pressure variations into proportional voltages. If the joystick input can measure joystick voltages, then shouldn't it follow that it can measure voltages from, say, a cassette player or microphone amplifier? Yes, it can. Basic can't do it because it's too slow. But machine code - at 3,600 samples per second-can pull in a reasonable representation of a voice.

Once you've got the voice stored as a series of numbers, reproducing it is easy. You swing through memory, taking each byte and feeding it to the digital-to-analog converter. The reproduced sound appears at the output. The only thing you need to keep in mind is that homing in on the sound sample takes longer than reproducing the sound by outputting a sample value...so you've got to add a little delay to keep the input and output rates matched.

Look at Listing 3, a complete record-reproduce program for the Color Computer. The heart of the joystick input program you've already seen is found in Lines 240520. The output routine is in 620 - 690. You can see that Lines 650 - 670 add the delay needed to keep input and output matched.

There are only a few other items to note. First of all, direct addressing is used to speed the program along (Lines 220 - 230). Next, interrupts are turned off to keep the sampling rate rock solid (Line 200). And finally, the "fast RAM" mode is used during the input and output sections (Line 210).

What is fast RAM? What are the mysterious high-speed POKEs all about? Here's the deal. The innards of your Color Computer are created from off-the-shelf components suited to many purposes. One of these is called the SAM (Synchronous Address Multiplexer). The SAM can support several computer configurations - that is, several combinations of types and sizes of RAM. The Color Computer uses several memory sizes (4K, 16K, 32K, 64K) but supports only one RAM type: dynamic.

Dynamic memory, through creative development and lots of luck, is low in power required and physically compact. Best of all, it is inexpensive. On the other hand, its special construction requires a continual refresh of its contents. This refresh is accomplished by reading 128 sequential memory locations at least every microsecond. The refresh complicates computer design because it has to be squeezed in between sequential instructions carried out by the central processing unit (CPU).

Designers at Motorola solved the problem by developing a combination of three sophisticated parts: the 6809 CPU itself, the SAM, and the 6847 video display generator. These work together to execute computer instructions, refresh the dynamic memory, and provide a video display.

Imagine the master clock of the Color Computer as a sequence of regular on-off pulses. During pulses 1, 3, 5, 7, 9 and so forth, the CPU executes its instructions from memory. During even-numbered pulses 2, 4, 6, 8 and so on, the memory is freed from the CPU to create the video display or to carry out the dynamic memory refresh. Since the video display generator also uses sequential addresses when it draws the screen, any video display has the effect of refreshing the memory.

When you turn your Color Computer on, it creates those alternating pulses - first one forthe CPU, then one for the video or refresh. It provides the pulses to all of memory. When you POKE 65495,0 (the usual so-called "high-speed" mode), you keep the refresh and video to the dynamic memory, but drop the extra pulse out when the computer uses the Basic ROM. Basic ROM is static and needs no refresh.

The "super high speed" mode is POKE 65497,0. If you try it, though, your video display will go into a frenzy, and you might lose your programs. That's because this POKE tells the SAM to bother with neither refresh nor video, but rather to consider the computer a machine with static RAM and no display output. No refresh, no video.

In this mode you might lose your programs because the refresh cycle is missing and the memory gradually "forgets" its contents. The mode conditions are summarized in Table 1.

But why does the super high speed work for program Listing 37 In this case, sequential memory is being filled with voice information, and then the voice information is played back. At this program's speed, the very act of filling and reading back the sequential memory acts as a memory refresh! The contents remain intact, undisturbed... though the video display is useless.

Once you've saved the source program in Listing 3 (w VOICE), you can assemble it to memory (A/IM/AO), quit the editor/assembler (Q), and protect Basic memory (CLEAR 200,&H3FOO). To use it, you'll need a joystick cable adaptor (see Figure 4). Turn the volume up on your television or monitor, pop a voice or music cassette into the recorder, and run the following lines:

10 EXEC &H3FOO 20 EXEC &H3F80 30 GOTO 10

The screen will go haywire, but the computer will record and play back the sound every two seconds. If you want to see the actual sound displayed as a sound wave, tap the Break key and enter and run Listing 4.

USING VOICE WITH BASIC

Since Basic programs have to run at normal speed to refresh the RAM, the voice you use with Basic won't have the quality you can hear at the higher speed. No matter; for some programs, any voice at all is better than none, so drop Lines 120, 130, 210, 550, 610 and 700 from Listing 3. You'll be able to store four seconds of sound in the 16K of memory above location $3FFF.

DIGITAL PUNCH IN THE NOSE

Now I'll turn away from digital voice recording to explore the first of two techniques for keeping the time of day. Keeping the" real time" is tricky because computer time is relative to its own master clock. The Color Computer's master clock (running at 894,886 pulses per second) is meaningful in just one way - you know exactly how much time each processor instruction takes. That's it; there's no easy way a program can know, so to speak, when one second has passed. Something has to knock on its door, interrupt its reverie, and punch it in the nose.

That digital punch is known as an interrupt. The Color Computer was built with interrupts in mind. The cursor flashes to the rhythm of interrupts, the Sound command counts them out to learn when it's done, and the timer runs with them. Fancy games depend on their presence.

Using interrupts isn't difficult, though it does call for a slight change of perspective. When you think of a program, you probably think of it as a logical series of commands followed one at a time without distraction. Interrupts seem to defy this concept, forcing the program away from its a ppoi nted tasks to work on someth i ng else.

That scenario is basically correct. The surprise is that the program in progress seems to have amnesia - it never remembers that it has been distracted from its work, can never recall what has happened during those lost microseconds.

The ideal interrupt happens like this: a signal (say, one synchronized with the video display) appears on the CPU's interrupt-request (IRQ) connection. If the machine code program in progress (such as the Basic interpreter) has enabledthe interrupt process, then this signal will be accepted as soon as the CPU is finished with its present instruction. The machine state (all the registers, program counter, and flags) gets stashed, and the program counter is given a new value. The new value in the program counter points to an "interrupt service routine."

The interrupt service routine takes care of whatever the programmer had in mind for that particular occurrence of the interrupt. When the interrupt service routine is finished, the original machine state (group of registers and flags) is restored and the main program continues exactly where it left off. A little time has mysteriously disappeared during the course of the main program.

A real-time clock is a perfect example of interrupt use.

VIDEO SYNCHRONIZATION

The Color Computer invites interrupt exploitation because both vertical and horizontal video signals can be used to generate interrupts. Television images require electrical pulses to cause each frame to begin at the top of the screen, and other pulses to cause each scanning line to begin at the left side of the screen. The signal to begin each frame is called vertical synchronization, and the signal to begin each line is called horizontal synchronization.

Vertical sync, which occurs 60 times every second, is an ideal candidate for interrupt use. After six pulses have occurred, then, 1/10 second has passed; after 60 pulses, one full second has passed. By keeping strict track of the pulse count, you can have a real-time clock.

Look at Listing 5, beginning at Line 200. At each interrupt pulse, the CPU will be directed there. Register X points to the final character in the clock image stored in memory, in ASCII, which starts at 00:00:00.00. The final digit is the 1/60 of a second counter. This value is incremented (Line 220), and checked to see if it has reached six. If it's less than six, the image is transferred to the screen by the exit routine beginning at Line 490. If the counter has reached six, it is reset to zero and the 1/10 of a second counter is incremented. If it hasn't reached ten, the routine exits; otherwise, the one-second counter is incremented. And so on, up to a total count of 99:59:59.95.

The exit routine transfers ten characters of the image to the screen. The 1/60 of a second dig it is not displayed.

The amazing thing about this 116-byte routine is that, as programs go, it is totally mundane. It's nothing more than increment, test, proceed, move memory, and exit. The only item to note is found at Line 570. The command JMP $894C lets Basic complete its part of the interrupt service routine chain (cursor, timer, sound) before returning to the program in progress.

Save the source code (W CLOCK), assemble this program into memory (A/IM/AO), quit the editor/assembler (Q), protect memory (CLEAR 200,&H3FOO) and execute the machine code program (EXEC &H3FOO). The clock will appear in the top corner of the screen, in reverse-video characters. This software clock will survive resets and CLOADs (not necessarily CLOADMs), and will run under most program conditions. Naturally, if you have a 32/64K machine, you'll wantto move it up in memory.

INTERRUPT THEORY

I passed by that interrupt theory pretty quickly to give you a chance to see it perform. There are some important things to understand before you put interrupts to work for yourself.

First of all, since interrupts come through at a regular pace, you've got to make sure you keep ahead of that pace. If you don't, you will not get back to the main course of your program properly.

Rule Number 1 is: make your interrupt routines short and efficient. When using the relatively laggard 60-persecond pulse of the vertical sync, that isn't much of a problem, because 1/60th of a second is 16,667 microseconds, or 14,915 Color Computer master clock pulses. The clock interrupt routine is lengthiest at the change back to 00 hours. Including the machine state saving at the interrupt itself, this requires 303 master pulses plus some more for Basic's timer, cursor and sound. The shortest execution for just a 1/60 second count is only 35 master clock pulses. Overall, the clock routine's time is minuscule with respect to the 14,915 master pulses available.

But what if you wanted to create a kind of super stopwatch? The Color Computer gives you a chance to do that, too. There isn't room to go into the details, but the horizontal synchronization from the video can also be used as an interrupt. This interrupt occurs 15,750 times each second, or once every 63.5 microseconds. This time, 63.5 microseconds is just over 56 computer clock cycles... hardly time to do much of anything. If you think 56 clock cycles isn't any time at all, though, turn to Steve Bjork's article on interrupts (Display Modes, December, 1983 TCCM); the pro speaks!

Figure 3 shows the schematic for interrupt handling in the Color Computer. Shown is the 6821 Peripheral Interface Adaptor (PIA). At the left the vertical (or field) synchronization is marked FS, and feeds CB1; horizontal synchronization is marked HS, and feeds CA 1. By proper programming (refer to the 6821 data sheet for details), either can be fed through to the CPU's interrupt request pin via IRQA and IRQB (right side of the PIA).

Oh yes. Here's Rule Number 2: if you are using interrupts in an independent program that does not work with the Basic ROMs at all, be sure to reset the interrupt latch by reading the correct PIA location (LDA $FF02). Otherwise, further interrupts won't be passed through the PIA, and you'll lose all the timing.

WHAT DOES IT ALL MEAN?

I won't tie all this together until later in this series, but keep in mind that all these concepts involve timing - the ultra-fast timing of digital recording, the hidden timing of interrupts, and (in the next part) the slow timing of interfacing with external electronics.

Ed's Note: Articles referred to, except Part I of this series, are found in back issues of The Color Computer Magazine, unless otherwise noted.

PROGRAM LISTING 1

BASIC emulation of a joystick input routine. 16K Extended Color BASIC.

 1 CLS
 2 X=&HFFOO          '* PORT VALUE
 3 DAC = &HFF20      '* D/A CONVT.
 4 ADC = &HFFOO      '* COMPARATOR
 5 POKE &HFF01,&H34  '* CTRL. INFO
 6 POKE &HFF03,&H37  '* CTRL. INFO
 7 A = &H80          '* B 10000000
 8 T1 = 6            '* ITERATIONS
 9 T2 = &H80         '* B 10000000
 10 POKE DAC,A       '* SEND VALUE
 11 B = PEEK (ADC)   '* BYTE BIT 7
 12 B = B AND &H80   '* TEST BIT 7
 13 IF B = 0 THEN 17 '* IF FLIPPED
 14 T2 = T2/2        '* ELSE LESS
 15 A = A + T2       '* ADD VALUE
 16 GOTO 19          '* GO TO NEXT
 17 T2 = T2/2        '* IT IS MORE
 18 A = A - T2       '* ELSE MORE
 19 T1 = T1 - 1      '*'SUB. VALUE
 20 IF T1>0 THEN 10  '* DONE YET?
 21 PRINT@0,"JOY ="; '* A MESSAGE
 22 PRINT INT(A/4)   '* A JOYSTICK
 23 GOTO 7           '* & DO AGAIN

PROGRAM LISTING 2

Machine code version of a joystick input routine, using a binary search.

00270         LDA        #$34
00280         STA        $FF01
00290         LDA        #$37
00300         STA        $FF03
00310 *
00320 NEXTIN  LDA        #$06
00330         STA        <TEMP1
00340         LDA        #$80
00350         STA        <TEMP2
00360 *
00370 AGAIN   STA        DAC
00380         ROL        ADC
00390         BCC        BIGGER
00400 LESSER  LSR        <TEMP2
00410         ADDA        <TEMP2
00420         BRA        JUMP
00430 BIGGER  LSR        <TEMP2
00440         SUBA        <TEMP2
00450         BRA        JUMP
00460 JUMP    DEC        <TEMP1
00470         BNE        AGAIN
00480         STA        ,X+
00490 *