Classic Computer Magazine Archive COMPUTE! ISSUE 49 / JUNE 1984 / PAGE 123

Apple Variable Save

Jeff Brewster

Modifying lines in Applesoft BASIC programs can be time-consuming when variables are lost. Here is a machine language program to solve that problem. It saves and automatically resets pointers to variables, letting you easily interrupt programs for modification and debugging.

In Applesoft BASIC you will lose variables whenever a program is modified. This is especially troublesome during program development and debugging when many changes must be made and their effects determined. Each time a line is changed, it is necessary to reexecute the entire program due to the loss of variables. When the program involves long calculations or many operator INPUTS, this requirement makes program modification a slow, frustrating process.

By using this short machine language program "VARSAV," you can avoid much of this trouble. A running program can be interrupted with CTRL-C or RESET; program lines can be modified, added, or deleted; and execution can be resumed with the CONT or GOTO command. All the variables will still be there, ready to use (provided no unusual commands are entered which would disturb the stored variables or their pointers—these forbidden commands are discussed below).

Programming Considerations

This modification to BASIC is implemented by having Applesoft call VARSAV when keyboard input is required, instead of the usual routine KEYIN. VARSAV consists of two parts: the functional part of the program and a short initialization sequence which must be run to connect VARSAV to Applesoft. The initialization routine sets the KSW pointer at $38-$39 so that VARSAV is called when keyboard input is required; it also patches a new routine into the RESET sequence so that VARSAV remains connected even after a system RESET. START calls KEYIN to read the keyboard and then saves or restores certain pointers which tell Applesoft where variables are located in memory.

VARSAV occupies 96 bytes, including the seven-byte storage area RSAVE, and can be located anywhere in memory. The program is entered most quickly from the monitor (CALL-151) using the hex dump in Program 1. It is convenient to type in the program as written, list it to find errors, and then make any location-dependent changes.

The main program is in page 3 of memory (pages are 256-byte groupings), a usually vacant area, while allowing the initialization routine to reside at the top of page 2. This keeps the initialization sequence, which is used only once, out of valuable page 3 memory space.

VARSAV is conveniently implemented on a disk system by including a BRUN VARSAV instruction in the greeting program so that VARSAV will be loaded and run whenever the disk is booted. The use of VARSAV is straightforward and nearly transparent to the operator. You needn't grasp the program's operation to use VARSAV, so skip the next section if the details do not interest you.

Saving And Restoring Variables

Variables are stored by Applesoft in tables, starting at the end of the program and moving up in memory. Simple variables are stored in the lower segment of the variable space; array variables are in the upper segment. As new variables are defined, they are added to the end of the existing tables. String variables are actually stored in two places: the name of the string and a pointer are stored in the appropriate variable table (simple or array), while the string itself is stored at the top of available memory. New strings are added at the top of memory, working down, while their pointers are stored in the variable table, working up.

To keep track of the variables, Applesoft has four pointers in zero page ($69 to $70,105 to 112 decimal) which define the start of the simple variable table, the start of the array variable table, the end of variable storage, and the start of string storage. Their functions are described more fully on page 140 of the Applesoft II Reference Manual.

The first pointer is set automatically to the end of the program by Applesoft when the program is loaded, or by entering or deleting a program line. This pointer can be changed to a higher value with LOMEM or a POKE, permitting the programmer to leave a space in memory between the program and the variable tables. The other pointers are not directly accessible.

At the beginning of a program, the second and third pointers are set equal to the first, while the fourth pointer is set equal to HIMEM. As variables are assigned by the program, the pointers are updated. Since variables are never deleted from the variable tables, the pointers never decrease in value during program execution. When a new line is entered, however, these pointers are reset to their initial (default) values, so that it appears to Applesoft that no variables have been defined. The variables and strings themselves are still in memory waiting to be used—Applesoft just doesn't see them.

If the pointers could be saved somewhere before they were reset, and then restored after the new line input, Applesoft would then be able to use the variables already assigned. This could be done by using the monitor M command (Move) to store the pointers in a convenient location, returning to BASIC to make program changes, and then using the monitor again to restore the variable pointers from the storage area before continuing execution. VARSAV simply performs these operations automatically via the routines SAVE (save pointers) and RESTOR (restore pointers) each time the keyboard is read.

The appropriate operation is selected by comparing the current value of the pointer to the end of variable storage ($6D-$6E) to the stored value of this pointer. If the stored value is less than the current pointer value, a SAVE operation is performed; a RESTOR operation occurs if the current pointer value is less than the saved value. Generally, this means that when the pointers are updated they are SAVEd the next time keyboard input is requested. RESTOR occurs after keyboard input only if the variable pointers have been reset to their default values.

VARSAV makes this comparison each time the keyboard is read unless the character entered is CTRL-C. In that case, a SAVE operation is performed regardless of the current value of the variable pointers. This exception is necessary in order to permit the variable tables to be cleared. To clear the variables, enter the CLEAR command (then carriage return) followed immediately by CTRL-C.

Program Modification And RESET

How to use VARSAV is best learned by considering the sample program "VARSAV Test" (Program 2). Assume that VARSAV is in effect and that VARSAV Test is RUN. Execution will halt at statement 110 with a SYNTAX ERROR due to the misspelled NEXT. At this point the storage area holds the default values of the variable pointers, while the pointers themselves contain the current values assigned by Applesoft. These values must be saved before changing line 110. Entering the following line (or hitting any key) will accomplish this:

110 NEXT I

As the first character of the line is entered, a SAVE operation is performed, preserving the variable pointers. When you hit RETURN, Applesoft will process the line, checking the first nonblank character to determine whether this is an immediate mode command or new program line input. Since the first character is a number, the line is treated as new line input, and Applesoft clears the variable pointers to their default values and stores the new line in memory.

Suppose the command GOTO 90 is entered next. When the G is entered from the keyboard, VARSAV will test the end of variable space pointer and determine that its (default) value is less than the stored value. This results in a RESTOR operation which sets the variable pointers back to their original (correct) values. The variables will be printed out as if there were no changes made in the program at all.

To further complicate things, the effect of the RESET key has to be reckoned with. As mentioned previously, VARSAV is called via the KSW vector at $38-$39. Applesoft makes an indirect jump to the address held by the KSW vector whenever keyboard input is required. VARSAV sets the KSW vector to point to itself instead of the normal input routine KEYIN.

When RESET is hit, a number of operations occur which set the Apple's video output, I/O vectors, and soft switches to defined states. The RESET sequence ends with an indirect jump to the address held in the soft entry vector (SOFTEV) at $3F2-$3F3, which returns control to the current operating language. As part of the sequence, the KSW vector is changed to its default value (pointing to KEYIN), thus disconnecting VARSAV.

To counter this, VARSAV sets the soft entry vector to cause a jump to its own reset routine, which reconnects VARSAV via the KSW vector, and then exits normally to BASIC.

The task of setting these two vectors (KSW and SOFTEV) is even more complicated when DOS is present. DOS is also connected to Applesoft through the KSW vector, and calls to VARSAV must be routed through DOS. In addition, DOS must set its own pointers after a system RESET just as VARSAV must. Thus, VARSAV must pass the value of KSW to DOS, and warmstart DOS (and BASIC) after a system RESET.

As was mentioned, only the pointers, not the variables themselves, are lost when program changes are made. This is true only when the change does not lengthen the program. If the program is lengthened, the lower end of the variable table will be overwritten by program lines and permanently lost.

This problem is easily avoided by using LOMEM to establish a space in memory between the end of the program and the start of the variable tables. This space is then available for additional program line storage without disturbing the variables. A space of 256 bytes is adequate for about eight BASIC lines; such a space is easily allocated by using the following statement as the first line of each program:

1 LOMEM : PEEK (105) + PEEK (106)*256 + 256

If many changes are anticipated, the space can be made larger by increasing the last value in line 1. A more compact equivalent statement is:

1 POKE 106, PEEK (106) +1

Again, the space can be increased in 256-byte increments by increasing the last value in the line.

Using VARSAV

Once VARSAV has been loaded into memory, start the program from the beginning to set the KSW and SOFTEV vectors. The program as presented can be started with CALL 755. If the program is relocated, start it using a CALL to the first byte of the program. Load or enter a BASIC program as usual (try Program 2 the first time). Before running the program, enter CLEAR followed by CTRL-C to initialize the storage registers; then set LOMEM at least several hundred bytes beyond the end of the program to allow room in memory for added program lines. This can be done by entering LOMEM from the keyboard, or by incorporating one of the statements found in the previous paragraph, into the program.

Start execution as usual with RUN or GOTO. The program can be interrupted at will, changed, and execution will still continue without any loss of variables. Problems with VARSAV will occur if commands are entered from the keyboard which alter the variable tables or their pointers. Changing HIMEM or LOMEM may do this. Changing LOMEM will have no effect unless followed by CTRL-C, in which case all variables are lost; changing HIMEM will affect only strings.

Of course, altering HIMEM or LOMEM can destroy variables whether VARSAV is in use or not, so these commands should never be used after variables have been assigned in a program. Another problem can result if a program is run when the pointer storage area of VARSAV contains garbage, or pointer values from another program. The CLEAR, CTRL-C sequence described above should always be used to clear the pointer storage area before running a program.

This could also be done automatically by placing the following line at the beginning of each program:

2 CLEAR: CALL 808

With these simple precautions in mind, VARSAV can make programming and debugging in Applesoft a more pleasant, a faster job.

Program 1: Hex Dump Of VARSAV

02F0- 00 00 00 A9 45 A0 03 80
02FB- F2 03 BC F3 03 20 6F FB
0300- A9 0B A0 03 85 38 84 39
0308- 4C EA 03 84 F9 20 IB FD
0310- 85 FA C9 83 F0 12 A5 6E
0318- CD 50 03 90 18 D0 09 A5
0320- 6D CD 4F 03 90 0F F0 18
0328- A0 07 B9 69 00 99 4B 03
0330- 88 10 F7 30 0B A0 07 B9
0338- 4B 03 99 69 00 88 10 F7
0340- A4 F9 A5 FA 60 20 00 03
0348- 4C BF 9D 00 00 00 00 00

Program 2:vARSAVTest

10 REM VARSAV TEST
20 LOMEM:  PEEK (105) + PEEK (106) * 256 + 256 
30 CLEAR : CALL 808: REM SAVE ROUTINE AT $328
40 A - 1:B = 2:C = 3 
50 A$ = "A":B$ = "B":C*$ = "C" 
60 FOR I = 1 TO 10 
70 ARRAY(I) = I 
80 NEXT I 
90 FOR I = 1 TO 10 
100 PRINT ARRAY(I) 
110 NESTI: REM THAT'S RI8HT! 
120 PRINT 
130 PRINT A, B, C 
140 PRINT 
150 PRINT A$, B$, C$ 
160 REM  TRY CHANGING THIS LINE