MANIPULATING STRINGS
More power and speed from BASICby BRIAN WEISS
Learn how to manipulate the Variable Name Table and Variable Value table in your BASIC programs. Professional programmers use these powerful techniques to add speed and variety to their code. The BASIC listings work with all Atari computers of any memory size.
If you program in BASIC, you've almost certainly
used string variables to store and manipulate character strings. In this
article, we'll see how Atari BASIC handles string variables. Then we'll
show you how to use this information to harness the impressive power and
speed of string manipulation in Atari BASIC.
These techniques come in handy whenever you have to move
or modify a large area of memory. Some possible applications are: redefining
character sets, changing display lists, manipulating machine language programs
from BASIC, moving players in Player/Missile graphics, and changing screen
memory for animation or page flipping.
VARIABLE TABLES
Atari BASIC uses two tables to keep track of the variables in your
program: the Variable Name Table and the Variable Value Table.
The Variable Name Table holds the names of all the variables
used in your program. It also tells the computer if a variable contains
a string, a number, or a numeric array.
The Variable Value Table records the size and contents
of each variable.
Whenever you use a new variable, whether it's in a program
or a direct command, the computer updates both tables. Moreover, when you
SAVE a program to disk or cassette, the tables are saved as well. Both
tables will remain in memory until you LOAD another program, issue a NEW
command, or turn off the computer.
FINDING TABLES
The location of these tables in memory depends upon the length of your
program. To find them, we check the contents of four special memory locations
which point to the start of the tables. These are:
VNTP= PEEK (130) + PEEK (131) *256
VVTP=PEEK (134) + PEEK (135) *256
VNTP is the starting address of the Variable Name Table
and VVTP is the starting address of the Variable Value Table.
The Variable Name Table stores the names of all variables
in the order they appear in your program listing. It also stores the type
of each variable (string, numeric, or numeric array).
Listing 1 displays the contents of the Variable Name Table
in a readable format. The subroutine in lines 1000 through 2005 can be
appended to any BASIC program for a listing of the variables used. Type
in Listing 1, check it with TYPO II and SAVE a copy.
INTERPRETING TABLES
The Variable Value Table tells the computer where to find the contents
of each variable. It also contains the size of each variable. It uses eight
bytes per variable to store this information. We'll refer to these bytes
as byte one, byte two, etc.
Byte one determines whether the variable represents a
string or a number. (A 129 in this location would denote a string variable.)
Byte two is a reference number (0 through 127) assigned
to that variable. This is the number which the computer uses to identify
each variable.
Byte three and byte four tell the computer where it can
find the contents of the variable.
Byte five and byte six contain the length of the variable,
and byte seven and byte eight contain the maximum size of the variable.
In the case of string variables, this value is equal to its dimensioned
length. For example, consider the BASIC line:
10 DIM A$(12):A$="ABC"
In this case, A$ is three characters long, but its maximum
size is 12.
Interpreting bytes three through eight requires an understanding
of how the computer stores numbers in memory locations. A single memory
location can only store numbers between 0 and 255. The computer breaks
up larger numbers into two parts and uses two memory locations to store
them.
The first location contains the number of 256's in the
number. Programmers refer to this as the "high byte" of a number. The second
location, the "low byte," contains the rest of the number.
To calculate the size of a string variable, we multiply
byte five by 256 and add byte six. We used the same method to calculate
the starting addresses of the Variable Name Table (VNTP) and the Variable
Value Table (VVTP) at the beginning of this article.
Finding the location of a variable in memory is slightly
more complicated. Strings and arrays are stored in the String and Array
Table. Byte three and byte four contain a pointer, or "offset value" used
to locate a variable in this table.
First, multiply byte three by 256, and add byte four to
determine this offset value. Now, add this to the starting address of the
String and Array Table. This address can be found with the equation: STARP
= PEEK (140) + PEEK (141) * 256. The final value is the actual address
of the string. You could also find this address with BASIC's ADR function.
The location of the String and Array Table varies with
the size of your BASIC program. For this reason, references to this table
should only be done under program control, not through direct commands.
Listing 2 will display the values of byte one through
byte eight for each string variable in the Variable Value Table.
Listing 3 takes the same information and interprets it
for you, printing the actual size and location of each string variable
in the program. Both of these listings should be checked with TYPO II and
SAVEd before you RUN them.
LOCATING VARIABLES
Searching through the variable tables for information about a particular
variable is a complicated, error-prone, and often unnecessary procedure.
We can easily design and build our own variable tables, if we follow one
simple rule: The order of variables in the tables must be the same as the
physical order of the variables in your program. Consider the following
program:
10 DIM A$(3):A$="ABC"
20 GOSUB 900
30 DIM B$(3):B$="DEF"
40 END
900 DIM C$(3):C$="GHI"
910 RETURN
In this program, A$ will be the first variable in the variable
tables because it's the first variable in the program. B$ will be the second,
and C$ will be the third. (Note that the computer builds the variable tables
according to the physical order of variables in your program, NOT the logical
order.)
If you want to manipulate a variable through the variable
tables, it's wise to declare that variable in the first line of your program.
This places it at the-top of your variable tables.
Remember to type NEW before typing in your program to
assure that no information is left in the tables from earlier programs
or direct commands.
If you forgot to do this, you can LIST the programs to
disk or cassette, type NEW, and ENTER the program again. Do not use SAVE
and LOAD since these commands save the variable tables along with the program.
CHANGING VARIABLES
Both variable tables are in RAM which means that their contents can
be changed using BASIC's POKE statement.
For example, suppose we wanted to change the name of the
first variable used in Listing 1 from A$ to B$. Since A$ is the first variable
used, it will be at the beginning of the table and its name will be in
location VNTP. LOAD in Listing 1 and then type:
POKE VNTP, ASC ("B")
Now LIST the program. All references to A$ are now B$.
VALUE TABLE CHANGES
More powerful effects can be achieved by changing the Value Table.
By changing a string variable's entry in this table, we can position it
anywhere in memory. We can also change its size.
If we place our string variable in a region of memory
used for other purposes, we can use it to change those memory locations.
For example, if we relocate a string variable to an area reserved for Player/Missile
graphics, we can control the players with several well-placed POKEs to
the variable tables.
To do this, of course, you'd need a working knowledge
of Player/Missile graphics, and that's beyond the scope of this article.
Instead, we'll relocate a string variable to screen memory. In this way,
we'll change what's on the screen by changing the appropriate entries in
the Variable Value Table.
Recall that the Variable Value Table contains information
about the location of string variables. This information is kept in bytes
three and four in the table. In Listing 3, A$ is the first variable dimensioned.
Since its byte one value is in memory location VVTP, its byte three value
can be found by PEEKing (VVTP + 2), and its byte four value is in (VVTP
+ 3).
SLIDING STRINGS
Let's move A$ to screen memory. The address of the beginning of screen
memory is calculated in line 100 of listing 3, and stored in the variable
SCRN.
Next, we use SCRN to calculate A$'s new byte three and
byte four values for the Variable Value table. Use the following formulas:
Offset = (new location)- (PEEK(140)-PEEK (141) * 256)
Byte four = INT (Offset/256)
Byte three = Offset- Byte four * 256
Lines 150-170 perform these calculations. These new values
are POKEd into the Variable Value table in line 200. These POKEs slide
the contents of the string variable into screen memory.
Lines 250-290 change the variable's size by altering the
values for bytes five and six in the Variable Value Table. We can calculate
the new values with these formulas:
Byte six = INT (size/256)
Byte five = size-byte six * 256
In this example, we use a size of 400 bytes. This allows us to control the top ten lines of the Graphics 0 display screen.
MODIFYING MEMORY
Once relocated, a string variable can be used to modify the area of
memory it occupies. Manipulating the string contents alters the contents
of the memory locations. An example is the line:
A$="ABCD"
This will put a 65 in memory location SCRN, 66 in SCRN+1,
67 in SCRN+ 2, and so on. Since we are dealing directly with the screen,
we must use internal character codes rather than ATASCII. In line 400 of
Listing 3, A$ is completely filled with CHR$(0), the ATASCII "heart" character.
This puts a 0 in the first 400 locations of the screen memory area, and
10 blank lines are on the screen.
Line 420 puts the word "HELLO" on the second line of the
screen by placing the characters "(% , ,/" into A$, and then sliding A$
to screen memory In this example, when a 40 (ATASCII code for a left parenthesis)
is POKEd into screen memory the letter "H" appears on the screen.
The speed you can achieve with this "string sliding" is
rivaled only by machine language. Imagine the graphics effects possible!
FOUR STEPS
Four basic steps are needed for positioning string variables in memory:
1. Dimension the variable in the beginning of your program.
2. Calculate VVTP, the starting address of the Variable Value Table, from locations 134 and 135.
3. Select a new memory location for your string variable, break the address into low and high bytes, and POKE these new values into the Variable Value table at byte three and byte four.
4. Calculate the new size of the string variable and place these values into byte five and byte six. Byte seven will contain the new value you need for byte five, and byte eight will contain the value you need for byte six.
Once the string variable is positioned, characters in the
string will correspond to numbers in the memory locations. This method
can be used to place numbers in memory by placing characters in the string.
You can also to read numbers from memory by reading the string.
A string can even be positioned in the area of memory
where a program is stored-resulting in a program that can write other programs!
As you learn more advanced programming techniques, you'll discover many
more uses for relocating string variables.
Brian Weiss is a computer science major at the University of Maryland and has been programming with the Atari for four years.
Listing 1 VTABLE1.BAS Download
Listing 2 VTABLE2A.BAS Download
Listing 3 VTABLE2B.BAS Download
Listing 4 VTABLE3.BAS Download