001 REM ------------ LAWRENCE UNIVERSITY ------------ REM ------------ COMPUTER CENTER ------------ REM ------------ APPLETON, WISCONSIN 54911 ------ 002 REM ------------ (414) 739-3681 ------------ !--------------- REM -- PROGRAM NAME, VERSION AND DATE -- 003 REM -- MOVERX VERSION 1A 12-JULY-74 !--------------- REM -- PROGRAM AUTHORSHIP -- 004 REM -- MOVERX WAS WRITTEN BY MARK WILLIAMSON REM -- OF THE LAWRENCE UNIVERSITY COMPUTER CENTER. !--------------- 005 REM -- PURPOSE OF PROGRAM -- REM -- MOVERX IS A GENERAL PURPOSE FILE MOVER AND PERIPHERAL REM -- INTERCHANGE PROGRAM. 006 !--------------- REM -- OPERATING SYSTEM AND REQUIREMENTS -- REM -- MOVERX IS WRITTEN IN BASIC-PLUS FOR OPERATION UNDER 007 REM -- RSTS-11 ON A PDP-11; AT LEAST 8K OF USER CORE MUST REM -- BE AVAILABLE. !--------------- 008 REM -- AVAILABILITY -- REM -- MOVERX IS A NON-PROPRIETARY PROGRAM PRODUCT OF LAWRENCE REM -- UNIVERSITY. IT IS DISTRIBUTED AT COST FOR EDUCATIONAL 009 REM -- USE ON THE CONDITION THAT IT NOT BE SOLD, RENTED, OR REM -- LEASED FOR PROFIT. !--------------- 010 REM -- LIMITATIONS -- REM -- MOVERX WILL SUPPORT ANY NUMBER AND TYPE OF DISK, BUT REM -- IT WILL SUPPORT ONLY TWO DECTAPE DRIVES. !--------------- 011 REM -- FURTHER DOCUMENTATION -- REM -- COMPLETE DOCUMENTATION IS AVAILABLE IN REM -- ESPD NO. PDP11/73/011. !--------------- 012 REM -- DISCLAIMER -- REM -- NEITHER THE AUTHOR OF THIS PROGRAM NOR LAWRENCE UNIVER- REM -- SITY ASSUME ANY LIABILITY, EXPRESSED OR IMPLIED 013 REM -- WITH RESPECT TO THE CORRECTNESS OR PERFORMANCE OF THIS REM -- PROGRAM. !--------------- 20 DEF FNA$(X$) : D1$=SYS(CHR$(6%)+CHR$(-10%)+X$) : FNA$=D1$ : FNEND ! FUNCTION TO CONVERT ASCII TO INTERNAL FORMAT 21 DEF FNC$(Y$) : CHANGE Y$ TO H% : K%=0% : FOR I%=1% TO H%(0%) : J%=H%(I%) : IF J%<=32% OR J%=91% OR J%=93% THEN 22 ELSE K%=K%+1% : H%(K%)=H%(I%) 22 NEXT I% : H%(0%)=K% : CHANGE H% TO Y$ : IF K%=3% THEN 23 ELSE IF K%=1% THEN Y$=CHR$(48%)+CHR$(48%)+Y$ ELSE Y$=CHR$(48%)+Y$ 23 FNC$=Y$ : FNEND ! LINES 21-23 ARE A FUNCTION TO EDIT AN ACCOUNT NUMBER. ! THE ACCOUNT NUMBER IS RETURNED AS A SIX DIGIT NUMBER. ! FOR EXAMPLE, 10,99 BECOMES 010099 AND 1,2 BECOMES 001002 50 DIM M%(30%),M0%(30%),N%(30%),H%(30%) ! THESE ARE YOUR BASIC ARRAYS (EVERYBODY USES 'EM.) 70 & : & "MOVERX V1A -- SYSTEM MOVER -- LAWRENCE" : D$=SYS(CHR$(0%)) : & ! WE USE '&' FOR 'PRINT'. CRANK 'ER UP. 90 M%(I%)=0% FOR I%=1% TO 30% : M%(0%)=30% : D1%,N1%=0% ! INITIALIZE THE OLD COUNTERS AND THE M% ARRAY 110 INPUT "FROM DEVICE";W1$ : W1$="DF:" IF W1$="" : W1$="DT0:" IF W1$="DT:" ! ESTABLISH YOUR PEACHY DEFAULTS AND GET THE INPUT DEVICE 130 IF INSTR(1%,W1$,":") THEN 150 ELSE & W1$;"-NOT A VALID "; "DEVICE" : GOTO 110 ! ALL VALID DEVICES END WITH A COLON. 150 IF INSTR(1%,W1$,"DT") THEN W1%=-1% ELSE W1%=0% ! SET AN INDICATOR IF THE INPUT DEVICE IS DECTAPE. 170 IF INSTR(1%,W1$,"KB") THEN & : & "USE 'PIP' FOR PAPER TAPE." : GOTO 50 ! ICSNAY ON PAPER TAPE. 190 INPUT "TO DEVICE";W2$ : W2$="DT0:" IF W2$="" OR W2$="DT:" : IF INSTR (1%,W2$,":") THEN 210 ELSE & W2$;"-NOT A VALID DEVICE." : GOTO 190 ! GET THE OUTPUT DEVICE AND CHECK FOR THE POPULAR COLON. 210 IF INSTR(1%,W2$,"DT") THEN W2%=-1% ELSE W2%=0% ! CHECK IF OUTPUT DEVICE IS DECTAPE 230 IF INSTR(1%,W2$,"KB") THEN & "USE 'PIP' FOR PAPER TAPE. OR USE 'PUNCH'" : GOTO 50 ! ZIP NIP ON PAPER TAPE. 250 IF NOT(W1% OR W2%) THEN INPUT "RETAIN ORIGINAL DATES";Y1$ : IF ASCII(Y1$)<>78% THEN B6%=-1% ELSE B6%=0% ! CHECK IF ORIGINAL DATES ARE USED (FOR DISK ONLY) 270 P1%=SWAP%(CVT$%(MID(SYS(CHR$(6%)+CHR$(14%)),7%,2%))): P0%=ASCII(CHR$(P1%)): P1%=ASCII(CHR$(SWAP%(P1%))): IF P1%<>1% THEN A$,A9$="["+FNC$(NUM$(P1%))+","+FNC$(NUM$(P0%))+"]": H%=0%: GOTO 410 290 ! SEE IF THIS YOKEL IS PRIVILEGED OR NOT AND MAKE ALLOWANCES. 310 INPUT "MOVE ALL ACCOUNTS";Y1$ : IF ASCII(Y1$)=89% THEN H%=-1% : GOTO 410 ! SEE IF WE SHOULD MOVE ALL ACCOUNTS AND SET AN INDICATOR 330 & : & "FROM ACCOUNT N,M FORM ( IF NO MORE)"; : INPUT LINE A$ : H%=0% : IF A$=CHR$(13%)+CHR$(10%) THEN 32767 ! GET THE INPUT ACCOUNT AND QUIT IF IT'S 350 Y1$=FNC$(LEFT(A$,INSTR(1%,A$,",")-1%)) : Y2$=FNC$(RIGHT (A$,INSTR(1%,A$,",")+1%)) : A$="["+Y1$+","+Y2$+"]" ! MAKE ALL ACCOUNT NUMBERS UNIFORM 370 & : & "TO ACCOUNT N,M FORM ( IF SAME AS 'FROM')"; : INPUT LINE A9$ : IF A9$=CHR$(13%)+CHR$(10%) THEN A9$=A$ : GOTO 410 ! GET THE OUTPUT ACCOUNT AND SEE IF IT'S THE SAME AS 'FROM' 390 Y1$=FNC$(LEFT(A9$,INSTR(1%,A9$,",")-1%)) : Y2$=FNC$(RIGHT(A9$, INSTR(1%,A9$,",")+1%)) : A9$="["+Y1$+","+Y2$+"]" ! MAKE THE OUTPUT ACCOUNT UNIFORM 410 INPUT "MOVE ALL FILES";Y1$ : IF ASCII(Y1$)=89% THEN H1%=-1% ELSE H1%=0% ! SEE IF ALL FILES ARE TO BE MOVED AND SET THE INDICATOR 430 IF Y1$<>"I" THEN 530 ELSE IF A$="" THEN & "INVALID OPTION" : GOTO 410 ! THE I (INDIVIDUAL MOVE OPTION) NEEDS AN ACCOUNT 450 INPUT "FILE TO MOVE";N1$ : ON ERROR GOTO 490 : OPEN W1$+N1$+A$ FOR INPUT AS FILE 1% : CLOSE 1% : ON ERROR GOTO 0 460 S0%=1% : IF W1% AND E$=".BAC" THEN S0%=2% ! SET UP QUEUE FOR MOVE 470 I$=W1$+N1$+A$ : O$=W2$+N1$+A9$ : L%=5% : GOSUB 20000 : & N1$;" MOVED." : GOTO 50 490 & : & "CAN'T FIND ";W1$+N1$+A$ : RESUME 510 510 ON ERROR GOTO 0 : GOTO 50 ! LINES 430-510 HANDLE THE INDIVIDUAL FILE MOVE OPTION. ! MOVERX WASN'T DESIGNED FOR INDIVIDUAL FILES SO THIS ! DOESN'T WORK TOO WELL! 530 CHANGE FNA$(W1$) TO N% UNLESS W1$="DF:" 550 IF NOT (W2%) THEN 590 ELSE OPEN "KB:" AS FILE 1% : & "MOUNT TAPE ON ";W2$;" -- HIT RETURN WHEN READY." : INPUT #1%,A% : CLOSE 1% : IF P1%=1% THEN INPUT "ZERO TAPE";Y1$ 570 IF ASCII(Y1$)=89% THEN D$=FNA$(W2$) : Y1$=SYS(CHR$(6%)+CHR$(13%)+RIGHT(D$,3%)) ! GIVE HIM TIME TO PUT A TAPE ON IF HE NEEDS IT. 590 IF W1% THEN 1150 ! SEPARATE ROUTINE FOR DECTAPE INPUT 610 IF NOT(H%) THEN Q%=1% : GOSUB 1030 IF W2% : GOTO 750 ! PRINT A HEADER FILE ON THE DECTAPE IF WE DON'T MOVE ! ALL ACCOUNTS 630 M%(1%)=6% : M%(2%)=14% : M%(3%)=2% ! INITIALIZE THE ARRAY FOR THE MFD 650 Q%=0% : ON ERROR GOTO 1090 : CHANGE M% TO D$ : CHANGE SYS(D$) TO M0% : ON ERROR GOTO 0 : M%(3%)=M%(3%)+1% : IF M%(3%)>255% THEN M%(3%)=0% : M%(4%)=M%(4%)+1% 670 ! GET THE ACCOUNTS FROM THE MFD ONE-BY-ONE 690 Z7%=M0%(29%) ! THIS IS FOR CLUSTERSIZES 710 A$="["+FNC$(NUM$(M0%(8%)))+","+FNC$(NUM$(M0%(7%)))+"]" : N%(3%),N%(4%)=0% : N%(5%)=M0%(7%) : N%(6%)=M0%(8%) ! GET THE INPUT ACCOUNT AND SET THE DIRECTORY INDICES 730 A9$=A$ : GOTO 770 ! ON MOVE ALL ACCOUNTS INPUT AND OUTPUT ARE THE SAME 750 CHANGE FNA$(A$) TO M0% : N%(5%)=M0%(5%) : N%(6%)=M0%(6%) : N%(3%),N%(4%)=0% ! FOR INDIVIDUAL ACCOUNTS SET UP THE DIRECTORY INDICES 770 L%=1% : GOSUB 10000 : S1$=N$+E$ : S2$=A$ ! GET THE DIRECTORY ENTRIES FOR THIS ACCOUNT 790 IF Q% THEN 810 ELSE & : & "ACCOUNT ";A$ : GOSUB 1030 IF W2% : Q%=Q%+1% ! PRINT OUT THE ACCOUNT INFO IF IT'S FIRST TIME THROUGH 810 IF H1% THEN 830 ELSE & N$;E$; : INPUT Y1$ : IF ASCII(Y1$)<>89% THEN 770 ! IF WE ARE NOT MOVING ALL FILES, SEE IF WE MOVE THIS ONE 830 IF N1%<=56% OR W2%=0% THEN 950 ! SEE IF THE OUTPUT DECTAPE IS FULL 850 & : & W2$;" FULL. DO YOU WISH TO CONTINUE ON "; : & "DT1:"; IF W2$="DT0:" : & "DT0:"; IF W2$="DT1:" : INPUT Y1$ : IF ASCII(Y1$)=89% THEN IF W2$="DT0:" THEN W2$="DT1:" ELSE W2$="DT0:" 870 ! TELL THE USER HIS TAPE IS FULL AND SEE WHAT THE HELL TO DO ! ABOUT IT. 890 OPEN "KB:" AS FILE 1% : & "MOUNT FRESH TAPE ON ";W2$;" -- " "HIT RETURN WHEN READY." : INPUT #1%,A% : CLOSE 1% : N1%=0% ! GIVE TIME TO CHANGE TAPES. 910 IF P1%=1% THEN INPUT "ZERO NEW TAPE";Y1$ : IF ASCII(Y1$)=89% THEN D$=FNA$(W2$) : Y1$=SYS(CHR$(6%)+CHR$(13%)+RIGHT(D$,3%)) ! SEE IF PRIVILEGED USERS WANT TO ZERO THE NEW TAPE 930 GOSUB 1030 ! GO WRITE A NEW HEADER RECORD ON THE TAPE 950 O$=W2$+N$+E$+A9$ : I$=W1$+N$+E$+A$ : S0%=1% : L%=1% : GOSUB 20000 : N1%=N1%+1% : S1$=N$+E$ : S2$=A$ : & SPACE$(12%);S1$ : GOTO 770 ! GO MOVE THE FILE (THIS IS YOUR BASIC MOVERX) 970 ON ERROR GOTO 1010 : N1%=57% : CLOSE 1%,2% : KILL O$ : IF NOT(W2%) THEN & "DISK FULL ERROR!!!!!" : STOP 990 GOTO 830 1010 RESUME 830 ! LINES 970-1010 PROVIDE FOR A FULL DECTAPE 1030 A1$=MID(A$,2%,3%)+MID(A$,6%,3%)+".ACC" : ON ERROR GOTO 1070 : OPEN W2$+A1$ FOR OUTPUT AS FILE 3% : & #3%," " : CLOSE 3% ! PRINT THE HEADER FILE FOR TAPE (XXXYYY.ACC) 1050 ON ERROR GOTO 0 : N1%=N1%+1% : RETURN 1070 IF ERR<>4% THEN ON ERROR GOTO 0 ELSE N1%=57% : RESUME 850 ! IF THE HEADER OVERFLOWS TAPE THEN COMPLAIN 1090 IF ERR<>5% THEN ON ERROR GOTO 0 ELSE & : & "MOVING COMPLETE!"; CHR$(7%);CHR$(7%);CHR$(7%) : RESUME 32767 1110 ! WE ARE FINSIHED (MUTED REJOICING) 1130 IF ERR=5% AND H% THEN RESUME 650 ELSE IF ERR=5% AND P1%<>1% THEN RESUME 1090 ELSE IF ERR=5% THEN RESUME 330 ELSE ON ERROR GOTO 0 ! WE GET HERE FROM THE DIRECTORY LOOKUP 1150 CHANGE FNA$(W1$) TO N% : N%(3%),N%(4%),H2%=0% ! THIS IS THE BEGINNING OF THE DECTAPE INPUT SECTION 1170 L%=2% : GOSUB 10000 : S1$=N$+E$ : S2$=A$ : IF E$=".ACC" THEN 1270 ! GET THE DIRECTORY ENTRIES ONE-BY-ONE 1190 IF H% THEN 1210 ELSE IF NOT(H2%) THEN 1170 ! IF WE FOUND A TAPE ACCOUNT THAT MATCHES THEN CONTINUE 1210 IF H1% THEN 1230 ELSE & S1$; : INPUT Y1$ : IF ASCII(Y1$)<>89% THEN 1170 ! IF WE'RE IN SELECTIVE MODE THEN SEE IF THIS IS THE ONE 1230 I$=W1$+S1$ : O$=W2$+S1$+A9$ : S0%=2% : L%=2% : GOSUB 20000 : & SPACE$(12%);S1$ ! GO MOVE THE SELECTED FILE (YOUR BASIC MOVERX AGAIN) 1250 GOTO 1170 ! DAMN THIS GOTO BELONGS TO THE LAST LINE BUT NOW IT'S THIS LINE 1270 A1$="["+LEFT(N$,3%)+","+RIGHT(N$,4%)+"]" : IF H% THEN 1320 ! GET THE INPUT ACCOUNT FROM DECTAPE (IT'S REALLY A FILE NAME) 1290 IF A1$<>A$ THEN H2%=0% : GOTO 1170 ! THIS ISN'T THE RIGHT ACCOUNT 1310 H2%=-1% : GOTO 1170 ! THIS IS THE RIGHT ACCOUNT 1320 & : & "ACCOUNT ";A1$ : S2$,A$,A9$=A1$ : GOTO 1170 ! TELL EVERYBODY WHAT ACCOUNT THIS IS 1330 IF H% THEN 1350 ELSE IF P1%<>1% THEN RESUME 1090 ELSE RESUME 330 ! THIS IS THE END 1350 & : & "USER FILES RESTORED FROM TAPE!!!!!!" : RESUME 32767 ! THIS IS IT SO QUIT 10000 IF L%=1% THEN ON ERROR GOTO 1130 ELSE ON ERROR GOTO 1330 10010 N%(0%)=30% : N%(1%)=6% : N%(2%)=15% : CHANGE N% TO D$ : CHANGE SYS(D$) TO N% : ON ERROR GOTO 0 ! GET THE NEXT DIRECTORY ENTRY 10015 T%=0% : K%=256.*N%(14%)+N%(13%) 10020 N$=RAD$(N%(7%)+SWAP%(N%(8%)))+RAD$(N%(9%)+SWAP%(N%(10%))) : E$="."+RAD$(N%(11%)+SWAP%(N%(12%))) : IF E$=".BAC" THEN IF P1%<>1% THEN 11000 10040 P$="<"+MID(NUM$(N%(15%)),2%,LEN(NUM$(N%(15%)))-1%)+">" 10050 IF N$+E$=S1$ AND A$=S2$ THEN 11000 10060 IF N%(14%)=0% AND N%(13%)=0% THEN 11000 ! DON'T MOVE ZERO BLOCK FILES 10070 RETURN 11000 N%(3%)=N%(3%)+1% : IF N%(3%)>255% THEN N%(3%)=0% : N%(4%)=N%(4%) +1% 11010 GOTO 10000 11020 ! LINES 10000-11010 ARE THE DIRECTORY LOOKUP SUBROUTINE. ! THIS SUBROUTINE GETS THE DIRECTORY INFO ! AND PUTS IT INTO ASCII FORMAT. 20000 IF N%(15%)<>60% AND NOT(W1% OR W2%) THEN NAME I$ AS I$+"<60>" ! IF THE INPUT FILE ISN'T PROTECTED 60 THEN FIX IT. 20001 IF N%(15%)=155% AND W1% THEN P$="<60>" ELSE IF N%(15%) AND 1% THEN P$="<"+NUM$(N%(15%)-1%)+">" ! GET RID OF WIERD PROTECTION CODES 20002 IF W1% AND W2% THEN S0%=1% ! IF IT'S DECTAPE TO DECTAPE MAKE THE BLOCK SIZES MATCH 20003 OPEN I$ FOR INPUT AS FILE 1% : E8%=0% 20004 ON ERROR GOTO 20190 20005 IF E$=".BAC" THEN OPEN O$+P$ FOR OUTPUT AS FILE 2%, CLUSTERSIZE Z7% ELSE OPEN O$+P$ FOR OUTPUT AS FILE 2% 20006 ! WE USE THE UFD CLUSTERSIZE AS FILE CLUSTER ON .BAC FILES. 20007 D$=SYS(CHR$(6%)+CHR$(-7%)) ! TRAP CTRL/C 20008 IF NOT(W1% OR W2%) THEN GOSUB 30000 20010 ON ASCII(MID(SYS(CHR$(6%)+CHR$(-8%)+CHR$(2%)),3%,1%))/2%+1% GOTO 20020,20030,20040,20030,20050,20060,20050,20020,20050 20020 E0%=26% : E1%=0% : O0%=512% : GOTO 20070 20030 E0%= 0% : E1%=1% : O0%=128% : GOTO 20070 20040 E0%=26% : E1%=0% : O0%=510% : GOTO 20070 20050 PRINT : PRINT "PROGRAM ERROR!!!!!" : STOP 20060 E0%=26% : E1%=1% : O0%=128% 20070 ON ERROR GOTO 20190 20080 S2%=O0% : S3%=0% : FIELD #2%,O0% AS O0$ 20090 ON ERROR GOTO 20190 20100 IF E8% THEN 20140 20110 GET #1% : S1%=RECOUNT 20120 IF S1%>S2% THEN 20130 ELSE FIELD #1%,S1% AS I0$ : FIELD #2%,S3% AS O0$, S1% AS O0$ : LSET O0$=I0$ : S3%=S3%+S1% : S2%=S2%-S1% : IF S2% THEN 20100 ELSE PUT #2% : S2%=O0% : S3%=0% : GOTO 20100 20130 S9%=S1%-S2% : FIELD #1%,S2% AS I0$, S9% AS I1$ : FIELD #2%,S3% AS O0$, S2% AS O0$ : LSET O0$=I0$ : PUT #2% : S1%=S9% : S2%=O0% : S3%=0% : FIELD #1%,S9% AS I0$ : LSET I0$=I1$ : GOTO 20120 20140 ON S0% GOTO 20160, 20200 20160 IF S3%=0% THEN 20200 20170 IF S3%=O0% THEN PUT #2% : GOTO 20200 20180 FIELD #2%,S3% AS O0$, 1% AS O0$ : LSET O0$=CHR$(0%) : S3%=S3%+1% : GOTO 20170 20190 IF ERR=28% THEN & : & "YOU JUST LOST PROGRAM ";I$ : GOTO 32767 ! IF THE LOUT TYPES CTRL/C TOUGH COOKIES 20195 IF ERR=13% THEN RESUME ELSE IF ERR=11% THEN RESUME 20140 ELSE IF ERR=4% THEN RESUME 970 ELSE ON ERROR GOTO 0 20200 IF B6% THEN GOSUB 31000 20250 IF S0%=2% THEN IF E$<>".BAC" THEN PUT #2% ! PUT THE PARTIAL BUFFER EXCEPT FOR .BAC FILES 20251 ! SEE IF THE LAST BUFFER IS CORRECT 20300 CLOSE 1%,2% : ON ERROR GOTO 0 : NAME O$ AS O$+P$ ! SAVE THE PROTECTION CODES 20310 RETURN ! GO BACK TO TE GOOD STUFF 30000 PUT #2%, RECORD K% : CLOSE 2% : OPEN O$ FOR INPUT AS FILE 2% : RETURN 31000 Z6%(0%)=9% : Z6%(1%)=6% : Z6%(2%)=-11% : Z6%(3%)=2% : Z6%(I%)=N%(I%+13%) FOR I%=4% TO 9% : CHANGE Z6% TO P8$ : Y1$=SYS(P8$) : RETURN 32767 END ! GOTT SEI DANK!!!!