Classic Computer Magazine Archive ANTIC VOL. 9, NO. 2 / JUNE 1990

BASIC Speedups Cleanups & Memory Boosters

Tips and tricks (some fairly drastic) for turbocharging your programs

Speed up your programs and streamline your code with these tips and hints for intermediate (and advanced beginner) BASIC programmers.

By Greg Vozzo

Atari BASIC (Beginner's All-Purpose Symbolic Instruction Code) is perhaps the most well-known and easy-to-use language available for the Atari. Its advantages include a versatile math package, English-related commands such as PRINT, GOTO, and REM, and good support of many external peripheral devices (disk drives, printers, monitors, etc.). For XL and XE owners, it has the distinct advantage of being built right into the computer. However, it has two notable disadvantages - it's slow, and programs take up a lot of space in memory. For many large projects, Atari BASIC is not the ideal language to work with. Still, there are ways to get programs to run faster and take up less memory.

You'll have to consider what your particular program needs, of course. Some of these tips have drawbacks, or may seem contradictory. Using variable names instead of often-used numerical constants saves memory space, but make the program slower. Some techniques used to save memory, such as removing REM statements or shortening variable names, for instance, can result in almost unreadable programs. Always work with backups, just in case something goes wrong while you're "improving" that special program.

Less Memory
Once you finish a program, there are ways to break it down to consume less memory. First, remove any REM statements. REMarks take up considerable space, and should not be needed once the program works properly. Make sure, however, that none of your GOTOs or GOSUBs branch to lines containing only REM statements - sloppy programming in any case. (If you plan to share your program with other programmers, or even submit it to Antic, it's a good idea to leave in at least a few REM statements to make customizing or debugging easier. - ANTIC ED)

Try putting as many statements as possible on a program line. Often, a programmer can compress two or more program lines into one this way. Some ways to do this are putting as many elements within a DATA statement as can be allowed by the computer and chaining PRINT statements together. Also, use ?, not PRINT. This doesn't save memory, but does save space on a program line.

You can also change IF...THEN GOTO/GOSUB's to ON...GOTO/GOSUB's. Lines like:

    110 PRINT A:IF A=2 THEN 1000
    120 IF A=1 THEN GOSUB 110 130 GOTO 20
can become:
    110 ? A:ON A=2 GOTO 1000:ON A GOSUB 110:GOTO 20

Put operations used several times in different places in the program in subroutines. Some examples of such operations are mathematical functions, FOR/NEXT loops that act as a pause, and statements that print a commonly-used message to the screen. However, avoid using subroutines that are only accessed once. Change them to in-line code.

Chain programs. A "loader" program could be used to set memory locations, display lists, character sets, interrupts, or perhaps a title screen, and then RUN the main program - erasing the loader from memory in the process.

Instead of using GOTO to go to the first line in the program, use RUN.

Don't use SETCOLOR to alter the screen color registers. Use an equivalent POKE command instead, determined with the following formula: SETCOLOR A,B,C equals POKE 708+A,B*16+C

Use variables in place of numerical constants used often by a program. Examples:

Keep the names of strings, variables, and arrays short.

If a lot of variables are set at the same point in a program, use READ/DATA to initialize them. For example:

    READ A,B,X,Y,NUM,PL,SHIP:DATA 0,1,14,8,10,1,5
Numerical constants take up a lot of memory. The following are some common situations in which a change can be made for the better.
    IF N=0...becomes IF NOT N...
    IF A>0...
    becomes IF A...
    IF X<>0...
    becomes IF X...
    ON A GOTO 100,200,300,400...
    becomes GOTO A*100
Use characters in place of decimal DATA when possible (if the number of elements in the DATA statement(s) is not small, and the numerical range used is 0-255). Allocate a string to read a whole line of such DATA with one simple command. Then, if necessary, use a FOR/NEXT loop to transfer the elements from the beginning of the string to the end.

If the elements applied to one-dimentional arrays fall between 0 and 255, replace the array with a string, as with the above tip.

Use strings in place of commonly-used text. Then, whenever it's necessary to print this text, just print the string.

Whenever possible, avoid using program-reserved memory space when storing flags, variables, and machine-language subroutines in unused memory. If a section of a RAM-resident character set is not being used, use that space. Page six (1536-1791) is always free. Finally, there are some sections of the DOS file management program (begins at memory location 1792) that may not be needed. See "Past Page Six" on page 90 of the April, 1984 issue of Antic for a list of these sections.

Use cursor control characters within text where possible in place of close-quotes and POSITION commands. This way, more space will be saved, and more text strings can be chained together.

Use this simplified format of a string if a large field is to be filled with the same character:
A$="X":A$(200)=A$:A$(2)=A$ This example fills the first 200 bytes in A$ with X's.

You can insert code into the program that will delete those lines and routines the program only uses once. This can be hazardous, and you must be sure to place the code so it will be executed after the lines to be deleted. This procedure is done with the forced-read method, described as follows:

Clear the text screen.

Along the left margin, display all of the line numbers that are to be deleted.

Reserve about three lines at the top of the screen.

At the bottom of your list, have printed: POKE 842,12:CONT (or replace CONT with a GOTO statement).

POSITION the cursor at the top left corner of the screen, and execute within the program: POKE 842,13:STOP

Repeat the procedure if more lines need to be deleted.

Finally, once you have observed all of these guidelines, LIST the program to disk, cassette, or RAMdisk. Type NEW, then ENTER the program back. Now SAVE it. This process clears the memory of any old variable names no longer in use. Since the process is a slow one, I recommend using a RAMdisk if you have one. (If you use DOS 2.5 with a 130XE computer, the file RAMDISK.COM will install one as drive 8).

Improving Speed
Many programs require speed, and with a relatively slow language like BASIC, maintaining speed can be difficult and crucial. Here are a few ways to get your BASIC program running faster:

Place the most crucial subroutines and loops at the beginning of the program. When BASIC looks for a line in a GOTO or GOSUB call, it starts at the top. By placing speed-dependent segments at the start, BASIC can spend less time looking for your code and more time executing it.

Turn off the screen display whenever possible. One way to do this is with POKE 559,0.

Use a RAMdisk, if you have one, for extra-fast storage and retrieval. This works both for data files and for programs you want to chain for less memory consumption.

Whenever possible, use POKE and PEEK equivalents for commands such as SETCOLOR, SOUND, STICK, STRIG, PADDLE, and PTRIG. ( COMPUTE!'s Mapping the Atari is an excellent source for such equivalents - see excerpts running in Antic August 1989 through December 1988/January 1990 issues. - ANTIC ED)

Mathematical operations tend to be slow. Make your mathematical functions as efficient as possible. Simplify complex functions wherever possible. One example is the exponent function (^). It can sometimes be replaced with a series of multiplications. For example, N^5 becomes N*N*N*N*N.

While variables are good for saving memory space, they slow down the program. Replace them with numerical constants, if possible.

Break down short FOR/NEXT loops into step-by-step code. For example:

    FOR I=0 to 3:SOUND I,0,0,0:NEXT I


    SOUND 0,0,0,0:SOUND 1,0,0,0:SOUND 2,0,0,0:SOUND 3,0,0,0

Store player-missile graphics in strings. Use a shorter display list, if possible. To do this, you must have a good understanding of what a display list is and how it works. Simply use and reuse lines of screen memory, and if any line of the display will never be used, skip over it with a blank scan line, or group of blank scan lines. This way, less processing is spent on the screen display, and the screen memory left over can be used for other purposes, such as alternate display lists and machine language subroutines.

One thing many programmers like to do is insert machine language subroutines (called with a USR command). These offer the maximum speed of the machine, and can be used in anything from interrupt generating to complicated, speedy, and precise graphics management. Their purposes are up to you.

Once your program is up to speed, recode it. Make it compact, clean, and fast. Discard anything unnecessary, and keep the different segments of code in an efficient arrangement, so that the speed-dependent code is at the program's beginning, and the code that doesn't rely on speed resides at the very end.

If you apply these techniques properly and neatly, you should end up with a shorter, faster, complete and error-free program. However, make sure the program works before you recode it. Once you remove all those REM statements and shorten all your variable names, for instance, you may find it hard to debug your own program!

Greg Vozzo is a longtime Atari 8-bit programmer from Brightwaters, New York.