` COMPUTE! ISSUE 37 / JUNE 1983 / PAGE 238`

Using The Atari Timer
Stephen Levy

Because FOR/NEXT loops are not accurate timers, the solution is to incorporate Atari's internal counters into programs where you want something delayed or timed reliably.

Have you ever written a program and wanted a specific time delay? What did you do? Some of us figured a FOR/NEXT loop was the answer, so we set to work with our stopwatches until we found that the following takes about three seconds to write "STOP":

10 PRINT "BEGIN"
20 FOR X=1 TO 1000
30 NEXT X
40 PRINT "STOP"

Then we went along and wrote our programs and found that our three-second delay had become five, six, or even ten seconds. Why? Because the Atari FOR/NEXT loops take longer as you add lines of code to the program.
There is a better way. Yes, machine language routines are great for timing on the Atari, especially if you know how to use locations 536 to 558 (\$218 to \$22E). But it can be most disconcerting if you allow some of those registers to drop to zero unchecked.

Accurate Delays
BASIC programmers, there is a way. Use memory locations 18, 19, and 20. (In the May 1981 issue of COMPUTE!, Richard Bills shows how to use these locations for timing in "Real-Time Clock on the Atari.")
These timers work like the mileage gauge on a car's speedometer: one counter counts up and then sets the one next to it which, in turn, sets the next one. Each counter on the speedometer goes up when the one to its right hits ten. In the computer, they count up to 255 before going back to zero.
Register number 20 counts at the rate of 60 numbers per second up to number 255, then increments register 19 by one and starts over. When register 19 reaches 255, it increments register 18 by one. If you POKE zero into all three registers, it will take about 1092 seconds before a one appears in register 18 (more than 18 minutes). The table gives some times (it assumes all three registers began with zero). Notice that it would take more than 77 hours for memory location 18 to reach 255.
Well, how does all this help? Let's look at our short program again. We can rewrite it this way:

10 PRINT "BEGIN": POKE 20,0
20 IF PEEK(20)<180 THEN 20
30 PRINT "STOP"

This routine will continue to take three seconds no matter how long your program. Well, not exactly; since it is written in BASIC, the longer the program, the longer the routine will take. But the influence of the program length will usually be negligible.
Included here are three programs which demonstrate a much more functional use of this timer. Type in Program 1, leaving out the REM statements. This program tells the user the time interval between the pressing of RETURN after typing RUN and the pressing of RETURN a second time. Notice that if you press another key the computer goes back to line 130.
This short program demonstrates several useful concepts. First, the computer is looking for a particular input, in this case the RETURN key (ATASCII 155). Second, line 150 PEEKS at registers 18, 19, 20. Notice we POKEd location 20 last on line 110 and PEEKed at it first on line 150. Third, line 160 contains the important formula for converting the information in locations 18, 19, 20 to seconds. Why 4.267? Because 256 divided by 60 numbers per second equals 4.267. Fourth, lines 170 to 190 convert the total number of seconds to minutes and seconds.
Program 2 is a bit more useful. It is a timed math quiz in which the user is allowed eight and one half seconds to answer. Line 55 is used to check if a key has been pressed. If no key has been pressed, then the program goes back to check how much time has elapsed. Once a key is pressed, the computer GETs the ATASCII code and calls it Al. At lines 70 and 80, Al is converted to its CHR\$ and placed in its proper place in ANS\$. If Al equals 155 (ATASCII code for the RETURN key), then the program moves to line 200, where the value of ANS\$ is put into variable ANS.
The final illustration, Program 3, is also a math quiz. In this case the user is given unlimited time. This program combines elements of both programs 1 and 2.
This Atari timing device should be beneficial whether you wish to impose a time limit, simply time answers, or have users compete against each other or themselves. The timer has applications for both educational programming and games. With some experimentation you should be able to adapt this timing device for use with your own programs.

Sample Times
 LOC.20 LOC.19 LOC.18 TIME MIN:SEC 60 0 0 0:01 60 1 0 0:05 0 2 0 0:08 100 2 0 0:10 0 3 0 0:12 100 4 0 0:18 21 14 0 1:00 42 28 0 2:00 84 56 0 4:00 176 112 0 8:00 0 255 0 18:08 0 60 2 40:40 0 0 16 291:17 0 0 100 1820:35 0 0 150 2730:52 0 0 255 4642:29

Program 1: Atari Timer
10 REM PROGRAM 1
15 REM
20 REM THIS PROGRAM DEMONSTRATES HOW
30 REM TO USE ATARI TIMER:
40 REM ADDRESS 18,19,20
50 REM IT FIGURES HOW LONG IT TAKES
60 REM YOU TO PRESS THE <RETURN> KEY.
70 REM RUN THE PROGRAM THEN PRESS
80 REM <RETURN>
90 REM PROGRAM RUNS BETTER WITHOUT TH
E
95 REM REMARK STATEMENTS OR GOTO 100
100 OPEN #1,4,0,"K:"
110 FOR Z=18 TO 20:POKE Z,0:NEXT Z
130 GET #1,D:IF D=155 THEN 150
140 GOTO 130
150 A=PEEK(20):B=PEEK(19):C=PEEK(18)
160 SEC=INT((4.267*256*C)+(B*4.267)+(
A/60))
170 MIN=INT(SEC/60)
180 M=MIN*60
190 SEC=SEC-M
200 PRINT MIN;" MINUTES ":SEC;" SECON
DS"

Program 2: Timed Math Quiz
1 REM PROGRAM 2
2 REM
3 REM THIS IS A TIMED MATH QUIZ
4 REM CHANGE LINE 50 TO A=1
5 REM ALLOWS 4 1/4 SECOND
6 REM A=2 ALLOWS 8 1/2 SECONDS
7 REM A=3 ALLOWS 12 3/4 SECONDS, ETC.
10 OPEN #1,4,0,"K:":DIM ANS\$(10)
15 PRINT :Q1=INT(RND(0)*20):Q2=INT(RN
D(0)*20):X=1
20 PRINT Q1;" + ";Q2;"=";
25 POKE 18,0:POKE 19,0:POKE 20,0
45 A=PEEK(19):B=PEEK(20)
50 IF A=2 THEN 100:REM 8 1/2 SECONDS
55 IF PEEK(764)=255 THEN 45
60 GET #1,A1:IF A1=155 THEN 200
70 ANS\$(X,X)=CHR\$(A1)
80 PRINT ANS\$(X,X);:X=X+1:GOTO 45
100 PRINT :PRINT "TIME'S UP"
110 PRINT "THE ANSWER IS ";Q1+Q2
115 FOR W=1 TO 400:NEXT W
120 ANS\$=" ":GOTO 15
200 ANS=VAL(ANS\$):PRINT
210 IF ANS=Q1+Q2 THEN PRINT :PRINT "C
ORRECT":GOTO 115
220 PRINT :PRINT "SORRY":PRINT :GOTO
110

Program 3: Revised Math Quiz
1 REM PROGRAM 3
2 REM
3 REM THIS PROGRAM COMBINES ELEMENTS
4 REM OF PROGRAMS 1 AND 2.
5 REM IT GIVES MATH QUIZ AND TELL HOW
6 REM LONG IT TOOK: YOU TO DO EACH
7 REM PROBLEM.
10 OPEN #1,4,0,"K:":DIM ANS\$(10)
15 PRINT :Q1=INT(RND(0)*20):Q2=INT(RN
D(0)*20):X=1
20 PRINT Q1;" + ";Q2;"=";
25 POKE 18,0:POKE 19,0:POKE 20,0
60 GET #1,A1:IF A1=155 THEN 190
70 ANS\$(X,X)=CHR\$(A1)
80 PRINT ANS\$(X,X);:X=X+1:GOTO 60
110 PRINT "THE ANSWER IS ";Q1+Q2
115 FOR W=1 TO 1000:NEXT W
120 ANS\$=" ":GOTO 15
190 A=PEEK(20):B=PEEK(19):C=PEEK(18)
200 ANS=VAL(ANS\$):PRINT
210 IF ANS=Q1+Q2 THEN PRINT :PRINT "C
ORRECT":GOTO 230
220 PRINT :PRINT "SORRY"
230 SEC=INT((4.267*256*C)+(B*4.267)+(
A/60))
240 MIN=INT(SEC/60)
250 M=MIN*60
260 SEC=SEC-M
270 IF MIN<>0 THEN 290
280 PRINT "THAT TOOK YOU ";SEC;" SECO
NDS":GOTO 300
290 PRINT "THAT TOOK YOU ";MIN;" MINU
TES":PRINT "AND ";SEC;" SECONDS"
300 GOTO 115