Part 18 Timing Subjects covered... PAUSE, PEEK, INKEY$ Quite often you will want to make the program take a specified length of time, and for this you will find the PAUSE statement useful. PAUSE n ...stops computing and displays the picture for n frames of the TV (there are 50 frames per second in Europe and 60 in USA). The value of n can be up to 65535, which gives you a pause of just under 22 minutes. If n=0 then it means 'pause indefinitely'. A pause can always be cut short by pressing a key. This program works the second hand of a clock... 10 REM first we draw the clock face 20 FOR n=1 TO 12 30 PRINT AT 10-10* COS (n/6* PI ),16+10* SIN (n/6* PI );n 40 NEXT n 50 REM now we start the clock 60 FOR t=0 TO 200000: REM t is the time in seconds 70 LET a=t/30* PI: REM a is the angle of the second hand in radians 80 LET sx=80* SIN a: LET sy=80* COS a 200 PLOT 128,88: DRAW OVER 1;sx,sy: REM draw second hand 210 PAUSE 42 220 PLOT 128,88: DRAW OVER 1;sx,sy: REM erase second hand 400 NEXT t The clock will run down after about 55.5 hours because of line 60, but you can easily make it run longer. Note how the timing is controlled by line 210. You might expect 'PAUSE 50' to make it tick once per second, however, the computing takes a bit of time as well and has to be allowed for. This is best done by trial and error, timing the +3 clock against a real one, and adjusting line 210 until they agree. You can't do this very accurately - an adjustment of one frame per second is equal to 2% (or half an hour in a day). There is a much more accurate way of measuring time. This uses the contents of certain memory locations. The data stored is retrieved by using PEEK. Part 25 of this chapter explains what we're looking at in detail. Type in the expression... PRINT (65536* PEEK 23674+256* PEEK 23673+ PEEK 23672)/50 This prints the number of seconds since the +3 was turned on (up to about 3 days and 21 hours, after which it goes back to 0). Here is a revised clock program to make use of this... 10 REM first we draw the clock face 20 FOR n=1 TO 12 30 PRINT AT 10-10* COS (n/6* PI ),16+10* SIN (n/6* PI );n 40 NEXT n 50 DEF FN t()= INT ((65536* PEEK 23674+256* PEEK 23673+ PEEK 23672)/50): REM number of seconds since start 100 REM now we start the clock 110 LET t1= FN t() 120 120 LET a=t1/30* PI: REM a is the angle of the second hand in radians 130 LET sx=72* SIN a: LET sy=72* COS a 140 PLOT 131,91: DRAW OVER 1;sx,sy: REM draw hand 200 LET t= FN t() 210 IF t<=t1 THEN GO TO 200: REM will wait until time for next hand 220 PLOT 131,91: DRAW OVER 1;sx,sy: REM rub out old hand 230 LET t1=t: GO TO 120 The internal clock that this method uses should be accurate to about 0.01% (approx 10 seconds per day) so long as the +3 is simply running the program. However, when you use the BEEP statement (described in part 19 of this chapter) or operate the disk drive or any peripheral attached to the +3 (e.g. a printer or second disk drive), the internal clock stops temporarily, losing time. The numbers 'PEER 23674', 'PEEK 23673', and 'PEEK 23672' are held inside the +3 and used for counting in 50ths of a second. Each is between 0 and 255 and they gradually increase through all the numbers from 0 to 255; after 255 they drop straight back to 0. The one that increases the most often is 'PEEK 23672' - every 1/50 second it increases by 1. When it is at 255, the next increase 'nudges' it to 0, and at the same time it increments 'PEEK 23673' up by 1. When (every 256/50 seconds) 'PEEK 23673' is nudged from 255 to 0, it in turn increments 'PEEK 23674' up by 1. This should be enough to explain why the expression above works. Now, consider this carefully: suppose our three numbers are 0 (for 'PEEK 23674'), 255 (for 'PEEK 23673') and 255 (for 'PEEK 23672'). This means that it is about 21 minutes after switch on. Our expression ought to yield (65536x0+256x255+255)/50 which is equal to 1310.7. But there is a hidden danger - the next time there is a 1/50 second count, the three numbers will change to 1, 0 and 0. Every so often, this will happen when you are half way through evaluating the expression - the +3 would evaluate 'PEEK 23674' as 0, but then change the other two to 0 before it can PEEK them. The answer would then be (65536x0+256x0+0)/50 which is equal to 0, which is obviously wrong. A simple way of avoiding this problem is to evaluate the expression twice in succession and take the larger answer. Now if you look carefully at the previous program, you can see that it does this implicitly. Here is a trick to apply the rule. Define the functions... 10 DEF FN m(x,y)=(x+y+ ABS (x-y))/2: REM the larger of x and y 20 DEF FN u()=(65536* PEEK 23674+256* PEEK 23673+PEEK 23672)/50: REM time (may be wrong) 30 DEF FN t()= FN m( FN u(), FN u()): REM time (correct) You can change the three counter numbers so that they give the real time instead of the time since the +3 was switched on. For instance, to set the time at 10.00am, you work out that this is 10 x 60 x 60 x 50 which is equal to 1800000 fiftieths of a second (and 1800000 is equal to 65536 x 27 + 256 x 119 + 64 x 1). To set the three numbers to 27, 119 and 64, you type... POKE 23674,27: POKE 23673,119: POKE 23672,64 In countries with mains frequencies of 60 Hz (cycles per second), these programs must replace 50 by 60 where appropriate. The function INKEY$ (which has no argument) reads the keyboard. If you are pressing just one key, (or say, CAPS SHIFT and just one other key), then the result is the character which that key gives normally, otherwise the result is an empty string. Try this program, which works like a typewriter. 10 IF INKEY$ <> "" THEN GO TO 10 20 IF INKEY$ ="" THEN GO TO 20 30 PRINT INKEY$ ; 40 GO TO 10 Here line 10 waits for you to life your finger off the keyboard, and line 20 waits for you to press a new key. Unlike INPUT, INKEY$ doesn't wait for you, so you don't have to press ENTER. Exercises... 1. What happens if you miss out line 10 in the 'typewriter' program? 2. Another way of using INKEY$ is in conjunction with PAUSE, as in this alternative 'typewriter' program... 10 PAUSE 0 20 PRINT INKEY$ ; 30 GO TO 10 To make this work, why is it essential that a pause should not finish if it finds you already pressing a key when it starts? 3. Adapt the 'clock second hand' program so that it also shows minute and hour hands, re-drawing them every minute. If you're feeling ambitious, arrange so that every quarter of an hour, it puts on some kind of show - perhaps you could produce the 'Big Ben' chimes using PLAY (described in part 19 of this chapter).