Super Text Mode
After a program is written and debugged, it should be cleaned and polished. When you think of all the work you did to get it working, the least you can do is mount it well--and that entails making it look and run right.
The first display a program generates is supremely important, as it sets the tone for all that is to follow. If you have been wanting a professional quality title card to distinguish your programs, here is a routine that will fill the bill. It can be tailored to display your message in a large, custom font, and then to cycle through a veritable rainbow of color. From there, another message can flash into the text window. After the title card has cycled fully, the rest of your program will execute.
Programs that plot and fill character sets into a non-text mode (in this case graphics 7) have appeared in Byte, and Compute! over the past two years. The routine that follows has some new features, and allows you to create your own, customized displays with a minimum of fuss.
If you are short on memory for a specific application, or don't have a disk drive, you might not want to commit many lines of Basic to the likes of this routine. However if you have a disk, the program can run as a separate file, invoking your main program file as its final act. It takes about 50 sectors on disk, and is well worth every bit of that space.
The routine appears in Listing 1. I have left the code relatively free of REM statements to conserve memory. If typed in exactly as shown, the program will display the letters A through U on the screen, cycle through the rainbow and text window displays, and then start all over. In order to display letters V through Z, change line 120 to RESTORE 862. This will at least give you a view of all the letters in the font, so you can ensure that the program has been entered correctly. The only reason the alphabet has been split in this manner is because the screen is capable of displaying only three rows of seven characters at one time.
The program breaks down as follows:
Line 10 initializes, while POKE statements suppress the cursor and move the margins out to 40 columns. It also invokes two subroutines: the first reads machine language data into a string which will then execute the rainbow segment from a USR call in line 30. The second subroutine reads data which define the placement and choice of characters.
Lines 50 through 70 constitute the secondary message, which will appear in the text window. There is no reason why this font, which is in graphics 0, could not be modified, perhaps along the lines of the program that appeared in the Upstart Atari article (see pages 135-138).
Line 80 creates a pregnant pause, then starts the whole procedure over again. Before it does so, however, it POKES the attract mode into operation. You may or may not like the effect this creates, but the command shows that color background capability is there. This is also the line from which the rest of another program would take off.
Lines 130 through 230 are really the heart of the program, and exemplify a powerful and efficient manner of reading plotting (as well as other) information from an upcoming series of DATA statements. This handsome approach has appeared in Compute!, though I have improved upon it here.
Briefly, the following happens when reading DATA statements: if preceded by a P, upcoming data pertains to plotting. Read the numbers, PLOT and DRAWTO as necessary.
If preceded by an R, the following data will indicate where the plot should begin (always at the 0,0 point of any letter). These numbers always occur at the outset of a letter plot, and must be manipulated by the user in order to ensure correct placement. The font is "proportionally spaced"; for example, an I is narrower than an M, and care must be taken to lay out words so that spacing between letters is pleasing. Shades of art direction! The first number is the vertical coordinate, the second the horizontal. And remember, the Atari does not use the Cartesian coordinate system, but rather places 0,0 at the upper left-hand corner.
If preceded by an S, the data pertain to sound statements. Thus the user can create a tone for each letter, building into and moving between chords, if so desired, by cycling voices. The first number indicates which voice to use, the second what pitch. I worked exclusively with pure tone (10). By altering the distortion value in line 160, you can experiment with sound effects.
The next data identifier may seem a bit mysterious, as it is not used in the demonstration version of the program. It is a dummy identifier, placed there only for possible use as a time delay. As certain letters require fewer steps to draw than others (I as opposed to S, for example, they will plot much more quickly. By padding the DATA statements for the letter I with D's, you would be able to even out its plot time, to create a truly professional-looking display.
If preceded by a letter F, the numbers indicate a following fill statement. These ensure that the insides of each character will be delineated from the outside, so that the rainbow can then well up from within. And if the word END is encountered, the job of this section of code is terminated.
What follows are the somewhat lengthy DATA statements themselves. "Why the jump from line number 230 to 650?" the more observant Atarians out there may ask. "Well, for a good reason," I respond. The line numbers that initiate each letter correspond exactly to their ATASCI code times 10.
An observant but somewhat slower subgroup might ask as a follow-up, "so what?" Well I'm glad you asked that question. In a subsequent version of this program, (which I haven't yet written because I am hoping one of you will do it for me), the user will be able to input an entire message into a character string, and through the use of techniques outlined in Self Modifying Programs (pages 138-140), the program will then modify itself into the specific message, deleting all extraneous material.
A hint at a possible approach: 1) find out what letter the user wants, 2) LIST CHR$ (user's letter) *10+2, give it a new line number (how about that gap between lines 230 and 650), then re-enter the line. Do this for +4, +6, and +8, and you will have the entire letter re-entered. Preset R (origin) and S (sound) values that the user can fiddle with later. There will be plenty of time for that, what with the time saved not having to edit the whole thing by hand. Then have the program automatically delete lines 650 through 904 completely. Voila, a custom title card, in minimal memory!
Want to learn more about how your disk drives work? Need a way to retrieve data from crashed disks? Want to look at and alter disk information sector by sector? Interested in backing up your disks? If your answer to any of these questions is yes, you are a candidate for a disk utility package.
Every time I have been about ready to write something on disk utilities, another package makes its appearance. The latest I have had a chance to become acquainted with is Diskey from Adventure International. This packs the most features I have yet seen in a disk utility, and is accompanied by a rare bonus: sparkling, well-written documentation by the software author himself. The tutorial value of the manual alone makes the package worthwhile.
But just wait until you see the software. Disk maps are presented simultaneously in hexadecimal and ASCII format. The software allows for sector-by-sector data examination and alteration. It provides tools by which to salvage damaged disks. It provides functions to compare, copy, reformat, search, create disk files from tape autoboot files, erase (write zeros), disable verify, calibrate drive speed, and manipulate disk directories as well as DOS files.
Another unique function of Diskey is its ability to flag "dead" disk sectors. This is a capability previously unavailable in any disk utility I have seen. Though the potential for misuse is there, author Sparky Starks stops short of spelling out a means to write bad sectors. He states strongly in the manual foreword his equation of software pirates with common thieves.
As a learning tool, Diskey is superlative. The documentation and software work in tandem to provide the most solid disk tutorial you can find anywhere. And, hard as it may seem to imagine, even the driest stuff is presented in a fresh, almost breezy manner.
Diskey is more than a professional utility: it is obviously a labor of love. There are many more features in the software than would have been necessary to create a salable package. For over 50 reasons (the product has over 50 separate commands), Diskey very quickly attained a preeminent position in my utilities box. How about an assembly language tutorial, Mr. Starks?
Obviously, you must have a disk drive to run the package; in addition, you must have at least 32K and Atari Basic. The system is optimally configured, however, with a 48K system, two drives, and an 80-column printer like the Atari 825.
The package lists for $49.95. For more information, contact Adventure International, Box 3435, Longwood Fl., 32750. (305) 830-8194.
This part of the column was initiated as an attempt to respond to the many questions we have received at the magazine concerning Atari memory map locations, and ways of "tweaking" them.
I have at least three letters from Atari Basic hobbyists, all asking the same question: how can Basic programs be made unlistable? First of all, let me go on record as one of the category of folks who believe in keeping things listable wherever and whenever it is feasible to do so. The problem of code theft is not nearly as acute in Basic as it is in machine language, nor is that diehard pirate going to be deterred by the mere fact that a program is unlistable in its usual environment. My feeling is, in the spirit of enlightenment, if other people stand to learn something from a bit of my code, more power to them.
That disclaimer having been duly filed, let's look at the only tried, true, and simple method I have seen to help protect your precious Basic files from prying eyes.
Most approaches I have seen to rendering Basic programs unlistable are unsatisfactory. In my Upstart Atari article, I noted the memory locations you can alter to disable the BREAK key (see Poking Around, pp. 137-138). (A quick aside-a couple of folks wrote in telling me they experienced problems disabling BREAK. The POKE commands must be reasserted often. For instance, POKE again after every graphics mode command. If you put enough sets of them in your program or stick them in the right places in the main loops, you will effectively disable the key.)
I have not found a way to disable the RESET key, but with the command POKE 580,1 you can make the key into a "true" reset: that is, pressing the key will initiate a cold start, as if the system has been powered down and up again. This will flush any resident program from memory. To return to the normal RESET mode, POKE 581,1.
The trouble with merely disabling these keys is that the program can still be listed before it is ever run. Still another approach I have seen converts program listings into control characters or variables into carriage returns. Likewise, the fixes do not become operative until the programs are run. If the user asks for a LIST directly after loading, a full listing will be obtained.
How then, to protect a program before it can be listed? The answer lies in the creation of a "RUN only" file. This type of file can not be LOADed or ENTERed, nor can it ever be LISTed. It executes perfectly in every other respect, but can only be invoked with the command RUN"D:FILENAME", (or RUN "C:" if you are using a cassette-based system). In order to create such a file, append the following line:
It does not matter if the line is at any time executed by the main program; the code therefore remains unaffected in any way. It is imperative, however, that the line be the chronologically last line of code. When you are ready to protect a program (that is, do not intend to alter it any further), type this line with a higher line number than any other in the program, choose a filename, than GOTO the line. Listing 2 is a working example.
That is all there is to the technique: "RUN only" files can be simply generated to disk or tape. Attempts to do anything other than RUN will result in a nasty case of system lock-up. And yes, even autorun files can be protected in this manner.
Well, we have finally managed to confirm the existence of the Atari 600, and have heard that at least two Atari plants are currently tooling up to produce them. The 600, as its model number implies, will fill the gap between the Atari 400 and 800., It was rumored that the machine would be unveiled at the Winter CES in Las Vegas. It will sport 48K standard, and a full-stroke keyboard. Owners of 400s and 800s need harbor no fears of obsolescence: the 600 will be completely compatible with its predecessors.
Many Atari types are awaiting with curiosity the final verdict on the Commodore 64, which features graphics, sound, and gaming capilities very much akin to those of Atari computers. Atari has, in the meantime, added to its busy legal docket a suit against Commodore, concerning the design implementation of Commodore joysticks, which are for use with the VIC-20 and all latest generation machines. It seems the sticks are not only Atari-compatible, but nearly identical in many respects.
Atari, which patented its stick when the VCS was first introduced in 1977 and improved the design several times since, claims patent infringement. The Atari joystick connector has set an informal design standard in the industry. The Colecovision videogame uses an Atari-compatible format, and it was rumored that the new microcomputer, to be released by Apple this year will also make use of Atari-compatible digital sticks. But compatibility and patent infringement are two separate concepts.
While we're on the topic of joysticks, let me tell you about two hot sticks we've been playtesting. The first is the Pointmaster joystick. This stick has an extra long handle with built-in grip and handle-mounted trigger button, making it perfect for "flyer" games like Star Raiders and Protector II. The stick is very much like the one in the stand-up arcade version of Zaxxon, and once you play a few games of Raiders with it, you won't want to use anything else. Conversely, the stick is cumbersome in maze games like Jawbreaker or MBAFAS ("move back and forth and shoot") games like Threshold. Still, at $17.95, it offers a real boost to your "flyer" game collection.
For more information, contact Discwasher, 1407 North Providence Road, Columbia, MO, 65201. (314) 4490941.
The other sticks we looked at, called Game Mate 2, are pretty nearly regulation Atari sticks, with one big difference: they are wireless, and work by remote control. My main fear was that there would be a time lag between the movement of my hand and what I saw on the screen. I experienced no such sensation--the sticks seemed as fast as any I had ever tried. My only reservation is their size. They are quite bulky, and take a while to get used to.
With the VCS, the console power supply plugs into the Game Mate receiver unit, and then into the VCS console. For the 400 and 800 computers, however, an additional 9-volt power supply is a necessary purchase. Each stick also takes a 9-volt transistor battery. The units operate at distances of up to 20'.
Complete with receiver and two sticks, Game Mate 2 lists for $99.95, but I have already seen this price substantially discounted. If the luxury of wireless sticks is appealing to you, this product will assuredly not disappoint.
For more information, contact Cynex Manufacturing Corporation, 28 Sager P1., Hillside, NJ, 07205. (201) 399-3334.
Smoothly we seque from sticks to the games played with them. We have confirmed 400/800 versions of Galaxian and Defender in ROM form from Atari. Both games are spin-offs from the new 5200 model videogame. The 5200 may yet prove to be a boon to owners of Atari computer systems, if it spurs game development common to all machines. Galaxian has already been demonstrated, and is a solid implementation. One can only hope that Defender will be up to snuff.
Datasoft also has an ambitious project on its drawing boards right now: Zaxxon for the Atari. We can't wait.
I must admit it: when I first heard that Big Five Software was releasing a game for Atari, I sort of chuckled. Somehow I assumed that because Miner 2049'er was from one of the best TRS-80 game houses, it would probably run in graphics 5. Did I make a mistake. Miner 2049'er, in ROM cartridge format, is bound to be one of the runaway hits of the year. With superlative graphics, humor, and 10 completely different screens to master, the game leaves Colecovision's Donkey Kong pale by comparison.
10 CLR :POKE 752,1:DIM D$(3),C$(32):TIME=10:POKE 82,0:GOSUB 1000:GOSUB 100 20 C$(15,15)=CHR$(33) 30 X=USR(ADR(C$),TIME) 40 GRAPHICS 7+32:POKE 752,1:SETCOLOR 2,0,0 50 ? "--------------------------------------" 60 ? "--OUTPOST ATARI---CREATIVE COMPUTING--" 70 ? "--------------------------------------" 80 FOR I=1 TO 2500:NEXT I:POKE 77,254:GOTO 10 90 REM BRANCH HERE TO REST OF CODE 100 GRAPHICS 23:SETCOLOR 0,0,0:SETCOLOR 1,0,14:SETCOLOR 2,0,0:SETCOLOR 4,0,0 110 COLOR 2:FCOLOR=1 120 RESTORE 650 130 READ D$:IF ASC(D$)<64 THEN 220 140 IF D$="P" THEN READ ROW,COLUMN:GOSUB 230:PLOT COLUMN,ROW:GOTO 130 150 IF D$="R" THEN READ RORIGIN,CORIGIN:GOTO 130 160 IF D$="S" THEN READ VOICE,PITCH:SOUND VOICE,PITCH,10,6:GOTO 130 170 IF D$="D" THEN 130 180 IF D$="END" THEN RETURN 190 IF D$<>"F" THEN GOTO 130 200 READ ROW,COLUMN:GOSUB 230:POSITION COLUMN,ROW:POKE 765,FCOLOR 210 XIO 18,#6,0,0,"S:":PLOT COLUMN,ROW:GOTO 130 220 ROW=VAL(D$):READ COLUMN:GOSUB 230:DRAWTO COLUMN,ROW:GOTO 130 230 ROW=ROW+RORIGIN:COLUMN=COLUMN+CORIGIN:RETURN 650 REM "A"---------------------------- 652 DATA R,0,0,S,0,1 654 DATA P,2,7,2,13,4,16,6,18,8,19,25,19,25,13,F,19,13,P,6,9,F,6,11,F,7,12,F,8,13,F,13,13,13,7 656 DATA 8,7,7,8,6,9,P,19,13,19,7,25,7,25,1,F,8,1,F,6,2,F,4,4,F,2,7,2,13,P,13,7,8,7,7,8,6,9 660 REM "B"---------------------------- 662 DATA R,0,22,S,1,7 664 DATA P,2,1,2,13,4,16,6,18,8,19,10,19,12,17,13,15,15,17,17,19,21,19,23,17,25,15,25,1 666 DATA P,6,7,F,6,11,F,8,13,F,10,11,10,7,6,7,P,15,7,F,15,11,F,18,13,F,20,11,20,7,16,7,P,25,1,F,2,1 670 REM "C"---------------------------- 672 DATA R,0,44,S,2,11 674 DATA P,2,7,2,13,4,16,6,18,8,19,8,13,F,6,11,F,6,9,8,7,19,7,21,9,P,19,19,21,19,23,16,25,13 676 DATA P,21,9,F,21,11,F,19,13,19,19,P,25,13,25,7,F,23,4,F,21,2,F,19,1,F,8,1,F,6,2,F,4,4,F,2,7 680 REM "D"---------------------------- 682 DATA R,0,66,S,3,13 684 DATA P,2,1,2,13,4,16,6,18,8,19,17,19,21,19,23,17,25,15,25,1,P,6,7,F,6,11,F,8,13,F,18,13,F,20,11,20,7,6,7 686 DATA P,25,1,F,2,1 690 REM "E"---------------------------- 692 DATA R,0,88,S,0,15 694 DATA P,2,1,2,19,8,19,8,7,11,7,11,15,16,15,16,7,19,7,19,19,25,19,25,1,F,2,1 700 REM "F"---------------------------- 702 DATA R,0,110,S,1,18 704 DATA P,2,1,2,19,8,19,8,7,11,7,11,15,16,15,16,7,25,7,25,1,F,2,1 710 REM "GÓ---------------------------- 712 DATA R,0,132,S,2,23 714 DATA P,2,7,2,13,4,16,6,18,8,19,8,13,F,6,11,F,6,9,8,7,19,7,21,9,P,19,19,21,19,23,16,25,13 716 DATA P,18,19,14,19,14,11,F,18,11,F,18,13,F,19,13,F,21,11,21,9 718 DATA P,25,13,25,7,F,23,4,F,21,2,F,19,1,F,8,1,F,6,2,F,4,4,F,2,7 720 REM "H"---------------------------- 722 DATA R,25,0,S,3,28 724 DATA P,2,13,2,19,25,19,25,13,F,16,13,P,2,7,11,7,F,11,13,F,2,13,P,16,13,16,7,25,7,25,1,F,2,1,2,7 730 REM "I"---------------------------- 732 DATA R,25,28,S,0,31 734 DATA P,2,1,2,7,25,7,25,1,F,2,1 740 REM "J"---------------------------- 742 DATA R,25,44,S,1,38 744 DATA P,2,13,2,19,20,19,21,18,23,16,25,13,25,7,P,2,13,F,18,13,F,20,12,F,21,9,19,7,F 746 DATA 19,1,F,20,1,F,22,2,F,23,4,F,25,7 750 REM "K"---------------------------- 752 DATA R,25,66,S,2,42 754 DATA P,2,1,2,7,11,7,P,19,19,13,14,8,19,2,19,2,13,F,8,13,F,11,7,P,19,19,25,19,25,13,F,19,13,F,16,7,25,7 756 DATA 25,1,F,2,1 760 REM "L"---------------------------- 762 DATA R,25,88,S,3,47 764 DATA P,2,1,2,7,19,7,19,19,25,19,25,1,F,2,1 770 REM "M"---------------------------- 772 DATA R,25,110,S,0,57 774 DATA P,2,1,2,7,5,10,2,13,2,19,25,19,25,13,F,10,13,13,10,F,10,7,25,7,25,1,F,2,1,2,7,6,10,F,4,11,F,3,12,F,2,13 780 REM "M"---------------------------- 782 DATA R,25,132,S,1,63 784 DATA P,2,1,2,7,8,13,2,13,2,19,25,19,25,13,F,19,13,F,13,7,25,7,F,25,1,F,2,1,2,7,9,13,F,2,13 790 REM "O"---------------------------- 792 DATA R,50,0,S,2,76 794 DATA P,2,7,2,13,4,16,6,18,8,19,19,19,21,18,23,16,25,13,P,8,7,6,9,F,6,11,F,8,13,F,19,13,F,21,11,21,9,19,7,8,7 796 DATA P,25,13,25,7,F,23,4,F,21,2,F,19,1,F,8,1,F,6,2,F,4,4,F,2,7 800 REM "P"---------------------------- 802 DATA R,50,22,S,3,86 804 DATA P,2,1,2,13,4,16,6,18,8,19,13,19,15,18,17,16,19,13,P,6,9,F,6,11,F,7,12,F,8,13,F,13,13,13,7 806 DATA 8,7,7,8,6,9,P,19,13,19,7,25,7,25,1,F,2,1 810 REM "Q"---------------------------- 812 DATA R,50,44,S,0,96 814 DATA P,2,7,2,13,4,16,6,18,8,19,19,19,21,18,23,16,P,8,7,6,9,F,6,11,F,8,13,F,19,13,F,21,11,21,9,19,7,8,7 816 DATA P,23,16,27,19,29,16,F,25,13,F,25,7,F,23,4,F,21,2,F,19,1,F,8,1,F,6,2,F,4,4,F,2,7 820 REM "R"---------------------------- 822 DATA R,50,66,S,1,103 824 DATA P,2,1,2,13,4,16,6,18,8,19,10,19,12,17,13,15,15,17,17,19,25,19,25,13 826 DATA P,6,7,F,6,11,F,8,13,F,10,11,F,10,7,6,7 828 DATA P,25,13,F,22,13,F,19,12,F,18,9,18,7,25,7,25,1,F,2,1 830 REM "S"---------------------------- 832 DATA R,50,88,S,2,115 834 DATA P,2,7,2,13,4,16,6,18,8,19,8,13,F,6,11,6,9,8,7,10,9,10,13,12,16,14,18,16,19 836 DATA 19,19,21,18,23,16,25,13,25,7,P,17,7,19,9,F,19,11,F,17,13,F,15,11,F,15,9 838 DATA P,25,13,F,25,7,F,23,4,F,21,2,F,19,1,F,17,1,17,7,P,15,9,F,14,7,F,12,4,F,10,2,F,8,1,F,6,2,F,4,4,F,2,7 840 REM "T"---------------------------- 842 DATA R,50,110,S,3,128 844 DATA P,2,1,2,19,8,19,8,13,25,13,25,7,F,8,7,8,1,F,2,1 850 REM "U"---------------------------- 852 DATA R,50,132,S,0,146 854 DATA P,2,13,2,19,19,19,21,18,23,16,25,13,25,7 856 DATA P,2,19,2,13,19,13,F,21,11,21,9,19,7,2,7,2,1,P,25,7,F,23,4,F,21,2,F,19,1,F,2,1 858 DATA P,20,13,F,2,13 859 END 860 REM "V"---------------------------- 862 DATA R,35,25,S,0,153 864 DATA P,2,1,2,7,14,7,16,9,16,11,14,13,2,13,2,19,17,19,25,11,F,25,9,F,17,1,F,2,1 866 DATA P,16,9,F,16,11,F,14,13,F,2,13 870 REM "W"---------------------------- 872 DATA R,35,47,S,1,172 874 DATA P,2,1,2,7,19,7,16,10,19,13,2,13,2,19,25,19,25,13,F,22,10,25,7,25,1,F,2,1 876 DATA P,16,10,F,19,7,P,2,13,F,19,13 880 REM "X"---------------------------- 882 DATA R,35,69,S,2,191 884 DATA P,2,1,2,7,9,10,2,13,2,19,8,19,13,15,19,19,25,19,25,13,F,18,10,25,7,25,1,F,18,1,F,13,5,F,8,1,F,2,1 886 DATA P,10,10,F,2,13 890 REM "Y"---------------------------- 892 DATA R,35,91,S,3,205 894 DATA P,2,1,2,7,9,10,2,13,2,19,8,19,13,15,16,13,25,13,25,7,F,16,7,F,13,5,F,8,1,F,2,1 896 DATA P,10,10,F,2,13 900 REM "Z"---------------------------- 902 DATA R,35,113,S,0,255 904 DATA P,2,1,2,19,8,19,19,10,19,19,25,19,25,1,F,19,1,F,8,10,8,1,F,2,1 1000 DATA END 1010 RESTORE 1040 1020 FOR I=1 TO 32:READ C:C$(I)=CHR$(C):NEXT I 1030 RETURN 1040 DATA 104,104,104,72,162,57,160,0,173,0,210,101,20,141,22,208,141,10,212,136,208,242,202,208,237,104 1050 DATA 56,233,1,208,228,96
10 ? "THIS PROGRAM IS UNLISTABLE" 20 ? "EVER THOUGH THE RESET ADN" 30 ? "BREAK KEYS REMAIN ENABLED." 40 ? 50 ? "TRY IT!" 60 FOR X=1 TO 1000:NEXT X 70 GRAPHICS 0:GOTO 10 80 REM REMEMBER TO "GOTO 10000" 90 REM TO SAVE THE UNLISTABLE FILE! 10000 POKE PEEK(138)+256*PEEK(139)+2,0:SAVE "D:OUTPOST":NEW
John Anderson is an associate editor for Creative Computing magazine.