No gossip to start with this month. Instead, let's start right off into a whole series of interesting tidbits (and even a few tidbytes).
Which Is It? GTIA Or CTIA?
Several articles have been written on how to tell whether you have a GTIA or CTIA in your system. Most of them suggest that you use a GRAPHICS 9 statement and observe the screen (it turns black with a GTIA, remains blue with a CTIA).
But suppose you want to write a program that takes advantage of all the capabilities of the GTIA. What does the poor user with only a CTIA do? If you are commercially clever, you will have your program sense which chip is in use and adapt itself accordingly. This program will enable you to do just that:
100 GRAPHICS 0 : REM ALWAYS USE THIS MODE 110 PRINT "NOW TESTING FOR CTIA VERSUS GTIA" 120 PRINT "================================" 130 POKE 559, 58 : POKE 53277, 2 : REM ENABLE PLAYERS 140 POKE 54279, 240 : REM USE ROM FOR PLAYER DATA 145 POKE 53248, 80 : REM CENTERED PLAYER 150 POKE 53278, 0 : REM CLEAR COLLISION REGISTERS 160 POKE 623, 65 : REM ENABLE GTIA, IF IT EXISTS 170 POKE 20, 0 180 IF PEEK(20)<2 THEN 180 190 POKE 623, 1 : REM DISABLE GTIA 200 POKE 559, 34 : POKE 53277, 0 : REM TURN OFF PLAYERS 210 FOR A = 53261 TO 53265 : POKE A, 0 : NEXT A : REM (AND PLAYER DATA) 220 IF PEEK(53252) THEN PRINT "SORRY, ONLY ACTIA" : GOTO 240 230 PRINT "AHA ! A GTIA." 240 END
First of all, to give credit where it is due, I should mention that I was inspired to try this by a remark I read in one of Craig Chamberlain's articles in the M.A.C.E. newsletter (Michigan Atari Computer Enthusiasts, in the Detroit area). Portions of that article were also reprinted recently in COMPUTE!.
But let's now discuss the program. First, we must explain why and how it works: there is no way to inquire of the chip itself which it is. Even the operating system does not know which is installed. But.... (There had to be a "but," or there wouldn't be this article.)
There are a few subtle differences between how the two chips view players and missiles. In particular, the GTIA doesn't believe that players can collide with "printed" characters, so it never reports such a collision. The CTIA, though, considers a character to be just another kind of COLORed (and SETCOLORed) display.
The first thing our listing does is insure that we have some mode zero characters on the screen (lines 100 - 120). Then we enable the player DMA and the players themselves (line 130). And we tell the chips that the player data memory is smack in the middle of the ROMs! (Why? To insure that lots of data bits will be on, forcing lots of collisions between the player and the playfield screen characters.)
With line 145, we place the player somewhere left of the center of the screen, insuring that it will collide with our printed message. Then, after clearing the collision registers (to insure that the later results will be valid), we enable the special modes of the GTIA (lines 150 and 160).
We wait for at least one full screen scan (lines 170 and 180), to be sur.e that the collision will "take" (if it's going to). Then we turn everything back off again (lines 190 - 210).
Finally, we inspect the collision register for player zero. If a collision did occur, it must be because the older CTIA was installed. If no collision occurred, we presume that we have a GTIA.
All of this is a little complicated, but I sincerely hope that some of you game developers out there will start designing some good GTIA-based games, now that you can have them modify themselves for the CTIA owner.
A Few Abbrev'd REMs. Period.
In his article on "The Atari Wedge" (in the November 1982 COMPUTE!), Charles Brannon mentions that BASIC treats a line beginning with a period as a REMark, claiming that it is a lucky fluke. Well, it really isn't a fluke. It's just one of those things that got designed into Atari BASIC and then forgotten about.
The rule for using abbreviations in Atari BASIC (and BASIC A +, naturally) is fairly simple: when a statement begins with an abbreviation (any alphabetic characters followed by a period), BASIC searches the keyword name table for the first statement name which matches the abbreviation, starting at the first character of the abbreviation and ending at the period.
This means, for example, that "L." will match "LIST" only because LIST is the first word in the keyword name table that begins with an "L". If "LET" had been placed before "LIST" in this table, then "L." would have been interpreted as a LET statement. Boy, aren't we lucky that LIST comes before LET!
Luck had nothing to do with it. The order of those keywords was carefully chosen to provide the maximum usability of the shortest abbreviations. (Actually, I now believe that there are a few variations in the order that might be more useful; but remember that the order was set by intuition, not experience, since the language didn't then actually exist.)
Anyway, Atari had asked for a very short abbreviation for REMark statements (e.g., "!", as is used by most Microsoft BASICs). But what could be shorter than a single period? It's even easier to use than "!" (no shift key needed). How to produce that result? Trivial! Place REM as the first statement name in the keyword table.
So try it sometime. Why type in three characters ("REM") when one will do? Of course, because of the tokenizing nature of Atari BASIC, any abbreviated statement(s) are LISTed in their full form. So "." will be LISTed as "REM".
And a P.S. for those of you into BASIC internals: note that this implies that the token value for REM must be zero, since the token values relate directly to the order of the names in the keyword table.
Page 6 Preached Again
I kind of promised myself that I would get down off my soap box this month and quit ranting and raving. But I couldn't go one whole column without a little preaching, could I?
Stay out of page 6! I can't believe it! It seems that every other article and/or utility program and/or device driver that I run across wants to place itself in page 6 (memory locations $600 to $6FF, 1536 to 1791 decimal). It won't work!
How can I possibly install a printer driver in page 6 and then put my player vertical move routine there and my disk block input and output and .... Ah, come on, folks. Give us a break.
If you are writing a complete "system" (a game, or data base program, or whatever), then you are naturally free to configure memory as you wish, including doing whatever you want to page 6. But if you are going to publish a utility in a magazine or include a device driver with your printer interface board or do anything that others might use or modify, please don't make it fixed-assembled in page 6. Please.
Besides, it is not true that BASIC leaves all of page 6 alone. If you do an INPUT from disk (or cassette or anything other than the screen), and if the data you input exceeds 128 bytes, BASIC will use at least a portion of page 6 as its buffer. (However, it is probably — not surely, just probably — safe to use memory from $680 to $6FF.)
A little history: If you examine your Atari BASIC reference, you will find that there are two memory usage tables. One claims that all of page 6 is available for the user. The other claims that only the upper half is available. In general, you should believe the latter. It is not a design flaw nor an error that BASIC sometimes uses the bottom half of page 6. It is necessary and documented.
I think it was someone at Atari (my rumor sources say Chris Crawford, but this is unconfirmed) who began using all of page 6 for assembly language routines. And, as I stated above, there is really nothing wrong with doing so within a "closed" environment (where you write all the software, both BASIC and assembler). Just don't do it for public consumption.
So what should you do, instead? The best solution is to write self-relocatable code and load it wherever there is free memory (e.g., in a BASIC string). (Showing how to write self-relocatable code might be an instructive article, in and of itself. Any takers?)
The second best solution is to perform my favorite trick: place your code at LOMEM and move LOMEM up. Even here, though, it is best to use relocatable code, so you can run under a variety of operating system configurations and varying heights of LOMEM (as I documented in last month's column).
And, last but not least, I have some good, practical (and a little bit selfish) reasons for avoiding page 6: BASIC A + uses a good portion of it ($610 through $642, actually). Does that make us a villain? Perhaps a little, to the article writers. But we aren't that terrible: I understand that Microsoft BASIC uses all of page 6. And who knows what other languages and operating systems and peripheral devices and whatever will also use page 6? Why complicate both your and others' lives by putting your routines there also?
Some FORTH-Right Comments
I received a very well written and thought-out letter from Steven Weston, of Del Mar, California, regarding the benchmarks I reported in my September 1982 column. Mr. Weston shares the predilections of some others, considering FORTH to have been slighted in that column (and in the following one, I presume).
First, I should like to report that he translated the BASIC benchmark to FORTH and obtained a time of a little under 118 seconds. Which is interesting, since ValFORTH (the version he used) makes use of the Atari floating point routines, I believe. So why should it be slower than Atari BASIC? If I were guessing (which means I'm about to take a flyer), I would presume that the floating point words for ValFORTH are written in FORTH words, instead of being written as low-level (assembly language) words. The very operation of stacking and unstacking the floating point numbers must then be relatively slow and painstaking.
If this is indeed true, then my comment is a positive one: the FORTH user indeed has the choice of implementing "commands" (words) either way, with other FORTH words or with assembly language. This flexibility is poorly supported by most other languages. (Although many C compiler implementations come close to having such accessible assembly code. C/65 functions, for example, need very little overhead in the assembly language code to "unstack" their parameters.) Want a faster FORTH instead of a smaller one? Recode some routines in assembly language.
What Benchmarks Really Test
Before going on to the second point of Mr. Weston's letter, I should like to note that I feel that perhaps he (and many other readers) missed part of the point of the benchmarks: I was really trying to show how useless any one benchmark is, since it is so easy to dream up benchmarks which show off the best features of a given language. I would be hard pressed to construct even a set of ten benchmarks which would adequately compare languages.
And even if I thought I succeeded, how much is the human interface to a language worth? PILOT is still the easiest language on the Atari to learn and interface to. By definition, it therefore out-benchmarks every other language for beginners. But would anyone seriously propose using PILOT for generating prime numbers? I think not. Benchmarks are usually worth the paper they are printed on and no more.
So now to Mr. Weston's second point. I quote: "...the bottom line on languages is to use that language which is best suited to the task. [With Atari BASIC] the lack of integer based math is a serious deficiency which can preclude its use by professional software authors." He goes on to ask why I don't provide a "toolbox" of integer math routines to be interfaced to Atari BASIC "instead of defending an inadequate situation."
Well. Kudos and jibes all in one it seems. Anyway, he is absolutely right: pick the language that fits the job instead of making the job fit the language. You will remember, I hope, that in a recent column I mentioned that I collect languages like some people collect games. I keep hoping to find one that will be useful to me.
But now let me disagree a little on a couple of points. And I do so because I have received too many comments in this same vein. (1) Integer math is not needed by all "professional software authors." The person writing a financial package needs integer math about as much as the game writer needs floating point. If you need integer math, choose a language which supports it. (2) BASIC is, unfortunately, a non-extensible language. Sure, we could put integer math routines in memory somewhere and use them from BASIC. But BASIC would still insist on thinking of its variables and constants as floating point, and the conversion time (from floating point to integer to floating point, ad nauseam) would wipe out all speed advantages gained. (3) I don't think Atari BASIC is an "inadequate situation." Sure, I think there are other solutions. Why else would our company produce languages such as BASIC A + and C/65 (and probably more to come)? But "inadequate"? I think not, if it is used for and how it was meant to be used. (If anything is inadequate, it is the 6502 microprocessor, which does not lend itself to the implementation of powerful language compilers.)
But, if you are a beginner, don't let anyone (including me) pressure you into trying to learn a new language before you are ready. It is true that you are not going to write "Super Invading Packers with Tronic Fighters" with Atari BASIC. But just look at what you can write! Ten years ago, a computer fanatic would have sacrificed his left thumb for what we now take for granted. Seven short years ago, the "hot" computer game that everybody was rewriting (to make it fit in their expanded memory 8K byte gigantic machine) was Wumpus. Today, I seldom see a published program that doesn't make Wumpus look like something out of the dark ages. Hang in there, folks, you ain't seen nuthin' yet.
The New BASIC Standard?
Well, I finally got time to take a long, hard look at the new ANSI BASIC specification. Whew! I think the tower of Babel must have seemed organized by comparison. Even ADA and PL/1 look like closely designed languages compared to ANSI BASIC. I think that the rule in designing it was "If someone wants it, let's put it in."
You certainly won't see any microcomputer interpreter implementations of it in the near future. I estimate it would take over 80K bytes of Z-80 code to do it (which translates to maybe 100K to 120K of 6502 code). It is definitely designed to be compiled, not interpreted, and then only by big machines.
The error descriptions alone would take a few kilobytes (and they are required!). And what do lines like the following mean?
MAT PRINT #N, SAME, IF THERE EXIT FOR: A$; B$, C ASK #3: access outin, organization org$, rectype internal, pointer p$
I am disappointed. I had hoped that the committee would distill the best of the various BASICs and come up with a somewhat enhanced version of the original ANSI standard BASIC. Instead, they seem to have distilled out the biggest features of the biggest BASICs they can find. And who will use the standard? Not the micros. (At least not in the near future. I understand that Microsoft's representative on the committee dropped out. From frustration? I would have.) Not those who need to contract with the government. (Soon, you will have to use ADA if you work with the defense department and various allied agencies.) Not the big business computer users. (They can't afford to go from COBOL, a clumsy but eminently maintainable language, to a BASIC as kludged up by the committee, with a lack of the data structures that made COBOL successful.)
I guess I believed that the only BASIC users that would be left in a few years would be the hobbyists and the time-sharing companies. Now, I think the only ANSI BASIC users will be the time-sharing companies. Maybe.
As much as I disagree with much of what Microsoft has done, I would rather have seen Microsoft BASIC (version 5, on the CP/M machines) become the standard than the hodgepodge the ANSI committee has selected. ANSI, on a scale of 10,1 give you a 2.
The New Atari Computers
Perhaps by the time you read this, the new Atari computers will be on display at the Consumer Electronics Show (early January, in Las Vegas). Don't expect any real surprises. I expect to hear of a 64K machine (with no software to take advantage of the extra 16K). And probably a low-end 16K machine.
Obviously, Atari needs to get in there and fight with Commodore, both on price and features. Price is easy. Features? Well, if Commodore follows through as they claim they will, it could be a tough fight. And I think the 400 replacement might outstrip the VIC-20. I guess I should note that I am not as much of an Atari loyalist as this paragraph makes me sound. It's just that I like a good, competitive race. The consumer is bound to win.
Oh, yes, one more thing. No more right-hand cartridge slot in the new machines. And no memory board slots at all. Ouch? I don't know. I hope there will be a good way to expand the new machines, but we will all have to wait to see what it is.
All this talk about benchmarks and ANSI BASIC has made me regain interest in a project I thought of doing a while back. So, starting next month, we will begin writing a BASIC interpreter right here in this column. And we will write it in BASIC. Interested? I am.