I am much gratified by the response to my decision to work harder on answering readers' questions. I have received several very interesting letters with both good comments and good questions. Since it is always fun to defend Atari BASIC against the outside world, let me start with a subject near and dear to my heart.
Several readers have asked me why Atari BASIC compares so unfavorably to other computers on certain benchmarks. The two most commonly mentioned are the BYTE magazine benchmarks and the Creative Computing benchmark invented by David Ahl. Stan Smith, of Los Angeles, asked some very pointed questions, which I will try to answer here.
The BYTE benchmark is reproduced below in Atari BASIC. It is the often-mentioned "Sieve of Erastothenes," a program which produces (and counts) prime numbers. Its primary advantage as a benchmark is that it can be implemented in virtually any language (although only with much difficulty when using Logo and its ilk). It relies only on addition and logical choices, with very little number crunching.
10 DIM N$(8192)
30 FOR I=1 TO 8192:IF N$(I,I)="
1" THEN 60
50 K=K+PRIME:IF K<8193 THEN N$(
60 NEXT I
70 PRINT CNT : REM BETTER PRINT
An aside: If you have seen the BYTE original and are puzzled by my changes, be aware of three things: (1) I had to use a string because there is not enough room for an array of 8192 elements. (2) The math was modified very slightly to accommodate the fact that string indices start at one, instead of zero. (3) Multiple statements per line simplify the original somewhat.
Anyway, why is Atari BASIC so slow (317 seconds versus, for example, the IBM PC at 194 seconds)? Primarily for three reasons. First, note all the numbers in this listing, which must be treated as integers. Line numbers and indices are always kept and calculated as floating-point numbers, but all must be converted to integers before being used. (You simply can't GOTO line 137.38, can you?) And, sigh, the routine in the Atari Operating System ROMs which converts numbers to integers is incredibly slow (in fact, it is the only floating-point routine we modified when we produced BASIC A+ and BASIC XL).
Second, Atari BASIC performs FOR-NEXT loops by remembering the line number of the FOR statement. Then, when NEXT is encountered, BASIC must search for the FOR line, just as if a GOTO had been used. (Other BASICS remember the actual memory address of the FOR statement. Faster, but less flexible. Atari BASIC allows you to STOP in the middle of a loop, change the program, and continue, something no other home computer BASIC allows. (This - among many other things - is in direct opposition to Consumer Reports' claim that Atari BASIC is hard for beginners.)
Third, if you type in and use this listing as shown, you are paying almost a 50 percent penalty in speed, thanks to Atari's screen DMA and Vertical Blank Interrupts taking up a significant portion of the processing time. The simple addition of the following two lines will improve the time for this little test to 211 seconds:
5 POKE 54286,0 : POKE 54272,0
65 POKE 54286,64
All of a sudden, Atari BASIC isn't even near the bottom of the list. And, yet, there is more we can do to improve the machine's performance. As many have suggested, you can install the Newell Fastchip, a replacement for the floatingpoint routines built into your computer (available from many dealers, produced by Newell Industries of Plano, Texas).
Or you can change to another BASIC. Obviously, there is Atari's Microsoft BASIC. It produces results very close to those of Applesoft; but it, too, can be improved by turning off screen DMA, etc. And there is OSS's own BASIC XL. Using a combination of clever programming and a Fastchip, the BASIC XL program below will count up all those prime numbers in 58.5 seconds, about three times as fast as Microsoft BASIC on an IBM PC can do it. 'Nuff said. (Except a P.S.: The Set 3 in line 10 requests zerotime FOR loops, something not available in many BASICs, which alone accounts for about 20 seconds worth of improvement.)
10 FAST: POKE 54286,0: POKE 542
72,0: SET 3,1: DIM N$(8192):
30 FOR I=0 TO 3191
50 IF NOT PEEK(N+I) THEN PRIME=
IME TO 8191 STEP PRIME: POKE
N+K,1: NEXT K
60 NEXT I
70 POKE 54286,64: POKE 559,34:
Measures Of Accuracy
The Ahl benchmark is listed below. It purports to measure both accuracy and number-crunching ability. It does neither very well. Still, we have to ask why Atari BASIC is near dead last in its rankings, requiring 6 minutes and 45 seconds to complete the test.
10 FOR N=1 TO 100: A=N
20 FOR I=1 TO 10: A=SQR(A): R=R
+RND(0): NEXT I
30 FOR I=1 TO 10: A=A^2: R=R+RN
D(0): NEXT I
40 S=S+A: NEXT N
50 PRINT "ACCURACY="; ABS(1010-
S/5), "RANDOM="; ABS(1000-R)
The culprit here (in terms of time-wasting) is line 30, with its A=A^2. Atari BASIC, in common with most small computer BASICS, calculates powers according to a formula:
x^y = exp(y * log(x))
where log() is the natural logarithm function and exp() is the exponent-of-e function.
If you don't understand that, don't worry about it. The point is that the calculation of such a simple thing as a number to the second power involves the calculation of a logarithm and an exponentiation. And why is that so bad? Simply because the floating-point routines in the Atari OS ROMs are too slow. Again, the solution is to install the Newell Fastchip and/or turn off DMA and VBI (as outlined above).
I am indebted to Clyde Spencer, one of the founders of the Bay Area Atari Users Group (one of the oldest), for supplying me with a most surprising figure. Spencer reports that, using the Fastchip and with DMA turned off, he obtained a timing of 1 minute 38 seconds, a very respectable (albeit not record-shattering) performance. I still wouldn't use my Atari for advanced scientific applications, but it is more than adequate for most purposes.
There is a problem with the "accuracy" figures in this test, however. First, because Ahl's accuracy number is the result of 1000 simple sums, it is clearly possible that a particular machine may exhibit wildly variant results for various numbers and still show a good figure in his test. (To illustrate, assume that the SQR() function randomly tosses in an error of plus or minus one. If it tossed in an equal number of errors, they would balance to zero. Yet choosing to make the loop just one unit shorter [FOR N=1 TO 999] might give a completely different result. To be fair, this is a very unlikely result with modern math algorithms; but, still, one never knows.) A minor change to his program would improve the testing qualities considerably:
40 S=S+ABS(A-N):NEXT N
Do you see the difference? This method produces the sum of the errors, and doesn't fall prey to offsetting errors.
The Random Number Trap
There is no hope for the accuracy of this random number tester, though. I will quote Clyde Spencer on this matter: "If the numbers are truly random and not normally distributed, any difference between 0 and 1000 is possible. All you can say is that you would have a high probability of ... being near zero for a perfect random number generator." The benchmark test falls into the infamous BASIC repeating-random-sequence trap.
In most BASICS, when you command a program to run, the pseudorandom generator is always reseeded with the same number. So each and every time you will get the same results, with Ahl's test. And, depending on what seed is chosen, you may get truly phenomenal results (because you happened to hit a hot spot in the generator's sequence). Now, though, try starting the generator off with a different (and randomly chosen) seed each time. What happens? The test's randomness figure wanders all over the place.
Once again, to quote Spencer...... in eight tests I obtained numbers ranging from 1.6 to 24.2, with the mean being 7.02 ......
Finally, I would like to point out that Ahl's test penalizes small machine BASIC interpreters in yet another way: When you have 32K bytes to spend on a BASIC, one thing you do is insure that numbers to a power are performed by successive multiplications, if possible. Thus Cromemco 32K Structured BASIC (for example) performs A^2 with just one multiply. In other words, it converts A^2 to A*A. If you manually substitute that same form in Ahl's program, the times for almost all of the smaller and less expensive machines will improve dramatically. (Surprisingly, though, the accuracy figures may not change. After all, the original version may have had offsetting errors.) Of course, if you need to use noninteger powers in your programs, this comment doesn't apply, and the benchmark's results are a bit more meaningful for you.
Well, what does all this long-winded discussion boil down to? Two simple points: (1) Always presume that a benchmark program is worth slightly less than the paper it is printed on. (2) If you want to do number crunching on your Atari computer (against my best advice), go out and buy the Newell Fastchip. (And it won't hurt to try some other languages.)
Besides noting that GRAPHICS 15 on the XL machines is easily accessible (it's equivalent to mode 7½ on older machines), Mark Butler, of Antioch, California, asked for some information about the HELP key.
Simply put, pushing the HELP key on an XL machine causes an interrupt (I'm not sure which one) that, in turn, causes the Operating System to set a HELP flag. The magic location is $2DC, 732 decimal. Pushing HELP, either alone or in combination with CONTROL or SHIFT, forces the OS to put a value here, as shown below:
||Value in $2DC
|HELP alone||$11 (17 decimal)|
|SHIFT +HELP||$41 (65)|
To use $2DC, you must POKE it back to zero after you have decided that someone needs HELP which you are going to act on.
Butler also requested a program which would, for example, print out an error message for the last BASIC error number when the HELP key is pressed. While not a really difficult project, it is a bit too heavy for this column. On the other hand, it would be trivial to add a HELP capability to many BASIC programs. Why not try it?
As long as we are on this subject, I would like to also note the effects of the 1200XL's function keys on another memory location, $2F2 (754 decimal). The various possible values are listed below. Note that CONTROL used with a function key is not generally accessible after keyboard input, since these combinations have special meanings to the OS and the editor handler. We will thus ignore them here.
||Value in $2F2
|F1 alone||$03 (3 decimal)|
|SHIFT +F1||$43 (67)|
|F2 alone||$04 (4)|
|SHIFT +F2||$44 (68)|
|F3 alone||$13 (19)|
|SHIFT +F3||$53 (83)|
|F4 alone||$14 (20)|
|SHIFT +F4||$54 (84)|
Too bad all machines don't have function keys, isn't it?
Cassettes And The XL Machines
Guy Servais, of Norfolk, Virginia, was one of several who I inadvertently ignored when I discussed holding down the OPTION key while booting an 800XL computer. My apologies for slighting you cassette owners.
Still, my general comments apply: If you purchase a cassette program which includes instructions telling you to remove your BASIC cartridge, you must hold down the OPTION key while booting that cassette. The kicker here, though, is that you must also hold down the START button to force the boot in the first place. Under the conditions mentioned, I recommend holding down both buttons until you actually hear the tone on the tape being accepted by the computer.
Servais also asked me if you can "disable the built-in BASIC ... and can type in programs written in machine language." I can only presume that he has either seen or used other brands of computers which have some sort of minimonitor which allows you to access the bits and bytes of memory. (For example, Apple II computers have a small monitor which you can get to.)
Sorry, Guy, but there ain't no such thing on an Atari computer. You have three choices:
1. Use BASIC. This isn't quite as bad as it sounds. Look at the MLX machine language loader which COMPUTE! uses. It is a good tool for entering machine language written by others.
2. Buy a cartridge-based assembler. The old Atari Assembler Editor cartridge is often available at a substantial discount. It's not great, but it's much better than the simple monitors on other machines.
3. Buy a disk drive. This will open up a whole new vista in machine language. There are several appropriate assemblers for disk users.
Even though I have said this before, it bears repeating: The first peripheral you should buy is a disk drive. Only use cassette if you are desperate, and never waste your money on a printer until you have a disk.
Can You Help?
Servais mentioned one more thing in his letter which disturbed me. He is experiencing the infamous Atari BASIC editing lockup in his 800XL with the built-in BASIC. I had believed that the 800XL's BASIC had cured that problem (though it left a few other bugs lying around). Now, truthfully, I haven't used much besides BASIC XL in the last year, so I have not been aware of this problem at all.
Has anyone documented the circumstances under which lockup occurs? Please write and tell us. Once again, since BASIC is in ROM, I doubt there is a fix for the problem. But if we are aware of why and how it occurs, we may be able to warn others away from those conditions.