COMPUTE! ISSUE 56 / JANUARY 1985 / PAGE 135
I have almost worked my way through my backlog of letters, so I will once again appeal to all of you to keep those cards and letters coming. Since it can sometimes take quite a while for a letter sent to COMPUTE!’s editorial offices to wend its way to me, I have decided to give you an address where you can write me directly:
P.O. Box 710352
San Jose, CA 95171-0352
Before I start answering questions this month, I would like to talk a little about the future of Atari.
I had the rare privilege to attend the meeting of the San Leandro (California) Atari User Group on the evening that Leonard Tramiel agreed to come and answer questions.
I hope the name Tramiel is familiar to all Atari owners by now. Jack Tramiel, the founder and former leader of Commodore, bought Atari from Warner Communications in July. Leonard, Jack’s son, is now head of software at Atari. And though I am sure some favoritism was involved in choosing him for the position, I think it was probably an excellent appointment.
Leonard Tramiel is an articulate, humorous, open, and opinionated person. He endeared himself to me when he espoused one of my favorite opinions: The IBM PC is an eight-bit machine, and the Apple Macintosh is a 16-bit machine, and no amount of marketing ballyhoo is going to change that. (We are referring to the fact that the width of the data path to the Central Processing Unit (CPU) controls processing speed as much as, if not more than, the speed of register operations. Whew! Got that? There will be a quiz on Monday.)
Anyway, while Leonard was extremely careful to avoid divulging any technical details about future Atari computers, he went a long way toward reassuring many listeners (for example, me) that Atari in general (and Leonard Tramiel in particular) knows what it is doing and where it is going. By the time you read this, the Winter Consumer Electronics Show (CES) in Las Vegas will be underway. And we’re expecting to see the introduction of 16-bit and 32-bit Atari computers.
However, I also came away with the feeling that Atari will not abandon the eight-bit, 6502-based market for some time to come. In particular, Leonard stated emphatically several times that the 800XL would undergo only those modifications which would make it “both less expensive and more reliable.”
Possibly Leonard missed his calling: As a public relations person he did an outstanding job. I didn’t take a formal poll, but I believe the impression he left on the audience was in the range of 90 to 95 percent positive. If there were any real negatives, it was regarding his stand that he wouldn’t guarantee that current Atari peripherals would work on the new machines.
The attitude of some in the audience was, “Well, if I can’t use my peripherals on the new machines, I am going to look at all computers instead of just Atari’s.” That’s a reasonable attitude, but the response was just as rational: “If Atari can’t convince you to buy the new machines on their merits and prices alone, then we don’t know what we are doing.” And finally, my view is that—with the possible exception of printers—there are very, very few Atari peripherals that I would want on a new, super-duper computer. (Who wants to talk to a disk drive at 19200 baud? Who really likes the kludge that became the 850?)
In summary, then, I have a better feeling about the future of Atari than I have had in a year or more now: to the point that our company, OSS, is continuing with plans for more and new Atari-compatible products. I will withhold judgment of the new machines until I see their software (Please give us an operating system! Not CP/M, MS-DOS, or Apple or Commodore style!), but with Leonard Tramiel’s leadership I have some hopes in that direction, also.
I’ve received a few letters in recent weeks asking if there is a good list of important memory locations for Atari computers. Oh, come now, COMPUTE!. Can it be that you are not advertising your 1983 book Mapping the Atari? To my knowledge, this is the one and only complete memory map of Atari computers. Further, it is much more than a memory map. It gives example programs, discusses which system routines will use and/or change certain locations, and much, much more. And yet there are readers of this magazine who are not aware of this book! How can that be?
Well, to be fair, the cover of Mapping the Atari does state that it is intended for owners of Atari 400 and 800 models. However, the people who wrote me own either 1200XLs or 800XLs. Does that matter? Not really.
More than 99 percent of the significant memory locations are the same in all Atari computers: 400, 800, 1200XL, 600XL, 800XL. Notice that I did qualify that just a little. Just what is a significant memory location?
Sidetrack: If you have been reading this column for any time at all, you know that I feel that the compatibility problems which many software vendors suffered when the XL machines appeared are the fault of the vendors. Since the first documentation from Atari appeared in the marketplace, Atari made a point of specifying which memory locations would control what functions, which subroutine entry points (mainly vectors) would remain unchanged, and which parts of the operating system (OS) were subject to change. Surely, when Atari released its first revision of the OS in early 1982, you would think the vendors and authors would have been put on notice: “Hey, guys, things are subject to change, and this proves it.” The reply: “Yeah, but if I know that this routine at $D099 will save me two bytes of code, I’m gonna use it.”
The only consolation I seem to get is that every other machine seems to have the same kind of problem: Apple programmers had to go back to the drawing board when the He and lie arrived. Many major programs for the IBM PC simply do not run on the PC-AT. Nobody can write machine language software for Commodore computers and expect it to work on more than a single model. The list goes on.
Back to the memory map: Generally, if you use Mapping the Atari with an XL machine, you can trust most of the RAM locations that are listed. Atari did publish a set of locations that were changed in the XL machines, but there were not many. Even the ones that did change were ones unlikely to be used: OLDROW and OLDCOL moved, but the only routines that use them are FILL and DRAWTO. And even if you were to call for a FILL, you probably would do so after a PLOT, which automatically sets up OLDROW and OLDCOL for you.
The ROM locations listed in the book are a bit more subject to change. As a rule of thumb, I would trust only the information about the last few bytes of a cartridge, the floating point ROMs, and $E400 through $E462. Also, it’s a pretty sure bet that if the book mentions a difference between OS revision A and revision B when discussing a location, there will be yet another difference in the XL machines. (Example: Anybody who thinks that EOUTCH—output a character to the screen—is at an immutable location should refrain from using a machine manufactured after 1916.)
So all you XL machine owners should rush out and buy a copy of Mapping the Atari. And then you should write to COMPUTE! and tell them (don’t ask) to publish an update, either in the form of a revised book or a low-cost appendix, for XL computers.
As long as we are on the subject of only using legal memory locations (see how I sneaked that in?), let me respond to a couple of people who have asked a relevant question: “I have an 800XL, and I can’t get it to put characters to the screen if I follow the instructions in Machine Language for Beginners. How can I change the program so it will work?”
When Richard Mansfield wrote that book, he was writing for Commodore, Apple, and Atari owners. And all the machines he was writing for except Atari have a documented entry point for a routine which will put a single character on the screen. So, for uniformity, he used an undocumented subroutine call on the Atari computers which does much the same thing. At the time he did this, that particular location had been written up several times in both the professional and amateur press, so he felt fairly safe. Ah, well, Richard, even the best of us have to be bitten once in a while.
The proper way to do any input/output (I/O) on an Atari computer is via Central Input/Output (CIO) calls. In early 1982, I wrote a series of articles on CIO calls which appeared in this column. I am not going to repeat that series, but I will give you a few pointers to get you started with CIO.
There are two things you can do if you want more info on the subject: (1) Find a library (perhaps a user group library) with back isues of COMPUTE! (don’t write the magazine; they don’t have any). (2) Get your hands on a copy of the Atari Technical Reference Manual (it used to be $30 from Atari customer service, but I don’t know where you can get it now). The manual includes a pretty fair description of CIO along with lots and lots of other very worthwhile goodies.
Without further ado, then, let’s look at how to put a character on the screen.
0200 IOCB0 = $0340 0210 IOCBCMD = $0342 0220 IOCBLEN = $0348 0230 CMDPUT = $0B 0240 CIO = $E456 0250 ; 0260 ;Enter with character in A register 0270 ;Routine will print it to screen 0280 ; 0290 PUTSCREEN 0295 LDX #CMDPUT 0300 STX IOCBCMD ; request output 0310 LDX #0 ; multi-purpose zero 0320 STX IOCBLEN ; first, zero length 0330 STX IOCBLEN+1 ; (both bytes) 0340 JMP CIO ; and now X is channel for CIO
That’s it. Simply put those six lines of code anywhere in your machine language program. Then, when you want to print a character on the screen, use JSR PUTSCREEN after placing the character in the A register.
In theory, you can get an error when you call CIO (a minus value in the Y register indicates this), but in practice I don’t believe you will ever see one as a result of putting a character to the screen.
How, you may ask, is this any better than calling a point in the OS ROM which does the same thing? Answers: (1) This way works on all Atari computers (well…the 6502-based ones, at least). (2) This follows Atari’s rules. If you do it this way, Atari could scramble the OS ROMs anyway they wanted, but your program would still run.
Of course, the equates at the beginning of the program fragment are the keys to the whole thing. IOCB stands for Input/Output Control Block. Technically, you are supposed to put the channel number times 16 in the X register and then access the appropriate IOCB via X (see below). Since the screen is always open on channel zero, I took a legitimate shortcut. Similarly, CIO is actually a vector in the OS ROMs which is guaranteed to stay in place. If you follow the rule about using the X register to access the IOCBs, you are already set up for CIO, which requires the channel number times 16 in the X register.
Oh, yes. Normally, CIO expects to transfer an entire buffer (for example, a line of text), in which case you must give CIO the buffer address and its length. But CIO cleverly provides for situations in which you want to print only a single character: Tell CIO that the length pf the buffer is zero, and it will output a single character (or input a character, but that’s a topic for another time) via the A register.
And that’s about it. Simple, really. Before we quit for this month, though, I would like to show you how simply that routine could be converted to output a character to any channel.
0200 IOCB0 = $0340 0210 IOCBCMD = $0342 0220 IOCBLEN = $0348 0230 CMDPUT = $0B 0240 CIO = $E456 0250 ; 0260 ;Enter PUTC with the character 0270 ; in the A register and the 0275 ; channel number times 16 in the 0280 ; X register. 0285 ; 0290 PUTC 0300 PHA ; save character for a moment 0310 LDA #CMDPUT ; request output... 0320 STD IOCBCMD,X ; ... on this channel 0330 LDA #0 0340 STX IOCBLEN ; now, zero length 0350 STX IOCBLEN+1 ; (both bytes) 0360 PLA ; recover the character 0370 JMP CIO ; and now X is channel for CIO
Do you see the really minimal changes we made? This is one of the beauties of the Atari OS. It is so completely organized (orthogonal is a good computerese word for it) that it’s actually easy to learn and use. Perhaps we’ll do a little more of this if you would like. Write and tell me.
COMPUTE! ISSUE 57 / FEBRUARY 1985 / PAGE 139
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) 20 N$="0":N$(8192)="0":N$(2,8192)=N$ 30 FOR I=1 TO 8192:IF N$(I,I)="1" THEN 60 40 PRIME=I+I+I:CNT=CNT+1:K=I 50 K=K+PRIME:IF K<8193 THEN N$(K,K)="1":GOTO 50 60 NEXT I 70 PRINT CNT:REM BETTER PRINT 1899!!!
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 54272,0:SET 3,1:DIM N$(8192):N=ADR(N$) 30 FOR I=0 TO 3191 50 IF NOT PEEK(N+I) THEN PRIME=I+I+3:CNT=CNT+1:FOR K=I+PRIME TO 8191 STEP PRIME:POKE N+K,1:NEXT K 60 NEXT I 70 POKE 54286,64:POKE 559,34:PRINT CNT
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+RND(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.
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:
|Key(s) Pressed||Value in $2DC (732)|
|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.
|Key(s) Pressed||Value in $2F2 (754)|
|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?
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
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.
COMPUTE! ISSUE 58 / MARCH 1985 / PAGE 90
It’s tidbit time again this month! I love saving up strange, exotic, or frustrating facts and then dumping them on you all at once.
Before I do anything else, though, let me quickly fix the big boo-boo in my January column or I will be inundated with threatening letters. In the second assembly language listing there, the one which purported to show you how to output a character to any channel, there are two lines in error. Lines 340 and 350 were given as using a STX instruction. The correct lines are as follows:
340 STA IOCBLEN,X ;zero both bytes 350 STA IOCBLEN+1,X ;of buffer length
I apologize now if I managed to destroy anyone’s hard work. And since I goofed in January, it’s only fair to show my ignorance this month.
The first of the tidbits this month came to me in the way of an innocent question from Roger Bocek of Campbell, California. He had stopped in at our office to pick up some software, happened to run into me, and said, “Say, I’ve been meaning to ask you. Why does DOS use three sectors for its boot area when it uses only about 200 bytes of boot code?”
Five minutes later, after rummaging through the listing in Inside Atari DOS (from COMPUTE! Books, of course), I came up with the brilliant answer: “I dunno.” But I always like to find a use for everything, even my own ignorance.
As we have discussed in this column many times in the past, when you ask BASIC to do I/O (Input/Output) to or from most devices attached to your computer (particularly the disk drive), what actually happens is quite complex. BASIC interprets your request into a call to CIO (Central Input Output), which in turn determines what device you are using and vectors to the appropriate driver routine. We assume here that CIO accesses FMS, the File Management System for the disk, usually called DOS (Disk Operating System).
Finally, then, FMS makes a call to SIO (Serial Input Output), the routine which does the actual physical reading and writing to the device. In the case of the disk drive, this involves the actual transfer of a single sector of 128 bytes (or 256 bytes in non-1050 double density).
Most BASIC programmers seldom—if ever—have need to read or write a physical disk sector. Most avoid writing because it is dangerous, since disturbing the format of portions of a sector can destroy DOS’s ability to manage the disk for you. (Reading a sector, though, can be informative, especially if you are trying to either understand DOS or find lost information.)
On the other hand, some programmers like to hide things on a disk. Perhaps high game scores, a password, or some sort of software protection. The best place to hide such information is someplace unknown to DOS.
Now, the fact that standard Atari DOS (version 2.0S and its derivatives, including OS/A+ and DOS XL versions 2) leaves sector number 720 available has been documented before: DOS manages sector numbers 0 to 719, but the disk drive understands only sectors 1 to 720. DOS has been fixed to think that sector 0 is always in use, but sector 720 remains outside its ken. Many programs, including some found in old issues of COMPUTE!, have read and written data directly to sector 720.
Lo and behold, thanks to a quirk which began who knows how and where, sector 3 is also free for this kind of use! It is the last sector of the traditional three-sector boot process. But for some reason lost in programming legend, it turns out that none of the disk boot code used by DOS is present in sector 3: sectors 1 and 2 contain all the boot that is needed. So, if you are looking for another 128 bytes of hidden disk space, you now know where to find it.
A word of warning, though: If you erase, write, modify, or rename the DOS.SYS file, sector 3 will automatically be rewritten by DOS (it thinks it needs to reestablish the boot code). So, if you choose to use sector 3 for your own purposes, be sure to do so on a disk which either never receives a DOS.SYS file or which has one that you feel is reasonably permanent.
I have not included a program here to access sectors directly because the technique has been shown many times, many places before. For example, Mapping the Atari (COMPUTE! Books) gives some helpful hints, and the Atari technical manuals go into SIO calls in some detail. If enough of you write and request a column on this topic, though, I may present more here in the future.
Many game programmers like to hide their signatures in their work, often to the consternation of their employers, the game manufacturers. Famous examples include the message evoked from Super Breakout (the Atari home computer version) when you push CONTROL, SHIFT, and I at the same time. Or how about the power dot in the old Atari VCS Adventure game, which got you into an otherwise inaccessible room? In fact, the practice is so widespread that some players spend hours looking for these hidden messages in each new game, even the games that don’t have any.
Well, it turns out that game programmers are not the only ones who like to get their ego stroked at the same time they put one over on management. Paul Laughton, the prime programmer behind Atari BASIC and Atari DOS (and Apple DOS and … but that’s another story), told me of one signature that even got into some of Atari’s operating system ROMs.
If you want to see this signature, you’ll have to find a 1200XL and be patient. Simply remove all cartridges, disconnect all peripherals, and turn it on. Push the HELP key to get to the self-test program, and with SELECT, choose all tests before pushing START. Then wait. The self-test program will cycle through the ROM and RAM tests and the sound register tests before it gets to the keyboard test.
Now how the heck can you have a meaningful keyboard test which is self-running? Answer: You can’t. To really test a keyboard, someone should hit at least some keys. Nevertheless, the program makes a valiant effort to pretend that it is hitting some random keys. Or does it? Aha! If you look fast and carefully, you will find that the keyboard taps out “Michael Colburn” every single time.
It goes without saying that Michael Colburn had a hand in writing the self-test code. You have to try this on a 1200XL because Atari discovered this signature and changed it when the 600XL and 800XL OS ROMs were produced. The message “Copyright 1983 Atari” is tapped out now, but that’s not nearly so interesting as the original.
More on the keyboard self-test: It seems kind of sad to me that Atari managed to find the energy and time to change that signature but couldn’t see fit to fix the test itself.
If you try the manual mode of the keyboard test on a 600XL or 800XL, you will notice two things wrong: (1) The keyboard layout pictured on the screen is mixed up. The layout shown is actually the 1200XL scheme, including even the F1 to F4 function keys. (2) The display does not show you all legal keypress combinations. In particular, it shows no CONTROL+SHIFT combinations (that is, three-key combinations) at all. And it can’t see CONTROL-1 or BREAK. On a 1200XL, the same key combinations are invisible and the CONTROL+function key combinations don’t display properly.
Well, I always said I thought the self-tests were a waste of valuable ROM space, but it would have been nice if they did their jobs right. (My other objection: If you are going to have self-tests, then test everything you can. Like the serial bus, reporting all devices which respond. Like collision detection and other aspects of the GTIA. Like whether the joysticks and paddles work. We have an 800XL which thinks the joystick button is always pushed, but no self-test detects that fact.)
This not-so-little tidbit is a dig at Tom Halfhill. Since he gets to edit my columns before you see them, the very existence of these paragraphs shows his senses of humor and fair play. (See, Tom, I told them you were a nice guy. Now will you leave this in?)
In the December 1984 and January 1985 issues of COMPUTE!, Tom wrote a pair of well-balanced and interesting articles on the new MSX computers. If you didn’t read them at the time, I urge you to go back and do so. I’m not sure that I agree with all of Tom’s conclusions (as you are about to see), but the articles give you the best info I have seen yet on most aspects of this possible new Japanese invasion.
Anyway, the only reason that I bring all this up is that Tom had Assistant Editor Philip Nelson run a simple benchmark program on all the computers that COMPUTE! regularly reports on. Tom then concluded that MSX BASIC showed “streamlined performance.” Why’d you go do that? You know that I love to eat benchmarks alive. Here goes:
Aside from the fact that the benchmark sorts an array in perhaps the most inefficient way possible, there is nothing wrong with the program as presented. It isn’t much good at measuring arithmetic performance, but it is at least as good as the classic BYTE Prime Number benchmark at showing efficiencies (or lack thereof) in logical and branching operations. And the timing numbers presented seem reasonable and correct. So what’s my problem?
Well, first of all, I’m a bit tired of seeing little old 8K Atari BASIC pitted against 32K monsters like MSX BASIC. And I don’t really like it when documented, easy-to-use methods of speeding up Atari programs are ignored. Tom says that an Atari 800XL takes 8:55 (minutes: seconds) to run the little benchmark. True. But turn off the screen direct memory access which uses so much CPU time (via POKE 559,0 or with the F2 key on a 1200XL), and the timing immediately drops to 6:10. Which is faster than MSX BASIC’s 6:20.
Let me play devil’s advocate: Isn’t this cheating? There are ways to speed up that program on other computers, too. For example, the Commodore 64 loses some time to screen DMA also, doesn’t it? Answer: Okay, valid objection. But Atari computers, in general, pay the biggest penalty for text mode screens, and I think benchmark programs should at least include a footnote to this effect or maybe mention effective clock rates. (Would it be more legit if we just put a GRAPHICS 19 statement in? That helps almost as much. All right, all right, next subject.)
Well, then, how about trying a bigger, more competitive BASIC on that same Atari computer? Glad you asked. BASIC XL handles that program in 4:08. That’s two-thirds the time of MSX BASIC and more than a minute and a half faster than the IBM PC. (Just for the record, running the benchmark in FAST mode with the screen turned off gives a time of 2:42, more than twice as fast as the IBM PC. And all these times are without the Newell FastChip, which would make even more of a difference.)
I admit I am prejudiced towards BASIC XL. Also, it was handy so I used it first. But another timing of which I am proud is Cromemco 32K Structured BASIC, which handled that program in 4:33 (floating point mode) and 3:13 (integer mode) and which runs on the same Z80 processor at the same clock rate doing the same 14-digit BCD arithmetic as the MSX machine. (And if you count the Cromemco S-10 as a personal computer—which you should if you call an IBM PC or a Commodore 8032 by that name—then I will be glad to dispute Tom’s claim that MSX BASIC “may be the most powerful BASIC on any personal computer.”)
One more thing before I draw my conclusions: I would very much like to change that benchmark just a little bit. Add lines 1 through 99, each consisting of just a REMark statement, and change the names of the variables to VARIABLE1, VARIABLE2, etc. If MSX BASIC holds true to the standard Microsoft BASIC patterns, its speed will suffer considerably. And so will all the other derived-from-Microsoft times. (Atari BASIC will slow down from the extra lines, but not from the long variable names. BASIC XL in FAST mode and Cromemco BASIC will not change by even a second.)
So the question becomes: Why is MSX BASIC so doggoned slow? Here we have a 32K language running on a very fast 8-bit processor, and it really only shows off halfway decently when you run very small benchmark programs with one- or two-character variable names. Why? Because Microsoft has never significantly improved BASIC. The versions of the BASIC language used in all these machines (even the IBM PC with its so-called 16-bit processor) are still derived from the original Microsoft BASIC designed for an 8K Altair many years ago.
When you are trying to fit a computer language as complex as BASIC into 8K (and that includes Atari BASIC), you have to make sacrifices somewhere, and performance is usually the first thing to go. But why, when a computer manufacturer gives you 32K of room for a language, do you need to keep the same scheme? Isn’t it time to rethink the methodology of the interpreter? Data General and Hewlett-Packard and Digital Equipment Corporation knew how to build superfast interpreters back before microcomputers were even dreamed of. But they usually ran those languages in 64K memory spaces, the same total size as most of today’s 8-bit micros.
When we started building Cromemco 32K Structured BASIC back in 1978, we had already written an 8K BASIC using many of the same techniques Microsoft used. But since this time we had 32K to work with, we studied the minicomputer languages and started from scratch with better methods. If we were to do it again today, we’d start from scratch again and get even more power and better times. Microsoft has never done this.
To be fair, BASIC is not exactly a hot item around Microsoft nowadays. Apparently Microsoft assigns higher priority to other languages, operating systems, operating environments, and word processors, than to redesigning BASIC. Why not leave “improvements” to BASIC to junior programmers, as a maintenance chore?
In his January article, Tom wondered if the hardware technology of the MSX might not be a little tired and boring compared to what other manufacturers will be showing soon. Somehow I can’t help but wonder and hope if someday maybe—just maybe—BASIC users will get bored with tired software technology, too.
Boy, did I get on my soap box this month. Well, it’s relaxing (for me, at least) once in a while, and I promise that next month will bring something different.
COMPUTE! ISSUE 59 / APRIL 1985 / PAGE 123
As I write this, the Winter Consumer Electronics Show (CES) in Las Vegas has just ended. By now you have probably read in the papers and magazines just what real marvels the new Atari Corporation introduced at CES. While I didn’t get a chance to attend CES (though others from my company were there), I did have the privilege of getting some preshow information about Atari’s new products. Also, thanks to being just a bit nosey, I learned a little about how Atari developed their remarkable new computers and even a little bit of what’s yet to come.
(An important aside: The issue of COMPUTE! which will carry this article is dated April 1985. However, since this issue will most likely appear on newsstands and in subscribers’ mail by about mid-March, you might be reading this before April. If so, be sure to keep all of what I am about to reveal secret until at least the first of April.)
Anyway, as I started to say, I was lucky enough to be privy to some early information and (thanks to my nosey nature) overhear even more. One thing I overheard was a simple question, “Should we take the Mac with us?” (An obvious reference to an Apple Macintosh.) It seems that in the process of designing the 130ST and 520ST computers, the engineers at Atari looked at several existing computers. Now, no rival companies were about to be so generous as to donate machines. So, looking back, it seems obvious that Atari had to go out and buy several—including the Mac, of course.
In the process of evaluating the various computers, Atari also was able to look at the microprocessors (CPUs) which they used. It comes as no surprise that the 8/16 bit 8088 used by the IBM PC was rejected early on as being unable to achieve the speed Atari desired. So what processor got the nod for the 130ST and 520ST?
Although I have managed to enjoy Leonard Tramiel’s company in several meetings, the one time we managed to get in a really interesting discussion of processors he had to depart early (for another meeting, probably). Before he left, he did seem to indicate that his personal choice for a CPU might be the National Semiconductor 32016 and 32032 processors. They are very powerful and very orthogonal machines, but (and this is speculation on my part) the fact that they are available only from National Semi probably makes choosing them difficult for any company.
In any case, Atari chose to go with the tried and true Motorola 68000 series of processors, the same one used in the Apple Macintosh and Lisa computers. (An aside: The official meaning of the ST designation is “Sixteen/Thirty-two” for the 16-bit bus and 32-bit registers of the 68000 chip. XE implies XL compatibility, but Extended.)
What about all the loyal Atari 400/800/1200XL/600XL/800XL owners? Has Atari completely forgotten them? No way! Apple has Mac and Lisa, both built around a 68000 chip, in its “sort of 32-bit” division, and the IIe and IIc, both using a 650x CPU, in its 8-bit division.
Lo and behold! We already saw that Atari has the 130ST and 520ST built around the 68000. Does it really surprise you to learn that the 65XE and 130XE will be produced using a 650x processor? And we were even given the privilege of having a set of drawings for a portable computer (in the 650x line) dropped flat on the table in front of us!
The same day we saw those plans for the portable, we also got to see some of the features that the new machines will be sporting. On that day I decided that my predictions of success for Atari, which I made in this column in December, could very well have been ridiculous underestimates.
What kind of features impressed me? I think it will be obvious to you when you read a spec sheet at your local dealer or the other CES coverage in this issue. In the meantime, I’ll give a brief list of what I think are the best features of each machine at the end of this column. I tried to ask some of my contacts at Atari about a couple of things I am not quite clear on, but the lure of CES left the software and engineering departments virtually shut down for these four days.
If there is any area of concern to those of us here at Optimized Systems Software, it is about those products where our software sales overlap those of Atari Corporation. New prices on Atari software have made us rethink some of our plans, but we think that there will always be sophisticated and/or advanced users out there who will be willing to pay a little more for higher quality. And we are not alone: The number of companies showing Atari-compatible software or hardware at CES was almost amazing. Will we stay in the Atari software market? How could we not?
“What the heck,” you ask, “was all that about?” The answer: Every word that you just read was true. Even the subheadlines are properly explained in the text. Oh, I may have bent some words here and there to make the headlines more spectacular, but that was the whole purpose of this exercise. I always wanted to show how you can take an innocuous and/or positive review and generate sensational National Enquirer-type headlines.
If you’re an acrostics fan, you may have already caught the significance of the first letter of each headline. (Go back and reread them if you want a minor laugh.) This is, of course, my annual attempt at some humor. It’s not very subtle or well-hidden this year, because I thought it would be fun to find out how many COMPUTE! readers actually plow through all my verbiage. If you got to here unscathed, congratulations. Time for a complete change of pace.
This is just a simple table of what I feel are the most important features of four of the new Atari machines. I am sure that more info will be available by the time you read this, but maybe these specs will whet your appetite.
It’s time, once again, to respond to some letters. I may have made a mistake in publishing the P.O. box where you can write me directly, since I find myself with about five or six times as much mail to answer as I had before. Until I get adjusted to answering this much correspondence, please bear with me.
For this month, I have decided to select some letters which (I think) really need answers. Surprisingly, for such varied topics, the answers to all may be much the same.
Bob Dorn, of College Park, Georgia, was the first of three or four to ask me how to use an Atari 1030 direct-connect modem to upload and download files. Well, you got caught in the great Atari let’s-protect-the-poor-dumb-user game. For reasons best understood only by now-extinct marketing people at the old Atari, neither the 835 or 1030 modem came with software support for uploading and downloading programs, text files, and so on. I guess those marketers never used a computer with a modem, so they couldn’t see any use for the capabilities.
Luckily, many other people, including a few software gurus, found themselves in the same fix you are in. One commercial company which seems to be doing a lot of work with these modems is Gardner Computing, P.O. Box 388, Holbrook, NY 11741. I am not endorsing them (I have never used any of their products—I have only read their ads), and I apologize in advance for inadvertently slighting any other companies supplying similar software.
There are other solutions. See the “Readers’ Feedback” letter headlined “Atari Modem Update” in the February 1985 issue of COMPUTE!. There are also some programs floating around in public domain user group libraries which allow upload/download and more. As a general rule, such programs come without documentation (or, at most, with a few paragraphs on the disk with the program), so you may need to do a little detective work to use them.
Again, though, there may be another solution. Join your local user group. Come on now, what will it cost you? One evening and a couple of dollars a month will probably be the best investment you ever made in computing. And so many user groups have people who know the answers. To almost anything you ask!
Another practical reason for joining such a group is that Atari has already announced that its primary means of providing programming support to users will be through the user group network. The toll-free phone lines are gone, and the support group is decimated. This may be the only way to get technical answers in the future (aside from writing to me or “Readers’ Feedback”).
All of this, and we haven’t even mentioned the fact that most user groups have literally hundreds of programs available for next to nothing. Okay, okay. Some of the programs don’t work right, are poorly written, are too slow, etc. So what? You are getting what you paid for and more. If nothing else, a cruddy little Atari BASIC subroutine may lead your computer to uses you hadn’t thought of yet.
So join, join, join. Why wait five months for my answer to appear in this magazine when help is available two miles from your home?
How do you know where/who/when/what your local group is? Well, try asking at local computer stores, even those that don’t sell Atari products. Look in your local paper. Look in Atari-oriented magazines, which sometimes have listings of clubs. If you are really desperate, send me a self-addressed and stamped card or envelope. No guarantees, because I don’t know where all the clubs are, but if there’s one on my list I will tell you. Please use me only if all else fails, because (1) I’m always too busy, (2) it may take me some time to answer, and (3) if I ask my kids to help me with this, they will charge me.
From going to users who can’t find what they need, we go to a couple of readers who have found too much. Jamie Patterson, of Hooker, Oklahoma, sent me a well-argued plea for some help in choosing material about his three-month-old baby, an 800XL computer. I quote: “How does a three-month-old know which books to choose?”
Darned good question. My usual answer, when I want to choose a new computer book, is to go to two or three bookstores that carry a couple of hundred computer books each and browse. This works because there are at least a dozen such bookstores within reasonable distance of my house. Now, I have to admit I don’t know where Hooker, Oklahoma, is, but if it isn’t within 20 miles of a major computer bookstore, my method won’t work for Jamie. What can he do?
The editors of COMPUTE! might like me to answer, “Buy a COMPUTE! book.” But whatever book you buy, you must choose one which is at the right level for you. From COMPUTE! Books, the most general material may be found in the First, Second, and Third Book of Atari, along with the two books on Atari Graphics. Some, but not all, of this material is relevant to someone who has learned the fundamentals of Atari BASIC.
Suppose, though, that you aren’t even to that level yet. You don’t know a PRINT from a PLOT statement. Where do you turn? Since Atari stopped shipping copies of Inside Atari BASIC with the XL computers, buyers have been left to choose their own tutorial. And what should they choose?
My trouble is that every time I look at a book that purports to teach BASIC (or word processing or assembly language or …), I find something wrong. I don’t like the order of presentation of the topics. There are mistakes in the section on how to speed up your programs. The author encourages poor programming style. The list goes on and on. So I refuse to make a firm recommendation.
What, then, can Jamie Patterson and others like him do? What else? Join a user group. Ask other Atari owners. Ask to look at their books. Okay, so maybe none of the over-200 user groups is close enough to Jamie. And, besides, he asked me for an answer. I guess I should do something, right?
So here it comes. I am asking you, my readers, to make some comments on the books you have learned from. Don’t stick to learning BASIC. Any aspect of Atari computers is eligible, even manufacturers’ manuals. To make life easier for me, just send the title(s) of the book(s), the level (1 to 10, with 1 being rank beginner), and your overall rating (0 for trash to 10 for perfection). A postcard will do fine.
I don’t want any experts evaluating these books; I can mishandle that aspect myself. Instead, I want actual real-life experiences. Did or did not the book teach you what it said it would? If it did, was it an uphill battle or did the style make it downright easy for you? I can’t respond personally to these rating cards, but I will report the results received by April 20 in the August or September issue (sorry, but that’s the fastest turnaround possible).
Robert Glover, of Cleveland, Tennessee, has been the proud owner of an Atari 400, an 800, and now an 800XL. He asks me why he can’t simply use the binary save option of Atari DOS to make a copy of the 800’s operating system ROMs and then load that file into his 800XL as a home-brew translator disk. He suggests that I perform this service in my column.
Well, in theory, and with some modifications to his method, I might be able to do so. Why won’t I? First, there are several problems to over come. Two of the simpler examples: (1) You can’t write/save ROM directly with DOS 2.0S; you have to copy it down to RAM first. (2) Joystick ports 3 and 4 are used for output in an 800XL and for input in an 800.
Also, how many readers have access to both an 800 and 800XL? And, finally, why go to that kind of trouble when the translator disks are so available?
Ah, but that last point was raised by Mr. Glover. He says he cannot find the translator disks anywhere. Hmmmm. Guess where I am going to suggest he look? Right. Ask your local user group. And that brings us back to the quandary of the last reader: What if there is no user group nearby?
I have a couple of partial solutions. First, there are a few mail-order organizations which, in addition to selling commercial software, sell public domain programs for reasonably low prices. Right now, LotsaBytes (15445 Ventura Blvd., Suite 10, Sherman Oaks, CA 91413) seems to be the leader in this category, but I should also mention DynaComp, Antic, and ANALOG (the latter two offer primarily games and BASIC utilities from their magazines).
Perhaps even better, many user groups (especially the larger ones) allow mail-order memberships. Since there are so many of these groups just crying for members, I hesitate to recommend one over another. But because their newsletter has been around the longest and may have the greatest number of readers, I will at least mention the very friendly people of ACE (3662 Vine Maple Dr., Eugene, OR 97405).
So my message this month is clear: Atari is very, very, very much alive and well. Keep your interest in your machine similarly healthy by joining a user group.
COMPUTE! ISSUE 60 / MAY 1985 / PAGE 75
Several of you were kind enough to write and point out (with only a few snickers) that I goofed in my February column’s description of the HELP key. Specifically, I gave you the wrong value for SHIFT + HELP. Here is the corrected table. Remember, though, that you must POKE location 732 back to zero if you PEEK there and find that the HELP key has been pressed.
|Key(s) Pressed||Value in 732 ($2DC)|
|HELP alone||17 ($11)|
|CONTROL + HELP||145 ($91)|
|SHIFT + HELP||81 ($51)|
I was inundated with letters from people who responded to my request for help in that same February issue. I had asked if anyone knew how and why the Atari BASIC built into the XL machines caused the infamous keyboard lockup. As I stated then, I was under the impression that the oh-so-little (but oh-so-damaging) coding mistake which caused the problem with Atari cartridge BASIC had been fixed.
Well, it turns out that I was both right and wrong. I was right about that particular bug being fixed. I was right in believing that Atari had a version of BASIC which corrected the problem. What I had not been aware of was the number of 600XLs and 800XLs that Atari has sold which contain an intermediate version of BASIC with even more severe problems.
If we call the original Atari BASIC revision A, then the most current version being shipped and installed by Atari (in XE machines as well) is revision C. So what about revision B? In fact, Atari gave me an early release of rev B in cartridge form. (“Rev” is the usual contraction of “revision” if you’re into techie language.) However, when I learned that it had significant problems and that Atari was dropping it in favor of rev C, I promptly ignored and forgot about rev B.
Unfortunately, Atari didn’t do likewise. Atari (the old Atari, that is) ordered a few thousand (tens of thousands? hundreds of thousands?) ROMs using rev B, which they certainly weren’t going to throw away, so kerplunk into all the 800XL and 600XL computers they went.
As I said, I had kind of ignored rev B because I was under the mistaken impression that very few machines using it had been shipped. Boy, did my mail tell me I was wrong! So now, how can I help all of you out there who are stuck with rev B BASIC? Three ways: First, show you how to tell what revision of BASIC you really have. Second, tell you how to avoid the problem most of the time. Third, tell you how to fix the problem permanently.
I am indebted to Matt Ratcliff for showing me a location within Atari BASIC which tells you what version of BASIC you have.
|If you PRINT PEEK(43234) and see this value:||The you have this revision of Atari BASIC:|
Despite what you may have heard or read from other sources, there is no practical way to avoid some of the problems associated with rev B. Many Atari “experts” won’t believe me, but that’s not surprising. Even though we wrote—and, in 1983, COMPUTE! published—The Atari BASIC Source Book, with the complete source code of Atari BASIC rev A and a detailed explanation of the keyboard lockup bug, I saw a user group newsletter just three weeks ago in which someone claimed that hitting SYSTEM RESET cleared up the problem. Honest, there is no reasonable way to avoid the bug in rev A, either.
However, there is a way to minimize the effects of the worst bug in rev B: Don’t use the SAVE or CSAVE commands. Instead, use LIST and ENTER. (Disk users simply substitute the words LIST and ENTER for SAVE and LOAD, respectively. Cassette users use LIST "C" and ENTER "C" in place of CSAVE and CLOAD.) Even this technique will not help you avoid the bug. It will just make it easier for you to recover when you get bitten.
In a nutshell, the problem in rev B is that your program and/or your data can get hopelessly scrambled. Unlike rev A, though, you may not notice the scrambling until some time after it first occurs, since the scrambling often does not cause a lockup. How can you tell if your data is scrambled? You can’t, easily. How can you tell if your program is scrambled? Just LIST it on the screen or a printer. If it looks okay, it probably is okay.
So start by deciding how much time you are willing to throw away, if worst comes to worst. (For me, that’s about 15 minutes. If I were using cassettes, I might make that 30 minutes.) Then, every time you have typed that much time’s worth of new material into your program, LIST the program on the screen or printer to be sure it’s okay. If it is not okay, even if some lines just look funny or scrambled, turn off your power and reboot. Do not attempt to fix your program. The odds are you will only make the situation worse. Only after rebooting should you re-ENTER the last listing from your disk or cassette.
If the screen or printer listing appears okay, you can go ahead and LIST the program to disk or cassette. This way you can have reasonable confidence in that version if you need to re-ENTER it later.
Sidelight for all Atari cassette users: The technique I just described is a good idea no matter what version of BASIC you are using. Remember that you can easily verify a LISTed tape by re-ENTERing it back over itself. Do not type NEW before using ENTER "C". If a tape has an error, the most you will wipe out using this trick is one line. If it has no errors, the ENTER will terminate normally. (Disk users may also use this verification trick, but it seems unnecessary if you always use write-with-verify mode on the disk. Atari DOS defaults to this mode.)
You probably noticed that I said there was no easy way to tell if your data (strings, arrays, etc.) had been scrambled. As far as I can tell, though, any scrambling in these areas is fixed every time you use the RUN command. (If you want to feel super-safe, type NEW and re-ENTER your last LISTed version.) And there appear to be only two ways the bug can occur while a program is running: (1) If you ENTER an overlay in the middle of your program. (2) If you DIMension a string or array when you are several levels deep in a GOSUB and/or FOR nest (several means 64 GOSUBs or 22 FORs or some combination of the two which uses about 256 bytes of stack space).
Maybe the best solution of all is to forget about rev B BASIC entirely and get a different BASIC for your computer. You could buy one of the enhanced BASICs available on disk or cartridge from several independent companies. Or you could buy one of the new XE-series computers, which have rev C BASIC built-in. Or you can order a rev C BASIC cartridge from Atari itself. Perhaps to atone for the bugs in rev B, Atari is offering the rev C cartridges at a nominal cost. Send $15 (no extra shipping and handling charges) to:
390 Caribbean Drive
Sunnyvale, CA 94088
The cartridge works with all eight-bit Atari computers. (Remember that when you plug in a cartridge on an XL or XE, the built-in BASIC is disabled and control passes to the cartridge.)
When I told you above that you need to LIST your program periodically, did you automatically start allocating two or three cassettes or a blank disk for each program? If you didn’t, you might as well ignore my advice. Never use the same cassette or same filename on a disk to keep successive LISTings of SAVEd programs. If you have a good version of a program SAVEd as "D:MYPROG.SAV" and then, in the process of adding more lines to that program, you encounter one of the nasty editing bugs, what happens when you SAVE it again with that same filename? You just wiped out your last good copy.
At the very least, keep the last two versions of every program, every word processing document, every data file, etc. (I always keep three copies and usually keep at least as many as a blank disk will hold.) Unless, of course, you value your own time at less than 25 cents an hour.
More than a few of you have written with questions about my enhanced DOS 2.0S (from COMPUTE!, August and September 1984) for the 1050’s dual density. First, I want to thank you for the nice words and shrug off the complaints. Then, I have the pleasure of telling you that Atari will soon be releasing DOS 2.5, which uses 1024 sectors (out of a possible 1040) on a 1050 drive in dual density mode. It is very, very compatible with DOS 2.0S. Do I have to tell you that it’s completely incompatible with my earlier version? I don’t? Good, then I won’t mention who helped write it for Atari.
The ink wasn’t dry on the March issue of COMPUTE! when I started getting letters (and even two phone calls) asking me to please explain how to read/write a sector directly from/to the disk. I said I would oblige if enough of you asked, so sector I/O, and a recap of Atari I/O in general, is a future topic. But first, next month’s column will explain the bugs in rev C BASIC in more detail and even divulge how they happened.
COMPUTE! ISSUE 61 / JUNE 1985 / PAGE 75
Last month I showed some ways to minimize the problems caused by the bugs in revision B Atari BASIC (the built-in BASIC in the 600XL and 800XL). But many of you are curious about exactly why these bugs happen, and what effect they can have on your programs.
Let me begin by telling what did not cause the error. Rev B BASIC has a peculiar problem: Each time you LOAD (or CLOAD or RUN "filename") a program, rev B adds 16 bytes to the size of your program. If you then save the program, the next time you load it in it grows by another 16 bytes, and so on.
Now believe it or else, these additional 16 bytes were put in deliberately. It seems that there is a minor, undocumented bug in the Atari S: (graphics screen) driver. Under some circumstances, it will use a few bytes below MEMHI (contents of locations $2E5–$2E6, 741–742 decimal). So, if you have a program which extends right to the very top of memory, you can wipe out a little bit of the runtime stack where GOSUBs and FORs are remembered. Somebody at the old Atari apparently had the bright idea that if BASIC told you that memory was full when your program got within 16 bytes of MEMHI, the screen/BASIC conflict could be avoided.
Pretty good idea. Except for a few problems. First, BASIC doesn’t save the string/array space of the runtime stack; both are created when a program is run. So the nice fact that the saved file is guaranteed to have 16 bytes of space left is negated as soon as you DIMension a string or an array or use a GOSUB or FOR. Second, the 16 bytes are added to all of BASIC’s size pointers before the comparison with MEMHI is made. Good. But the newly increased value is then stored as the new pointer value. That effectively moves the program upward in memory by 16 bytes, meaning that the desired 16 bytes of free space aren’t there anyway!
Well, the point of this digression is twofold: (1) This is yet another reason to use LIST and ENTER with rev B BASIC, since ENTERing a program does not trigger this silly 16-byte bug. (2) Several people wrote and suggested that this 16-byte bug is what causes the infamous keyboard lockup bug. Sorry, folks.
Last month, I mentioned the detailed explanation of the rev A Atari BASIC lockup bug which is to be found in COMPUTE! ’s Atari BASIC Source Book. Well, apparently somebody at Atari read the book. Or maybe they just noticed that my company had fixed the lockup bug in one of the three or four revised versions of BASIC that we did for Atari back in 1979 (yes, that’s 1979). It turns out that the lockup resulted from two missing instructions (and a total of two bytes) within the routine which “contracts” memory. (We say “contracts” because it is used when you delete a program line, so the program is contracted in size.)
Then that same somebody looked at the “expand” routine and saw almost identical code. “Aha!” they say, “Methinks there is a bug here which just hasn’t been discovered yet!”
But they were wrong. The reason the bug appeared in the contract routine is because that routine was written after the expand routine and copied its pattern too closely. So our unknown someone at Atari blindly added code to the healthy expand routine and introduced a very nasty new bug. In fact, because this bug appears when you add lines to an existing program, it is probably more likely to occur than the original rev A bug!
To see a demonstration of the bug, enter the following statements in direct mode (without line numbers):
DIM A$(249) A$="ANY STRING YOU LIKE" PRINT A$ PRINT A$, PRINT A$,
The last two statements won’t print A$ properly in either rev A or rev B Atari BASIC—in fact, they’ll mess it up two different ways. Cute, eh? The problem is that tacking that comma on the end of the PRINT statement moves the string/array space (and thus A$) by one byte. Except it doesn’t, really, so the variable value table address of A$ points to the wrong place in memory! Imagine your program being destroyed in a similar way. Is it any wonder you experience keyboard lockup and scrambled listings?
What former Atari employee did I bribe to get all this information about the bugs in rev B BASIC? Did I get the listing on a microdot hidden in a pack of blank disks? Sorry to disappoint you, but I did what any other hacker would do: I dragged out my trusty machine language debugger and carefully disassembled certain portions of rev B BASIC.
Finally, here’s how the two bugs we have discussed were fixed in rev C BASIC, which is built into the new XE series computers (and also is available for older Ataris on cartridge at nominal cost—see last month’s column). Since both bugs were caused by adding things to code which worked before, you would think that Atari could simply take the “fixes” back out. Nope. Instead, they patched over the extraneous instructions with what are effectively NOP (NO oPeration) instructions. Tacky? Well, I’ve certainly done it to DOS here in this column enough times, so who am I to say?
COMPUTE! ISSUE 62 / JULY 1985 / PAGE 92
From time to time a new product comes to my attention which stands above the rest in terms of performance and value. A recent example is the MicroNet from Micro Peripheral Products (MPP) of Albany, Oregon. The MicroNet is a wondrously simple device that allows you to connect up to eight Atari computers (though not the new ST machines, yet) to a single printer and one or more disk drives. You simply connect a standard Atari serial cable (the kind that goes from the computer to the disk drive, printer interface, etc.) from each computer to any of eight sockets on the deceivingly small MicroNet box. Then you connect a similar cable from the MicroNet to the drives and printer, just as if the MicroNet were an Atari computer. The result? All eight computers think the disk drive(s) and printer are their very own! Well … almost.
This is not a sophisticated high-speed network with several megabytes of mass storage and an automatic printer spooler online. It’s still using the clunky 19,200-baud Atari serial bus, slow enough when only one computer is using a drive. With eight computers, you may have to wait eight times as long to read something from a disk (though a delay this drastic is unlikely). And what about printing? You sure don’t want to use the slow Atari 1027 printer in this configuration! Still, let’s take a look at situations where this system makes sense.
First and most obvious is the classroom. A teacher can put the day’s lessons on a disk from any one of the computers, write-protect the disk, and then let each student boot his/her own computer and start using the appropriate materials. Or the teacher can boot each computer—it would take only two or three minutes. Reports on each student’s performance could be kept on a second disk or printed on the shared printer, The total cost of this system, assuming eight computers? Look at the chart below. Prices are rounded up from retail, and an enterprising dealer should be able to offer a substantial discount on a package like this:
8 800XL or 65XE computers ...... $ 800 8 color TVs or monitors ........ $1600 2 disk drives .................. $ 400 1 fast printer ................. $ 400 1 printer buffer ............... $ 200 1 MicroNet ..................... $ 200 TOTAL $3600
Surprised by the last two items? The printer buffer is recommended by MPP. By spooling printer data into the buffer at high speed, a single computer won’t tie up the MicroNet bus for so long. And if you were surprised at the low cost of the MicroNet, you read it correctly: The actual suggested retail price is only $199.95. Hard to believe!
That puts the per-station cost at $450, less than the price of a black and white, nongraphics terminal on a conventional time-sharing system. Or about one-third the cost per station of an Apple lie network system.
Could the MicroNet be used for business applications? Well, maybe. A big fat maybe. The MicroNet provides no file protection whatsoever. No password security. No way of stopping user No. 2 from zapping user No. 1’s files. Et cetera. And there’s certainly nothing to prevent two users from trying to write to the same disk file at the same time. Lots of potential problems. The easiest solution is to write software which is alert to the possible problems.
For example, the MicroNet gives exclusive control of the disk drive to a single computer long enough for it to create a file, A program running on another computer could look for the existence of that file as a signal that it could not write to a certain database file. Sounds clumsy, but many of the cheapie time-sharing systems of the 1960s and 1970s had this problem and solved it the same way.
The MicroNet system can definitely be crashed if its users are hostile, and that’s one reason I suggested that teachers write-protect their master disks before letting all the clever kiddies take a crack at crashing it. (My own little seven-year-old knows that crashing a disk means he doesn’t get to play on the computer for a while. He is now beautifully conscientious about popping the disk before turning off the power.)
The MicroNet is obviously an economical solution to some problems. It is not all things to all people; but, at its price, it is certainly worth looking at. (For more information, write to MPP at 225 Third Avenue SW, Albany, OR 97321.)
Next month: Part 1 of my long-promised series on Atari input/output. Theory and a little bit of practice. See you then.
COMPUTE! ISSUE 63 / AUGUST 1985 / PAGE 34
Much of what I’m about to discuss this month has appeared in this column before. And the bulk of this information can also be found in the Atari Technical Reference Manual—presuming you can read “techlish.” But this intro is necessary so we can start talking about the meat of our subject next month.
Still with me? Let’s go. Atari’s operating system (OS)—which, like the OS in any eight-bit computer, takes up the bulk of Read Only Memory (ROM)—is really a thing of beauty. In fact, it may be the only consistent OS to be found in any microcomputer, short of those sporting UNIX or its derivatives. CP/M and MS-DOS are such kludges that most commercial programs bypass the OS. (That’s why there are so many “almost PC-compatibles.”) The Commodore 64’s operating system comes close, but its disk input/output is difficult at best. And Apple’s ProDOS manual states that “users desiring to perform I/O to devices other than the disk drive are on their own!”
Atari users, on the other hand, enjoy a system with such complete support that, for most programs, all necessary input/output operations can be executed by calling a single subroutine! That subroutine is called, appropriately, Central Input/Output (CIO). By calling CIO with the proper values in certain memory locations and the proper pointer in the 6502’s X register, your programs can perform such diverse operations as formatting a disk, drawing a line on the graphics screen, fetching a keystroke from the keyboard, sending output to the printer, or reading 25,000 bytes from a disk file.
Yet, CIO is invisible to most Atari users. For example, many of the capabilities which magazine and newsletter articles attribute to BASIC are not part of BASIC at all. None of the graphics (including the so-called BASIC graphics modes) in Atari BASIC are actually performed by BASIC. Instead, BASIC simply translates the graphics command into a call to CIO. Atari developed this system in 1978, and it wasn’t until the Macintosh appeared that such a revolutionary concept was repeated in a popular computer.
Generally, you have to become a machine language programmer to appreciate and use all the features of CIO. So why read any of this, then? Because calls to CIO can’t perform every input/output task possible on Atari computers. What can’t CIO do? First, let’s take a glance at what it can do.
When CIO is called by a program, it expects the X register to contain a pointer to an Input/Output Control Block (IOCB). IOCBs are blocks of memory 16 bytes long which control CIO functions. The pointer value for the X register is easily calculated—it’s actually the BASIC file number (as in OPEN #1,4,0,"K:") multiplied times 16, because there are 16 bytes per IOCB. One of the bytes within the IOCB then tells CIO what function the program is requesting.
There are seven fundamental functions available: OPEN, CLOSE, STATUS, PRINT, INPUT, Block PUT, and Block GET. In addition, there are some extended functions. BASIC programmers are familiar with these because of the XIO statement, which allows you to call the functions from BASIC. But several other BASIC statements (including NOTE, POINT, DRAWTO, and LOCATE) access the CIO extended functions, too.
After CIO examines the IOCB and determines which function is being requested, it decides which device (keyboard, disk, screen, etc.) should service the request. Then it calls an appropriate routine within the device driver for that device. (For example, the Disk Operating System—or more properly, the File Management System—is the device driver for the disk drive.) If the request is for an extended function, it is passed on unchanged to the device driver.
Well, with 256 possible command values, you would think that there isn’t any request, however bizarre, which couldn’t be serviced via CIO, In theory, true. In reality, you have to stop adding functions somewhere or you run out of memory. Thus Atari’s CIO-based graphics have no function for drawing a circle, and DOS provides no command to format a disk without also writing a boot and directory.
If you want to draw a circle, you can write a routine to calculate and PLOT points or change screen memory directly. If you want to mess with the disk drive, though, you have to learn about another routine within the Atari ROMs, Serial Input/Output.
SIO—which lets Atari computers talk to devices (such as printers and disk drives) which hook up to the serial bus—has acquired an undeserved aura of mystery. Actually, though, in some ways it is easier to call SIO than it is to call CIO!
For example, there is only one SIO “device” and only one Device Control Block (DCB). So even the X register pointer required by CIO isn’t necessary when calling SIO. Intrigued? I hope so, because it’s time to sign off for now. But after this brief overview, we’re ready for next month’s column: We’ll show how to write a program to call SIO.
COMPUTE! ISSUE 64 / SEPTEMBER 1985 / PAGE 110
Last month, I introduced the structure of Atari’s operating system (OS). My most important point was that the OS consists of several layers. When you type in a BASIC statement such as LPRINT "Hi There!", you cause a fairly complex chain of events. First, BASIC figures out that LPRINT means you want to use a printer, so it calls the OS to open a channel to the printer (always channel number 7, in this case). Then BASIC sends the bytes to be printed to a part of the OS called Central Input/Output (CIO), which in turn realizes that a file to the printer has been opened on that channel. CIO calls the printer driver, which collects bytes until it has a block of them (or until it gets a carriage-return character or a CLOSE command). Finally, the printer driver sends a block of bytes to the printer by calling Serial Input/Output (SIO)—another subroutine inside the OS, and the subject of this month’s discussion.
I’d like to point out that this process stops at SIO only as far as the computer is concerned. The printer interface (for example, an 850 Interface Module) also contains a microprocessor which collects the block sent to it by SIO. Then the interface passes the block, a byte at a time, to the printer. Within the printer, yet another microprocessor is usually employed to control the various motors and hammers and wheels that actually place the characters on paper.
Did you note that the process of printing even a single character most probably requires the use of three microprocessors? Did you stop to think that each of these processors requires software to make it work? Did you ever wonder why there are so many people making a living at programming? (Though barely, in the case of some of us.)
Perhaps the most amazing thing is that, for the most part, the three microprocessors work reliably and efficiently together. (It is even more amazing when you consider that either the printer or interface module is often made by a company other than the one which made the computer!) The secret to success here is standardization. The usual printer connection is a fairly simple one, originally defined by a company named Centronics and now adopted by almost every manufacturer in the microcomputer market.
The way your Atari computer “talks” to your interface module, though, is strictly an Atari invention—the SIO. There is a well-defined protocol associated with SIO. It includes such niceties as Command and Data Frames, Acknowledgment, Nonacknowledgment, Command and Bus Errors, and more. Luckily, 99 percent of all Atari programmers need never learn these gory details, since there really isn’t anything you can do to change their workings.
Some programmers, however, do want to send and receive blocks via SIO. And usually the blocks to be transferred are disk sectors. So let’s look at how one reads or writes a specific disk sector.
When SIO is called by a program, it expects to find certain information in a Device Control Block (DCB). There is only one DCB, located at $0300–$030B (768–779 decimal). It contains four one-byte values and four two-byte (word) values, all of which must be set up properly. The accompanying table briefly describes each location in the DCB. See COMPUTE! Books’ Mapping the Atari for more details.
Does all this look confusing? Not to worry. Program 1 below is a subroutine which does most of the work for you. Just type it in, LIST it to disk or cassette, and use it in your own programs whenever you wish. Program 2 demonstrates how to use the subroutine, though I hope the comments make it pretty much self-explanatory. (Perhaps I should note that a command of R reads a sector, P writes a sector without verifying it, and W both writes and verifies a sector.) To use Program 2, you must add the subroutine from Program 1. You can either type in the lines from Program 1, or ENTER them from disk or tape if you have LISTed out a copy of Program 1. Program 3 is the source code behind the DATA statements in line 9210 of Program 1.
If you type in and use Program 2, you might like to remember that the volume table of contents (VTOC) of a DOS 2.0-compatible disk is in sector 360. The directory occupies sectors 361 to 368. Sectors 1, 2, and 3 are for booting only. All other sectors from 4 to 719 should be DOS file sectors. (See COMPUTE! Books’ Inside Atari DOS for more info. Caution: The diagram of the sector link bytes is wrong.)
Finally, I give you a hint and challenge for next month: Most drives not made by Atari allow the user to specify their configuration (for example, single or double density). You can read their configuration blocks with an SIO command of N (or write via O). But be careful! DSIZE must be given as 12 bytes. Can you modify our subroutine to read the configuration block? Good luck.
|DCB Layout Table|
|300||768||DDEVIC||1||Name of device on SIO bus (all disk drives use "1," $31, as a name).|
|301||769||DUNIT||1||Unit number of device (to distinguish D1: from D2:, for example).|
|302||770||DCOMND||1||Command, usually an ATASCII letter, such as "R" for read sector (but "1" will format a disk!).|
|303||771||DSTATS||1||Direction control before call to SIO; status of operation upon return.|
|304||772||DBUF||2||Address of buffer to read from or write to, as appropriate.|
|306||774||DTIME||2||Timeout value. SIO waits this many seconds before giving up.|
|308||776||DBYTE||2||Number of bytes to transfer (always 128 or 256 for disks).|
|308||778||DAUX||2||Purpose varies; always sector number when used with disks.|
For instructions on entering this listing, please refer to “COMPUTE!’s Guide to Typing In Programs” published bimonthly in COMPUTE!.
9000 REM ................ 9010 REM DISK SECTOR I/O ROUTINE 9020 REM . ENTER: 9030 REM . sector number in SECTOR 9040 REM . drive number in DRIVE 9050 REM . buffer address in ADDR 9060 REM . command in CMD$ 9070 REM . density in DENSITY 9080 REM (only "R","W","P" are valid for CMD$) 9090 REM (only 1=SGL and 2=DBL are valid for DENSITY) 9100 REM . EXIT: 9110 REM . status in SIOSTATUS 9120 REM 9160 TRAP 9220:REM activated if SIOCALL$ already DIM'd 9170 DIM SIOCALL$(16) 9180 RESTORE 9210 9190 FOR CNT=1 TO 14:READ BYTE 9200 SIOCALL$(CNT)=CHR$(BYTE):NEXT CNT 9210 DATA 104,32,89,228,173,3,3,133,212,169,0,133,213,96 9220 TRAP 40000:REM turn off TRAP 9230 POKE 768,ASC("1"):REM don't ask me why 9240 POKE 769,DRIVE:REM must be 1 through 8 9250 POKE 770,ASC(CMD$) 9260 POKE 771,128:REM assume write 9270 IF CMD$="R" THEN POKE 771,64 9280 POKE 773,INT(ADDR/256):REM buffer address 9290 POKE 772,ADDR-256*PEEK(773) 9300 POKE 774,3:REM short timeout 9310 POKE 775,0:REM (high byte of timeout) 9320 POKE 776,128:POKE 777,0:REM assume single density 9330 IF DENSITY=2 THEN POKE 776,0:POKE 777,1 9340 POKE 779,INT(SECTOR/256) 9350 POKE 778,SECTOR-256*PEEK(779) 9360 SIOSTATUS=USR(ADR(SIOCALL$)) 9370 RETURN
For instructions on entering this listing, please refer to “COMPUTE!’s Guide to Typing In Programs” published bimonthly In COMPUTE!.
1000 REM PROGRAM TO DEMONSTRATE SECTOR READ SUBROUTINE 1010 REM NOTE: rather than ask questions, we 1020 REM . assume that we will work with drive 1030 REM . number 1 and that it is single 1040 REM . density (128 byte sectors 1050 REM 1100 DIM BUFFER$(256):REM guaranteed adequate 1110 ADDR-ADR(BUFFER$):REM required by subroutine 1120 DRIVE=1:REM assumption ... easily changed 1130 DENSITY=1:REM assumption...ditto 1140 DIM CMD$(1):CMD$="R":REM always, for this demo 1150 REM 1160 PRINT "What sector to display"; 1170 INPUT SECTOR 1180 GOSUB 9000 1190 GRAPHICS 0 1200 PRINT "Read Sector ";SECTOR;" gave Status ";SIOSTATUS 1210 SIZE-DENSITYf128:REM size is 128 or 256 1220 SECTOR-PEEK(ADDR+SIZE-3) 1230 FILE;INT(SECTOR/4) 1240 SECTOR=SECTOR-4*FILE 1250 SECTOR=SECTOR*256+PEEK(ADDR+SIZE-2) 1260 CNT-PEEK(ADDR+SIZE-1 1270 PRINT "If DOS file sector, this is file #";FILE 1280 PRINT " there are ";CNT;" bytes in this sector" 1290 PRINT " and the next sector is number ";SECTOR 1300 PRINT 1310 FOR LINE=0 TO DENSITY*128-1 STEP 8 1320 BYTE=LINE:GOSUB 1500:PRINT ":"; 1330 FOR CNT=0 TO 7 1340 BYTE=PEEK(ADDR+LINE+CNT):GOSUB 15002:PRINT " "; 1350 NEXT CNT 1360 FOR CNT=0 TO 7 1370 BYTE=PEEK(ADDR+LINE+CNT) 1380 IF BYTE>127 THEN BYTE=BYTE-128 1390 PRINT CHR$(27);CHR$(BYTE); 1400 NEXT CNT 1410 PRINT 1420 NEXT LINE 1430 PRINT 1440 GOTO 1160 1450 REM ....................................... 1460 REM A QUICKY DECIMAL TO HEX CONVERTER 1500 TRAP 1520 1510 DIM HX$(16):HX$="0123456789ABCDEF" 1520 TRAP 40000 1530 HX=INT(BYTE/16)+1:PRINT HX$(HX,HX);:HX=BYTE-16*HX+17:PRINT HX$(HX,HX); 1540 RETURN
Note: This listing is provided for informational purposes; it requires an assembler to enter into your computer.
*= anyplace CALLSIO PLA ;throw away count ; of arguments JSR SIOV ;(at $E459) LDA DSTATS ;SIO status ; (from DCB) STA FR0 ;floating point ; register 0, $D4 LDA #0 STA FR0+1 ;(to get a two- ; byte value) RTS ;back to BASIC caller
COMPUTE! ISSUE 65 / OCTOBER 1985 / PAGE 110
Way back in 1978, when Atari announced the double-density 815 disk drive, Percom Data Corporation saw the prototypes displayed at several shows and decided it could easily build a better drive which would sell for less.
Because Percom produced both single- and double-sided disk drives using both single and double density, and because it wanted to maintain compatibility with both the single-density 810 and double-density 815 drives, Percom invented the configuration block (more on this below). With some cooperation from a small, brand-new software company (wonder who that could be) which had inherited the source code rights to Atari’s File Management System (FMS), Percom succeeded in establishing standards which have been adhered to by all other Atari-compatible drive manufacturers. All Atari-compatible drive manufacturers except one, that is: Atari. Before the 815 even hit the market, Atari dropped it from the product line. Years later, in 1984, Atari introduced the “enhanced density” 1050, which is actually somewhere between single-and double-density. Sigh.
As of this writing, the following drives and/or modification kits are known to be capable of understanding the Percom-standard double-density mode and configuration table: Percom, Indus, Amdek, Astra, Trak, Rana, SWP (ATR-8000), Happy Doubler, and ICD’s US Doubler.
As defined by the Percom standard, a config block is a set of 12 bytes within the memory of the disk control microprocessor—which is inside your disk drive(s). You read a drive’s config block by passing “N” to it as an SIO command. You can write a new config block to a drive via an “O” command. The “N” and “O” commands closely parallel the “R” and “W” sector input/output commands, except the data length is always 12 bytes and, no sector number is needed. The 12 bytes in the block are shown in the table.
|Byte #||# of
|0||1||Number of Tracks|
|2-3||2||Sectors per Track|
|4||1||Number of Sides or Heads|
|5||1||Density (0=Single, 4=Double)|
|6-7||2||Bytes per Sector|
|9||1||Serial Rate Control|
This table requires some explanation. First, all the double-byte values are in high-byte/low-byte order, the opposite of normal 6502 practice (because that’s how the microprocessor Percom used in their drives worked). Also, not all these values have meaning to all manufacturers. In fact, some don’t allow you to change more than two or three of the values listed here.
The Step Rate controls the speed of a drive’s head stepping motor, and the values used here have no universal meaning. A step rate of 2 may mean 6 milliseconds per track to one drive, 20 milliseconds per track to another, or be illegal to yet another.
Number of Sides is actually one less than the actual number. So most drives use a zero here, meaning one head.
Changing the value of Drive Selected may turn the drive off as far as the computer is concerned. Percom must have had its reasons for this, but I don’t know what they were.
For the Density byte of the config block, I don’t know of any drives which use values other than 0 (FM mode, single density) or 4 (MFM mode, double density). If you find a drive that actually uses some other value (not just ignores it), let me know.
The Serial Rate Control value and Miscellaneous bytes have no universal meanings. Some drives will remember these values if you change them; other drives ignore your values.
So that leaves Number of Tracks, Sectors per Track, and Bytes per Sector, all of which should be self-explanatory. Again, though, many drives ignore values outside certain legal ranges. Indus drives, for example, reject any changes to the number of tracks or sectors. In fact, Indus pays attention only to the Bytes per Sector and the Density bytes. Experiment with your own drive(s). See what they will and will not allow. And even if they seem to allow a change, do they execute it or ignore it? (Fun, if you’re a masochist, right?)
And just how do you read and/or change the config block? Have a look at the BASIC program following this column. It should be pretty much self-explanatory. You can use the subroutines at 8010, 8210, and 9010 in your own programs. Remember what we said at the beginning, however: Atari drives do not follow the Percom config block standard. As a result, this program works only on Atari-compatible disk drives, not on the Atari 810 or 1050.
For instructions on entering this listing, please refer to “COMPUTE!’s Guide to Typing In Programs” published bimonthly in COMPUTE!.
1010 REM 1020 REM CONFIGURE FROM BASIC 1030 REM 1050 DIM TEMP$(20),TBL$(12),CMD$(1) 1060 GRAPHICS 0:PRINT "*** DISK CONFIGURATION PROGRAM ***" 1070 PRINT :PRINT :PRINT "What disk drive will we work with"; 1080 INPUT DRIVE 1090 IF DRIVE<1 OR DRIVE>8 OR DRIVE<>INT(DRIVE) THEN RUN 1100 GRAPHICS 0:PRINT "DRIVE #";DRIVE; 1110 GOSUB 8000 1120 IF SIOSTATUS<128 THEN 1170 1130 PRINT " won't let me read" 1140 PRINT " the configuration block." 1150 PRINT SPRINT "It gave me error #";SIOSTATUS 1160 STOP 1170 PRINT " looks like this:":PRINT 1180 PRINT TRACKS;" TRACKS of ";SECTORSPERTRACK;" SECTORS each" 1190 PRINT :PRINT "each sector has ";BYTESPERSECTOR;" BYTES, & density" 1200 PRINT " is ";DENSITY;", considered "; 1210 IF DENSITY=0 THEN PRINT "SINGLE density, 1220 IF DENSITY=4 THEN PRINT "DOUBLE density," 1230 IF DENSITY<>0 AND DENSITY<>4 THEN PRINT "UNKNOWN DENSITY," 1240 PRINT " with ";SIDES;" SIDE(s)." 1250 PRINT :PRINT "the STEP RATE setting is ";STEPRATE 1260 PRINT "other settings are SELECT";SELECT;"," 1270 PRINT "ACIA=";ACIA;", and MISC=";MISC 1280 PRINT :PRINT "SELECT A CHOICE:" 1290 PRINT " 0 - quit and save configuration" 1300 PRINT " 1 - change drive setting(s)" 1310 PRINT " 2 - work with another drive" 1320 PRINT :PRINT "your choice ";:INPUT CHOICE 1330 IF CHOICE=0 THEN JUNK=USR(58484) 1340 IF CHOICE=2 THEN RUN 1350 GRAPHICS 0:PRINT "Enter new values. Hit RETURN to" 1360 PRINT "leave a value unchanged." 1370 PRINT 1380 PRINT "TRACKS";:TEMP=TRACKS 1390 GOSUB 7000:TRACKS=TEMP 1400 PRINT "SECTORS PER TRACK";:TEMP=SECTORSPERTRACK 1410 GOSUB 7000:SECTORSPERTRACK=TEMP 1420 PRINT "BYTES PER SECTOR";:TEMP=BYTESPERSECTOR 1430 GOSUB 7000:BYTESPERSECTOR=TEMP 1440 PRINT "NUMBER OF SIDES";:TEMP=SIDES 1450 GOSUB 7000:SIDES=TEMP 1460 PRINT "DENSITY";:TEMP=DENSITY 1470 GOSUB 7000:DENSITY=TEMP 1480 PRINT 1490 PRINT "STEP RATE";:TEMP=STEPRATE 1500 GOSUB 7000:STEPRATE=TEMP 1510 PRINT "SELECT";:TEMP=SELECT 1520 GOSUB 7000:SELECT=TEMP 1530 PRINT "ACIA";:TEMP=ACIA 1540 GOSUB 7000:ACIA=TEMP 1550 PRINT "MISCELLANEOUSWORD";:TEMP=MISC 1560 GOSUB 7000:MISC=TEMP 1570 GOSUB 8200 1580 IF SIOSTATUS<128 THEN 1100 1590 PRINT :PRINT 1600 PRINT "Unable to set that configuration!" 1610 PRINT " drive issued error #";SIOSTATUS 1620 PRINT :PRINT "(hit RETURN to continue)" 1630 GOTO 1100 7000 REM ENTER DATA OR NO CHANGE 7030 PRINT " [";TEMP;"] ? "; 7040 INPUT TEMP$ 7050 IF LEN(TEMP$) THEN TEMP=VAL(TEMP$) 7060 RETURN 8000 REM EXTRACT INFO FROM TABLE 8030 TBL=ADR(TBL$):ADDR=TBL 8040 CMD$="N":GOSUB 9000:REM ---READ BLOCK--- 8050 TRACKS=PEEK(TBL+0) 8060 STEPRATE=PEEK(TBL+1) 8070 SECTORSPERTRACK=PEEK(TBL+2)*256+PEEK(TBL+3) 8080 SIDES=PEEK(TBL+4)+1 8090 DENSITY=PEEK(TBL+5) 8100 BYTESPERSECTOR=PEEK(TBL+6)*256+PEEK(TBL+7) 8110 SELECT=PEEK(TBL+8) 8120 ACIA=PEEK(TBL+9) 8130 MISC=PEEK(TBL+10)*256+PEEK(TBL+11) 8140 RETURN 8200 REM PUT NEW INFO INTO TABLE 8230 TBL=ADR(TBL$):ADDR=TBL 8240 POKE TBL+0,TRACKS 8250 POKE TBL+1,STEPRATE 8260 POKE TBL+2,INT(SECTORSPERTRACK/256) 8270 POKE TBL+3,SECTORSPERTRACK-PEEK(TBL+2)*256 8280 POKE TBL+4,SIDES-1 8290 POKE TBL+5,DENSITY 8300 POKE TBL+6,INT(BYTESPERSECTOR/256) 8310 POKE TBL+7,BYTESPERSECTOR-PEEK(TBL+6)*256 8320 POKE TBL+8,SELECT 8330 POKE TBL+9,ACIA 8340 POKE TBL+10,INT(MISC/256) 8350 POKE TBL+11,MISC-PEEK(TBL+10)*256 8360 CMD$="O":GOSUB 9000:REM ---WRITE BLOCK--- 8370 RETURN 9000 REM DISK DENSITY CHANGE ROUTINE 9030 REM 9040 REM ENTER: DRIVE NUMBER IN DRIVE 9050 REM . buffer address in ADDR 9060 REM . command in CMD$ 9070 REM 9080 REM (ONLY "N" AND "O" ARE VALID FOR CMD$) 9090 REM 9100 REM EXITS status in SIOSTATUS 9110 REM 9130 TRAP 9190:REM activated if SIOCALL$ already DIM'd 9140 DIM SIOCALL$(16) 9150 RESTORE 9180 9160 FOR CNT=1 TO 14:READ BYTE 9170 SIOCALL$(CNT)=CHR$(BYTE):NEXT CNT 9180 DATA 104,32,89,228,173,3,3,133,212,169,0,133,213,96 9190 TRAP 40000:REM turn off TRAP 9200 POKE 768,ASC("1"):REM don't ask me why 9210 POKE 769,DRIVE:REM must be 1 through 8 9220 POKE 770,ASC(CMD$) 9230 POKE 771,128:REM assume output 9240 IF CMD$="N" THEN POKE 771,64 9250 POKE 773,INT(ADDR/256):REM buffer address 9260 POKE 772,ADDR-256*PEEK(773) 9270 POKE 774,3:REM short timeout 9280 POKE 775,0:REM (high byte of timeout) 9290 POKE 776,12:POKE 777,0:REM assume std config block 9300 SIOSTATUS=USR(ADR(SIOCALL$)) 9310 RETURN
COMPUTE! ISSUE 66 / NOVEMBER 1985 / PAGE 135
My coworkers and I have received many requests from owners of the Atari 600XL, 800XL, and 130XE for a simple way to turn off the BASIC built into those computers. Of course, the method recommended by Atari is to hold down the OPTION button when you boot the system. If you forget to do this when booting a program that doesn’t require BASIC, the ROM-based BASIC occupies address space that costs you more than 8,000 bytes of RAM. There are other reasons for turning off BASIC as well. For instance, you might like to turn it off temporarily to gain extra memory while duplicating a few files or disks. These jobs take less time and fewer disk swaps if the computer can use the 8K of memory vacated by disabling BASIC. And avoiding a reboot or two can save time, too.
Our solution is a pair of short machine language programs that let you turn BASIC on and off from DOS. (Note that they can’t turn off a BASIC cartridge—or any other cartridge, for that matter—so they serve no purpose on the Atari 400, 800, and 1200XL computers.) Atari manuals suggest that turning off the built-in BASIC is as simple as changing one bit in the XL/XE memory control location (which used to control joystick ports 3 and 4 in the 400 and 800). That may be true if you’re writing a machine language program that takes over complete control of the computer, but in many cases it doesn’t work.
First, whenever you press the RESET button, the operating system restores the built-in BASIC to the state in which you booted it. Second, if you’re using ordinary graphics mode screens (without a custom display list, etc.), the screen handler doesn’t use the memory freed by removing BASIC. It thinks you’re still using a 40K machine. Going the other way—turning on BASIC after booting without it— can be even messier. If you suddenly enable BASIC without doing something about the screen, you’ll find yourself staring at garbage as BASIC blithely wipes out the display list, screen memory, and perhaps more. Fortunately, all of these problems can be solved by following these few steps:
We can tell the operating system we changed the state of BASIC via the flag in memory location 1016 ($3F8). The master top-of-RAM pointer is RAMTOP at location 106 ($6A). Channel 0 is closed and reopened to force the screen driver to use the highest available memory. Don’t worry if that sounds a bit arcane. The program listed here automatically creates two machine language programs that do all the work for you. Be sure to save a copy before you run it.
100 DIM NAME$(20) 110 LINE=800:GOSUB 210 120 LINE=900:GOSUB 210 130 END 210 CHECK=0:RESTORE LINE 220 FOR CNT=1 TO 57:READ BYTE 230 CHECK=CHECK+BYTE:NEXT CNT 240 READ TEST I IF CHECK<>TEST THEN STOP 250 READ NAME$:OPEN #1,8,0,NAME$ 260 RESTORE LINE 270 FOR CNT=1 TO 37:READ BYTE 280 PUT #1,BYTE:NEXT CNT 290 CLOSE #1 300 RETURN 810 DATA 235,255,0,4,44,4,173,1,211,9,2,141,1 830 DATA 211,169,1,141,248,3,169,12,32,24,4 840 DATA 169,192,133,106,169,3,141,66,3,169,42 860 DATA 141,68,3,169,4,141,69,3,162,0,76,86 870 DATA 228,69,38,0,226,2,227,2,0,4 880 DATA 5045,D:BASICOFF.COM 910 DATA 255,255,0,4,44,4,173,1,211,41,253,141 930 DATA 1,211,169,0,141,248,3,169,12,32,24,4 940 DATA 169,160,133,106,169,3,141,66,3,169,42 950 DATA 141,68,3,169,4,141,69,3,162,0,76,86 970 DATA 228,69,38,0,226,2,227,2,0,4 900 DATA 5295,D:BASICPN.COM
The program writes two binary files to disk on drive 1, naming them BASICON.COM and BASICOFF.COM. The first turns BASIC on and the second turns it off. To use either of them from DOS, simply choose the L (load binary file) option and enter the filename when prompted, (OS/A+ and DOS XL users need only type BASICON or BASICOFF in response to the D1: prompt.)
The next time you need to duplicate a disk or large file, load BASICOFF.COM first, copy the disk or file, then load BASICON.COM to reactivate BASIC. You’ll save time, especially on a singledrive system. If you’re writing machine language programs, call BASICOFF as a subroutine when you start your program.
COMPUTE! ISSUE 67 / DECEMBER 1985 / PAGE 132
This month we’re going to look at good old Atari BASIC. For once, though, I’m not going to talk about its problems. Instead, I’m going to tell you about a few of its many virtues. If you’ve been reading my column since it first appeared in the September 1981 issue of COMPUTE!, then some of this may seem repetitive; but it’s time to introduce newcomers to some of this material.
Unfortunately, I am beginning to see more and more poorly written Atari BASIC programs. Generally, what happens is that someone not too well-versed in Atari BASIC attempts to translate a program from another computer’s BASIC and botches the job. The last straw, for me, was a recently released book which is full of CAI (Computer Assisted Instruction) programs. All the programs do much the same thing, and all the programs are…well, just a lot of work for so little value.
Now, I’m all for using a computer for drill and practice, even though most of the educational programs which do this are dull and unimaginative (and often overpriced). But even the plainest of CAI programs can at least free up a teacher or parent for 20 or 30 minutes while a student is checking his or her knowledge. And if all you want your CAI program to do is ask questions and wait for a response, then all such programs can be essentially the same. So that’s what I’m going to give you this month: a “formula” program for drill and practice.
I also mentioned that we would look at some of the virtues of Atari BASIC, so let’s do that first. Among microcomputer BASICs, Atari BASIC is nearly unique in its flexibility in the use of GOTO, GOSUB, and RESTORE. Specifically, each of these statements accept any numeric expression as the line number they reference. Combined with Atari BASICs variable-name flexibility, this means you can code such oddities as:
RESTORE 20000 + 10 * CURRENTROOM
Most Atari BASIC books refer to these capabilities briefly, if at all. But there is some real hidden power here, as we are about to find out. Rather than belabor the point, let’s take a look at the accompanying listing and analyze it a step at a time.
Line 1010 is fairly obvious, so let’s start with lines 1060 to 1080. The variables being set here are actually going to be used as labels, the targets of GOTO and GOSUB statements. The only thing you have to be careful of with this method is renumbering—some renumbering utilities warn you when they encounter a variable being used as a label, and some don’t.
Now, after setting the DATA pointer in line 1090, we get a line of DATA, assigning the first byte to the variable TYPE$. The action we take next depends on what type of line we got. We use an exclamation point to indicate a screen clear is needed, a colon for an extra blank line, and a period to flag an ordinary text line. In any of these cases, we print the rest of the line and get another one. If the type is an asterisk, the program halts. If the type is a question mark, then it’s time for the student to answer.
At this time, let’s look at the DATA in lines 10000–10003. The first line begins with an exclamation point, so the screen is cleared and it is printed. Then the colon asks for a blank line before the next line is displayed. Finally, the question mark tells the program to ask for a response. But what’s the rest of that funny stuff: 1 =, Y, 0, 10010?
Back at lines 1200–1260, you can see that the digit (a 1 in line 10002) tells the number of possible answers to the question, and the next character indicates the type of answer which is acceptable (the equal sign here asks for an exact match). The program then prompts the user for an answer (the # 16 suppresses the INPUT prompt) and prepares to test its validity. The loop in 1310–1360 checks each valid answer against the user’s response.
If an exact answer is needed, even the length of the answer counts. (Example: In line 10002, we have allowed only a single exact answer, the letter Y.) Another flag indicates whether the valid answer can be found somewhere in the user’s response line. Line 10012, for example, passes any answer containing the word GRANT (such as MIGRANT WORKERS), so some care is needed in using this type. Finally, if none of the valid answers matches the user’s response, the program falls through to lines 1400–1420.
So far, all this has been very straightforward, and it would work on almost any BASIC. Now comes the tricky stuff. Look at line 1320, where we READ numbers into the variables GOSUBLINE and DATALINE. What we’re doing is establishing an action to take and a new set of DATA to access if the user’s response matches a valid answer. Similarly, in line 1420 we read values to be used if no valid answer is given. Finally, the “magic” of this program is revealed in lines 1510 and 1520.
If we READ a number other than zero for GOSUBLINE, the program actually GOSUBs to that number. And, in any case, we change the DATA pointer to the new DATALINE. If you can’t predict what happens if you answer DUCK to the second question (because of the DATA in lines 10012–10014), please type this program and try it out.
Now, the real beauty of this program is that it works with almost any kind of question and answer session. It allows for multiple choice questions (use a format like ?3=,A,0,100, B,0,100,C,0,200), true/false, and so on. It provides for special help if needed (via the GOSUBLINEs). And, last but by no means least, it is expandable. You could add many different statement types, question types, or whatever quite easily. And it’s all made possible thanks to Atari BASIC.
1000 REM === INITIALIZATION === 1010 DIM LINE$(120),ANS$(20),TYPE$(1) 1060 INEXACT=2000:EXACT=2100 1070 MAINLOOP=1100:QUESTION=1200 1080 MATCHED=1500 1090 RESTORE 10000:REM where we start 1100 REM === THE MASTER LOOP === 1110 READ LINE$:TYPE$=LINE$ 1120 IF TYPE$="?" THEN GOTO QUESTION 1130 IF TYPE$="!" THEN PRINT CHR$(125) 1140 IF TYPE$=":" THEN PRINT 1150 IF TYPE$="*" THEN END 1160 PRINT LINE$(2) 1170 GOTO MAINLOOP 1200 REM === PROCESS A QUESTION === 1210 QCNT=VAL(LINE$(2,2)) 1220 TYPE$=LINE$(3) 1230 POSITION 2,20 1240 PRINT CHR$(156);CHR$(156); 1250 PRINT "Your Answer?" ; 1260 INPUT #16,LINE$ 1300 REM === PROCESS THE ANSWER === 1310 FOR ANS=1 TO QCNT 1320 READ ANS$,GOSUBLINE,DATALINE 1330 IF TYPE$="#" THEN GOSUB INEXACT 1340 IF TYPE$="=" THEN GOSUB EXACT 1350 IF MATCH THEN GOTO MATCHED 1360 NEXT ANS 1400 REM === ANSWER DOESN'T MATCH === 1410 REM (read error conditions and fall thru) 1420 READ GOSUBLINE,DATALINE 1500 REM === ANSWER MATCHED === 1500 IF GOSUBLINE THEN GOSUB GOSUBLINE 1520 RESTORE DATALINE 1530 GOTO MAINLOOP 2000 REM === INEXACT MATCH ROUTINE === 2010 MATCH=0:ALEN=LEN(ANS$) 2020 SIZE=LEN(LINE$)-ALEN+1 2030 IF SIZE<1 THEN RETURN 2040 FOR CHAR=1 TO SIZE 2050 IF LINE$(CHAR,CHAR+ALEN-1)=ANS$ THEN MATCH=1:RETURN 2060 NEXT CHAR 2070 RETURN 2100 REM === EXACT MATCH ROUTINE === 2110 MATCH=(ANS$=LINE$) 2120 RETURN 1000 DATA ! READY to try out this program? 10001 DATA:(answer Y or N) 10002 DATA ?1=,Y,0,10010 10003 DATA 0,10000 10010 DATA !A tribute to Groucho Marx: 10011 DATA :who is buried in Grant's tomb? 10012 DATA ?2#,GRANT,0,10040 10013 DATA DUCK,10020,10030 10014 DATA 10050,10060 10020 REM special sound routine 10021 FOR FREQ=120 TO 20 STEP -10 10022 FOR VOLUME=15 TO 0 STEP -0.5 10023 SOUND 0,FREQ,10,VOLUME 10024 NEXT VOLUME:NEXT FREQ 10025 RETURN 10030 DATA !You said the secret word! 10031 DATA :You Win $100. 10032 DATA * 10040 DATA !Great! you get the consolation 10041 DATA .prize of $50. 10042 DATA * 10050 REM raspberry 10051 FOR VOLUME=15 TO 0 STEP -0.25 10052 SOUND 0,4,80,VOLUME:NEXT VOLUME 10053 RETURN 10060 DATA !Sorry. You lost. 10061 DATA *