Classic Computer Magazine Archive COMPUTE! ISSUE 72 / MAY 1986 / PAGE 90

64 Autobooter

Terry Roper

Now you can throw away your list of start-up SYS addresses for different machine language programs. Using a unique loading method, this clever utility lets you transform a BASIC or machine language program into an autobooting program that runs as soon as it loads-no matter where it normally loads into memory. In addition, the autobooting program can survive many system crashes that would destroy a conventionally loaded program. A disk drive is required.


"64 Autobooter" can add autobooting-the ability to run automatically after loading-to many different BASIC and machine language programs. While you may be familiar with other autoboot utilities, the most common techniques have significant drawbacks: Either they require a separate boot file to load and run the main program, or they increase the size of your program significantly. But Autobooter programs don't suffer from either problem. The autobooting file is all in one piece and is only 257 bytes longer than the original program. Even better, Autobooter programs can survive unscathed in situations that would erase or scramble programs loaded the normal way.

Creating Autoboot Files
Type in 64 Autobooter and save a copy before you run it. Using the program is just a matter of responding to a few prompts. First, you type a filename for the program you wish to convert. This file may be any program file on disk, but it may not exceed 7,935 bytes in length (more on this later). As a rough guide, 7,935 bytes take up about 31 blocks on the disk directory.
    After you supply the filename, the disk drive makes two passes through the program file. The first pass counts every byte of the file to make sure that it's within the 7,935-byte limit and calculates the load address for the new Autobooter version. The second pass stores the file in memory. When the drive stops, you are asked whether the program is BASIC or machine language (ML). If the program is all BASIC (or it begins with a BASIC line like SYS 2061), type B to choose BASIC. If it is an ML program that loads at some address other than the start of BASIC, enter the normal SYS address when prompted.
    Finally, you'll be prompted to enter a filename for the new autobooting file. At this point, the program writes the autobooting file back to disk, using the last filename you specified. The new file consists of a copy of the original file plus 257 bytes (about one disk block) of machine language. This one-block addition is the only penalty you pay for the convenience of using Autobooter files.
    When this process is complete, the new file is ready to use. An autobooting file is a self-sufficient, autobooting version of the original, but with some unusual differences. The most unusual fact is that all Autobooter files share exactly the same ending address, even though nearly all of them have different load addresses. And loading ML files with the Autobooter method does not disturb the computer's start-of-variables pointer at locations 45-46 ($2D-2E). So you can load an ML program with the assurance that any BASIC program previously in memory will still run and save correctly.

An Impressive Demonstration
Here's a short demonstration that shows how useful 64 Autobooter can be. Choose a BASIC program that you would like to convert to Autobooter form. It can be any program, as long as the original file contains fewer than 7,935 bytes. Follow the procedure for converting the program to Autobooter format, then perform these steps:

1. Type NEW.
2. Type LOAD "FILENAME",8,1 (replace FILENAME with the filename of your autobooting file). The program should load and run automatically; if it doesn't, reload 64 Autobooter and check for typing errors.
3. When you're satisfied that your program is running as usual, stop the program by pressing RUN/ STOP (or RUN/STOP-RESTORE if necessary).
4. Now it's time to get tough. Type NEW, then LIST to confirm that the program is gone. Type POKE 1,0 and press RETURN. The program should be running once again, even though that POKE is one that normally locks up the computer.
5. Press RUN/STOP to stop the program, then load any other BASIC program into memory. This ensures that the first program is completely overwritten by new data.
6. Type POKE 1,0 and press RETURN. Immediately, the autobooted program reappears in memory and begins to run. You should be able to VERIFY at this point with normal results.

    What's going on here? For one thing, you've seen how durable these files can be. Even after you destroy the program in its normal location, you can resurrect it instantly with POKE 1,0. Another advantage is that you no longer need to memorize different SYS addresses for every machine language program. Regardless of where an Autobooter program normally loads, whether it's BASIC or ML, you can restart it with POKE 1,0.
    It's not hard to see how this would come in handy. For instance, suppose you're using a BASIC program. Suddenly, the need arises to run a program that occupies the same memory area. If the original program is in Autobooter format, this presents no problem at all. Load the second program and run it as usual. When you're finished, type POKE 1,0 to restore the autobooted program.
    A second advantage has to do with loading ML files. Under ordinary circumstances, loading an ML program into high memory after loading a BASIC program can cause an OUT OF MEMORY error when you try to run the BASIC program. If the ML program is an Autobooter file, you'll avoid this error.

Wraparound Addressing
By now you might be wondering how these unusual features are possible. We mentioned earlier that Autobooter files may not exceed 7,935 bytes in length. This is necessary for two reasons. The 257-byte ML program attached to your original file must always load into memory beginning at location $FF00 (65280). The rest of your original file comes into memory directly below the ML code in the area from $E000-$FEFF (57344-65279). As you may know, loading a program into this zone causes it to be stored in the RAM underlying the Kernal ROM chip.
    Why is it so crucial to load the last 257 bytes at $FF00? If you're paying close attention, you may have noticed that 257 plus $FF00 equals more than 65535, the highest address that the 64's microprocessor can refer to. After you load the byte that goes into location $FFFF, there are still two bytes to load. Since it's impossible to use a higher address, the computer wraps around to the bottom of its addressing range and loads the last two bytes into addresses $00 and $01.
    Loading a file in this wraparound fashion has two important consequences. It allows you to change the contents of the 64's onchip I/O port (location 1) as well as the vector to its main IRQ handler ($FFFE-$FFFF). Let's look at location 1 first. The chief function of location 1 is to control whether the 64 "sees" ROM and I/O chips or the underlying RAM at memory locations above $A000 (40960). Under normal circumstances, the computer sees BASIC ROM at locations $A000-BFFF, I/O chips at locations $D000-DFFF, and the Kernal ROM at locations $E000-FFFF. When you load an Autobooter file into memory, it loads the value $35 into location 1, switching out the ROM in locations $E000-$FFFF and exposing the underlying RAM.
    Once the ROM is switched out, the microprocessor can see the rest of the Autobooter file that was just loaded. Among other things, this file loaded new information into locations $FFFE-$FFFF. This pair of locations contains a vector, or twobyte address, which points to the 64's main IRQ/BRK handler routine in ROM. Sixty times every second, and whenever the computer encounters a BRK instruction, the computer jumps to the address pointed to by this vector. Autobooter files replace the normal vector with a new one that points to the new ML that we just loaded into underlying RAM.
    The rest of the ML program moves the autobooted program to its normal load address, switches ROM back in (by putting a value of $37 in location 1), and runs the program as usual. (Incidentally, the Commodore 128 normally has a value of $77 in location 1 while it's in 64 mode. This has no effect on Autobooter files, but does prevent certain commercial programs from working properly. Pressing CAPS LOCK restores the normal value of $37, which fixes the problem in at least some of the cases.)

Mysterious VERIFY Errors
Although the computer normally resets the computer's start-ofvariables pointer after every load, 64 Autobooter does this job on its own. If the program is ML which doesn't load at the start of BASIC, the start-of-variables pointer is not changed. This lets you load ML programs without disturbing any BASIC program in memory. If the Autobooter file is BASIC, the pointer is set to the end of the program text as usual.
    Some Autobooter files may give you mysterious VERIFY errors. Don't panic-it's not uncommon for ML programs to alter themselves once run. Naturally, a file that's been modified isn't the same as the original file on disk. If a BASIC program was saved from an abnormal location it won't VERIFY either; this is due to the relinking process that occurs after every BASIC program is loaded. A good method for initial testing of ML files is to create them as usual but enter 42100 instead of the normal SYS address. This returns you to BASIC without starting your program; the file should VERIFY correctly.
    Here's a subtle bug to look out for. Suppose you have the following program:

100 A0=828:POKE AO,0

    This defines the variable A0, but not the variable AO (with the letter O instead of a zero). Since undefined numeric variables always equal zero, the POKE is directed to location 0, the data direction register for location $01. If you run this program and then try to start an autobooting program with POKE 1,0, it fails because the new bit pattern at location 0 prevents any new value from being stored in location 1. Hit RUN/ STOP-RESTORE to fix both locations, then try again.
    As a matter of fact, it doesn't hurt to hit RUN/STOP-RESTORE before activating any autobooting program. Many ML programs change the IRQ vector at locations $0314-$0315. If you try to activate an Autobooter file under these conditions, the computer will probably crash as soon as the interrupt is reenabled.
    Finally, while some cartridges don't interfere with Autobooter files, others cause erratic behavior. Cartridges can reconfigure the computer in many different ways, so you'll have to find out by trial and error whether a particular Auto-booter file works with a given cartridge.

64 Autobooter
For instructions on entering this listing, please
refer to "COMPUTE!'s Guide to Typing In
Programs" in this issue of COMPUTE!.

BC 100 POKE 55,0:POKE 56,48:CL
       R
HR 110 PRINT:PRINT "AUTO BOOTM
       AKER":IFPEEK(24591)=164
        THEN150
GP 120 PRINT:PRINT"JUST A MOME
       NT..."
DE 130 FOR J=12288 TO 12744:RE
       AD D:S=S+D:POKE J,D:NEX
       T
JE 140 IF S<>51414 THEN PRINT:
       PRINT"MISTYPED DATA":EN
       D
GF 150 OPEN 15,8,15:SYS 12288
GX 160 PRINT:PRINT"FILE FOR AU
       TO BOOTMAKER";
SJ 170 GOSUB370:PRINT:PRINT"ME
       ASURING YOUR FILE"
AJ 180 OPEN 5,8,5,"0:"+N$+",P,
       R":GOSUB350:IF El$<>"00
       " THEN160
CR 190 SYS 24834:CLOSE 5:B=PEE
       K(24578)+256*PEEK(24579
       ):PRINT B;"BYTES"
AG 200 IF B>7935 THEN PRINT CH
       R$(18);STR$(B-7935)"
       (2 SPACES)BYTE OVERFLOW
       ":GOTO160
CR 210 PRINT:PRINT"READING FIL
       E INTO MEMORY"
PF 220 OPEN 5,8,5,"0:"+N$+",P,
       R":SYS24834:CLOSE 5
BH 230 FOR J=0 TO 31:POKE24592
       +J,PEEK(24112+J):POKE24
       624+J,PEEK(22032+J)
HH 240 POKE 22032+J,0:NEXT
CE 250 PRINT:PRINT"BASIC OR ML
       (B/M)";:GOSUB370
QR 260 IF N$="B" THEN POKE 245
       82,1:POKE 24583,8:GOT03
       00
EH 270 POKE 24587,1:PRINT:PRIN
       T" JUMP TO ADDRESS";:GO
       SUB370
JG 280 H$=(VAL(N$)-1)/256:L%=(
       VAL(N$)-1)-H%*256
FR 290 POKE 24588,L%:POKE 2458
       9,H%
BF 300 PRINT:PRINT"PREPARING T
       O WRITE NEW FILE"
XK 310 PRINT"INSERT ANOTHER DI
       SK IF DESIRED"
SA 320 PRINT:PRINT"NEW FILENAM
       E";:GOSUB370:PRINT#15,"
       I0"
PE 330 OPEN 5,8,5,"0:"+N$+",P,
       W":GOSUB350:IF E1$<>"00
       "THEN300
JF 340 SYS 24950:CLOSE5:CLOSE1
       5:END
PP 350 INPUT#15,El$,E2$,E3$,E4
       $:IF El$="00"THENRETURN
MP 360 PRINT CHR$(18);El$","E2
       $","E3$","E4$:CLOSE5:RE
       TURN
MC 370 T=POS(T)
FF 380 FORJ=0TO25:WAIT 197,64:
       NEXT:POKE 198,0:PRINT T
       AB(T)
AJ 390 N$="":INPUT N$:IF N$=""
       THENPRINT:PRINT:PRINT:G
       OTO380
AS 400 RETURN
KS 410 DATA 162,0,189,18,48,15
       7,0,96
BG 420 DATA 189,18,49,157,0,97
       ,232,208
XK 430 DATA 241,96,0,0,0,0,0,0
CK 440 DATA 0,0,4,93,255,0,227
       ,167
KB 450 DATA 115,164,0,0,0,0,0,
       0
RM 460 DATA 0,0,0,0,0,0,0,0
KK 470 DATA 0,0,0,0,0,0,0,0
FJ 480 DATA 0,0,0,0,0,0,0,0
BX 490 DATA 0,0,0,0,0,0,0,0
JJ 500 DATA 0,0,0,0,0,0,0,0
EX 510 DATA 0,0,0,0,0,0,0,0
AS 520 DATA 0,0,0,0,0,0,0,0
DX 530 DATA 0,0,162,250,154,16
       2,7,189
KH 540 DATA 8,255,72,202,16,24
       9,64,162
MG 550 DATA 47,224,32,176,12,1
       89,16,255
KJ 560 DATA 157,48,253,189,48,
       255,157,16
MM 570 DATA 245,189,196,255,15
       7,0,2,202
KQ 580 DATA 16,231,173,11,255,
       208,14,173
CC 590 DATA 2,255,105,1,133,45
       ,173,3
HG 600 DATA 255,105,8,133,46,1
       74,4,255
XG 610 DATA 172,5,255,134,251,
       132,252,174
KD 620 DATA 6,255,172,7,255,13
       4,253,132
GM 630 DATA 254,160,0,174,3,25
       5,240,14
PX 640 DATA 177,251,145,253,20
       0,208,249,230
SQ 650 DATA 252,230,254,202,20
       8,242,174,2
EE 660 DATA 255,240,8,177,251,
       145,253,200
CF 670 DATA 202,208,248,76,0,2
       ,169,55
CM 680 DATA 133,1,88,169,0,32,
       189,255
JG 690 DATA 169,15,168,162,8,3
       2,186,255
CQ 700 DATA 32,192,255,169,15,
       32,195,255
CG 710 DATA 104,208,11,32,51,1
       65,162,44
DA 720 DATA 160,2,134,122,132,
       123,169,13
PC 730 DATA 76,210,255,138,0,0
       ,0,0
RH 740 DATA 0,0,0,0,92,255,92,
       255
KR 750 DATA 80,255,47,53,173,1
       78,97,73
XG 760 DATA 255,141,178,97,174
       ,179,97,172
PC 770 DATA 180,97,134,251,132
       ,252,162,5
PB 780 DATA 32,198,255,32,228,
       255,141,6
ME 790 DATA 96,32,228,255,141,
       7,96,160
GF 800 DATA 0,32,228,255,44,17
       8,97,48
JK 810 DATA 7,145,251,44,178,9
       7,16,22
XM 820 DATA 238,2,96,208,3,238
       ,3,96
QA 830 DATA 56,173,179,97,233,
       1,141,179
PR 840 DATA 97,176,3,206,180,9
       7,32,183
EF 850 DATA 255,41,64,208,8,20
       0,208,209
PB 860 DATA 230,252,76,37,97,1
       73,178,97
RQ 870 DATA 240,19,56,173,181,
       97,237,2
DM 880 DATA 96,141,4,96,173,18
       2,97,237
DF 890 DATA 3,96,141,5,96,76,2
       04,255
JQ 900 DATA 56,169,0,237,2,96,
       133,251
HD 910 DATA 169,96,237,3,96,13
       3,252,162
BA 920 DATA 5,32,201,255,173,4
       ,96,32
KA 930 DATA 210,255,173,5,96,3
       2,210,255
MG 940 DATA 160,0,177,251,32,2
       10,255,230
GM 950 DATA 251,208,2,230,252,
       165,252,201
QG 960 DATA 97,208,239,165,251
       ,201,2,208
SX 970 DATA 233,76,204,255,0,0
       ,96,0
AP 980 DATA 255