LOAD and LINK by Lew THOMAS<37> One of the deficiencies of the HP-71 operating system is its inability to know whether LEX files which are required for a BASIC program to run are in RAM until the program is running. After many frustrating occasions of running programs (often from swap disks), and being interrupted in the middle by an error message which said that a LEX file was missing, I decided to do something about the situation. I wrote two BASIC programs, 'TKNIDFL' and 'FNDTKID' which perform the following functions: 1. Create a DATA file containing Token and ID reference to LEX file names. 2. Load a selected BASIC program from disk or tape if it isn't in RAM. 3. Check for missing Token and ID numbers and through ref- erence to the DATA file, attempt to find and load the miss- ing LEX files. To conserve memory and time, I use 'TKNIDFL' to create the 'TKNID' data file. The functions available in 'TKNIDFL' are identified in lines 1-10 of the program. Individual LEX files may be selected or all on a disk or tape may be selceted by 'f(auto)'. After the LEX file is selected it is loaded into RAM and the subroutine 'TKNIDCK' is called to find the Tokens and ID in that LEX file and write the ID number, Token low, Token high and LEX file name to the 'TKNID' data file. Multiple Token and ID combinations in a LEX file are entered into the data file as multiple entries. For example, 'EDLEX' data entries are: F0 01-07 EDLEX 52 02-03 EDLEX The LEX file is then purged if it wasn't in memory already. The process in repeated until all the desired LEX files on the disk are processed/selected. No provisions have been made for multiple disks, so copy all your desired LEX files onto one disk, or modify the program to suit your needs. Once 'TKNID' data file is created, 'TKNIDFL' is not needed in RAM. The second program, 'FNDTKID', will load the selected BASIC program through 'LOADONLY' if it isn't in RAM, check it for missing LEX file calls, search the 'TKNID' data file for the LEX file and if it finds a match, will load the LEX file from the disk and continue the process until all the BASIC program lines have been checked. 'FNDTKID' needs 'PEEKUTIL' and 'BASICLEX' to run, but notice that through error checking, line 70-150, the program will attempt to load those LEX files if they are not in RAM! Lines 170-190 make sure it's a BASIC file, then lines 200-360 check each BASIC line for missing 'XFN' or 'XWORD'. If 'XFN' or 'XWORD' are found, the Token and ID numbers are extracted and the subroutine 'FNLX' is called to find the LEX file and load it. The program doesn't deal with Token and ID conflicts, it loads the first LEX file with a Token and ID match. Conflict issues should be resolved before the 'TKNID' data file is made. ('CHKLEX', 'HELPLEX' and MIchael Markov's update to 'CHKLEX' may be used to check for conflicts.) If you do not have the necessary files to run these programs, check first with your local HPX Chapter because I believe they are readily available. If that fails, send me a disk and I will send the necessary files to you. I have also sent these prog- rams to Michael Markov for inclusion in future swap disks. If you find errors in these programs, please let me know. I have used them many times without a problem, and haven't looked up a Token/ID in quite some time! Your comments concerning the usefulness of these programs to you are invited. A special thanks to Joe Horn for information on 'LIST$', which is the heart of this program, and to all of you who create those beautiful LEX files. *****TKNIDFL***** 0001 ! TKNIDFL allows one to create a file of LEX TKNID 0002 ! It reads one CAT entry from the disc and waits for one of the 0003 ! following responses: 0004 ! S-Select File to be Processed 0005 ! UpArrow-Previous File in Cat 0006 ! DnArrow-Next File in Cat 0007 ! Q-Quit Selection 0008 ! I-Index Change, N=Name of LEX file 0009 ! Copyright @ 3/9/87 .Lew THOMAS (408)983-1083 0010 ! 'AUTO'-Automatic Copy of all remaining files. 0011 ! Requires PEEKUTIL, KEYWAIT and BASICLEX 0015 DISP "LEX Program TKNIDFL" @ X=0 @ DESTROY ALL 0017 DISP "S,I,F,Up,Dn,f(auto),Q" 0020 DELAY 1,1 @ M=0 @ CFLAG ALL 0030 DIM R$(50)[10] 0040 DIM G$[50] 0044 ON ERROR GOTO 46 0045 CREATE DATA TKNID,1,32 0046 OFF ERROR 0047 ASSIGN #1 TO TKNID 0050 N=1 0060 FOR I=1 TO INF 0070 G$=CAT$(I,":TAPE(1)") 0071 IF G$[1,8]="" THEN DISP "End of CAT" @ END 0075 IF G$[14,18]="LEX " THEN BEEP ELSE 300 0080 DISP G$[1,10]&G$[13,18]&G$[19,24] 0085 IF FLAG(1) THEN 170 0090 K$=UPRC$(KEYWAIT$) 0100 IF K$="#51" THEN 300 0110 IF K$="#50" THEN I=I-1 @ GOTO 70 0120 IF K$="N" THEN INPUT "File Name?";R$(N) @ I=I-1 @ GOTO 240 0130 IF K$="I" THEN DISP @ INPUT "Index=",STR$(I);I @ GOTO 70 0140 IF K$="S" THEN 170 ! ACCEPT 0150 IF K$="Q" THEN DISP "END" @ END ! END OF SELECTION 0152 IF K$="F(" THEN SFLAG 1 @ DELAY 0,0 @ GOTO 170 0160 GOTO 90 0170 M=VAL(G$[19,24])+25 0180 IF MEM+25-M<0 THEN DISP "No Memory for "&G$[1,8]&G$[19,24] @ GOTO 300 0190 R$(N)=G$[1,10] 0240 X=POS(R$(N)," ") 0250 IF X=0 THEN X=11 0260 B$=R$(N)[1,X-1]&":TAPE(1)" 0270 ON ERROR GOSUB 'ERP' 0280 COPY B$ 0282 ! 0285 CALL TKNIDCK(R$(N),X,#1) 0290 PURGE R$(N) 0300 NEXT I 0650 'ERP': IF ERRN=255030 THEN 670 ELSE DISP R$(N)&ERRM$ @ BEEP @ PAUSE 0660 ! 0662 CALL TKNIDCK(R$(N),X,#1) 0663 NEXT I 0670 RETURN 0710 SUB TKNIDCK(F$,N,#1) @ ON ERROR GOTO 890 @ Y=NOT LEN(F$) @ IF Y THEN END 0720 IF PEEK(HTD(ADDR$(F$))+16,2)#8 THEN DISP 'ERR:Not LEX file' @ END 0730 I=1 0740 S=HTD(ADDR$(F$))+37 0750 T$(I)=RPEEK$(S,6) 0810 PRINT F$&' ID=';T$(I)[5]&' TKNL=';T$(I)[3,4]&' TKNH=';T$(I)[1,2] 0840 A2=HTD(RPEEK$(S+6,5)) 0850 IF A2=0 THEN 895 0860 S=S+A2+6 @ I=I+1 0870 GOTO 750 0890 DISP 'ERR:';ERRM$ @ BEEP @ END 0895 FOR X=1 TO I 0900 PRINT #1;T$(X)[5],T$(X)[3,4],T$(X)[1,2],F$ 0910 NEXT X 0920 END SUB *****FNDTKID***** 0020 ! FNDTKID searches BASIC program, F$, for missing LEX files and loads them from the mass 0030 ! media. Needs the data file 'TKNID' to find the TKN/ID LEX file. 0040 ! Copyright 6 Mar 1987, Lew THOMAS, (408) 983-1083 0050 SUB FNDTKID 0055 INPUT 'Program Name?';F$ @ CALL LOADONLY(F$) @ CALL LOADONLY("TKNID") 0060 DIM Z$[100] @ B=0 0070 ON ERROR GOTO 120 0080 X$=RPEEK$(1,4) @ OFF ERROR 0090 ON ERROR GOTO 130 0100 Z$=LIST$(X,F$) 0110 OFF ERROR @ GOTO 170 0120 B$='PEEKUTIL'&':TAPE(1)' @ GOTO 140 0130 B$='BASICLEX'&':TAPE(1)' 0140 COPY B$ 0150 GOTO 70 0170 A=HTD(ADDR$(F$))+49 @ E=PEEK(A-17,5)-17 @ E=A+E 0180 ! 0190 IF RPEEK$(A-33,4)#"E214" THEN DISP "Not a BASIC file..." @ GOTO 380 0200 IF A=E THEN GOTO 380 0210 X=VAL(RPEEK$(A,4)) 0230 Z$=LIST$(X,F$) 0240 P=POS(Z$,'XFN') 0250 IF NOT P THEN 260 ELSE 290 0260 P=POS(Z$,'XWORD') 0270 IF NOT P THEN 320 0280 P=P+2 0290 T$=STR$(VAL(Z$[P+3,P+8])) @ L=LEN(T$) @ I$=T$[1,L-3] @ T1$=T$[L-2] 0300 T=VAL(T1$) @ I=VAL(I$) @ DISP 'ID(d/h)=';I$;'/';DTH$(I)[4,5];' TKN=';T1$ 0310 CALL FNLX(T,I) 0320 A=A+2 @ B=B+1 0330 IF B=23 THEN 350 0340 A=A+PEEK(A+2,2)+2 @ IF PEEK(A)=4 THEN 340 ELSE A=A+2 @ GOTO 200 0350 ! 0360 B=0 @ GOTO 340 0380 DISP 'Prog Check Complete' @ BEEP 0390 SUB FNLX(T,I) 0400 ASSIGN #1 TO TKNID 0410 ON ERROR GOTO 'ER' 0420 READ #1;I1$,T1$,T2$,F$ 0430 IF HTD(I1$)#I THEN 420 0440 IF HTD(T1$)<=T AND T<=HTD(T2$) THEN 'LDLX' ELSE 420 0450 'ER': IF ERRN=54 THEN DISP 'TKN/ID not in File..' 0460 IF ERRN#54 THEN DISP 'ERRN=';ERRN @ PAUSE 0470 OFF ERROR 0480 GOTO 'ES' 0490 'LDLX': DISP "Loading '";F$[1,POS(F$,' ')-1];"'" 0500 ON ERROR GOTO 'ER2' 0510 B$=F$[1,POS(F$," ")-1]&":TAPE(1)" 0520 COPY B$ 0530 DISP F$&' Loaded' 0540 GOTO 'ES' 0550 'ER2': IF ERRN=255022 THEN 'TRY2' ! File not found 0560 IF ERRN#255022 THEN DISP 'ERRN=';ERRN @ PAUSE 0570 OFF ERROR 0580 GOTO 'ES' 0590 'TRY2': DISP 'File not on media..' @ WAIT .5 0600 DISP 'Try Again?' 0610 K$=UPRC$(KEYWAIT$) 0620 IF K$='Y' THEN DISP 'Load new media (EOL)' @ GOTO 'TRY3' 0630 IF K$='N' THEN 580 0640 GOTO 'TRY2' 0650 'TRY3': K$=UPRC$(KEYWAIT$) 0660 GOTO 'LDLX' 0670 'ES': END SUB *****LOAD and LOADONLY SUBS***** 0250 SUB LOAD(F$) 0260 ON ERROR GOSUB 'ER1' 0270 CALL F$ 0280 GOTO 390 0290 GOTO 40 0300 'ER1': IF ERRN=57 OR ERRN=49 THEN 310 ELSE DISP ERRM$ @ BEEP @ PAUSE 0310 DISP "Loading '";F$;"'" 0320 OFF ERROR @ ON ERROR GOSUB 'ER2' 0330 COPY F$&':TAPE' 0340 OFF ERROR 0350 GOTO 270 0360 'ER2': IF ERRN=255059 OR ERRN=24 THEN DISP 'Insufficient Memory for';F$ 0370 IF ERRN=49 OR ERRN=255022 THEN DISP "Cannot Find '";F$;"'" ELSE DISP ERRM$ @ PAUSE 0372 BEEP @ DISP "Try Again,(Y/N)?" @ Y$=UPRC$(KEYWAIT$) 0374 IF Y$="Y" THEN 310 0376 IF Y$='N' THEN 390 ELSE 372 0380 BEEP @ WAIT 1 0390 END SUB 0410 SUB LOADONLY(F$) 0420 ON ERROR GOSUB 'ER1' 0430 CAT F$ 0440 GOTO 570 0450 'ER1': IF ERRN=57 OR ERRN=49 THEN 460 ELSE DISP ERRM$ @ BEEP @ PAUSE 0460 DISP "Loading '";F$;"'" 0470 OFF ERROR @ ON ERROR GOSUB 'ER2' 0480 COPY F$&':TAPE' 0490 OFF ERROR 0500 GOTO 430 0510 'ER2': IF ERRN=255059 OR ERRN=24 THEN DISP 'Insufficient Memory for';F$ 0520 IF ERRN=49 OR ERRN=255022 THEN DISP "Cannot Find '";F$;"'" ELSE DISP ERRM$ @ PAUSE 0530 BEEP @ DISP "Try Again,(Y/N)?" @ Y$=UPRC$(KEYWAIT$) 0540 IF Y$="Y" THEN 460 0550 IF Y$='N' THEN 570 ELSE 530 0560 BEEP @ WAIT 1 0570 END SUB