Listing of file='@BACKUP' on disk='vmedia/mvp-boot-2.6.2.wvd.zip'
# Sector 1510, program filename = '@BACKUP' 0010 REM % Prog = @BACKUP By PLS Date = 02/01/85 Rel 2.6 0015 REM % COPYRIGHT WANG LABORATORIES 1985 0020 REM %VARIABLES 0030 DIM A1$3,A2$3,G$8,D1$60,O$50 0040 DIM K$1,A$(16,2)8,E$50,Q$1,Q1$1,U9$8,E$(2)120,E1$(32)1,D2$60,P$3,Q7$13,Q6 $2,B$(8)1,C$1,N$5 0050 REM A$(-SECTOR BUFFER : REM A1$-INPUT ADDR : REM A2$-OUTPUT ADDR : REM D1$-BACKUP DESC. 0060 REM G$-DATE : REM O$-OPERATOR'S NAME : REM S2-# INPUT SECTORS : REM S0,M-PART OF ORIGINAL DISK CONTAINED IN THIS PLATTER : REM S9-START OUTPUT SECTOR OF CURRENT PLATTER 0070 REM S8-END OUTPUT DISK : REM N-# PLATTERS IN SET : REM N1-PLATTER # 0080 REM % MAIN LINE 0090 REM INIT : N1=1 : B$()=HEX(8040201008040201) : A1$="D11" : A2$="D10" : G$="mm/dd/yy" : S1,S0=0 0100 REM %INPUT 0110 REM ATTRIBUTES : PRINT HEX(020D0C030F020402000F) 0120 PRINT HEX(060E);TAB(20);"***** BACKUP UTILITY *****";AT(23,0,79);"Press ' FN' or 'TAB' to return to menu.";HEX(0F); 0130 REM %ADDRS 0140 PRINT AT(2,0); : LINPUT "Input Address: "-A1$ : GOSUB '205(1,A1$) : IF Q$<>" "THEN 140 0150 PRINT AT(2,34); : LINPUT "Output Address: ",-A2$ : GOSUB '205(2,A2$) : IF Q$<>" "OR A2$=A1$THEN 150 : SELECT #3<A2$> 0160 REM %DATE, DESC., OPERATOR'S NAME 0170 STR(G$,3,1),STR(G$,6,1)="/" : PRINT HEX(06);AT(4,0,160); : LINPUT "Today's Date is: ",-G$ : GOSUB '221(G$) : IF Q$<>" "THEN 170 : G$=U9$ 0180 PRINT AT(6,0); : LINPUT "Backup Description:",-D1$ 0190 PRINT AT(8,0); : LINPUT "Operator's Name: ",-O$ 0200 REM %INPUT DISK : DATA LOAD BA T#1,(0)A$() : ERRORGOSUB '90(A1$) : $CLOSE#1 : GOTO 200 0210 REM INDEX SECTORS : T0=VAL(STR(A$(),2,1)) : REM CURRENT END : S2,S1=VAL(STR(A$(),3,2),2)-1 : REM END OF DISK : S3=VAL(STR(A$(),5,2),2)-1 0220 REM OPTIONS 0230 PRINT AT(12,0,80);"Options: ";AT(13,0,80);"Current end (End of Catalogued Data) - ";S2;AT(14,0,80);"End of Catalogue Area (As specified in the Ind ex) - ";S3; 0240 PRINT HEX(06);AT(10,0); : CONVERT S2TO N$,(#####) : LINPUT "Copy starts at sector 0 and ends at sector:"-N$ : CONVERT N$TO S2 : ERRORGOTO 240 0250 IF INT(S2)<>S2OR S2<S1OR S2>2^16-1THEN 240 0260 IF S2<>S1AND S2<>S3THEN DATA LOAD BA T#1,(S2)A$() : ERRORGOTO 240 0280 REM %VERIFY INPUT INDEX : E$(),E1$()=ALL(00) : E1=0 : PRINT AT(18,20);"Verifying input index"; 0290 GOSUB '150(1,E1,T0-1) : IF E=0THEN 300 : REM RECOVER BAD SECTOR : GOSUB '125 : REM BAD SECTOR ON ENTRY : E1$()=E$() : E1=E : REM VERIFY NEXT RANGE : IF E1<=T0-1THEN 290 0300 E$()=ALL(00) 0310 REM %OUTPUT DISK : DATA LOAD BA T#2,(0)A$() : ERRORGOSUB '90(A2$) : $CLOSE#2 : GOTO 310 0320 REM %OUTPUT DISK : REM INDEX SIZE : S5=VAL(STR(A$(),2)) : REM CURRENT END : S6=VAL(STR(A$(),3,2),2) : REM PHYSICAL END : S7=VAL(STR(A$(),5,2),2) 0330 REM Figure out platter size. If not 1st diskette, skip routine. : IF N1>1THEN 360 0340 REM If formatted platter, default=3978. If scratched platter, default=No. indicated in catalog & warn if 'current end'<>index size(==> might be va lid data on platter) 0350 REM DEFAULT DISK SIZE : IF S5=0OR S5>S6+1OR S6>S7THEN S8=3874 : ELSE S8=S7 0360 IF S6<=S5THEN 390 : GOSUB '60 : IF Q$<>" "THEN 310 0370 PRINT HEX(06);AT(12,0,320);HEX(0D0A);"Warning: The contents of the output platter will be replaced by the backup data. Your output platter seems t o contain valid data." 0380 PRINT AT(16,0,240); : K$="N" : LINPUT "Are you sure you want to use this platter? (If not, mount a new p latter)"-K$ : ON POS("YyNn"=K$)GOTO 390,390,310,310 : ELSE GOTO 380 0385 S8=S8+1 : GOTO 420 0390 PRINT AT(12,0,400);AT(14,0); : REM % INITIALIZE OUTPUT DISK : IF N1>1THEN 440 : REM %OUTPUT DISK SIZE 0420 PRINT HEX(06);AT(11,0); : CONVERT S8TO N$,(#####) : LINPUT "Number of sectors in Output Platter: ",-N$ : CONVERT N$TO S8 : ERRORGOTO 420 0430 S8=S8-1 : IF INT(S8)<>S8OR S8>2^16-1THEN 385 : REM COMPARE AGAINST MIN # OF SECTORS NEEDED : IF S8-1<T0-INT(-S8/2000)+10THEN 385 : DATA LOAD BA T#2,(S8)A$() : ERRORGOSUB '90(A2$) : GOTO 385 0440 REM SCRATCH OUTPUT : PRINT HEX(06);AT(18,20,);"Scratching output platter"; : SCRATCH DISK T#2,LS=1,END =S8 : ERRORGOSUB '90(A2$) : GOTO 440 0441 LIMITS T"@RECOVER",A,B,C,D : IF S8<B-A+T0-INT(-S8/2000)+11THEN 470 0450 REM TRY TO SAVE 'START' : PRINT AT(18,20,60);"Saving 'START'"; : SAVE T#2,"START"1260,1280 : ERRORREM 0460 REM TRY TO SAVE '@RECOVER' : PRINT AT(18,20,60);"SAVING '@RECOVER'"; : MOVE T"@RECOVER"TO T#2, : ERRORREM 0470 REM CREATE & INIT '@BADSCTR' : PRINT AT(18,20,60);"Creating '@BADSCTR'"; : GOSUB '160(3,-INT(-S8/2000)+2,"@BADSCTR",A2$) : FOR I=1TO -INT(-S8/2000) : DATA SAVE DC #3,E$() : NEXT I : DATA SAVE DC #3,END : DBACKSPACE #3, BEG : I1 = -1 0480 REM CREATE '@INDEX' (& RECOVER BAD SECTORS) : PRINT AT(18,20,60);"Creating '@INDEX'"; : GOSUB '160(2,T0+2,"@INDEX",A2$) : REM START OUTPUT SECTOR : LIMITS T#2,"@INDEX",A,S9,C,C : S9=S9+3 0490 E$()=E1$()&ALL(00) : REM COPY INDEX : GOSUB '135(0,T0-1,A) : DSKIP #2,(T0)S : DATA SAVE DC #2,END : E$()=ALL(00) 0500 PRINT HEX(06);AT(15,0,240) : IF N1>1THEN 515 : REM %CALC. OUTPUT PARAMETERS & DISPLAY TITLES : REM # PLATTERS NEEDED = (# INPUT SECTORS)/(AVAILABLE SPACE IN OUTPUT PLAT TER) : N=-INT(-S2/(S8-S9)) : REM CREATE RND KEY : K=INT(RND(1)*1E6) 0510 REM DISPLAY LABEL : PRINT AT(4,34);"Backup Identification #: ";K; 0515 PRINT AT(12,0);"This is platter";TAB(20);" of";N;"which contains sectors" ;TAB(57);"through"; 0520 REM CALC LAST SECTOR CONTAINED IN CURRENT PLATTER : M=MIN(S2,S0+S8-S9-3) : REM DISPLAY PLATTER # & SECTORS TO COPY : PRINT AT(12,17);N1;AT(12,50);S0;AT(12,64);M 0530 REM CREATE '@LABEL' : PRINT AT(18,20,60);"Creating '@LABEL'"; : GOSUB '160(2,3,"@LABEL",A2$) : DATA SAVE DC #2,K,G$,D1$,O$,S2,N1,N,S0,M : DATA SAVE DC #2,END 0540 REM START & END SECTORS TO VERIFY : E1=S0 : E2=MAX(INT((M-S0)/25),1) : E3=0 : REM VERIFY CURRENT PORTION OF INPUT PLATTER : PRINT AT(18,20,70);"Verifying input data"; : GOSUB '100(19,10,0) 0550 GOSUB '150(1,E1,MIN(E1+E2-1,M)) : IF E=0THEN 560 : GOSUB '125 : E1=E : E3=E3+MAX(1,-INT(-25/MAX(1,(M-S0)))) : GOTO 550 0560 REM GET NEXT 100 SECTORS : E1=MIN(E1+E2,M+1) : E3=E3+MAX(1,-INT(-25/MAX(1,(M-S0)))) : REM DISPLAY % VERIFIED : GOSUB '100(19,10,MIN(4*E3,100)) : PRINT AT(21,10); : IF E1<=MTHEN 550 0570 REM %BACKUP LOOP : REM CREATE '@DATA' : GOSUB '160(2,MIN(S8-S9,S2-S0+3),"@DATA",A2$) : REM INIT COPY PARAMETERS : E3=0 : E1=S0 : E4=S9+1 : PRINT AT(18,20,60);"Copying Data"; : GOSUB '100(19,10,0) 0580 REM COPY : GOSUB '135(E1,MIN(E1+E2-1,M),E4) : E3=E3+MAX(1,-INT(-25/MAX(1,(M-S0)))) : E1=MIN(E1+E2,M+1) : E4=MIN(E4+E2,E4+M-S0+2) : GOSUB '100(19,10,MIN(4*E3,100)) : IF E1<=MTHEN 580 0590 REM %SET END OF FILE : DSKIP #2,M-S0+1S : DATA SAVE DC #2,END 0600 REM INIT SECTOR COUNTER : E1,E3=0 : E2=MAX(INT((M-S0+S9+2)/25),1) : GOSUB '100(19,10,0) : PRINT AT(18,20,60);"Verifying output data"; 0610 REM %VERIFY LOOP (100 SECTORS/TIME) : GOSUB '150(2,E1,MIN(S8-2,E1+E2)) : IF E=0THEN 620 : PRINT HEX(06070E);AT(13,10);"Error in sector ";E-1;" in output platter, m ount a new one and" : PRINT "key RETURN"; : LINPUT Q1$ : GOTO 310 0620 REM E2=LAST SECTOR VERIFIED : E1=MIN(S8-1,E1+E2+1) : E3=MAX(E3+1,-INT(-E1*25/MAX(1,(M-S0+S9)))) : GOSUB '100(19,10,MIN(4*E3,100)) : IF E1<=MIN(S8-2,S9+S2-S0+2)THEN 610 0630 PRINT AT(18,20,60) : REM VERIFY DONE : I1=-1 : REM REPORT BAD SECTORS : DATA LOAD DC OPEN T#2,"@BADSCTR" 0640 DATA LOAD DC #2,E$() : IF END THEN 670 : I1=I1+1 : B1=1 : IF POS(E$()<>HEX(00))=0THEN 640 : IF P$<>" "THEN 660 0650 PRINT AT(22,0,80); : LINPUT "ENTER PRINTER ADDRESS FOR LISTING OF BAD SECTORS"-P$ : GOSUB '206(15,P$) : IF Q$<>" "THEN 650 : PRINT HEX(0C);"PLATTER: ";A1$;" (";N1;"OF";N;") DATE: ";G$;" BACKUP I D:";K : PRINT : I1=0 0660 REM TRANSLATE BIT TO SECTOR ADDR & PRINT : SELECT PRINT <P$> : B5=POS(STR(E$())<>HEX(00)) : IF B5=0THEN 640 : GOSUB '145(B5,I1) : PRINT "ERROR IN SECTOR ";B6 : IF B5>=240THEN 640 : GOTO 660 0670 SELECT PRINT 005 : PRINT AT(19,10,160);BOX(-1,-50);AT(19,0); : I1=-1 : REM %OUTPUT PLATTER FULL OR BACKUP END : REM UPDATE START SECTOR : S0=M+1 : N1=N1+1 : IF S0>S2THEN 680 : PRINT AT(22,0,80);"MOUNT PLATTER # ";N1;" AND KEY RETURN"; : Q$=" " : LINPUT Q$ : PRINT AT(22,0,80); : GOTO 310 0680 REM %BACKUP DONE : PRINT HEX(020D0C0F);AT(19,0,4*80);"END OF BACKUP"; 0681 GOTO 9030 0690 REM %SUBROUTINES 0700 REM %DISPLAY ERR MSG 0710 DEFFN'90(STR(E$,,3)) : E=ERR-1 : RESTORE MAX(E,88)-87 : READ STR(E$,4,47) 0720 PRINT HEX(07060E);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,); : RETURN 0730 REM %CHECK OUTPUT PLATTER 0740 DEFFN'60 : Q$=" " : LIMITS T#2,"@LABEL",A,A,A,A : IF A<>2THEN RETURN 0750 DATA LOAD DC OPEN T#2,"@LABEL" : DATA LOAD DC #2,K2,U9$,D2$ : ERRORGOSUB '90(A2$) : GOTO 750 0760 IF K2<>KOR N1<=1THEN RETURN : Q$="I" : PRINT AT(13,0);"Output platter contains a portion of current backup, moun t a new one and" : LINPUT "key RETURN"-Q1$ : RETURN 0770 REM %SELECT/CHECK DISK ADDR & HOG DISK 0780 DEFFN'205(R,W3$) : Q$=" " : MAT SEARCH"310320330350360370B10B20B30B50B60B70D10D11D12D13D14D15D20D21D2 2D23D24D25D30D31D32D33D34D35D50D51D52D53D54D55D60D61D62D63D64D65D70D71D72 D73D74D75",=STR(W3$,,3)TO Q6$STEP 3 : IF Q6$<>HEX(0000)THEN 800 : Q$="I" : RETURN 0800 SELECT #R<W3$> : $OPEN 870,#R : ERRORGOSUB '90(W3$) : RETURN 0810 DATA LOAD BA T#R,(0)A$() : ERRORGOSUB '90(W3$) 0820 RETURN 0830 REM %SELECT/CHECK PRINT ADDR 0840 DEFFN'206(R,W3$) : Q$=" " : MAT SEARCH"00000501D204211212213214215216217",=STR(W3$,,3)TO Q6$STEP 3 : IF Q6$<>HEX(0000)THEN 850 : Q$="I" : RETURN 0850 SELECT #R<W3$> : $OPEN 870,#R : ERRORGOSUB '90(W3$) : Q$="I" : RETURN 0860 SELECT PRINT <W3$> : RETURN 0870 Q$="I" : PRINT AT(13,10,70);W3$;" is Hogged. Key RETURN to try again"; : LINPUT Q1$ : PRINT AT(13,10,70); : RETURN 0880 REM %CHECK DATE 0890 DEFFN'221(U9$) : Q$=" " : REM PAD SINGLE DIGITS WITH "0" : MAT COPY -STR(U9$,1,LEN(U9$))TO -U9$ : IF STR(U9$,7,1)="/"THEN STR(U9$,1,7)=STR(U9$,2,6)&"0" : IF STR(U9$,4,1)="/"THEN STR(U9$,1,4)=STR(U9$,2,3)&"0" : IF STR(U9$,1,1)=" "THEN STR(U9$,1,1)="0" 0900 REM CHECK FORM : IF VER(U9$,"##/##/##")<>8THEN 920 : REM CHECK MO. : CONVERT STR(U9$,1,2)TO U0 : IF U0<1OR U0>12THEN 920 : REM CHECK YR. : CONVERT STR(U9$,7,2)TO U9 : IF U9=0THEN 920 0910 REM DAYS/MO. (1 BYTE COUNT/MO.; ADJUST FEB. IF LEAP YR.) : Q7$=HEX(001F1C1F1E1F1E1F1F1E1F1E1F) : IF MOD(U9,4)=0THEN STR(Q7$,3,1)=HEX(1D) : REM CHECK DAYS : CONVERT STR(U9$,4,2)TO U6 : IF U6>=1AND U6<=VAL(STR(Q7$,U0+1,1))THEN RETURN 0920 Q$="E" : RETURN 0930 REM %'100 -- Display Bar : REM Entry-- : REM R=row : REM C=column : REM P=% (call 1st with 0%) : REM 0940 DEFFN'100(Z,Z1,Z2) : Z2=INT(Z2) : PRINT HEX(0202020F06); : IF Z2<>0THEN 950 : PRINT AT(Z,Z1,51);BOX(1,50); : P1=0 0950 ON SGN(Z2-P1)+2GOTO 960,1000,970 0960 P1=0 : GOTO 980 0970 REM Fill : P1=P1+1 0980 IF P1<>1THEN 990 : PRINT AT(Z,Z1+P1/2);HEX(EA); : GOTO 950 0990 IF MOD(P1,2)=0THEN PRINT AT(Z,Z1+P1/2);HEX(D5); : ELSE PRINT AT(Z,Z1+P1/2);HEX(FF); : GOTO 950 1000 PRINT HEX(020400000E0202000F); : RETURN 1010 REM %WRITE BAD SECTOR IN BIT MAP 1020 DEFFN'125 : E$()=ALL(00) : DATA LOAD DC OPEN T#3,"@BADSCTR" : DSKIP #3,INT((E-S0-1)/1920)S : DATA LOAD DC #3,E$() : DBACKSPACE #3,1S : REM WRITE BIT : B5=MOD(INT((E-S0-1)/8),240)+1 : B6=MOD(E-S0-1,8)+1 : STR(E$(),B5,1)=OR B$(B6) : GOSUB '170 : C8=C8+1 : RETURN 1040 REM % READ BIT MAP, COPY GOOD SECTORS/REPLACE BAD WITH HEX(00)'S 1050 DEFFN'135(B2,B3,D1) : IF INT((B2-S0)/1920)=I1AND INT((B3-S0)/1920)=I1THEN 1070 1055 IF B3<=T0-1 THEN 1070 1060 DATA LOAD DC #3,E$() : IF END THEN 1090 : I1=I1+1 1070 REM 1ST ACTIVE BYTE ON MAP : B5=POS(E$()<>HEX(00)) : IF B5=0AND B3<=T0-1THEN 1090 : IF B5=0 AND INT((B3-S0)/1920)=I1 THEN 1090 : IF B5=0THEN 1060 : REM BAD SECTOR FOUND : GOSUB '145(B5,I1) : IF B6<B2THEN 1070 : IF B6>B3THEN 1090 : IF B2<B6THEN GOSUB '140(B2,B6-1,D1) 1075 E=B6+1 : GOSUB '180 : IF Q$<>" "THEN A$()=ALL(00) : DATA SAVE BA T#2,(D1+B6-B2)A$() : IF Q$<>" "THEN 1080 : DBACKSPACE #3,1S : DATA LOAD DC #3,E$() : GOSUB '145(B5,I1) : DBACKSPACE #3,1S : DATA SAVE DC #3,E$() 1080 D1=D1+B6-B2+1 : B2=B6+1 : GOTO 1070 1090 IF B2<=B3THEN GOSUB '140(B2,B3,D1) : RETURN 1100 REM %COPY 1110 DEFFN'140(C1,C2,C4) : COPY T#1,(C1,C2)TO T#2,(C4) : RETURN 1120 REM %VERIFY 1130 DEFFN'150(R,V1,V2) : E0=5 1135 VERIFY T#R,(V1,V2)E : IF E=0THEN RETURN : E0=E0-1 : IF E0<>0THEN 1135 : RETURN 1140 REM %CREATE FILE 1150 DEFFN'160(R,F1,R$,W3$) : DATA SAVE DC OPEN T#R,(F1)R$ : ERRORGOSUB '90(W3$) : GOTO 1150 1160 RETURN 1170 REM %CREATE BAD SECTOR INFO. 1180 DEFFN'170 : DATA SAVE DC #3,E$() : DATA SAVE DC #3,END : E$()=ALL(00) : RETURN 1190 REM %READ BAD SECTOR 1200 DEFFN'180 : Q$="E" : I=1 1210 DATA LOAD BA T#1,(E-1)A$() : ERRORI=I+1 : IF I<=2THEN 1210 : RETURN 1220 REM FLAG SECTOR RECOVERED : Q$=" " : RETURN 1230 REM %GET ADDR FROM BIT MAP 1240 DEFFN'145(B7,B8) : FOR I=1TO 8 : C$=B$(I)AND STR(E$(),B7,1) : IF C$=HEX(00)THEN 1250 : REM SECTOR ADDR : B6=S0+(B7-1)*8+I-1+B8*1920 : STR(E$(),B7,1)=XOR B$(I) : I=8 1250 NEXT I : RETURN 1260 REM %START. 06/18/80. LOAD "@RECOVER" 1270 PRINT HEX(03060E);"LOADING - ";BOX(1,9);" @RECOVER"; 1280 LOAD T"@RECOVER" 9000 REM %ERRORS 9010 DATA "PIllegal Device Address","IDisk Hardware Error","IDisk Hardware Err or","ITimeout Error","IDisk Format Error","IFormat Key Engaged","IDevice Error (Platter may be protected)","ICyclic Read Error" 9020 DATA "ILRC Error","IIllegal sector address or platter not mounted","IRead After Write Error" 9030 DEFFN '126 9040 DEFFN '127 9050 LOAD RUN