Listing of file='@RECOVER' on disk='vmedia/701-2294P.wvd.zip'
# Sector 434, program filename = '@RECOVER'
0010 REM @RECOVER. 05/13/81. RECOVER DISK FROM BACKUP.
0020 DIM A1$3,A2$3,G$8,D1$60,O$50
0030 DIM K$1,A$(16,2)8,E$50,Q$1,Q1$1,E$(2)120,W3$3,F$8,N$8,P$3,D$(4)1,R9$8,R$8
,N1$8,Q6$2,N3$8,F2$1,B$(8)1,S2$5,C$1
0060 REM % MAIN LINE
0070 REM INIT
: D$()="ASPD"
: B$()=HEX(8040201008040201)
: P=1
: IF A1$<>" "THEN 90
: A1$="D10"
: A2$="D11"
: S1,S0=0
0080 REM %INPUT
0090 SELECT PRINT 005
: REM ATTRIBUTES
: PRINT HEX(020D0C030F020402000F)
0100 PRINT HEX(060E);TAB(20);"***** RECOVERY UTILITY *****"
0120 PRINT AT(2,0);
: LINPUT "Input Address: "-A1$
: GOSUB '205(1,A1$)
: IF Q$<>" "THEN 120
: SELECT #3<A1$>
0130 PRINT AT(2,40);
: LINPUT "Output Address: "-A2$
: GOSUB '205(2,A2$)
: IF Q$<>" "OR A2$=A1$THEN 130
0140 REM CHECK INPUT PLATTER
: GOSUB 830
0150 REM DISPLAY LABEL
: GOSUB 980
: REM RND KEY
: K1=K
0160 REM
: PRINT AT(14,0 );"1-Recover entire disk";HEX(0E);" ( WARNING! Output disk
will be scratched)";HEX(0F);AT(15,0);"2-Recover all active files";HEX(0E)
;" ( WARNING! Output disk will be scratched)";HEX(0F);AT(16,0);"3-Recover
specified files";
0170 PRINT AT(13,0,80);
: Q1$=" "
: LINPUT "Enter the number of the desired option: "-Q1$
: O=POS("123"=Q1$)
: Q1$=" "
: ON OGOTO 250,180,180
: ELSE GOTO 170
0180 PRINT HEX(06);AT(13,0,);
: REM OUTPUT PLATTER
: GOSUB '40(1,A1$,"@INDEX")
: DATA LOAD BA T#1,(A)A$()
: S2=VAL(STR(A$(),2))
: S3=VAL(STR(A$(),5),2)-1
0190 IF O=3THEN 340
0200 PRINT AT(14,0,9*80);"Default output index size (same as in backup data):"
;S2;AT(13,0);
: K$="N"
: LINPUT "Do you want to change the index size on the output platter?"-K$
: ON POS("YyNn"=K$)GOTO 210,210,230,230
: ELSE GOTO 200
0210 PRINT AT(13,0,80);
: CONVERT S2TO S2$,(#####)
: LINPUT "Index size on output platter: "-S2$
: CONVERT S2$TO S2
: ERRORGOTO 210
0220 IF S2<1OR S2>255THEN 210
0230 REM SCRATCH OUTPUT
: GOSUB '80(S2,S3)
: IF Q$<>" "THEN 210
0240 REM TO OPTIONS 2,3
: GOTO 340
0250 REM %RECOVER ENTIRE DISK
: PRINT HEX(06);AT(13,0,);TAB(20);HEX(0E);"Option - Recover entire disk."
0260 REM CHECK KEY
: IF K=K1THEN 270
: GOSUB '50("This platter does not belong to current set.")
: GOTO 260
0270 REM @DATA
: GOSUB '40(1,A1$,"@DATA")
: S8=A
: S9=A+M-S0
: REM CHECK PLATTER #
: IF N1=PTHEN 280
: REM WRONG #
: GOSUB '50(" ")
: GOTO 260
0280 REM INIT % COUNTER
: GOSUB '100(19,10,0)
: E1=S8
: E2=MAX(1,INT((S9-S8)/100))
: E3=0
: E4=S0
: PRINT AT(18,20,60);"RECOVERING SECTORS ";S0;" - ";M;
0290 REM % RECOVER
: GOSUB '140(E1,MIN(E1+E2-1,S9),E4)
: E1=MIN(E1+E2,S9+1)
: E3=E3+MAX(1,-INT(-100/MAX(1,(S9-S8))))
: E4=MIN(E4+E2,M+1)
: REM SHOW % COPIED
: GOSUB '100(19,10,MIN(E3,100))
: IF E1<=S9THEN 290
0295 GOSUB '145(S0,M)
0300 REM % VERIFY
: E1=S0
: E3=0
: E2=MAX(INT((M-S0)/100),1)
: PRINT AT(18,20,60);"VERIFYING SECTORS ";S0;" - ";M;
: GOSUB '100(19,10,0)
0310 GOSUB '150(E1,MIN(E1+E2-1,M))
: IF E<=0THEN 320
: PRINT AT(12,10,70);"ERROR IN SECTOR ";E-1;
: LINPUT "PROGRAM WILL BE TERMINATED. OUTPUT DISK MUST BE REFORMATTED. KEY
RETURN",Q1$
: GOTO 720
0320 REM % DISPLAY %
: E1=MIN(E1+E2,M+1)
: E3=E3+MAX(1,-INT(-100/MAX(1,(M-S0))))
: GOSUB '100(19,10,MIN(E3,100))
: IF E1<=MTHEN 310
: REM PLATTER #
: P=P+1
: IF P>NTHEN 720
: REM PROMPT FOR NEXT PLATTER
: GOSUB '50(" ")
: GOTO 260
0340 REM % RECOVER SPECIFIED/ACTIVE FILES
: PRINT AT(13,0,10*80);TAB(20);HEX(0E);"Option - ";
: IF O=2THEN PRINT "Recover active files only.";HEX(0F);
: ELSE PRINT "Recover Specified file.";HEX(0F);
0350 GOSUB '40(1,A1$,"@INDEX")
: T1,T3=A
: T2=B-2
: N$=ALL(00)
: GOSUB '40(1,A1$,"@DATA")
: S8=A
: S9=A+M-S0
: IF O=3THEN 450
0360 REM %ACTIVE FILES
0370 T3=T1
: IF N3$>HEX(FE)THEN 410
0380 IF POS(N$<>HEX(00))<>0THEN 400
: REM CHECK KEY
: IF K=K1THEN 390
: GOSUB '50("This platter does not belong to current set")
: GOTO 370
0390 REM CHECK PLATTER #
: IF N1=PTHEN 400
: GOSUB '50(" ")
: GOTO 370
0400 REM GET NEXT NAME
: GOSUB '130(0,1,N$,T3,T2)
: REM SECTOR #
: T3=T5
: N$=R9$
: IF Q$=" "THEN 430
: IF N3$<>" "THEN 420
: P=N1+1
: IF P>NTHEN 720
0410 REM DONE WITH THIS PLATTER
: N$=ALL(00)
: N3$=ALL(20)
: T3=T1
: GOTO 380
0420 REM SPANNING FILE LOCATION (LAST FILE TO RECOVER)
: N$=N3$
: GOSUB '130(1,1,N$,T1,T2)
: N3$=ALL(FF)
: REM LOCATION IN SET
: GOSUB 690
: REM RECOVER
: GOTO 630
0430 REM LOCATION IN SET
: GOSUB 690
: REM SKIP IF NOT ON THIS PLATTER
: IF P<>N1OR R3<1THEN 400
: REM RECOVER FILE OR WAIT TILL END IF IT SPANS
: DATA LOAD BA T#2,(0)A$()
: S4=VAL(STR(A$(),3),2)
: S4=S3-S4
: IF R5-R4<=R7-R6THEN 630
: N3$=R9$
: GOTO 400
0440 REM %SPECIFIED FILE
0450 PRINT AT(14,0,80);
: K$="Y"
: LINPUT "Do you want a print out of files you can recover?"-K$
: ON POS("YyNn"=K$)GOTO 460,460,480,480
: ELSE GOTO 450
0460 PRINT AT(14,0,80);
: LINPUT "Enter Printer Address"-P$
: GOSUB '206(P$)
: IF Q$<>" "THEN 460
: PRINT HEX(0C);"@RECOVER - INPUT DISK INDEX LISTING";HEX(0D0A);"NAME";TAB(
15);"STATUS";TAB(25);"START";TAB(35);"END"
: N$=ALL(00)
: T3=T1
0470 REM SCAN INDEX
: GOSUB '130(0,1,N$,T3,T2)
: IF Q$="N"THEN 480
: REM SECTOR #
: T3=T5
: N$=R9$
: PRINT N$;TAB(15);D$(MAX(1,-SGN(R3)+1));D$(ABS(R3)+2);TAB(25);R4;TAB(35);R
5
: GOTO 470
0480 SELECT PRINT 005
: PRINT AT(14,0 )
: T3=T1
0490 PRINT AT(15,0,320);
: N$=" "
: LINPUT "Name of file to be recovered",-N$
: IF N$=" "THEN 720
0500 REM SCAN INDEX
: GOSUB '130(1,1,N$,T1,T2)
: IF Q$=" "THEN 510
: PRINT AT(16,0);HEX(0E);"FILE ";N$;" Does not exist in this backup set. KE
Y RETURN";
: LINPUT Q1$
: PRINT AT(16,0,80);
: GOTO 490
0510 REM EXTRA SECTORS
: S2$=ALL("0")
: PRINT AT(18,0,80);
: LINPUT "Extra Sectors"-S2$
: CONVERT S2$TO E5
: ERRORGOTO 510
0520 E5=ABS(E5)
: DATA LOAD BA T#2,(0)A$()
: S3=VAL(STR(A$(),5),2)
: S4=VAL(STR(A$(),3,2),2)
: S4=S3-S4
: PRINT AT(15,0,320);
: REM LOCATION OF FILE IN SET
: GOSUB 690
0540 REM CHECK KEY
: IF K=K1THEN 550
: GOSUB '50("This platter does not belong to current set.")
: GOTO 540
0550 REM CHECK PLATTER #
: IF N1=PTHEN 560
: REM WRONG #
: GOSUB '50(" ")
: GOTO 540
0560 REM IS FILE ON OUTPUT DISK?
: GOSUB '40(2,A2$,N$)
: IF D<0 THEN 580
: IF D=0THEN 630
: U1=A
: U2=B
0570 K$="N"
: PRINT AT(18,0,80);"File ";N$;
: LINPUT " Already Exists. Ok to overwrite?"-K$
: ON POS("YyNn"=K$)GOTO 580,580,490,490
: ELSE GOTO 570
0580 REM CHECK OLD SIZE
: IF U2-U1<R5-R4+E5THEN 600
: SCRATCH T#2,N$
: ERRORGOSUB '90(A2$)
0581 IF ABS(R3)=1THEN SAVE T#2,(N$)N$10,10
: ELSE DATA SAVE DC OPEN T#2,N$,N$
: GOTO 640
0590 PRINT AT(18,0);HEX(07);"FILE SIZE EXCEEDS AVAILABLE DISK SPACE( ";S4;" SE
CTORS LEFT)";
: LINPUT "KEY RETURN",Q$
: PRINT AT(18,0,80)
: ON O-1GOTO 720,490
0600 REM CREATE JUNK NAME
: N1$="JUNKAAAA"
0610 GOSUB '40(2,A2$,N1$)
: IF D=0THEN 620
: I=POS(-N1$<"Z")
: STR(N1$,I,1)=ADDHEX(01)
: IF I<8THEN STR(N1$,I+1)=ALL("A")
: GOTO 610
0620 REM RENAME/SCRATCH
: SCRATCH T#2,N$
: ERRORGOSUB '90(A2$)
0621 DATA SAVE DC OPEN T#2,N$,N1$
: SCRATCH T#2,N1$
0630 IF R5-R4+E5+1>S4THEN 590
: REM %RECOVER
: IF ABS(R3)=1THEN SAVE T#2,(R5-R4+E5-2)N$10,10
: ELSE DATA SAVE DC OPEN T#2,(R5-R4+E5+1)N$
0640 REM COPY DATA
: PRINT AT(18,0,80);AT(18,20);"Recovering file ";N$
: GOSUB '40(2,A2$,N$)
: A3=A
: E7=R7-R6+1
0650 GOSUB '140(R6,R7,A3)
: REM GET NEXT FILE IF DONE
: IF R5-R4+1>E7THEN 660
: REM RESTORE TRAILER
: GOSUB '40(2,A2$,N$)
: DATA LOAD BA T#1,(R7)A$()
: DATA SAVE BA T#2,(B)A$()
: REM TURN FLAG OFF
: F2=0
: REM GET NEXT FILE
: ON OGOTO ,370,490
0660 REM SPANNING FILE
: A3=A3+R7-R6+1
: R7=MIN(S7-2,S8+R5-R4-E7)
: R6=S8
: E7=E7+R7-R6+1
: P=P+1
: REM FLAG CONDITION
: F2=1
: REM PROMPT FOR NEXT PLATTER
: GOSUB '50(" ")
0670 REM CHECK KEY
: IF K=K1THEN 680
: GOSUB '50("This platter does not belong to current set.")
: GOTO 670
0680 REM CHECK PLATTER #
: IF N1=PTHEN 650
: REM WRONG #
: GOSUB '50(" ")
: GOTO 670
0690 REM %FILE LOCATION IN SET
: DATA LOAD BA T#1,(0)A$()
: REM END CATALOG AREA
: S7=VAL(STR(A$(),5,2),2)-1
0700 REM PLATTER #
: P=INT(R4/(S7-S8-1))+1
: REM START& END
: R6=S8+MOD(R4,S7-S8-1)
: R7=MIN(R6+R5-R4,S7-2)
: RETURN
0710 REM % SUBROUTINES
0720 REM %END
: PRINT AT(18,0,240);AT(19,10);BOX(-1,-50);HEX(020D0C0F);AT(19,0);"END OF R
ECOVERY"
0721 END
0730 REM % DISPLAY ERR
0740 DEFFN'90(STR(E$,,3))
: E=ERR-1
: RESTORE LINE9000
: RESTORE MAX(E,88)-87
: READ STR(E$,4,47)
0750 PRINT HEX(0706);AT(14,10);"ERROR ";STR(E$,4,1);E+1;" at address ";STR(E$,
,3);AT(15,10);STR(E$,5,46);AT(16,10);
: LINPUT "KEY RETURN",Q1$
: Q$="I"
: PRINT HEX(06);AT(14,0,240);
: RETURN
0760 REM % CHECK/SELECT/HOG ADDR
0770 DEFFN'205(R,W3$)
: Q$=" "
: MAT SEARCH"310320330350360370B10B20B30B50B60B70D10D11D12D13D14D15D20D21D2
2D23D24D25D30D31D32D33D34D35D50D51D52D53D54D55D60D61D62D63D64D65D70D71D72
D73D74D75",=STR(W3$,,3)TO Q6$STEP 3
: IF Q6$<>HEX(0000)THEN 790
: Q$="I"
: RETURN
0790 SELECT #R<W3$>
: $OPEN 820,#R
: ERRORGOSUB '90(W3$)
: RETURN
0800 DATA LOAD BA T#R,(0)A$()
: ERRORGOSUB '90(W3$)
0810 RETURN
0820 Q$="I"
: PRINT AT(10,10,70);"Device ";W3$;" is hogged. Key RETURN when ready";
: LINPUT Q1$
: PRINT AT(10,0,13*80);
: RETURN
0821 REM % CHECK PRINTER ADDR
0822 DEFFN'206(W3$)
: Q$=" "
: MAT SEARCH"00001D204211212213214215216217005",=STR(W3$,,3)TO Q6$STEP 3
: IF Q6$<>HEX(0000)THEN 826
: Q$="I"
: RETURN
0826 SELECT PRINT <W3$>
: RETURN
0830 REM %CHECK INPUT PLATTER
: PRINT AT(14,10,8*80 + 70);HEX(060E);"Validating Input Platter";
0840 FOR I=1TO 4
: RESTORE LINE9040
: READ F$
: GOSUB '40(1,A1$,F$)
: IF D=2THEN 850
: PRINT HEX(07);AT(15,10,70);"Input platter illegal; it does not contain ";
F$;
: PRINT AT(16,10,5*80);
: LINPUT "Mount a new input platter and key RETURN",Q1$
: GOTO 840
0850 NEXT I
: PRINT AT(14,10,7*80);
: RETURN
0860 REM % WRONG KEY OR PLATTER #
0870 DEFFN'50(E$)
: PRINT AT(21,0,80);E$;AT(22,0,80);"Mount platter number ";P;"of current se
t and key RETURN";
: LINPUT Q1$
: PRINT AT(21,0,160)
0880 REM CHECK FORMAT
: GOSUB 830
: REM READ @LABEL
: GOSUB 1010
: GOSUB 990
: RETURN
0890 REM %Display Bar
0900 DEFFN'100(Z,Z1,Z2)
: Z2=INT(Z2)
: PRINT HEX(0202020F06)
: IF Z2<>0THEN 910
: PRINT AT(Z,Z1,51);BOX(1,50);
: P1=0
0910 ON SGN(Z2-P1)+2GOTO 920,960,930
0920 P1=0
: GOTO 940
0930 REM Fill
: P1=P1+1
0940 IF P1<>1THEN 950
: PRINT AT(Z,Z1+P1/2);HEX(EA);
: GOTO 910
0950 IF MOD(P1,2)=0THEN PRINT AT(Z,Z1+P1/2);HEX(D5);
: ELSE PRINT AT(Z,Z1+P1/2);HEX(FF);
: GOTO 910
0960 PRINT HEX(0202000F);
: RETURN
0970 REM % DISPLAY LABEL
0980 REM READ
: GOSUB 1010
: REM DISPLAY
: PRINT HEX(06);AT(4,0,19*80);"Date of Backup: ";G$;AT(4,34);"Backup Identi
fication #: ";K;AT(6,0);"Description: ";D1$;AT(8,0);"Created by: ";O$;
0990 PRINT AT(10,0,160);"This is platter ";N1;" of ";N;" which contains sector
s ";S0;" - ";M;" of original disk. "
: RETURN
1000 REM % READ @LABEL
1010 DATA LOAD DC OPEN T#1,"@LABEL"
: ERRORGOSUB '90(A2$)
: GOTO 1010
1020 DATA LOAD DC #1,K,G$,D1$,O$,S1,N1,N,S0,M
: RETURN
1030 REM % SCAN INDEX
1040 DEFFN'130(R,R0,R$,R8,R9)
: Q$="N"
: REM INDEX SECTORS
: FOR I=R8TO R9
: DATA LOAD BA T#R0,(I)A$()
: REM SLOT WITHIN SECTOR
: FOR J=1TO 16
: IF POS(STR(A$(),J*16-15)<>HEX(00))=0THEN 1080
: IF R8=T1AND I=R8AND J=1OR STR(A$(J,1),,1)=HEX(21)THEN 1090
1050 IF A$(J,2)<>R$AND R$>HEX(00)THEN 1090
: R9$=A$(J,2)
: IF POS(R$<>HEX(00))=0OR R<>0THEN 1060
: R$=ALL(00)
: GOTO 1090
1060 REM STATUS/TYPE
: $TRAN(STR(A$(J,1),2,1),HEX(01800200))R
: R3=VAL(STR(A$(J,1),2,1))
: IF STR(A$(J,1),,1)=HEX(11)THEN R3=-R3
1070 REM START
: R4=VAL(STR(A$(J,1),3,2),2)
: REM END
: R5=VAL(STR(A$(J,1),5,2),2)
: Q$=" "
: REM SECTOR
: T5=I
: I=R9
1080 J=16
1090 NEXT J
: NEXT I
: RETURN
1100 REM % SCRATCH OUTPUT DISK
1110 DEFFN'80(R1,R2)
: Q$=" "
: DATA LOAD BA T#2,(R2)A$()
: ERRORGOSUB '90(A2$)
: Q$="I"
: RETURN
1120 PRINT AT(18,20,60);"Scratching output disk";
: SCRATCH DISK T#2,LS=R1,END =R2
: PRINT AT(18,20,60);
: RETURN
1130 REM % COPY
1140 DEFFN'140(C0,C1,C2)
: COPY T#1,(C0,C1)TO T#2,(C2)
: RETURN
1150 REM % BAD SECTOR HANDLING
1160 DEFFN'145(B1,B2)
: REM ABS ADDR
: B1=B1+S0
: B2=B2+S0
: Q$=" "
: DATA LOAD DC OPEN T#3,"@BADSCTR"
: I1=-1
1165 I1=I1+1
: DATA LOAD DC #3,E$()
: IF END THEN RETURN
1170 P8=POS(E$()<>HEX(00))
: IF P8=0THEN 1165
: REM FIND BIT
: FOR I=1TO 8
: C$=B$(I)AND STR(E$(),P8,1)
: IF C$=HEX(00)THEN 1210
: REM BIT FOUND
: B6=I1*1920+(P8-1)*8+I-1+S0
: STR(E$(),P8,1)=XOR B$(I)
: IF B6<B1-S8THEN 1170
: IF B6>B2-S8THEN RETURN
: IF P$<>" "THEN 1190
1180 PRINT AT(14,0,80);
: LINPUT "Enter printer address for report of bad sectors"-P$
: GOSUB '206(P$)
: IF Q$<>" "THEN 1180
: PRINT AT(14,0,80);
1190 IF F2$<>" "THEN 1200
: F2$="1"
: PRINT HEX(0C);"@RECOVER. REPORT OF BAD SECTORS DATE: ";G$;" BACKUP I
D:";K
: PRINT
1200 REM DISPLAY ADDR
: SELECT PRINT <P$>
: PRINT "SECTOR #";
: IF O<>1THEN PRINT B6-R4+1;" OF FILE ";N$;
: ELSE PRINT B6;
: PRINT " WAS BAD AT BACKUP TIME AND WAS REPLACED WITH HEX(00)'s"
: SELECT PRINT 005
1210 NEXT I
: GOTO 1170
1220 REM % VERIFY
1230 DEFFN'150(V1,V2)
: VERIFY T#2,(V1,V2)E
: RETURN
1240 REM % LIMITS
1250 DEFFN'40(R,W3$,F$)
: LIMITS T#R,F$,A,B,D,D
: ERRORGOSUB '90(W3$)
: GOTO 1250
1260 RETURN
8960 REM %ERRS
9000 DATA "PIllegal device address","IDisk Hardware Error","IDisk Hardware Err
or","ITimeout Error","IDisk Format Error","IFormat Key Engaged","IDevice
Error (May Be a Protected Platter)","ICyclic Read Error"
9010 DATA "ILRC Error","IIllegal sector address or platter not mounted","IRead
After Write Error"
9020 REM %SYSTEM FILES
9040 DATA "@LABEL","@INDEX","@BADSCTR","@DATA"