A program to trace variables in Basic programs. Robert Milazzo.
A Program To Trace Variables In Basic Programs
Have you ever searched through a program looking for a variable? Have you ever deleted a line only to find that 87 GOTOS in your program then had to be sent somewhere else? If you believe you were meant for better things than tracing jumps and variables in your programs, read on.
I wrote Trace to solve both of the above problems. Trace is a Basic program that will trace any variable and print out on the display each and every line in which it occurs. Trace also has the ability to find every GOSUB, GOTO, IF-THEN, RESUME, and ELSE statement that jumps to a particular line.
Programs written in Basic have many advantages. They are easy to understand and, more important, easy to modify. Unfortunately, Basic has a well deserved reputation for being very, very slow. Trace will take between forty seconds and one minute to find all the lines in which a particular variable is located in a 5K program. This still beats listing the program and looking through all those multiple statement lines.
Running The Program
This program contains no frills or fancy displays. Every single convenience has been left out in the interest of speed and memory requirements. The reward for this is that Trace uses fewer than 800 bytes. Using Trace is very easy. Just follow these simple instructions:
1. CLOAD the program you want to trace through.
2. In the command mode enter the program in Listing 2.
3. CLOAD "Trace'.
4. POKE 16548, 233: POKE 16549,67 (Model 1, POKE 16549,66).
Now when you list the program you will find that both programs have been linked together. This technique can also be used on other programs that you want to merge.
Just type in RUN 65000 and you are off. The program will then ask you to enter the variable or line you wish to trace. If you want to trace variable A1, for example, type in A1. If you want to find all the lines that jump to line 1000, then enter 1000.
Tracing subscripted variables is done in a special way. Type in A( to find the array called A. The left parenthesis is important because it tells the program that it is looking for an array.
Understanding The Program
This program makes use of the way Basic stores programs in memory. Figure 1 shows how a short program is stored.
The start of the program storage area in the Model III is location 17385. Locations 17385 and 17386 contain the address of the beginning of the next line. This can be checked by multiplying the contents of 17386 by 256 and adding the result to the contents of location 17385.
The next two bytes (locations 17387 and 17388) represent the line number again in least significant followed by most significant byte format.
Location 17397 contains a zero: This marks the end of every line of a Basic program. In this case, it marks the end of line 10.
Hopefully, you can now see why every line has an overhead of five bytes. Two are needed as pointers to the next line, two are used to contain the line number, and one is needed to mark the end of the line. This is the reason multiple statement lines are used to save space.
The actual program data for line 10 begins at location 17389 and ends at location 17396. It is this part of the program with which we are most concerned. The first byte is a 129 and represents the Basic command FOR. All of the Basic commands are tokenized in this manner to save memory. The next byte is a 78, which stands for the variable N.
All Basic variables and numbers are stored in ASCII formats. The following 213 is another token that represents the equal sign. The 49 is the ASCII representation of the number 1. The following 189 is the token for the Basic command TO. The next three locations contain the ASCII representation of the number 100.
Armed with this knowledge, to find the variable B in a program, all you have to do is search through memory until an ASCII 66 is found. To find a GOTO 100 statement, all that is required is to find four consecutive bytes that equal 141, 49, 48 and 48. It is a little bit more complicated than this, but I think you can get the idea.
The Logic Of The Program
Trace has been written in a compressed format that undoubtedly makes the program harder to read. In return for the confusion, the program runs faster and uses less memory. I hope that the following comments can help clear up some of the confusion.
Lines 65000-65020 are simple enough. They clear the screen, set up the main program variables as integers, and prompt you to enter the target string. Defining as many variables as possible as integers definitely speeds things up. This is almost always true and should be kept in mind when writing your own programs.
Lines 65030-65060 are the main program loop. Each location starting with 17389 is checked, and its contents stored in the A variable. If the token that represents a DATA statement, or a REM, or simply a zero is discovered, then control passes to the subroutine at 65190. This is done to prevent the program from searching through lines in which variables or jumps can't possibly be found. If a quote is found, control passes to the subroutine at 65180. Again this is done to prevent the program from doing any work on the data that are enclosed by quotes.
Line 65050 tests whether or not a match has been found between the first character of D$ and the current memory location. If a match is found, then further testing begins at line 65070. If a match is not found, then the next location is tested.
Line 65070 tests whether the character is alphabetic or numerical. If the character is alphabetic, then the program jumps to line 65110. If it is numerical, then control drops to the next line in the program.
Lines 65080-65100 backspace through memory searching for the token that represents one of the jump statements. All spaces are ignored in line 65090. Five Basic keywords are scanned for. They are GOTO, GOSUB, RESUME, THEN and ELSE. If one of these tokens is not found, control passes back to the main loop.
Lines 65110-65170 comprise the main comparison loop. The contents of each successive memory location are converted to a string and added together to form Z$. If Z$ equals D$, then the required variable or jump has been found. If the two strings are found to be unequal, control passes back to the main loop.
Line 65180 is the subroutine responsible for skipping through all the string data that are enclosed by quotation marks.
Lines 65190-65210 keep updating the line pointers and the current line number being searched.
Line 65000 marks the end of the target program, and program operation ceases.
Modifications And Precautions
This program is very easy to use and to modify. A list of all the variables used in the program is provided so that you will be able to find your way around. Model I owners should change the 17389 in line 65030 to 17133. If the display is not to your liking, modify line 65170 until you are pleased. You can adjust the program to trace through only part of a program by putting the appropriate line number in line 65210.
I have run this program many times and haven't had any problems. If a problem does come up, check the listing or, better yet, run the target program before tracing. This will help weed out any syntax errors such as open quotes. Trace is very sensitive to this particular error in the target program and will react unreliably if one is found.
Table: Listing 1.
Table: Listing 2.
Table: Figure 1.