Listing of file='@RECOVER' on disk='vmedia/mvp-cs386-1.30-disk2.wvd.zip'
# Sector 1055, program filename = '@RECOVER' 0010 REM !@RECOVER 01/09/89 By PLS (Mod. by TBO) Rel 3.3 0015 REM ! (c) Copr. Wang Laboratories, Inc. 1985, 1986, 1989 : REM ! All rights reserved 0020 DIM A1$3,A2$3,G$8,D1$60,O$50,A$1 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(5);"***** Recovery Utility - (c) Copr. Wang Laborator ies, Inc. 1989 *****";HEX(0F);AT(23,0);"Press FN/TAB to return to menu."; HEX(01) 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 overwritten)";HEX(0F);AT(15,0);"2-Recover all active files";HEX(0 E);" ( WARNING! Output disk will be scratched)";HEX(0F);AT(16,0);"3-Recov er 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 720 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; : Q$=" " 0290 REM % RECOVER : GOSUB '140(E1,MIN(E1+E2-1,S9),E4) 0291 IF Q$ = "I" THEN 720 0294 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) 0652 IF Q$ = "I" THEN 720 0655 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 : KEYIN K$,720,720 : PRINT HEX(0E06);AT(18,0,);AT(19,10);BOX(-1,-50);AT(23,0);"Recovery comple ted - Press any key to exit.";HEX(01) : KEYIN K$ 0721 DEFFN'126 0722 DEFFN'127 : $CLOSE : PRINT HEX(060E);AT(23,0,);"(Returning to System Menu)";HEX(01) : $PSTAT=" " : LOAD T"@MENU" 0730 REM % DISPLAY ERR 0740 DEFFN '90(STR(E$,,3)) : E=ERR-1 0741 DEFFN'91(STR(E$,,3)) : RESTORE LINE9000 : RESTORE MAX(E,88)-87 : READ STR(E$,4,47) 0750 PRINT HEX(0706);AT(15,10);"ERROR ";STR(E$,4,1);E+1;" at address ";STR(E$, ,3);AT(16,10);STR(E$,5,46);AT(17,10); : LINPUT "KEY RETURN",Q1$ : Q$="I" : PRINT HEX(06);AT(15,0,240); : RETURN 0760 REM % CHECK/SELECT/HOG ADDR 0775 DEFFN'205(R,W3$) : IF W3$="340"THEN 785 : $TRAN(W3$,"AaBbCcDdEeFf")R : IF POS("DB3"=W3$)>0AND POS("123567"=STR(W3$,2))>0AND VER(STR(W3$,3),"H")> 0THEN 780 : Q$="I" : RETURN 0780 IF POS("3B"=W3$)=0OR POS("123"=STR(W3$,2))=0OR STR(W3$,3)<>"0"THEN 785 : IF STR(W3$,,1)="3"THEN STR(W3$,3)="1" : STR(W3$,,1)="D" 0785 Q$=" " 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 A$="N" : PRINT AT(18,0,60); : LINPUT "Use new disk index hashing algorithm? ",-A$ 1121 IF A$="N" OR A$="n" THEN GOTO 1129 1122 IF A$="Y" OR A$="y" THEN GOTO 1128 1123 GOTO 1120 1128 PRINT AT(18,0,60);"Scratching output disk"; : SCRATCH DISK ' T#2,LS=R1,END =R2 : PRINT AT(18,20,60); : RETURN 1129 PRINT AT(18,20,60);"Scratching output disk"; : SCRATCH DISK T#2,LS=R1,END =R2 : PRINT AT(18,0,60); : RETURN 1130 REM % COPY 1140 DEFFN'140(C0,C1,C2) : COPY T#1,(C0,C1)TO T#2,(C2) : ERRORGOSUB '90(A2$) 1141 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","IDestination platter too small or not mounted","IRead After Write Error" 9020 REM %SYSTEM FILES 9040 DATA "@LABEL","@INDEX","@BADSCTR","@DATA"