Classic Computer Magazine Archive Article from Atari Classics magazine

Besting Basic
    Back in the days of Analog and Antic, I wrote an article for publication. After a couple of rewrites, program revisions, and spell checks, I finally sent it off to Antic. It must have been fate, but that was the month they closed up shop! I never did see my article in print.
    Now with AC, I am again going to submit an article about using BASIC. If there are programmers out there who are still using the BASIC language, you may already know the tricks I am about to reveal. If not, you may look forward to adding a touch of professionalism to your BASIC programs with this article.

POWER TO THE PEOPLE
    With only a few alterations to RAM memory, you have the power to move data from anywhere in memory to any other RAM address, at amazing speeds! The program that follows will show you how to move the Atari character set to RAM, achieve the fastest screen printing speed available using only BASIC, and give you an idea about how to use this speed for character and/or player/missile animations.

ONE MOMENT PLEASE!
    No doubt you have seen a few BASIC programs that have you wait an awful long "moment" while the program does a few initialization procedures. Using the following technique, you can have your new character set in place and ready for use, in about one half second. Go ahead, if your going to, type it in now and give it a try. Be sure to time the initial interval between the time you enter RUN, and the time you see "The new font is ready." on the screen.

PROGRAM OUTLINE
    This program demonstrates a method of animation by placing different frames of an animated sequence, into memory normally used by one of the characters. To do this, the program first copies the internal character set from ROM, where it cannot be changed, to RAM, where it can be modified. It then uses a quick printing method to display a little demo window where the animation will occur, and finally loops indefinitely to animate one of the characters. As you will see, moving data, fast printing, and animation all use strings.

DOWN TO BUSINESS
    BASIC supports the use of strings quite well. To use the strings, BASIC has to know where they are in memory, how big they are, and how much space they use. Atari conveniently kept all this information grouped together in one table of data called the Variable Value Table. This table is kept in RAM, within reach of any application programmer! By altering data in this table, the programmer can change the address or the length of a string, as may be needed by the application.
    In the Variable Value Table, 8 bytes are reserved for each variable used in a BASIC program. One byte determines the type of variable, another the location of its name, two more each for the location, size, and dimensioned length. The table is formed as new variables are added to the program, so DIMensioning the strings first, puts them at the start of the table and makes them easier to find.

INITIAL SETUP Lines 0-60
    Because the strings will be used under program control, the DIM statement on line 10 is used simply to set the order of the variables in the table. The size of both SRC$ and DST$ will be changed as needed, there is no need to reserve space for them. PLR$ will hold the data for the character animation, so it does need to have space reserved.
    Line 20 sets up a new display list and eliminates the cursor.
    The address of the table is calculated on line 30. This is the address of the first byte of the 8 bytes reserved for the first variable in the program. The 8 bytes for the second begin after the first group, the 8 bytes for the third variable follow after the second, etc.

PLUCKING THE STRINGS
    The address of a string is actually calculated from the beginning of array space. This means the value stored in the table is an offset, not an actual address of the variable. The start of array space is stored in another pointer (STARP), and this value is retrieved on line 40. Adding the offset value to STARP will produce the actual address of the start of the string.
    The address of the ROM font is found using the pointer for the current font on line 50. The computer uses this address to find the start of the character set. If it is changed, then the computer will display characters according to the data found at the new address. There is no LSB for this pointer because the OS demands that any font must begin at an address divisible by 1024. Any address divisible by 1024 will have a LSB of 0 so no LSB is necessary. The program finds such an address by using the MSB of the display list, on line 60. With the above values calculated, the program is ready to begin moving the font data out of ROM and into RAM.

MOVING IN Lines 100-180
    Because the location pointer in the table is an offset, TEMP is used to determine what value, when added to STARP, will cause a string to reside at the FONT address. The font address is known, and STARP is known, to find the offset (or difference) is a simple calculation, as shown on line 100. TEMP is then broken into the LSB/MSB format in a subroutine at line 9000, and these values are loaded into the table on line 110. Line 120 alters the current length and dimensioned size of the variable by POKEing a 4 into the MSB of the values stored in the table. Because the program is altering values in the first group, the changes made will affect the first variable in the list. It now appears to the computer that SRC$ resides in ROM and has a length of 1024 bytes (4*256).
    As with SRC$, the table is adjusted to make DST$ appear to reside at the address calculated for the new font (DEST) in lines 130-150.
    Line 160 commands the computer to move the contents of SRC$ into DST$. SRC$ is the ROM font set, DST$ is where the new font will go. One command and ZIP! its done. The computer is then told to display the new font by POKEing the MSB of DEST into the current font pointer.
    Lines 170 and 180 inform the user that the move is completed. Line 190 moves the first 8 bytes of the character set, into the next set of 8 bytes. This simply moves the data for the space character, into the area for the character that will be animated.

SPRINTING Lines 200-280
    Using TEMP again to alter the address of SRC$, lines 200-220 make SRC$ appear to reside at the same address as screen memory.
    The computer does not use the ATASCII characters in screen memory. It uses internal values to represent ATASCII characters. Why? I dunno, ask Atari! (Also check why they used offsets in the value table.... ) Lines 230-280 assign SRC$ with ATASCII representations of the internal characters needed to produce the demo window. After a bit of use, trial and error, and other such sophisticated techniques, finding the right characters to use is not a big problem. In fact, lower case letters translate exactly. If lower case text is desired, then SRC$ may be assigned the same lower case letters needed for display. This program uses the CHR$ function to get characters into SRC$. I much rather prefer assignments; however, doing so would mean the printer for AC has to produce graphic characters for the program listing. I chose to leave out any graphic characters to give the printer a break. When using this method for printing, the SRC$="......" type of command works well, and will happen much faster than a PRINT statement could produce. After the program is typed in and RUN nnrp you ran experiment with SRC$ which will still be pointing to the screen.

    Example:
    SRC$(100)="Hello world."

GOING UP Lines 300-360
    Lines 300-310 assign PLR$ with values needed to animate one of the characters. DST$ is still at the new font location, so making changes to DST$ will affect the new character set. You should take note that DST$ could just as easily point to a PM image table to create PM images that move up, or down, or are animated. Line 330 does the actual assignment, while TEMP is used to cycle thru the various changes needed to animate the character. The SIN calculation is used simply as a delay, the statement LO=1 ^1 will produce an even longer delay, or remove it entirely to see the animation happen quicker.

EMULATIONS
    Other uses are possible, such as loading arrays with formatted data (SIN/COS data), fast sound routines, bit mapped manipulation or any routines where there is a need to move data from one memory address to another. I did not cover how the computer handles arrays, or ordinary (numeric) variables, but these are also in the variable value table, each one added as it is entered into the program. Feel free to experiment on your own, use the following table as a guide:

VARIABLE VALUE TABLE:
(134,135)

Byte Description Of 8 Byte Entry
 0     Defines the type of variable
 1     Locates the name in the Variable Name Table (132,133)
 2     (LSB) Offset from STARP
 3     (MSB) Offset from STARP
 4     (LSB) Current length
 5     (MSB) Current length
 6     (LSB) Dimensioned length
 7     (MSB) Dimensioned length


BASIC Listing
1 REM **********************
2 REM * FAST DATA MOVEMENT
3 REM *         by
4 REM *   Larry Serflaten
5 REM *    For: AC 1995
6 REM **********************
10 DIM SRC$(1),DST$(1),PLR$(16)
20 GRAPHICS 0:POKE 752,1:? " "
30 VVTP=PEEK(134)+PEEK(135)*256
40 STARP=PEEK(140)+PEEK(141)*256
50 FONT=PEEK(756)*256
60 DEST=(((PEEK(561)/4)-1)*4)*256
100 TEMP=FONT-STARP:GOSUB 9000
110 POKE VVTP+2,LO:POKE VVTP+3,HI
120 POKE VVTP+5,4:POKE VVTP+7,4
130 TEMP=DEST-STARP:GOSUB 9000
140 POKE VVTP+l0,LO:POKE VVTP+11,HI
150 POKE VVTP+13,4:POKE VVTP+15,4
160 DST$=SRC$:POKE 756,DEST/256
170 POSITION 9,20
180 ? "The new font is ready."
190 DST$(9,16)=DST$
200 TEMP=PEEK(88)+PEEK(89)*256
210 TEMP=TEMP-STARP:GOSUB 9000
220 POKE VVTP+2,LO:POKE VVTP+3,HI
230 SRC$(125,125)=CHR$(128)
240 SRC$(126,155)=SRC$(125)
250 SRC$(685,715)=SRC$(125)
260 SRC$(165,165)=CHR$(1)
270 SRC$(166,195)=SRC$(165)
280 SRC$(205,675)=SRC$(165)
300 FOR I=1 TO 15:READ A
310 PLR$(I,I)=CHR$(A):NEXT I
320 TEMP=1
330 DST$(9,16)=PLR$(TEMP)
340 TEMP=TEMP+1:LO=SIN(l)
350 IF TEMP>8 THEN 320
360 GOTO 330
8000 END
9000 HI=INT(TEMP/256)
9010 LO=TEMP-(HI*256)
9020 RETURN
9998 DATA 0,0,48,48,0,0,3,3
9999 DATA 0,0,48,48,0,0,3