Sitenotice: 11/29/2018: The wiki is back. It turns out, some anti-virus product on my web server had an issue with the latest version of PHP. My server techs have resolved this issue, and things should be working again. During the investigation, I did restore to a backup from September. There is a chance that any changes done since then were lost, but I do not recall any edits. --OS-9 Al

8/30/2016: Massive re-work is being done on the InfoBox Templates. Read that page to keep up with the plan for that, and adding better keyword tags (categories) to all the pages. --OS-9 Al (talk) 15:28, 31 August 2016 (CDT)

Undercolor/840101/A RealTime Talking Clock

From CoCopedia - The Tandy/Radio Shack Color Computer Wiki
Jump to: navigation, search

Home Articles Companies Publications Hardware People Software Timeline ... Emulators Internet Resources
(Don't see something listed? Click "edit" and add it! Together we can build this database. When making a new info page, refer to this InfoBox Template for guidelines.)



UnderColor, Volume 1, Number 1, December 10, 1984

  • Title: A RealTime Talking Clock
  • Author: Dennis Kitsz
  • Synopsis: The first of several parts.
  • Page Scans: Link

Article

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 real-time 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 be-

come 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-to-noise 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 ofjust 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) [5*(A/(A+B))].

The Basic command PRINT JOYSTK(0) causes the computer to sample the voltage at the joystick wiper. The number displayed is O to 63, representing a range from 0/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(0)

30 PRINT@269,USlNGA$;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 joystick 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-on-carry 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 JOSTK 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 240-520. 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 for the 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.

l 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 3? 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 (wvoice), you can assemble it to memory (A/IM/AO), quit the editor/assembler (Q), and protect Basic memory (CLEAR 200,&H3F00). 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 &H3F00

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 appointed tasks to work on something 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 enabled the 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/60 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 digit 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,&H3F00) and execute the machine code program (EXEC &H3F00). 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 want to 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-per-second 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 CA1. 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 $FFO2). 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.

Listings

PROGRAM LISTING I
Basic emulation of a joystick input routine.
16K Extended Color Basic
1 CLS
2 X=&HFF00          '* PORT VALUE
3 DAC = &HFF20      '* D/A CONVT.
4 ADC = &HFF00      '* COMPARATOR
5 POKE &HEF01,&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 '* IE ELIPPED
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 PRINTINT(A/4)    '* A JOYSTICK
23 GOTO 7           '* 8 DO AGAIN
PROGRAM LISTING 2
Machlne code verslon
of a Joystick
input routine,
uslng 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 *
32K Extended Color Basic
FF20 00100 DAC EQU $FF20
FF00 00110 ADC EQ0 $FF00
FFD9 00120 FAST EQU $FFD9
FFD8 00130 SLOW EQU $FFD8
4000 00140 MEHBOT EQU $4000
8000 00150 MEMTOP EQU $8000
00160 *
3F00 00170 ORG $3F00
3F 180 SETDP $3F
00190 *
3F00 1A 50 00200 START ORCC #$50
3F02 B7 FFD9 00210 STA FAST
3F05 86 3F 00220 LDA #$3F
3F07 1F 8B 00230 TFR A,DP
00240 *
3F09 82 4000 00250 LDX #MEMBOT
00260 *
3FOC 86 34 00270 LDA #$34
3FOE B7 FF01 00280 STA $FF01
3F11 86 37 00290 LDA #$37
3F13 B7 FF03 00300 STA $FF03
00310 *
3F16 86 06 00320 NEXTIN LDA #$06
3E18 97 9B 00330 STA <TEMP1
3F1A 86 80 00340 LDA #$80
3F1C 97 9C 00350 STA <TEHP2
00360 *
3F1E B7 FF20 00370 AGAIN  STA  DAC
3F21 79 FF00 00380        ROL  ADC
3F24 24 06   00390        BCC  BIGGER
3F26 04 9C   00400 LESSER LSR  <TEMP2
3F28 9B 9C   00410        ADDA <TEMP2
3F2A 20 06   00420        BRA  JUMP
3F2C 04 9C   00430 BIGGER LSR  <TEMP2
3F2E 90 9C   00440        SUBA <TEMP2
3F30 20 00   00450        BRA  JUMP
3F32 0A 98   00460 JUMP   DEC  <TEMP1
3F34 26 E8   00470        BNE  AGAIN
3F36 A7 80   00480        STA  ,X+
00490 *
3F38 8C 8000 00500        CMPX #MEMTOP
3F3B 26 D9   00510        BNE  NEXTIN
00520 *
3F3D 4F      00530        CLRA
3F3E 1F 8B   00540        TFR  A,DP
3F40 B7 FFD8 00550        STA  SLOW
3F43 39      00560        RTS
00570 *
3F80         00580        ORG $3F80
00590 *
3F80 1A 50   00600 PLAYBK ORCC #$50
3F82 B7 FFD9 00610        STA  FAST
3F85 8E 4000 00620        LDX  #MEMBOT
3F88 A6 80   00630 SPEAK  LDA  ,X+
3F8A B7 FF20 00640        STA  DAC
3F8D C6 2C   00650        LDB  #$2C
3F8F 5A      00660 LOOP   DECB
3F90 26 FD   00670        BNE  LOOP
3F92 8C 8000 00680        CMPX #MEMTOP
3F95 26 F1   00690        BNE  SPEAK
3F97 B7 FFD8 00700        STA  SLOW
3F9A 39      00710        RTS
00720 *
3F9B         00730 TEMP1  RMB 1
3F9C         00740 TEMP2  RMB 1
00750 *
0000 00760
00000 TOTAL ERRORS
ADC    FF00      MEMTOP 8000
AGAIN  3F1E      NEXTIN 3F16
BIGGER 3F2C      PLAYBK BF80
DAC    FF20      SLOW   FFD8
FAST   FFD9      SPEAK  3F88
JUMP   3F32      START  3F00
LESSER 3F26      TEMP1  3F9B
LOOP   3F8F      TEMP2  3F9C
MEMBOT 4000
PROGRAM LISTING 4
Short Basic routine to display the sound wave representation of the sound recorded by Listing 3.
32K Extended Color Basic
10 CLS0
20 FORX = &H4000 TO &H8000
30 SET (Y, PEEK(X)/8, 5)
40 Y=Y+1: IF Y>63 THEN CLS0: Y=0
50 NEXT
Program Listing 5
Real-time clock using the internal interrupts which occur 60 times each second.
32K Extended Color Basic
3F00          00100        ORG $3F00
00110 *
3F00 1A 50    00120 INTOFF ORCC #$50  * TURN INTERRUPTS OFF
3F02 8E 3E10  00130        LDX #START * POINT X TO SERVICE ROUTINE
3F05 BF 0103  00140        STX $0100  * STORE ROUTINE TO IRQ VECTOR
3F08 86 37    00150        LDA #$37   * VALUE 00110111 FOR MASKING
3F0A B7 EF03  00160        STA $FF03  * TURN ON VERTICAL SYNC
3F0D 1C EE    00170        ANDCC #$EF * TURN INTERRUPTS ON
3F0E 39       00180        RTS        * AND BACK TO BASIC "OK"
00190 *
3F10 8E 3F77  00200 START  LDX #IMAGE+10 * POINT X TO 1/10 SEC.
3F13 C6 30    00210        LDB #$30      * B BECOMES ASCII OFFSET
3F15 6C 84    00220        INC ,X        * INCREMENT 1/10 SECONDS
3F17 A6 84    00230        LDA ,X        * GET 1/10 SECONDS VALUE
3F19 81 36    00240        CMPA #$36     * IS 6/10 SECONDS COUNTED?
3F1B 23 2C    00250        BLT OUT       * IF NOT 6/l0 SECONDS, OUT
3F1D 8D 40    00260        BSR DEC1      * ELSE BACK UP 1 MEM. LOCATION
3F1F 81 3A    00270        CMPA #$3A     * IS IT 1 SECOND YET?
3F21 2D 26    00280        BLT OUT       * IF NOT 1 SECOND, OUT
3F23 8D 41    00290        BSR DEC2      * ELSE BACK UP 2 MEM. LOCNS.
3F25 81 3A    00300        CMPA #$3A     * IS IT 10 SECONDS YET?
3F27 2D 20    00310        BLT OUT       * IE NOT 10 SECONDS, OUT
3F29 80 34    00320        BSR DEC1      * BACK UP 1 MEM. LOCATION
3F2B 81 36    00330        CMPA #$36     * IS IT 60 SECONDS YET?
3F23 2D 1A    00340        BLT OUT       * IF NOT 60 SECONDS, OUT
3F2F 8D 35    00350        BSR DEC2      * ELSE BACK UP 2 MEM. LOCNS.
3F31 81 3A    00360        CMPA #$3A     * IS IT 10 MINUTES YET?
3F33 23 14    00370        BLT OUT       * IF NOT 10 MINUTES, OUT
3F35 8D 28    00380        BSR DEC1      * ELSE BACK UP 1 MEM. LOCATION
3F37 81 36    00390        CMPA #$36     * IS IT 60 MINUTES YET?
3F39 2D 0E    00400        BLT OUT       * IE NOT 60 MINUTES, OUT
3F3B 8D 29    00410        BSR DEC2      * ELSE BACK UP 2 MEM. LOCNS.
3F3D 81 3A    00420        CMPA #$3A     * IS IT 10 HOURS YET?
3F3F 23 08    00430        BLT OUT       * IF NOT 10 HOURS, OUT
3F41 8D 1C    00440        BSR DEC1      * ELSE BACK UP 1 MEM. LOCATION
3F43 81 3A    00450        CMPA #$3A     * IS IT 100 HOURS YET?
3F45 2D 02    00460        BLT OUT       * IF NOT 100 HOURS, OUT
3F47 E7 84    00470        STB ,X        * PLACE $30 (ASCII ZERO)
00480 *
3F49 108E 0414 00490 OUT   LDY #$0416    * POINT TO RIGHT SCREEN
3F4D 8E 3F6D   00500       LDX #IMAGE    * POINT X TO CLOCK IMAGE
3F50 C6 0A     00510       LDB #$0A      * COUNT 10 SCREEN POSITIONS
3F52 A6 80     00520 LOOP  LDA ,X+       * GET CHARACTER PROM CLOCK
3F54 A7 A0     00530       STA ,Y+       * AND PLACE IT ON THE SCREEN
3F56 5A        00540       DECB          * DONE WITH IMAGE YET?
3F57 26 F9     00550       BNE LOOP      * IF NOT, THEN GET NEXT CHAR.
00560 *
3F59 B6 EF02   00570       LDA $FF02     * CLEAR VERT. SYNC LATCH
3F5C 7E 894C   00580       JMP $B94C     * AND TO BASIC TO DO RTI
00590 *
3F5F E7 84     00600 DEC1  STB ,X        * PLACE $30 (ASCII ZERO)
3F61 6C 82     00610       INC ,-X       * BACK UP ONE MEM. LOCATION
3F63 A6 84     00620       LDA ,X        * GET VALUE FROM IMAGE
3F65 39        00630       RTS           * BACK TO MAIN PROGRAM
00640 *
3F66 E7 84     00650 DEC2  STB ,X        * PLACE S30 (ASCII ZERO)
3E68 6C 83     00660       INC ,--X      * BACK UP TWO MEM, LOCATIONS
3F6A A6 84     00670       LDA ,X        * GET VALUE FROM IMAGE
3F6C 39        00680       RTS           * BACK TO MAIN PROGRAM
00690 *
3F6D 30        00700 IMAGE FCC /00:00:00.00/
30
3A
30
30
3A
30
30
2C
30
30
00710 *
3F00           00720        END INTOFF
00000 TOTAL ERRORS
DEC1   3F5F
DEC2   3F66
IMAGE  3F6D
INTOFF 3F00
LOOP   3F52
OUT    3F49
START  3F10