Accurate Timing In Atari BASIC
John Navas, II
San Mateo, CA
Trying to accurately control time intervals in Atari BASIC is a frustrating experience. A FOR…NEXT loop is the method most often recommended to create a simple time delay. An example of this approach is:
FOR N = 1 TO 1000 : NEXT N
By adjusting the TO value or expression to a smaller or larger number than 1000, the length of the time delay can be made shorter or longer. Unfortunately, however, this method has several drawbacks:
- The exact time delay desired can only be found through a process of trial and error.
- The time delay for a given TO value or expression will vary significantly, depending on where it is located in a program (shorter near the beginning and longer near the end).
- The length of the time delay is significantly affected by the display mode (a given FOR…NEXT loop takes about 30% less time in GRAPHICS 3 than in GRAPHICS 0).
- Accurately timing more than one interval at the same time is very difficult.
- The BASIC program can't do anything else during the time delay interval.
These BASIC problems can be easily overcome in machine language. Although machine language programs can use a similar loop counter approach, they also have ready access to a number of superior alternatives provided by ATARI'S unique hardware and Operating System. These alternatives include the five system timers, the Real-Time CLOcK (RTCLOK), and the POKEY hardware timers (normally used to generate tones with the SOUND statement). Happily, there are simple ways to gain access to some of these facilities in Atari BASIC. This article describes how to use the system timers.
First, a short note on how system timers 3, 4 and 5 work. (Although there are five timers in all, only these three are readily useable in BASIC.) Each timer consists of a two-byte counter, CDTMV3-CDTMV5, and a one-byte flag, CDTMF3-CDTMF5. The actual hardware addresses are given in Program 1. To use a Timer, its flag must first be set to any non-zero value, and then its counter must be set to the value of the desired time interval. The operating system will subtract one from the counter every 1/60 second during the start of each new TV-picture frame (VBLANK) until the counter reaches zero. At zero, the operating system changes the flag back to zero and stops counting. All the BASIC program needs to do once the timer is running is to PEEK at the flag periodically to see if the time interval has run out. Note that all three timers may be used at the same time, if desired.
The timer counters are typical 6502 two-byte binary numbers, with the least significant byte at the lower hardware address. This means that each count in the lower address byte is worth 1/60 second up to a maximum of 255 counts for 4.25 seconds; each count in the higher address byte is worth 256 counts in the lower address byte, or just over 4.25 seconds. Only the lower address byte need be set if the desired time intervals do not exceed 4.25 seconds. Otherwise, Program 1 gives a simple method of calculating the correct values for each byte given a desired time interval in seconds.
Setting the timers is a little tricky. There are two or three bytes to set and the Operating System must be prevented from starting the countdown until all of them are set. Fortunately, there is an easy way: setting the CRITIC flag to a non-zero value suspends a number of Operating System processes including system timer counting. Program 1 shows the recommended procedure to set system timer 4 using the CRITIC flag.
Important: Do not leave CRITIC set to a non-zero value any longer than necessary!
Although the system timers are extremely useful, they do have a few limitations:
- The maximum time interval which can be set directly is a little more than 18 minutes (65535 counts of 1/60 second). Of course, longer intervals could be controlled by counting multiple runs of a timer.
- Very small timer counts will be imprecise because the Operating System is synchronized to the TV display and not to the BASIC program.
- When one timer is being set, the CRITIC flag stops the other timers. In multiple timer applications a small amount of time may be "lost".
- The Operating System uses System Timer 3 to OPEN the 410 program recorder. Any prior value in the timer will be lost.
- System timers 3, 4 and 5 are stopped during I/O operations because the Operating System sets the CRITIC flag. Significant amounts of I/O will cause time to be "lost".
For many applications, these limitations do not present any real problems. The system timers are powerful tools which are almost as easy to use as relatively crude FOR…NEXT loops; give them a try! For those other applications with different timing needs, there are the other timing alternatives mentioned above.
ATARI Personal Computer System OPERATING SYSTEM User's Manual, Atari Inc., Copyright 1980, Chapter 6.
Stewart, Ed, "Unleash the Power of Your Atari CPU", COMPUTE!, April 1981 #11, p. 102.
5 GRAPHICS 3 10 CDTMU3=548:CDTMF3=554:REM TIMER 3 15 CDTMU4=542:CDTMF4=556:REM TIMER 4 20 CDTMU5=544:CDTMF5=558:REM TIMER 5 25 CRITIC=66:REM CRITIC FLAG 30 NONZERO=l:ZERO=0 35 TIME=30.5=REM TIME EXAMPLE (SEC.) 40 TIME=TIME*60:REM CNURT TO 1/60 CNT 45 HI=INT(TIME/256 ):REM TIMER HI BYTE 50 LO=TIME-(HI*256}=REM TIMER LO BYTE 55 POKE CRITIC,NONZERO=REM STOP TIMER 60 POKE CDTMF4, NONZERO :REM SET FLAG 65 POKE CDTMU4,L0:REM SET LO BYTE 70 POKE CDTMU4+1,HI:REM SET HI BYTE 75 POKE CRITIC,ZERO :REM START TIMER 80 PRINT "TIMER STARTED" 85 COLOR INT(RND(0)*3)+1:REM EXAMPLE 86 PLOT RND(0)*39,RND(0)*19:REM EXAM 87 SOUND 8,RND(0)*128,10,8 :REM EXAMPL 90 IF PEEK(CDTMF4) THEN 85:REM CHECK 95 PRINT "TIME'S UP!"