David L. Evans
The PET Compactor program (July 1982) was a popular, very fast way to squeeze a BASIC program into the smallest amount of memory possible. It created "metalines," some far longer than 80 characters, using a new line number only when the program's logic demanded it. Here's the companion utility. Also written entirely in machine language (and requiring Upgrade or 4.0 BASIC, with disk), the Uncompactor stretches a compact BASIC program out into many small lines. This makes modifications and program analysis easier. Often, a compacted program cannot be changed at all without being uncompacted first. The program is provided as a hex dump, with instructions on how to enter it into your PET.
This machine language routine uncompacts fast. In fact, it represents a 3300% increase in speed over an uncompactor written in BASIC.
Unlike my "Compactor" program published last year, it requires no changes to run on either Upgrade or 4.0 PET BASIC. It achieves this by making heavy use of the "kernal" (the jump table located at the top of memory in all PET/CBMs). The kernal is used to PRINT, OPEN and CLOSE files, GET and INPUT bytes, and to restore the original environment (default parameters) of the PET.
The routines to GET, INPUT, and RESTORE are all straightforward; all the user does is execute a subroutine call to the desired routine.
For example, to use the routine RESTORE, the user types:
Both of the routines to GET and INPUT return the value that was input into the accumulator.
The PRINT routine (JSR $FFD2) requires that the accumulator be loaded with the byte that the user wishes to be printed. The routine to set the OUTPUT or INPUT device also requires the user to set up some parameters before calling them. The user must first open the file to be accessed, then load the X-register with the file number, and finally execute a subroutine call to the routine desired.
Example: To print a colon to file number two, do the following (this assumes that file number two has been opened):
LDX #$02 JSR $FFC9 ; set current output device LDA #$3A JSR $FFD2 ; print a colon JSR $FFCC ; restore default devices
All the routines discussed above are widely used. The routines to OPEN and CLOSE files, however, are not as well-known. Each routine requires that you have, somewhere in memory, a string of characters containing the OPEN/CLOSE command. BASIC is informed where the command string is, by setting locations $77 and $78 to point to it.
Example: To open file number 15,8,15, type the following:
LDA #<COMAND STA $77 LDA #> COMAND STA $78 JSR $FFC0 ;open the file COMAND .BYTE '15,8,15'
Note: My assembler uses "<" to load the LSB of a label and ">" to load the MSB of a label. To CLOSE a file, the same procedure is used.
The program is provided in the form of a hex dump of memory. To enter this into your computer, invoke the built-in monitor by typing SYS 4. Next, display the first block of memory by typing m 0400 047f. Type over the numbers already in memory with the new values in the program, hitting RETURN after each line of eight bytes. Repeat this procedure for the following blocks of memory until all changes have been made. Then save the program to disk by typing:
S "UNCOMPACTOR", 08, 0400, 08E7
Since the program occupies the normal BASIC program area, and since the first 13 bytes constitute a short "self-calling" routine, the program can be loaded and run as if it were in BASIC.
It is not necessary to initialize the drives used; the program will automatically do it for you. If the output file name exists on the destination diskette, the program will overlay it. Follow the directions printed on the screen and your program will then be uncompacted. When the program is finished, LOAD the new version of your program and type the CLR command. This is necessary to relink the BASIC program. Be sure to reSAVE your CLRed program or else you will lose it.
For those who do not want to type this in, send $3 and a tape or disk along with a SASE mailer to the address below. If you send a disk, I have DOS 2.0 so all disks will be written in DOS 2.0.