TITLE REFSTR - ROUTINE TO REFRESH A FILE STRUCTURE - V151 SUBTTL D BLACK 19 APR 88 SEARCH F,S,DEVPRM $RELOC $INIT ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION ; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988. ;ALL RIGHTS RESERVED. .CPYRT<1973,1988> XP VREFST,151 ENTRY REFSTR ;INTERNS FOR ONCMOD XP RB1UN,^D9 ;NO OF BLOCKS REFRESHER CREATES ON 1ST UNIT IN STR XP RBLUN,5 ;NO OF BLOCKS REFRESHER CREATES ON LAST UNIT IN STR ;QUOTAS FOR UFD'S WE CREATE QR==0 ;RESERVED QUOTA QF==377777777777 ;FIRST COME, FIRST SERVED QUOTA QO==377777777777 ;LOGGED OUT QUOTA ;LOCAL FEATURE TEST TO DOCUMENT CODE WHICH USED TO CREATE MAINT.SYS XPL FTMAINT,0 ;NOT USED SUBTTL REFRESH A FILE STRUCTURE ;ROUTINE TO REFRESH A FILE STRUCTURE ;ARGS T1=SIXBIT NAME OF STR ; P2=ADDR OF STR DATA BLOCK ; F=ADDR OF DDB REFSTR::PUSHJ P,SAVE4## ;SAVE PERMANENT ACS (P1-P4) PUSH P,JBTADR## ;MAY BE NEEDED LATER MOVEM P,SAVEP ;SAVE PDL IN CASE ERROR RETURN SKIPE .UONCE## ;USER-MODE? PUSHJ P,USRDTM## ;YES, SET UP DATE/TIME MOVEI T1,NU0DAC## MOVEM T1,JBTADR## MOVEI T1,RIPNDL##!RIPNFS## ;NO DELETE FILE BIT MOVEM T1,NDNCNF ;PLUS NO FAILSAFE BIT ADDI T1,RIPABC## ;ADD IN ALWAYS BAD CHECKSUM FOR SOME FILES MOVEM T1,NDCFAB ;AND SAVE ALL BITS HLRZ U,STRUNI##(P2) ;U=ADDR OF FIRST UNIT IN STR HRRZM U,FSTUNI ;REMEMBER FIRST UNIT SKIPN T1,@ONCMBF## ;USE MONITOR BUFFER ALREADY ALLOCATED FOR SAT RIB STOPCD REFERR,DEBUG,REFMBM, ;++MONITOR BUFFER MISSING MOVEM T1,SATRBA ;(ALSO SAVES POINTER) MOVSI P1,-CORN+1 ;MINUS NUMBER OF EXTRA BUFFERS WE NEED REF1: MOVEI T1,BLKSIZ## ;AMOUNT OF CORE FOR 1 BUFFER PUSHJ P,INICOR## ;GET A MONITOR BUFFER (SIZE OF DISK BLOCK) HRLI T2,-BLKSIZ## ;-SIZE OF A DISK BLOCK SUBI T2,1 ;MAKE AN IOWD MOVEM T2,SATRBA+1(P1) ;SAVE IOWD AOBJN P1,REF1 ;LOOP FOR ALL BUFFERS NEEDED MOVE T1,HOMRBA ;IOWD FOR HOME BLOCK MOVEM T1,@ONCMBF## ;SAVE IOWD IN MONITOR BUFFER PUSHJ P,GTHOM## ;READ IN A HOME BLOCK FROM 1ST UNIT JRST ERHMSG ;ERROR READING HOME.SYS HRRZ P2,UNISTR(U) ;RESET P2=ADDR OF STR DATA BLOCK MOVE T1,HOMRBA SKIPN J,HOMBPC##+1(T1) ;BLOCKS PER CLUSTER THIS STR JRST ZBCMSG ;ZERO BLOCKS PER CLUSTER SETO T2, LDB T4,STYCNP##(P2) ;T4=MAX CLUSTERS CAN ALLOCATE IN 1 PTR MOVEM T4,MAXALC ;SAVE FOR LATER HRRZI T1,HOMLEN##+1(T1) ;ADDR OF BEGINNING OF FILE LENGTHS HRLI T1,-LSTLEN ;NUMBER OF LENGTHS MOVSI T2,-ZERLEN-1 ;COUNTER FOR THOSE WHICH CAN BE 0 HRRI T2,FSTLEN ;BEGINNING OF DESTINATION TABLE HRREI P1,-2(J) ;TRY FOR ONLY 1 CLUSTER CAIG P1,0 ;SKIP IF AT LEAST 1 DATA BLOCK MOVEI P1,1 ;INSIST ON 1 REF1A: MOVE T3,(T1) ;T3=VALUE FROM HOME BLOCK AOBJN T2,REF1B ;JUMP IF 0 IS OK CAIN T3,0 ;SKIP IF NOT 0 MOVE T3,P1 ;SET TO MINIMUM VALUE (PROBABLY UFD'S) REF1B: MOVEM T3,-1(T2) AOBJN T1,REF1A ;LOOP FOR ALL LENGTHS SETZM FSTBK ;CLEAR UNIT TABLE MOVE T1,[XWD FSTBK,FSTBK+1] BLT T1,FSTUNW+LSTUNW-1 SUBTTL PRESERVE FE.SYS ;FIND FE.SYS, IF IT EXISTS HRRZ U,FSTUNI ;START AT FIRST UNIT JRST REF1D ; (HOME BLOCKS FOR THIS UNIT ALREADY IN CORE) REF1C: PUSHJ P,GTHOM## ;READ HOME BLOCKS JRST CRHMSG ;CAN'T READ HOME BLOCKS LDB J,UNYBPC## HRRZ P2,UNISTR(U) REF1D: MOVE T1,HOMRBA ;IOWD FOR HOME BLOCKS SKIPE T2,HOMFEB##+1(T1) ;UNIT CONTAIN FE.SYS? TLZN T2,FEVALID## ;YES, IS IT VALID? JRST REF1F ;NO HLRZ T3,T2 ;CHANGE PDP-11 SPLIT LSH T3,^D16 ;WORD FORMAT ANDI T2,177777 ;INTO 10 FORMAT IOR T2,T3 SUBI T2,1 ;YES, POINT AT RIB ADDRESS MOVE T3,T2 ;COPY BLOCK # HLRZ T4,STRBSC##(P2) ;BLOCKS/SCLUST IDIV T3,T4 ;IS IT STILL ON A SCLUST BOUNDARY? JUMPE T4,FERIB ;YES FELOSE: PUSHJ P,OTSET## ;NO, TELL HIM BAD NEWS MOVEI T1,[ASCIZ/ %Cannot preserve FE.SYS /] PUSHJ P,ICONM## ;START MESSAGE PUSHJ P,OPOUT## ;AND OUTPUT IT JRST REF1E ;FLAG NOT VALID FERIB: MOVEM T2,FERBD ;BLOCK IS OK, SAVE IT MOVEM U,FEUN MOVE T1,FERBA MOVEM T1,@ONCMBF## ;POINT TO ONCE AREA PUSHJ P,OMNRED## ;GO READ WHAT PURPORTS TO BE FE.SYS TLO S,-1 ;IO ERROR LDB J,UNYBPC## ;RESET J HRRZ P2,UNISTR(U) ; AND P2 TLZE S,-1 ;IO ERROR? JRST REF1E ;LOSE, TRY ANOTHER UNIT MOVE T1,FERBA ;WON, POINT AT RIB MOVE T2,RIBPPN##+1(T1) ;MAKE SURE IT REALLY IS A RIB MOVE T3,RIBNAM##+1(T1) ; FOR FE.SYS[1,4] CAMN T2,SYSPPN## CAME T3,[SIXBIT .FE.] JRST REF1E ;NO IT ISN'T HLRZ T2,RIBEXT##+1(T1) CAIE T2,'SYS' JRST REF1E MOVE T2,RIBALC##+1(T1) ;YES IT IS. CHECK LENGTH IDIVI T2,(J) ;INTEGRAL # OF CLUSTERS? JUMPN T3,FELOSE ;.. MOVEM T2,FELEN ;SAVE IF SO MOVE T4,1(T1) ;GET FIRST RIB WORD ADDI T4,(T1) ;RELOCATE TO BUFFER LDB T2,UNYLUN## ;GET UNIT POINTER TRO T2,RIPNUB## ;MAKE CHANGE-UNIT-PTR PUSH T4,T2 ;PUT IN MOVE T2,FERBD ;GET DATA BLOCK OF RIB IDIVI T2,(J) ;T2=CLUSTER ADDR OF FE.SYS'S RIB MOVE T3,FELEN ;LENGTH PUSH P,T4 ;SAVE T4 IDIV T3,MAXALC ;T3=#GROUPS IN FE.SYS JUMPN T4,FERB00 EXCH T4,(P) JRST FERB01 FERB00: DPB T4,STYCNP##(P2) ;BUILD IN T2 MOVE T4,(P) ;RESTORE T4 MOVEM T2,(P) ;AND SAVE T2 FERB01: MOVE T1,MAXALC ;GET MAX POINTER DPB T1,STYCNP##(P2) ;AND BUILD IT IN T2 FERB0: JUMPN T3,FERB1 ;MORE FULL POINTERS TO DO IF T3 NON-ZERO POP P,1(T4) ;NONE, PUT LAST CLUSTER IN SOJA T3,FERB2 ;FLAG NOT TO DO THIS AGAIN FERB1: SETZM 1(T4) ;DEFAULT NO POINTER SOJL T3,FERB2 ;WHICH IS CORRECT MOVEM T2,1(T4) ;ELSE SET FULL POINTER ADD T2,T1 ;AND POINT TO NEXT CLUSTER ADDM T1,(P) ;AND LAST NEXT CLUSTER FERB2: AOBJN T4,FERB0 ;LOOP OVER ALL RIB POINTER SLOTS JUMPGE T3,FELOSE ;IF TOO MANY TO FIT, LOSE JRST REF1G ;DONE REF1E: SETZM FEUN ;NOT FE.SYS, CLEAR FLAG SETZM FERBD ;CLEAR RIB BLOCK NUMBER TOO REF1F: HLRZ U,UNISTR(U) ;TRY NEXT UNIT JUMPN U,REF1C SUBTTL SET UP HOME.SYS AND SAT.SYS REF1G: HRRZ U,FSTUNI ;RESET U TO 1ST UNIT IN STR SETZB T1,UFDBKS ;CLEAR TOTAL BLOCKS ALLOCATED IN CURRENT UFD PUSHJ P,CHEKS1 ;COMPUTE CHECKSUM FOR A WORD OF 0 MOVEM T1,CHECK0 ;AND SAVE THAT SINCE WE NEED IT A LOT MOVSI T1,SYRDPR## ;STANDARD ACCESS CODE FOR SYSTEM FILES MOVEM T1,CURPRT ;SAVE FOR RIBSET ;HERE TO SET UP RIB IN CORE FOR HOME.SYS MOVE T4,HOMRBA ;POINTER TO HOME.SYS RIB IN CORE MOVE T1,HOMFNM ;NAME OF HOME.SYS FILE MOVSI T2,(SIXBIT .SYS.) MOVE T3,SYSPPN## ;IN SYS UFD MOVE P4,NDCFAB ;NO DELETE, NO CHANGE NAME, NO FAILSAFE BITS PUSHJ P,RIBSET ;SET UP RIB FOR HOME.SYS MOVEM T4,HOMRBP ;T4 IS POINTER TO RETRIEVAL POINTERS ;HERE TO SET UP RIB IN CORE FOR SAT.SYS MOVE T4,SATRBA ;POINTER TO SAT.SYS RIB IN CORE MOVE T1,SATFNM ;NAME OF SAT.SYS FILE MOVSI T2,(SIXBIT .SYS.) MOVE T3,SYSPPN## ;IN SYS UFD MOVE P4,NDCFAB ;ALL STATUS BITS PUSHJ P,RIBSET ;SET UP RIB FOR SAT.SYS MOVEM T4,SATRBP ;POINTER TO RETRIEVAL POINTERS FOR SAT.SYS ;HERE FOR NEXT UNIT IN STR REF2: MOVE T1,UNIHOM(U) ;LOGICAL BLOCK NUMS FOR HOME BLOCKS MOVEM T1,LBNLST MOVE T2,[XWD LBOBAT##,LBOBAT##] ;OFFSET FOR BAT BLOCKS ADD T2,T1 MOVEM T2,LBNLST+1 MOVE T2,[XWD LBOISW##,LBOISW##] ;OFFSET FOR ISW BLOCKS ADD T2,T1 MOVEM T2,LBNLST+2 PUSHJ P,REDBAT ;READ BAT BLOCK PUSHJ P,STNWUN ;STORE NEW UNIT POINTER IN SAT.SYS RIB PUSHJ P,HOMRBS ;STORE IN HOME.SYS RIB LDB T1,UNYLUN## JUMPN T1,SETSAT ;JUMP IF NOT FIRST UNIT MOVE T1,SATRBP MOVEM T1,SATUN ;SAVE INITIAL POINTER TO RETRIEVAL PTRS PUSHJ P,SATRBS ;AND SAVE A SPACE FOR 1ST RIB PTR (CLS CNT=0) MOVE T1,HOMRBP ;SAME THING FOR HOME.SYS MOVEM T1,HOMUN PUSHJ P,HOMRBS SETSAT: MOVE T1,UNIBPU(U) ;BLOCKS ON THIS UNIT IDIV T1,J ;THEORETICALLY, ((BLOCKS-1)/BPC)+1=CLUSTERS SUBI T1,1 ;-1 LDB T2,UNYSPU## ;T2=SATS ON THIS UNIT JUMPE T2,FEWSAT ;JUMP IF NO SAT BLOCKS ON UNIT IDIV T1,T2 ;THEORETICALLY, (CLUSTERS-1/SATS)+1=CLUSTERS/SAT MOVEM T1,LCLSAT ;-1=LAST CLUSTER IN FIRST SAT ADDI T1,1 ;+1 FOR ALL BUT LAST SAT, WHICH IS ADJUSTED ;TO MAKE THE TOTAL CORRECT MOVEM T1,SVSBTL ;SAVE CLUSTERS PER SAT IDIVI T1,^D36*^D118 JUMPG T1,FEWSAT SETZM BEGSAT ;BEGSAT=1ST CLUSTER THIS SAT SETOM DAREQ## ;MAKE SURE DA RESOURCE AVAILABLE SETOM SATIND ;USE SWPUN AS TEMP SAT INDEX, SET TO -1 ;HERE TO CREATE NEXT SAT BLOCK FOR THIS UNIT MRKSAT: HRRZ T1,SATBKA ;ADDR OF SAT BLOCK IN CORE MOVE T2,SVSBTL ;ACTUAL CLUSTERS THIS SAT PUSHJ P,MRKEND ;CLEAR BLOCK AND SET BITS IN LAST WORD ;HERE TO SCAN BAT BLOCK AND MARK CLUSTERS CONTAINING BAD BLOCKS HRRZ T1,BATBKA MOVE T2,[PUSHJ P,SETBAD] ;INSTRUCTION TO EXECUTE FOR BAD BLOCKS PUSHJ P,SCNBAT ;SCAN BAT BLOCK AND EXECUTE T2 FOR EACH BAD BLOCK ;HERE TO SET UP FE.SYS, IF THERE USED TO BE ONE SKIPE P3,FERBD ;WAS THERE AN FE.SYS? CAME U,FEUN ;YES, ON THIS UNIT? JRST MRKBD1 ;NO MOVE P4,FELEN ;YES, MARK ITS BLOCKS TAKEN IN SAT MRKFE: MOVE T1,P3 PUSHJ P,SETSWP ; NOTE THAT WE LEAVE THE RIB ALONE, ADD P3,J ; AS A VALID RIB EXISTS ON DSK. WE ARE JUST POINTING SOJG P4,MRKFE ; THE UFD AT IT AND MARKING ITS BITS IN SAT ;HERE TO MARK BITS FOR SWAPPING REGION MRKBD1: LDB P3,UNYK4S## ;P3=J FOR SWAP ON THIS UNIT JUMPE P3,MRKSW1 ;SKIP THIS IF NONE LSH P3,BLKSPK SKIPA P4,UNISLB(U) ;P4=1ST LOGICAL BLOCK MRKSW2: ADDI P4,1 ;P4=NEXT LOGICAL BLOCK MOVE T1,P4 ;T1=CURRENT LOGICAL BLOCK PUSHJ P,SETSWP ;SET BIT IN SAT BLOCK SOJG P3,MRKSW2 ;LOOP FOR ALL SWAP BLOCKS MRKSW1: SKIPE T1,BEGSAT ;SKIP IF THIS IS 1ST SAT ON THIS UNIT JRST ENDSAT ;HERE TO ALLOCATE BLOCKS IN HOME.SYS FILE PUSHJ P,GETHMC ;ALLOCATE BLOCK 0 JRST BADHOM ;CAN'T GET 1ST HOME BLOCK PUSHJ P,HOMRBS ;STORE RETRIEVAL POINTER LDB P3,STYCLP##(P2) ;REMEMBER LAST CLUSTER ALOCATED (FROM T2) MOVSI T3,-LBNLEN HLRZ T1,LBNLST(T3) PUSHJ P,GETHMB ;GET NEXT BLOCK IN THE GROUP AOBJN T3,.-2 ;LOOP FOR ALL OF 1ST GROUP MOVE T3,[XWD MNBOOT##,FBOOTB##] ;T3=-# BLOCKS FOR BOOTS, 1ST BLOCK HRRZ T1,T3 ;NEXT BLOCK TO ALLOCATE PUSHJ P,GETHMB ;ALLOCATE THE BLOCK AOBJN T3,.-2 ;LOOP FOR ALL BLOCKS TO ALLOCATE FOR BOOTS MOVSI T3,-LBNLEN HRRZ T1,LBNLST(T3) ;AND NOW 2ND GROUP PUSHJ P,GETHMB AOBJN T3,.-2 ;LOOP FOR ALL THE GROUP MOVE P1,UNISAB(U) ;ADDR OF FIRST SAB BLOCK IN CORE ENDSAT: SETZ T1, ;DONT CARE WHERE SAT GOES IN REGION PUSHJ P,RTAKBK ;GET A BLOCK FOR THE SAT BLOCK STOPCD REFERR,DEBUG,NSS,DIEUNI##, ;++NO SPACE FOR SAT PUSHJ P,SATRBS ;STORE RETRIEVAL POINTER IN SAT.SYS RIB LDB T4,STYCLP##(P2) ;CLUSTER FOR SAT BLOCK IMUL T4,J ;T4=LOGICAL BLOCK NUMBER OF BEGINNING OF CLUSTER MOVE T1,SATBKA ;IOWD FOR SAT BLOCK ADDI T1,1 ;MAKE AOBJN PTR PUSH P,R ;SAVE POINTER TO MON BUFFER SETZ R, ;NO RELOCATION PUSHJ P,SATCN## ;COUNT 0 BITS IN T2 POP P,R ;RESTORE R MOVE T3,T4 ;T3=BEGINNING OF CLUSTER EXCH T2,T3 ;T2=BEGINNING OF CLUSTER, T3=FREE CLUSTERS AOS T4,SATIND ;GET INDEX OF THIS SAT MOVE P4,T4 ;SAVE IN P4 FOR LATER ADD T4,UNISPT(U) ;POINTER TO SPT ENTRY FOR THIS SAT IFN FTXMON, ;MUST BE IN SECTION 1 TO REFERENCE THE SAB RING EXCH P1,P2 ;P2=ADDR OF THIS SAT DPB T3,SPYTAL## ;STORE COUNT OF FREE CLUSTERS PUSH P,T2 ;SAVE LOG BLOCK OF THIS SAT IDIV T2,J ;CLUSTER ADDR OF THIS SAT DPB T2,SPYCLA## ;STORE IN SPT ENTRY MOVE T1,SATBKA ;IOWD MOVE T2,(P) ;LOG BLOCK NUM S0PSHJ BLKWRT ;WRITE OUT THE SAT BLOCK LDB T1,UNYSIC## ;SAT'S IN CORE CAMLE T1,P4 ;SKIP IF INDEX IS GT LAST IN CORE PUSHJ P,SATIN ;ELSE READ INTO MONITOR CORE MOVE P2,SABRNG##(P2) ;ADDR OF NEXT SAT IN RING IFN FTXMON, ;BACK TO SECTION 0 FOR I/O EXCH P1,P2 MOVE T1,SATBKA SETOM 1(T1) ;SET 1ST WORD TO ONES PUSHJ P,CORONZ ;SET WHOLE BUFFER TO ONES POP P,T2 ;RESTORE LOGICAL BLOCK OF BEGINNING OF CLUSTER PUSHJ P,FINCLS ;WRITE OUT ONES IN ALL UNUSED BLOCKS THIS CLUSTER MOVE T1,UNIBPU(U) ;T1=BLOCKS ON THIS UNIT IDIV T1,J ;CONVERT TO FULL CLUSTERS ON UNIT MOVE T2,SVSBTL ;CLUSTERS IN THIS SAT ADDB T2,BEGSAT ;LAST CLUSTER IN THIS SAT+1 CAML T2,T1 ;SKIP IF NOT PAST END OF UNIT JRST ALSAUN ;NO MORE SATS THIS UNIT ADD T2,SVSBTL ;COMPUTE END OF NEXT SAT+1 SUBI T2,1 MOVEM T2,LCLSAT ;REMEMBER LAST CLUSTER THIS SAT ADDI T2,1 ;BUT WE NEED MORE CAMG T2,T1 ;SKIP IF GR THAN LAST BLOCK+1 JRST MRKSAT ;NO, KEEP GOING SUB T2,T1 ;FIND OUT HOW MUCH OVER SUBM T2,SVSBTL ;AND SUBTRACT THAT FROM SIZE OF LAST SAT SUBM T2,LCLSAT ;AND FROM LAST CLUSTER THIS SAT MOVNS SVSBTL ;EXCEPT IT COMES OUT NEGATIVE THAT WAY MOVNS LCLSAT JRST MRKSAT ;LOOP FOR ALL SATS THIS UNIT ALSAUN: MOVE T1,U ;REMEMBER CURRENT UNIT IN CASE IT'S THE LAST HLRZ U,UNISTR(U) ;NEXT UNIT IN STR JUMPN U,REF2 ;LOOP FOR ALL UNITS IN STR ;HERE AFTER ALL SATS ON ALL UNITS ARE WRITTEN HRLM T1,LSTUNI ;REMEMBER LAST UNIT IN STR HRRZ U,FSTUNI ;RESET TO FIRST UNIT IN STR ;HERE TO ALLOCATE SPACE FOR SYS UFD (NEED THIS TO STORE BLOCK NUMBER OF ; UFD IN RIB OF EACH FILE WE CREATE) MOVE T2,SYUFSZ ;NUMBER OF DATA BLOCKS FOR SYS UFD PUSHJ P,HIALCU ;ALLOCATE SPACE FOR SYS UFD MOVEM T1,SYSRBD ;REMEMBER FOR HOME BLOCK MOVEM U,SYSUN ;HERE TO WRITE RIBS FOR SAT.SYS AND HOME.SYS ON LAST UNIT ;ALLOCATE 1ST RIB FOR SAT.SYS PUSHJ P,CATKB ;GET A BLOCK FOR 1ST SAT.SYS RIB LDB T1,STYCLP##(P2) ;CLUSTER ADDR IMUL T1,J ;T1=LOGICAL BLOCK NUMBER OF RIB MOVEM T1,SATRBD ;REMEMBER LOGICAL BLOCK NUMBER OF SAT.SYS RIB MOVE T3,SATUN ;INITIAL PTR TO RETRIEVAL PTRS EXCH T3,SATRBP ;REMEMBER PRESENT, RESET INITIAL PUSHJ P,SATRBS ;STORE RETRIEVAL POINTER FOR SAT.SYS RIB MOVEM T3,SATRBP ;RESTORE PRESENT POSITION PUSHJ P,CMPSIZ ;COMPUTE NUMBER OF WORDS WRITTEN, SETS T4=PTR TO RIB MOVE T1,MFDRBD MOVEM T1,RIBUFD##+1(T4) MOVEM U,SATUN MOVE T2,SATRBD ;LOGICAL BLOCK NUM OF 1ST RIB PUSHJ P,FINCLS ;WRITE ONES IN REST OF CLUSTER HLRZ U,LSTUNI ;RESET TO LAST UNIT HRRZ T4,FSTUNI ;ADDR OF UNIT FOR 1ST RIB MOVE T3,SATRBD ;LOGICAL BLOCK NUM OF 1ST RIB FOR SAT.SYS PUSHJ P,FIL2RB ;ALLOCATE 2ND RIB AND WRITE OUT RIBS ;HERE WHEN SAT.SYS HAS BEEN CREATED ;ALLOCATE 1ST RIB FOR HOME.SYS HRRZ U,FSTUNI ;RESET TO FIRST UNIT PUSHJ P,CATKB ;ALLOCATE A BLOCK FOR 1ST HOME.SYS RIB MOVE T1,CHECK0 ;CHECKSUM OF 0 DPB T1,STYCKP##(P2) ;ALWAYS 0 OR 1ST WORD OF BLOCK 0 MOVE T3,HOMUN ;INITIAL POINTER TO RETRIEVAL PTRS EXCH T3,HOMRBP ;RESTORE INITIAL POINTER TO POINTERS PUSHJ P,HOMRBS ;STORE POINTER TO RIB MOVEM T3,HOMRBP ;BACK TO PRESENT POSITION MOVEM U,HOMUN LDB T1,STYCLP##(P2) ;CLUSTER OF RIB IMUL T1,J ;REMEMBER LOGICAL BLOCK NUMBER OF RIB FOR HOME.SYS MOVEM T1,HOMRBD MOVE T4,HOMRBA PUSHJ P,COMSIZ ;COMPUTE WORDS WRITTEN AND SET T4=PTR TO RIB MOVE T1,MFDRBD MOVEM T1,RIBUFD##+1(T4) ;HERE TO ALLOCATE 2ND RIB FOR HOME.SYS HLRZ U,LSTUNI PUSHJ P,C1TKB ;TAKE 1 BLOCK FOR 2ND RIB FOR HOME.SYS MOVE T1,HOMRBA ;CHECKSUM ON 1ST WORD OF GROUP PUSHJ P,CHEKSM PUSHJ P,HOMRBS ;STORE RETRIEVAL POINTER LDB P3,STYCLP##(P2) ;CLUSTER OF 2ND HOME.SYS RIB IMUL P3,J MOVEM P3,HOMSR2 ;SAVE BLOCK NUM OF 2ND HOME.SYS RIB IN TEMP MOVE P1,HOMRBA ;ADDR OF HOME.SYS RIB IN CORE -1 MOVE T2,J ;BLOCKS PER CLUSTER IMULB T2,RIBALC##+1(P1) ;CONVERT CLUSTERS ALLOCATED TO BLOCKS ADDM T2,UFDBKS ;KEEP COUNT OF BLOCKS ALLOCATED IN THIS UFD MOVE T2,HOMRBD ;LOGICAL BLOCK NUM OF 1ST RIB FOR HOME.SYS MOVEM T2,RIBSLF##+1(P1) MOVE T1,HOMRBA ;IOWD FOR 1ST HOM.SYS RIB HRRZ U,FSTUNI ;RESET TO FIRST UNIT PUSHJ P,BLKWRT HLRZ U,LSTUNI ;RESET TO LAST UNIT MOVEM P3,RIBSLF##+1(P1) ;LOGICAL BLOCK NUM OF 2ND RIB MOVE T2,P3 ;LOGICAL BLOCK NUM OF 2ND RIB PUSHJ P,BLKWRT ;WRITE IT OUT MOVE T1,SATBKA ;ADDRESS OF A SPARE BLOCK OF CORE (SAT BLOCK) PUSHJ P,CORZER ;CLEAR THE BUFFER ;HOME.SYS HAS NOW BEEN CREATED ;HERE TO WRITE ZEROS IN UNUSED BLOCKS IN HOME.SYS HRRZI P1,1(P1) ;ADDR OF HOME.SYS RIB IN CORE ADD P1,RIBFIR##(P1) ;MAKE POINTER TO 1ST RETRIEVAL POINTER MOVE T1,SYSPPN## MOVEM T1,DEVPPN(F) ;MAKE DDB LOOK LIKE HOME.SYS IN SYS MOVE T1,HOMFNM MOVEM T1,DEVFIL(F) ;TO ALLOW WRITING BLOCK 0 HOMZR2: MOVE T2,(P1) ;T2=NEXT RETRIEVAL POINTER LDB T1,STYCNP##(P2) ;T1=CLUSTER COUNT JUMPN T1,HOMZR1 ;JUMP IF NOT NEW UNIT POINTER JUMPE T2,MNTCRE ;JUMP IF FINISHED TRZ T2,RIPNUB## ;CLEAR BIT SET TO MAKE SURE NON-ZERO PUSHJ P,NEWUNI## ;SET UP U,DEVUNI(F) TO NEW UNIT STOPCD REFERR,DEBUG,NMU,DIESTR##, ;++NO MORE UNITS LDB J,UNYBPC## ;NEWUNI CLOBBERS J JRST HOMZR5 ;GO TO NEXT POINTER HOMZR1: IMUL T1,J ;T1=BLOCKS IN THIS GROUP LDB P3,STYCLP##(P2) ;P3=1ST CLUSTER THIS GROUP IMUL P3,J ;=1ST LOGICAL BLOCK MOVEI P4,-1(T1) ADD P4,P3 ;P4=LAST BLOCK OF GROUP MOVE T1,SATBKA ;SET T1=IOWD FOR BLOCK OF ZEROS CAMN P3,HOMRBD ;SKIP IF NOT 1ST RIB JRST HOMZR4 ;LEAVE IT ALONE HOMZR3: CAMN P3,HOMSR2 ;SKIP IF NOT 2ND RIB JRST MNTCRE ;ALL DONE JUMPE P3,HOMZR4 ;DON'T WIPE OUT BLOCK 0 PUSHJ P,HUSD ;SEE IF THIS BLOCK HAS VALID DATA SKIPA T2,P3 ;NO, SET T2=NEXT LOGICAL BLOCK TO CLEAR JRST HOMZR4 ;YES, LEAVE IT ALONE PUSHJ P,BLKWRT ;WRITE OUT BLOCK OF ZEROS HOMZR4: CAME P3,P4 ;SKIP IF JUST DID LAST BLOCK THIS GROUP AOJA P3,HOMZR3 ;DO IT FOR NEXT BLOCK HOMZR5: AOBJN P1,HOMZR2 ;LOOP FOR ALL RETRIEVAL POINTERS SUBTTL CREATE SYSTEM FILES ;HERE TO CREATE FILE MAINT.SYS - ALLOCATING BLOCKS FOR MAINTENANCE MNTCRE: IFN FTMAINT,< HRRZ U,FSTUNI ;U=1ST UNIT IN STR MOVE T1,MNTFNM ;NAME OF FILE OF MAINTENANCE TRACKS MOVSI T2,(SIXBIT .SYS.) MOVE T3,SYSPPN## MOVEI T4,1 MOVE P4,NDCFAB ;ALL STATUS BITS PUSHJ P,FIL1RB ;ALLOCATE 1ST RIB AND SET UP RIB IN CORE MOVEM T1,MNTRBD ;REMEMBER LOGICAL BLOCK NUM OF 1ST RIB FOR MAINT.SYS MOVEM U,MNTUN MOVE T2,T1 ;T2=1ST LOG BLOCK IN CLUSTER MOVE T1,[JRST ONCWAT##] ;SET UP WAIT ROUTINE IN CASE TAKBLK CHANGES SATS MOVEM T1,PWAIT1## PUSHJ P,FINCLS JRST MNTCR4 ;DONT NEED NEW UNIT POINTER MNTCR3: PUSHJ P,STNWUN ;STORE NEW UNIT POINTER IN SAT.SYS RIB MNTCR4: LDB T1,UNYKTP## ;GET KONTROLLER TYPE MOVE P1,MNTLST(T1) ;P1=POINTER FOR THIS KONTROLLER TYPE LDB T1,UNYUTP ;T1=UNIT TYPE CAIE T1,0 ;SKIP IF 0 (USE RH OF POINTER) MOVSS P1 ;(USE LH OF POINTER) MNTCR1: LDB P4,MNYCNT ;GET NEXT COUNT FILED JUMPE P4,MNTCR2 ;JUMP IF FINISHED LDB P3,MNYBLA ;GET 1ST BLOCK TO ALLOCATE MOVE T1,P3 ;PUT IN T1 MNTCR5: CAML T1,UNIBPU(U) JRST MNTCR6 ;DONT BOTHER IF GR THAN BLOCKS ON UNIT HRROI T2,1 PUSHJ P,TAKBLK## ;ALLOCATE NEXT BLOCK IN GROUP (SET BIT IN SAT TABLE) JFCL ;DONT CARE IF NOT AVAILABLE AOS T1,P3 SOJG P4,MNTCR5 ;LOOP FOR WHOLE GROUP MNTCR6: LDB T2,MNYCNT ;GET THIS COUNT FIELD AGAIN LDB T1,MNYBLA ;GET 1ST BLOCK OF GROUP PUSHJ P,ZEXBLK ;SET UP PTRS AND 0 BLOCKS IN CLUSTERS OUTSIDE REGION AOJA P1,MNTCR1 ;LOOP FOR ALL SECTIONS TO ALLOCATE MNTCR2: HLRZ U,UNISTR(U) ;NEXT UNIT IN STR JUMPN U,MNTCR3 ;LOOP FOR ALL UNITS HLRZ U,LSTUNI ;LAST UNIT PUSHJ P,CMPSIZ ;COMPUTE WORDS WRITTEN MOVE T3,MNTRBD ;LOGICAL BLOCK NUM OF 1ST RIB HRRZ T4,FSTUNI ;T4=ADDR OF 1ST UNIT PUSHJ P,FIL2RB ;ALLOCATE 2ND RIB AND WRITE OUT RIBS >; END IFN FTMAINT ;HERE TO ALLOCATE SPACE FOR CRASH.EXE - SPACE TO WRITE OUT A CRASH FILE MOVSI T1,SYNRPR## ;PROTECTION TO PREVENT READING EXCEPT R 1 MOVEM T1,CURPRT HLRZ U,LSTUNI ;TRY TO PUT IT ON LAST UNIT SKIPN T4,CRSBKN ;SKIP IF ALLOCATE CRASH.EXE JRST NOCRS ;NO CRASH.EXE MOVE T1,CRSFNM ;NAME OF CRASH.EXE FILE MOVSI T2,(SIXBIT .EXE.) MOVE P4,NDCFAB ;NO DELETE, FAILSAFE, BAD CHECKSUM TRO P4,RIPDMP## ;SHOW THAT FILE NEED NOT BE CONTIGUOUS PUSHJ P,FILDO ;CREATE FILE MOVEM P1,CRSRBD ;REMEMBER LBN OF 1ST RIB MOVEM U,CRSUN ;HERE TO ALLOCATE SPACE FOR SNAP.SYS - SPACE TO PERIODICALLY DUMP SYSTEM NOCRS: SKIPN T4,SNPBKN ;SKIP OF ALLOCATE CRASH.EXE JRST NOSNP ;NO SNAP.SYS MOVE T1,SNPFNM ;NAME OF SNAP.SYS FILE MOVSI T2,(SIXBIT .SYS.) MOVE P4,NDNCNF ;NO DELETE, NO FAILSAFE PUSHJ P,FILDO ;CREATE FILE MOVEM P1,SNPRBD MOVEM U,SNPUN ;HERE TO ALLOCATE SPACE FOR RECOV.SYS - SCRATCH SPACE FOR RECOVERY PROGRAM NOSNP: SKIPN T4,RCVBKN ;SKIP OF ALLCATE RECOV.SYS JRST NORCV ;NO RECOVERYS MOVE T1,RCVFNM ;NAME OF RECOV.SYS FILE MOVSI T2,(SIXBIT .SYS.) MOVE P4,NDNCNF ;NO DELETE, NO FAILSAFE PUSHJ P,FILDO ;CREATE FILE MOVEM P1,RCVRBD ;REMEMBER LOGICAL BLOCK NUM OF 1ST RIB MOVEM U,RCVUN ;HERE TO CREATE FILE SWAP.SYS FROM SWAPPING SPACE ON THIS STR NORCV: HRRZ U,FSTUNI ;1ST UNIT IN STR SWPCR4: LDB T1,UNYK4S## ;K FOR SWAPPING ON THIS UNIT JUMPN T1,SWPCR5 ;YES, CREATE SWAP.SYS HLRZ U,UNISTR(U) ;NEXT UNIT IN STR JUMPN U,SWPCR4 ;LOOP FOR ALL UNITS IN STR JRST NOSWAP ;NO SWAPPING SPACE - NO SWAP.SYS SWPCR5: HRRZ U,FSTUNI ;U=ADDR OF FIRST UNIT IN STR MOVE T1,SWPFNM ;NAME OF FILE OF SWAPPING SPACE MOVSI T2,(SIXBIT .SYS.) MOVE T3,SYSPPN## MOVEI T4,1 ;NUMBER OF BLOCKS TO ALLOCATE MOVE P4,NDCFAB ;ALL STATUS BITS PUSHJ P,FIL1RB MOVEM T3,SWPRBD MOVEM U,SWPUN MOVE T2,T3 ;T2=1ST LOGICAL BLOCK OF CLUSTER PUSHJ P,FINCLS LDB T2,UNYK4S## ;GET K FOR SWAPPING FOR 1ST UNIT JUMPE T2,SWPCR1 ;JUMP IF NO SPACE ON 1ST UNIT JRST SWPCR3 ;ALREADY HAVE 1ST NEW UNIT POINTER SWPCR2: LDB T2,UNYK4S## ;GET K FOR SWAPPING ON THIS UNIT JUMPE T2,SWPCR1 ;JUMP IF NO SPACE ON THIS UNIT PUSHJ P,STNWUN ;STORE NEW UNIT POINTER IN SWAP.SYS RIB SWPCR3: MOVE T1,UNISLB(U) ;FIRST LOGICAL BLOCK FOR SWAPPING IDIV T1,J ;CONVERT TO CLUSTER MOVE T4,T1 ;T1=1ST CLUSTER OF AREA MOVE T1,UNISLB(U) ;FIRST LBN LDB T2,UNYK4S## ;GET K FOR SWAPPING LSH T2,BLKSPK ;K FOR SWAPPING TIMES BLOCKS PER K = BLOCKS PUSHJ P,ZEXBLK ;SET UP PTR AND CLEAR BLOCKS OUTSIDE REGION SWPCR1: HLRZ U,UNISTR(U) ;NEXT UNIT IN THIS STR JUMPN U,SWPCR2 ;LOOP FOR ALL UNITS THIS STR HLRZ U,LSTUNI ;LAST UNIT SKIPN T2 ;T1 NON-ZERO IF SWAPPING SPACE ON LAST UNIT PUSHJ P,STNWUN ;ELSE STORE NEW UNIT PTR FOR LAST UNIT PUSHJ P,CMPSIZ ;COMPUTE SIZE OF FILE MOVE T3,SWPRBD HRRZ T4,FSTUNI ;T4=ADDR OF UNIT FOR 1ST RIB PUSHJ P,FIL2RB ;HERE TO CREATE FILE BADBLK.SYS FROM BAD REGIONS ON THIS STR NOSWAP: HRRZ U,FSTUNI ;ADDR OF FIRST UNIT IN THIS STR MOVE T1,BADFNM ;NAME OF FILE OF BAD REGIONS MOVSI T2,(SIXBIT .SYS.) MOVE T3,SYSPPN## MOVEI T4,1 MOVE P4,NDCFAB ;ALL STATUS BITS PUSHJ P,FIL1RB MOVEM T3,BADRBD MOVEM U,BADUN MOVE T2,T3 ;T2=1ST LOGICAL BLOCK IN CLUSTER PUSHJ P,FINCLS JRST BADCR2 ;ALREADY HAVE NEW UNIT POINTER FOR 1ST UNIT BADCR3: PUSHJ P,STNWUN ;STORE NEW UNIT POINTER FOR THIS UNIT BADCR2: PUSHJ P,REDBAT ;READ IN BAT BLOCK FOR THIS UNIT HRRZ P4,BATBKA AOS T4,P4 ADD P4,BAFFIR##(P4) LDB T1,BAYNBR## ;NUMBER OF BAD REGIONS FOUND BY MAP ADD T1,BAFCNT##(T4) ;+ THOSE FOUND BY MONITOR JUMPE T1,BADCR7 ;JUMP IF NONE MOVNS T1 ;NEGATE HRL P4,T1 BADCR1: MOVE T1,BAFELB##(P4) ;1ST BAD BLOCK OF REGION TLZ T1,BATMSK## MOVEI T2,BAPNTP## TDNN T2,BAFAPN##(P4) ;IF OLD-STYLE BAT BLOCK HRRZS T1 ; ONLY 18 BITS COUNT MOVE T2,P4 ;T2=ADDR OF THIS ENTRY LDB T2,BAYNBB## ;NUMBER OF BAD BLOCKS THIS REGION - 1 PUSHJ P,CKOVLP ;CHECK OVER LAP WITH EXISTING PNTRS SKIPLE T2 ;IGNORE ENTRY IF IT OVERLAPS WITH A PREVIOUS PUSHJ P,BADREG ;ADD REGION TO RIB ADDI P4,1 AOBJN P4,BADCR1 ;LOOP FOR ALL BAD REGIONS THIS UNIT BADCR7: HLRZ U,UNISTR(U) ;NEXT UNIT IN STR JUMPN U,BADCR3 ;LOOP FOR ALL UNITS THIS STR HLRZ U,LSTUNI ;RESET TO LAST UNIT PUSHJ P,CMPSIZ MOVE T3,BADRBD HRRZ T4,FSTUNI ;T4=ADDR OF UNIT FOR 1ST RIB PUSHJ P,FIL2RB ;HERE TO CREATE SYS UFD MOVSI T1,SYSPRV## ;SET ACCESS CODE FOR SYS UFD MOVEM T1,CURPRT HRRZ U,FSTUNI ;FIRST UNIT ON STR MOVE T1,FSTFL PUSHJ P,FILCHK ;CHECKSUM ON 1ST FILE NAME AND RETURN PTR IN P3 MOVE T2,MFDSIZ ;NUMBER OF DATA BLOCKS TO ALLOCATE FOR MFD PUSHJ P,HIALCU ;ALLOCATE SPACE FOR MFD MOVEM U,MFDUN MOVE T2,MFDRBD ;IN CASE OF ACCIDENTAL REFRESHING ADDI T2,2 MOVE T1,SATBKA ;COPY THE 2 MFD BLOCKS WE ARE GOING TO WIPE MOVEM T1,@ONCMBF## ; ELSEWHERE ON THE PACK SO A RECOVERY PROGRAM PUSHJ P,OMNRED## ; HAS SOMEWHERE TO START FROM JFCL MOVE T2,UNIBPU(U) SUBI T2,2 PUSHJ P,OMNWRT## ;1ST MFD DATA ON HIGHEST BLOCK - 2 JFCL MOVE T2,MFDRBD ADDI T2,1 PUSHJ P,OMNRED## JFCL MOVE T2,UNIBPU(U) SUBI T2,1 PUSHJ P,OMNWRT## ;2ND MFD DATA ON HIGHEST -1 JFCL LDB J,UNYBPC## ;RESET J MOVE T1,SATBKA ;ZERO BLOCK AGAIN PUSHJ P,CORZER SETZ P1, ;CLEAR COUNT OF WORDS WRITTEN IN UFD MOVSI T1,-LSTFL SKIPE FSTUNW(T1) ;SKIP IF NO FILE CREATED ADDI P1,2 ;COUNT 2 WORDS WRITTEN FOR EACH FILE CREATED AOBJN T1,.-2 MOVE T1,SYSPPN## MOVEM T1,SYSUFD ;SAVE IN NAME BLOCK PUSHJ P,UFALST ;SET UP A UFD AND WRITE ZEROS FOR DATA MOVE P4,SYUFSZ ;NUMBER OF DATA BLOCKS ADD P4,P1 ;PLUS FIRST BLOCK-1=LAST DATA BLOCK MOVE T1,SATBKA MOVEM T1,UFDSTP MOVSI P3,-LSTFL PUSHJ P,UFDSTO ;CREATE AND STORE ENTRY FOR NEXT FILE AOBJN P3,.-1 ;LOOP FOR ALL FILES IN SYS UFD PUSHJ P,NWBKUF ;OUTPUT LAST BLOCK OF DATA ;HERE TO CREATE PRINT UFD MOVSI T1,777000 ;INFINITLY WRITEABLE PRIVILEGES MOVEM T1,CURPRT MOVE T1,SPLPPN## ;PRINT UFD MOVEM T1,PRTUFD PUSHJ P,UFDSET MOVEM P1,PRTRBD ;SAVE LOGICAL BLOCK NUM OF 1ST RIB MOVEM U,PRTUN ;HERE TO CREATE CRASH UFD ON DISK PACK STR'S LDB T1,UNYKTP## ;CONTROLLER TYPE CAIGE T1,TYPDP ;SKIP IF BIG ENOUGH TO GET CRASH ON DISK JRST NOXPN ;DON'T BOTHER WITH THIS UFD MOVSI T1,750000 ;DON'T WANT PEOPLE READING MOVEM T1,CURPRT SKIPN T1,XPNPPN## ;CRASH PPN JRST NOXPN ;NO CRASH UFD DESIRED MOVEM T1,XPNUFD PUSHJ P,UFDSET MOVEM P1,XPNRBD MOVEM U,XPNUN ;HERE TO CREATE MFD NOXPN: MOVE T1,UFDPRT## MOVEM T1,CURPRT MOVE T1,FFAPPN## ;ALL PRIVILEGES PPN (1,2) MOVEM T1,ALPUFD PUSHJ P,UFDSET ;CREATE UFD MOVEM P1,ALPRBD MOVEM U,ALPUN MOVE T1,NEWPPN## MOVEM T1,XSYUFD MOVSI T2,SYSPRV## ;GET RIGHT PROTECTION MOVEM T2,CURPRT PUSHJ P,UFDSET ;EXPERIMENTAL SYS MOVEM P1,XSYRBD MOVEM U,XSYUN MOVE T1,OLDPPN## MOVEM T1,OLDUFD PUSHJ P,UFDSET MOVEM P1,OLDRBD MOVEM U,OLDUN MOVSI T1,MFDPRV## ;SET ACCESS CODE FOR MFD MOVEM T1,CURPRT MOVE T1,MFDSIZ ;BLOCKS TO ALLOCATE FOR MFD ADDI T1,2 ;+2 FOR RIBS PUSHJ P,LBNCLS ;CONVERT TO CLUSTERS IMUL T1,J ;AND TO BLOCKS ADDM T1,UFDBKS MOVEI P1,2*LSTUF ;NUMBER OF DATA WORDS TO WRITE MOVE T1,MFDPPN## ;NAME OF MFD MOVEM T1,MFDUFD ;SAVE IN NAME BLOCK PUSHJ P,FILCHK ;CHECKSUM ON 1ST NAME AND RETURN PTR IN P3 MOVE T1,MFDUFD ;RESET NAME OF MFD PUSHJ P,UFALST MOVE P4,MFDSIZ ;NUMBER OF DATA BLOCKS FOR MFD ADD P4,P1 ;P4=LAST DATA BLOCK MOVEI P3,MFDUFD-FSTFL ;PUT MFD IN ITSELF FIRST PUSHJ P,UFDSTO MOVE P3,[XWD -LSTUF,LSTFL] ;NOW DO UFD'S IN MFD MFDCRE: MOVE T1,FSTFL(P3) ;GET NAME OF THIS UFD CAME T1,MFDUFD ;SKIP IF MFD (ALREADY DONE) PUSHJ P,UFDSTO AOBJN P3,MFDCRE ;LOOP FOR ALL UFD'S TO CREATE PUSHJ P,NWBKUF ;OUTPUT LAST BLOCK OF DATA MOVE T2,P1 ;1ST BLOCK AFTER REDUNDENT RIB ADDI T2,2 ;(REMEMBERING TO USE 36-BIT ARITHMETIC) ADDI P4,1 ;LAST "REAL" BLOCK MFDCR1: CAMLE T2,P4 ;PAST REGION? SOJA P4,FEFIX ;YES, DONE MOVE T1,SATBKA ;NO, ZERO THIS MFD DATA BLOCK PUSHJ P,BLKWRT ;DO IT TO IT AOJA T2,MFDCR1 ;AND TRY NEXT BLOCK ;HERE TO SET UFD POINTER IN FE.SYS RIB AND WRITE IT FEFIX: SKIPN FERBD ;WAS THERE AN FE.SYS? JRST MFDCRD ;NO MOVE U,FEUN ;GET UDB ADDR MOVE T1,FERBA ;GET BUFFER ADDR MOVEM T1,@ONCMBF## ;POINT TO IT MOVE T2,SYSRBD MOVEM T2,RIBUFD+1(T1) ;POINT TO SYS UFD MOVE T2,FERBD ;POINT TO BLOCK TO WRITE PUSHJ P,OMNWRT## ;WRITE IT JFCL MOVE T1,FERBA ;GET BUFFER ADDR AGAIN ADD T2,RIBALC+1(T1) ;AND POINT TO LAST BLOCK SOJ T2, PUSHJ P,OMNWRT## ;.. JFCL ;HERE TO SET LOGICAL BLOCK IN STR OF 1ST RIB OF OUR FILES MFDCRD: MOVSI P3,-LSTUNW FLBKUP: MOVE U,FSTUNW(P3) ;SET UNIT OF 1ST RIB OF CURRENT FILE LDB T1,UNYLUN## ;LOGICAL UNIT NUMBER IMUL T1,STRBPU##(P2) ;TIMES BLOCKS PER UNIT ADDM T1,FSTBK(P3) ;PLUS LOG BLOCK ON THIS UNIT=BLK IN STR AOBJN P3,FLBKUP SUBTTL UPDATE HOME BLOCKS MOVE T1,HOMRBA MOVEM T1,@ONCMBF## ;STORE IOWD FOR HOME BLOCK HRRZ U,FSTUNI ;RESET TO 1ST UNIT ;HERE TO UPDATE HOME BLOCKS HOMUPD: PUSHJ P,GTHOM## ;READ HOME BLOCKS JRST HBEMSG ;ERROR READING HOME BLOCKS MOVE T2,HOMRBA ;IOWD FOR HOME BLOCK SETZM HOMPPN##+1(T2) ;PUT 0 IN PPN WHO LAST REFRESHED SETZM HOMREF##+1(T2) ;CLEAR NEEDS REFRESHING FLAG EXCH U,MFDUN ;U=UNIT MFD IS ON 1ST LDB T4,UNYLUN## ;T4= BIG AMT OF UNIT FOR MFD EXCH U,MFDUN ;RATE=U MOVEM T4,HOMUN1##+1(T2) ;STORE IN HOME BLOCK SKIPE T1,FEUN ;WAS THERE A SAVED FE.SYS? CAME T1,U ;ON THIS UNIT? SKIPA ;NO, BE SURE TO ZAP HOM BLOCK WORDS JRST FEOK SETZM HOMFEB##+1(T2) ;BE SURE FILE IS REALLY GONE SETZM HOMFEL##+1(T2) ;.. FEOK: MOVEI T2,HOMTAB##(T2) PUSH T2,SATRBD PUSH T2,HOMRBD PUSH T2,SWPRBD PUSH T2,[0] PUSH T2,BADRBD PUSH T2,CRSRBD PUSH T2,SNPRBD PUSH T2,RCVRBD PUSH T2,SYSRBD PUSH T2,PRTRBD PUSH T2,MFDRBD PUSH T2,MFDPTR HRRZ P1,HOMRBA ;ADDR-1 OF BUFFER IN CORE ADDI P1,1 PUSHJ P,WRTRUN## JRST EWHMSG ;ERROR WRITING HOME BLOCKS MOVE T1,[JRST ONCWAT##] MOVEM T1,PWAIT1## PUSHJ P,WTUSAT## ;WRITE OUT SATS THAT HAVE CHANGED ON THIS UNIT HLRZ U,UNISTR(U) JUMPN U,HOMUPD ;LOOP FOR ALL UNITS IN STR SUBTTL FINISH UP ;HERE WHEN ALL DONE TDZA T1,T1 ;INDICATE NO ERRORS REFERR: SETO T1, ;INDICATE ERROR MOVEM T1,ERRRET ;SAVE ERROR FLAG PUSHJ P,RSPWTC## ;RESTORE WAIT ROUTINE MOVE T1,FFAPPN## ;FULL-FILE-ACCESS PPN MOVEM T1,REFLAG## ;SET REFLAG NON-ZERO HRRZ U,FSTUNI ;RESET U TO FIRST UNIT HRRZ P2,UNISTR(U) ;TO RESET P2 WHICH WAS CLOBBERED FIXING HOME BLOCKS SKIPN ERRRET ;SKIP IF AN ERROR OCCURRED HRRZS STRREF##(P2) ;CLEAR NEEDS REFRESHING FLAG IN CORE MOVE T1,SATRBA ;IOWD FOR ORINGINAL MONITOR BUFFER MOVEM T1,@ONCMBF## SKIPE .UONCE## ;ARE WE IN USER MODE? JRST REFXI2 ;YES, THEN DON'T BOTHER TO RETURN THE CORE MOVSI P1,-CORN+1 ;MINUS NUMBER OF EXTRA BUFFERS WE OBTAINED REFXI1: HRRZ T2,SATRBA+1(P1) ;GET ADDRESS -1 ADDI T2,1 MOVEI T1,BLKSIZ## ;NUMBER OF WORDS OBTAINED PUSHJ P,GIVWDS## ;RETURN THEM SETZM SATRBA+1(P1) ;ZERO OUT POINTER AOBJN P1,REFXI1 ;LOOP FOR REMAINDER REFXI2: MOVE P,SAVEP ;GET SAVED PDL POINTER BACK SKIPN ERRRET ;DID AN ERROR OCCUR? AOS -1(P) ;NO, SET FOR SKIP RETURN POP P,JBTADR## ;RESTORE JBTADR (MAY BE IN INTTAB) POPJ P, ;RETURN SUBTTL ERROR HANDLING CRHMSG:! HBEMSG:! ERHMSG: MOVEI T1,[ASCIZ /% Error reading HOME blocks for unit /] PUSHJ P,ICONM## ;SAY WHAT OUR PROBLEM IS MOVE T2,UDBNAM(U) ;GET UNIT NAME PUSHJ P,PRNAME## ;SAY WHICH UNIT PUSHJ P,CRLFOP## ;FLUSH LINE JRST REFERR ;PUNT EWHMSG: MOVEI T1,[ASCIZ /% Error writing HOME blocks for unit /] PUSHJ P,ICONM## ;SAY WHAT OUR PROBLEM IS MOVE T2,UDBNAM(U) ;GET UNIT NAME PUSHJ P,PRNAME## ;SAY WHICH UNIT PUSHJ P,CRLFOP## ;FLUSH LINE JRST REFERR ;PUNT ZBCMSG: MOVE T1,STRNAM##(P2) ;GET STRUCTURE NAME MOVEI T2,[ASCIZ /has zero blocks per cluster/] PUSHJ P,SWARN## ;COMPLAIN ABOUT THE CONDITION JRST REFERR ;PUNT SUBTTL SUBROUTINES ;SUBROUTINE TO READ IN A SAT BLOCK INTO MONITOR CORE ;ARGS P2=ADDR OF IN-CORE BUFFER ; P4=INDEX OF SAT SATIN: SE1ENT ;MUST BE IN A NON-ZERO SECTION TO READ SATS MOVE T1,[JRST ONCWAT##] MOVEM T1,PWAIT1## ;SET UP WAIT ROUTINE PUSH P,R ;SAVE R MOVE R,P2 ;SAT BUFFER ADDRESS PUSHJ P,SATRED## POP P,R ;RESTORE R LDB J,UNYBPC## PJRST RSPWTC## ;RESTORE WAIT ROUTINE ;SUBROUTINE TO READ IN BAT BLOCKS AND TO RETURN NEW UNIT POINTER ;ARG U=ADDR OF CURRENT UNIT REDBAT: MOVE T1,BATBKA ;IOWD FOR BAT BLOCK MOVEM T1,@ONCMBF## ;STORE IN MONITOR BUFFER MOVSI P2,(SIXBIT .BAT.) MOVE P3,[EXP CODBAT##] MOVE P4,LBNLST+1 ;BLOCK NUMBERS FOR BAT BLOCKS PUSHJ P,REDRUN## ;READ BAT BLOCKS AND CHECK FOR ERRORS STOPCD .+1,INFO,ERB,DIEUNI##, ;++ERROR READING BAT BLOCK LDB J,UNYBPC## ;RESET BLOCKS PER CLUSTER HRRZ P2,UNISTR(U) ;AND ADDR OF STR DATA BLOCK POPJ P, ;SUBROUTINE TO SCAN BAT BLOCK AND EXECUTE AN INSTRUCTION FOR EACH BAD BLOCK ;ARGS T1=ADDR OF BAT BLOCK IN CORE - 1 ; T2=INSTRUCTION TO EXECUTE SCNBAT::PUSHJ P,SAVE4## ;SAVE P1-P4 MOVE P4,T1 ;P4=ADDR OF BAT BLOCK-1 MOVE P2,T2 ;P2=INSTRUCTION TO EXECUTE AOS T4,P4 ;ADDR OF CORE BLOCK FOR BAT BLOCK, SAVED IN T4 ADD P4,BAFFIR##(P4) ;P4=ADDR OF FIRST WORD FOR BAD REGION ENTRIES LDB T1,BAYNBR## ;NUMBER OF BAD REGIONS FOUND BY MAP ADD T1,BAFCNT##(T4) ;PLUS THOSE BY MONITOR JUMPE T1,CPOPJ## ;JUMP IF NO BAD REGIONS MOVNS T1 ;NEGATE HRL P4,T1 ;MAKES P4=-NUM OF ENTRIES,ADDR OF 1ST MRKBAD: MOVE T2,P4 ;ADDR OF BAD REGION PTR LDB P3,BAYNBB## ;NUMBER BAD BLOCKS-1 MOVE P1,BAFELB##(P4) ;P1=1ST BAD BLOCK TLZ P1,BATMSK## ;JUST LOGICAL BLOCK NUMBER MOVEI T3,BAPNTP## ;IF OLD-STYLE TDNN T3,BAFAPN##(P4) HRRZS P1 ; ONLY 18 BITS COUNT SUBI P1,1 MRKBD2: AOS T1,P1 ;P1=NEXT BAD BLOCK XCT P2 ;MARK THIS BLOCK IN SAT SOJGE P3,MRKBD2 ;LOOP FOR ALL BAD BLOCKS THIS REGION ADDI P4,1 ;COMPENSATE FOR 2 WORD ENTRIES AOBJN P4,MRKBAD ;LOOP FOR ALL ENTRIES POPJ P, ;SUBROUTINE TO SET BITS IN CURRENT SAT BLOCK ;ARGS T1=BLOCK NUMBER ;ENTER AT SETBAD TO MARK BAD BLOCKS ;ENTER AT SETSWP TO MARK SWAPPING SPACE SETBAD: SETSWP: MOVE T2,T1 IDIV T2,J ;T2=CLUSTER NUMBER CAML T2,BEGSAT ;SKIP IF BEFORE BEGINNING OF CURRENT SAT CAMLE T2,LCLSAT ;SKIP IF WITHIN CURRENT SAT (NOT PAST END) POPJ P, ;BLOCK NOT IN CURRENT SAT PUSHJ P,SAVE4## ;SAVE P1-P4 MOVE P1,J ;P1=BLOCKS PER CLUSTER MOVE P2,BEGSAT ;P2=1 REPRESENTED BY 1ST BIT MOVE P3,LCLSAT ;P3=GROUP REPRESENTED BY LAST BIT MOVE P4,SATBKA ;P4=IOWD PTR TO CORE BLOCK PUSHJ P,CHKBIT## ;SEE IF BIT ALREADY SET ORM T4,(T1) ;NO, SET IT POPJ P, ;YES, EXIT ;SUBROUTINE TO CHECK FOR POSSIBLE OVERLAPS IN BADBLK.SYS ;ARGS T1=1ST BLOCK OF NEW REGION ; T2=NO OF BLOCKS IN REGION -1 ;VALUES T1=1ST BLOCK IN REGION ; T2=NO OF BLOCKS IN REGION CKOVLP: PUSHJ P,SAVE1## ADD T2,T1 MOVE P1,T1 ;1ST BAD BLOCK IN NEW REGION MOVE T3,T2 ;LAST BAD BLOCK IN NEW REGION MOVE T4,SATRBA ADDI T4,1 ADD T4,RIBFIR##(T4) ;AOBJN WORD FOR CURRENT POINTERS CKOVL1: SKIPN T2,(T4) ;GET A RETRIEVAL POINTER JRST CKOVL3 ;DONE TLNN T2,-1 JRST CKOVL2 ;UNIT-CHANGE LDB T1,STYCLP##(P2) ;1ST CLUSTER IN THIS PNTR LDB T2,STYCNP##(P2) ;NO OF CLUSTERS IMULI T1,(J) IMULI T2,(J) ;CONVERT TO BLOCKS SUBI T2,1 ADD T2,T1 ;T2=LAST BLOCK IN CURRENT POINTER CAML T2,P1 CAMLE T1,T3 ;OVERLAP? JRST CKOVL2 ;NO CAMGE P1,T2 ;YES. AT FRONT? AOS P1,T2 ;YES, ADJUST FRONT CAMLE T3,T1 ;OVERLAP AT END? SOS T3,T1 ;YES, ADJUST END CKOVL2: AOBJN T4,CKOVL1 ;CHECK NEXT POINTER CKOVL3: MOVE T1,P1 ;(NEW) START OF REGION AOS T2,T3 SUB T2,T1 ;(NEW) LENGTH OF REGION POPJ P, ;SUBROUTINE TO SET NON ACTUAL DATA BITS IN LAST ACTUAL ;DATA WORD OF A BLOCK ;ARGS T1=ADDR OF CORE BLOCK -1 ; T2=ACTUAL NUMBER OF GROUPS=NUMBER ACTUAL DATA BITS MRKEND: MOVE T3,T2 ;T3=NUMBER GROUPS PUSHJ P,CORZER ;CLEAR THE WHOLE BUFFER IDIVI T3,^D36 ;T3=INDEX IN BLOCK PUSH P,T3 ;SAVE INDEX ADDI T2,-BLKSIZ##(T3) ;T2=ADDR OF WORD CONTIANING BITS JUMPE T4,MRKEN1 ;EXIT IF NO EXTRA BITS AOJ T2, ;ACCOUNT FOR REMAINDER MOVNI T3,-1(T4) ;T3=NUMBER CONTAINING BITS MOVSI T1,400000 ;LEFT MOST BIT ASH T1,(T3) ;SET ACTUAL DATA BIT IN T1 SETCAM T1,(T2) ;SET THE OTHERS IN THE BLOCK MRKEN1: POP P,T3 ;LAST WORD OF BLOCK SUBI T3,BLKSIZ##-1 MRKEN2: JUMPE T3,CPOPJ## ;EXIT IF DONE SETOM 1(T2) ;SET NEXT SAT WORD =-1 AOS T2 AOJA T3,MRKEN2 ;LOOP TILL END OF BUFFER ;SUBROUTINE TO GET A BLOCK FOR HOME.SYS ;ARG T1=LOGICAL BLOCK WITHIN UNIT ; P3=LAST CLUSTER ALLOCATED ;PRESERVES T3, USES P1,T4 GETHMB: PUSH P,T3 PUSHJ P,GETHMC ;TRY TO GET THE BLOCK JRST NOBLK ;COULDNT GET IT POP P,T3 LDB T1,STYCLP##(P2) ;GET CLUSTER JUST ALLOCATED EXCH T1,P3 ;UPDATE LAST CLUSTER ALLOCATED, SAVE PREVIOUS ADDI T1,1 CAME T1,P3 ;SKIP IF LAST FOLLOWS PREVIOUS PJRST HOMRBS ;NO, STORE NEW RETRIEVAL POINTER AND EXIT MOVE T4,HOMRBP MOVE T2,(T4) ;LAST RETRIEVAL POINTER STORED LDB T1,STYCNP##(P2) ;YES, NEED ONLY INCREMENT COUNT ADDI T1,1 DPB T1,STYCNP##(P2) MOVEM T2,(T4) ;STORE NEW PTR MOVE T1,HOMRBA AOS RIBALC##+1(T1) ;BUMP COUNT OF CLUSTERS ALLOCATED POPJ P, NOBLK: MOVE T1,T2 POP P,T3 CAMN T1,P3 ;IF ALREADY ALLOCATED TO US OK POPJ P, ; POP P,(P) ;REMOVE CALLER FROM STACK PJRST BADHOM ;TYPE AND HALT ;SUBROUTINE TO GET A BLOCK FOR HOME.SYS AND COMPUTE CHECKSUM ;ARG T1=LOGICAL BLOCK WITHIN UNIT ;PRESERVES T3, USES P1,T1,T2,T4 GETHMC: MOVE P1,T1 IDIV T1,J ;SEE IF BLOCK NEEDED STARTS A CLUSTER EXCH P1,T2 ;SAVE REMAINDER IN P1 AND REMEMBER BLOCK NEEDED SKIPN T1,T2 ;SKIP IF NOT BLOCK 0 ADDI P1,1 ;MAKE SURE CHECKSUM = 0 FOR BLOCK 0 PUSHJ P,RTAKBK ;TRY TO GET THE BLOCK POPJ P, ;COULDNT MOVSI T1,(SIXBIT .HOM.) CAIE P1,0 SETZ T1, ;ZERO IF NOT BEGINNING OF CLUSTER PUSHJ P,CHEKS1 ;IF NOT BEGINNING OF CLUSTER, 1ST BLOCK ALL 0 JRST CPOPJ1## ;SUBROUTINE TO ALLOCATE 1 BLOCK IN CURRENT SAT WHILE CREATING SATS ;ARG T1=LOGICAL BLOCK NUMBER TO ALLOCATE, OR 0 IF DONT CARE ;VALUE NON-SKIP RETURN IF CANT HAVE BLOCK, T2=CLUSTER NEEDED IF WAS NON-0 ; SKIP RETURN IF GOT BLOCK, T2=RETRIEVAL POINTER ;USES T1, PRESERVES T3 RTAKBK: PUSHJ P,SAVE1## ;SAVE P1 JUMPN T1,RSPBK ;JUMP IF NEED SPECIFIC BLOCK MOVE T1,SATBKA ;SEARCH WHOLE BLOCK MOVSI P1,400000 ;LEFT MOST BIT MOVE T2,BEGSAT ;STARTING AT BEGINNING OF THIS SAT RTAKB1: TDNN P1,1(T1) ;SKIP IF CLUSTER NOT AVAILABLE JRST ROK ;GOT ONE ROT P1,-1 ;WILL TRY NEXT CLUSTER ADDI T2,1 ;KEEP UP CLUSTER NUMBER JUMPGE P1,RTAKB1 ;JUMP IF STILL SAME WORD AOBJN T1,RTAKB1 ;BUMP INDEX AND KEEP ON IF MORE POPJ P, ;NO CLUSTERS AVAILABLE RSPBK: IDIV T1,J ;CONVERT LOGICAL BLOCK TO CLUSTER PUSH P,T1 ;SAVE CLUSTER NEEDED IDIVI T1,^D36 ADD T1,SATBKA ;ADDR-1 OF WORD CONTAINING BIT WE WANT MOVEI P1,^D36 SUBM P1,T2 ;T2=36-REMAINDER MOVSI P1,400000 ROT P1,(T2) ;SHIFT BIT INTO POSITION POP P,T2 ;T2=CLUSTER DESIRED TDNE P1,1(T1) ;SKIP IF AVAILABLE POPJ P, ;NO ROK: ORM P1,1(T1) ;SET BIT, TAKING CLUSTER MOVEI T1,1 DPB T1,STYCNP##(P2) ;SET CLUSTER COUNT TO 1 JRST CPOPJ1## ;SUBROUTINE TO CHECK IF A GIVEN BLOCK CONTAINS VALID DATA IN HOME.SYS ;ARG P3=BLOCK NUMBER TO CHECK ;RETURNS CPOPJ IF DOES NOT CONTAIN DATA ; CPOPJ1 IF IT DOES ;USES T3,T4 HUSD: MOVSI T4,-LBNLEN HLRZ T3,LBNLST(T4) ;T3=NEXT VALID DATA BLOCK TO CHECK FOR CAIE P3,(T3) ;SKIP IF THIS BLOCK HAS VALID DATA AOBJN T4,.-2 ;THIS BLOCK IS NOT THERE JUMPL T4,CPOPJ1## ;JUMP IF THIS BLOCKS CONTAINS DATA MOVSI T4,-LBNLEN ;NO, CHECK SECOND GROUP HRRZ T3,LBNLST(T4) CAIE P3,(T3) AOBJN T4,.-2 JUMPL T4,CPOPJ1## CAIGE P3,FBOOTB## ;SKIP IF BLOCK PAST BEGINNING OF BOOTS POPJ P, ;CANT BE PART OF BOOTS MOVEI T4,FBOOTB## ADDI T4,NBOOTB## ;LAST BLOCK+1 OF BOOTS CAIGE P3,(T4) ;SKIP IF PAST END OF BOOTS JRST CPOPJ1## ;NO, PART OF BOOTS IS CONSIDERED VALID DATA POPJ P, ;SUBROUTINE TO STORE AN RTP IN THE RIB OF SWAP.SYS ;ARGS T1=1ST LOGICAL BLOCK OF REGION ; T2=NUMBER OF BLOCKS IN REGION ZEXBLK: PUSHJ P,SAVE4## MOVE P1,T1 ;P1=1ST BLOCK OF REGION MOVE P3,T2 ;P3=NUMBER BLOCKS IN REGION MOVE T1,UNIBPU(U) ;BLOCKS ON THIS UNIT IDIV T1,J ;CLUSTERS ON THIS UNIT MOVE T1,UNIBPU(U) ;T2=BLOCKS PAST LAST EVEN MULTIPLE OF CLUSTER SIZE SUBI T1,1(T2) ;T1=LAST BLOCK OF LAST REAL CLUSTER CAMLE P1,T1 ;SKIP IF FIRST BLOCK IS WITHIN REAL CLUSTERS POPJ P, ;NO, FORGET THE WHOLE THING MOVE T2,P1 ;YES, T2=FIRST BLOCK IN REGION ADD T2,P3 ;+NUMBER OF BLOCKS=LAST BLOCK+1 SUBI T2,1 ;T2=LAST BLOCK OF REGION SUB T2,T1 ;-LAST BLOCK OF UNIT=NUMBER OF BLOCKS OVER SKIPLE T2 ;SKIP IF ALL WITHIN REAL CLUSTERS SUB P3,T2 ;NO, PRETEND REGION GOES TO END OF LAST REAL CLUSTER ADD P3,P1 ;P3=1ST BLOCK BEYOND REGION SUBI P3,1 ;P3=LAST BLOCK IN REGION IDIV P3,J ;P3=LAST CLUSTER IN REGION ADDI P3,1 ;P3=1ST CLUSTER BEYOND REGION MOVE T1,P1 ;T1=1ST BLOCK IN REGION IDIV T1,J ;T1=1ST CLUSTER IN REGION MOVE P4,T1 ;P4=1ST CLUSTER IN REGION SUB P3,P4 ;P3=NUMBER OF CLUSTERS IN REGION MOVE T3,MAXALC ;MAX CLUSTERS CAN ALLOCATE IN 1 PTR ZEXBL5: SETZ T2, DPB P4,STYCLP##(P2) ;STORE 1ST CLUSTER THIS PTR CAMG P3,T3 ;SKIP IF MORE IN REGION THAN IN 1 PTR JRST ZEXBL6 ;ALL SET DPB T3,STYCNP##(P2) ;STORE MAX PUSHJ P,SATRBS ;STORE PTR SUB P3,T3 ;P3=TOTAL LEFT ADD P4,T3 ;P4=1ST OF WHATS LEFT JRST ZEXBL5 ;LOOP TILL PTRS FOR WHOLE REGION ZEXBL6: DPB P3,STYCNP##(P2) ;STORE LAST COUNT PJRST SATRBS ;STORE LAST PTR AND EXIT ;SUBROUTINE TO ADD A BAD REGION TO THE RIB OF BADBLK.SYS ;T1 PASSES 1ST BLOCK OF REGION ;T2 PASSES NUMBER OF BLOCKS IN REGION BADREG: PUSHJ P,SAVE3## ;SAVE P1-P3 MOVE P3,T1 ;1ST BLOCK MOVE P1,T2 ;NUMBER OF BLOCKS BADRG1: PUSHJ P,BDREG ;PROCESS ONE BLOCK ADDI P3,1 ;ON TO THE NEXT BLOCK SOJG P1,BADRG1 ;LOOP FOR EACH BLOCK POPJ P, ;SUBROUTINE TO ADD A BAD BLOCK TO THE RIB OF BADBLK.SYS ;P3 PASSES THE BLOCK NUMBER BDREG: PUSHJ P,SAVE4## ;SAVE P1-P4 MOVE T1,UNIBPU(U) ;BLOCKS ON THIS UNIT IDIV T1,J ;T2=BLOCKS LEFT AFTER LAST FULL CLUSTER MOVE T1,UNIBPU(U) ;BLOCKS ON THIS UNIT SUBI T1,1(T2) ;LAST BLOCK OF LAST REAL CLUSTER CAMLE P3,T1 ;IS IT IN THE MAINT CYL? POPJ P, ;YES, DON'T PUT IN BADBLK IDIV P3,J ;CONVERT BLOCK TO CLUSTER LDB T3,UNYK4S## ;K FOR SWAPPING JUMPE T3,BDREG1 ;EASY IF NONE LSH T3,BLKSPK ;BLOCKS OF SWAPPING MOVE T1,UNISLB(U) ;1ST BLOCK FOR SWAPPING ADD T3,T1 ;1ST BLOCK BEYOND SWAPPING SUBI T3,1 ;LAST BLOCK OF SWAPPING IDIV T3,J ;LAST CLUSTER OF SWAPPING IDIV T1,J ;1ST CLUSTER FOR SWAPPING CAML P3,T1 ;IN SWAP.SYS? CAMLE P3,T3 BDREG1: SKIPA P4,SATRBA ;NO, GET ADDR-1 OF RIB POPJ P, ;YES, DON'T PUT IN BADBLK TOO ;HERE TO SCAN THE RTP'S THAT ALREADY EXIST MOVEI P4,1(P4) ;ADDR OF RIB ADD P4,RIBFIR##(P4) ;AOBJN PNTR TO RTP'S BDREG2: SKIPN T2,(P4) ;PICK UP AN RTP JRST BDREG3 ;EOF, HAVE TO ADD NEW RTP LDB T1,STYCNP##(P2) ;CLUSTER COUNT JUMPN T1,BDREG4 ;GO IF GROUP POINTER HRRZ P1,T2 ;ZERO MEANS CHANGE UNIT TRZ P1,RIPNUB## ;REMEMBER UNIT NUMBER JRST BDREG5 ;AND GET NEXT RTP BDREG4: LDB T4,UNYLUN## ;GET THIS UNIT'S NUMBER CAME T4,P1 ;IS THIS RTP FOR THIS UNIT? JRST BDREG5 ;NO, GET NEXT RTP LDB T4,STYCLP##(P2) ;CLUSTER ADDRESS ADD T1,T4 ;1ST CLUSTER BEYOND GROUP CAML P3,T4 ;IS OUR CLUSTER IN THIS GROUP? CAML P3,T1 SOSA T4 ;NO, GET 1ST CLUSTER BEFORE GROUP POPJ P, ;YES, OUR CLUSTER IS ALREADY IN THE RIB LDB T3,STYCNP##(P2) ;CLUSTER COUNT CAML T3,MAXALC ;CAN IT BE EXPANDED? JRST BDREG5 ;NO, TEST NEXT RTP MOVEI T3,RIPNUB## ;1ST RTP CAME T3,-1(P4) ;IS THIS THE 2ND RTP? (THE RIB) CAME P3,T4 ;IS OUR CLUSTER JUST BEFORE THE GROUP? JRST BDREG6 ;NO ;HERE TO ADD A CLUSTER TO THE BEGINNING OF THE GROUP DPB P3,STYCLP##(P2) ;STORE NEW 1ST CLUSTER ;HERE TO ADD A CLUSTER TO THE (END OF THE) GROUP BDREG7: LDB T1,STYCNP##(P2) ;OLD CLUSTER COUNT ADDI T1,1 ;ADD ONE DPB T1,STYCNP##(P2) ;NEW CLUSTER COUNT MOVEM T2,(P4) ;STORE NEW RTP HRRZ T1,SATRBA ;ADDR-1 OF RIB AOS RIBALC##+1(T1) ;ONE MORE CLUSTER ALLOCATED POPJ P, ;HERE IF CLUSTER CAN'T BE ADDED TO FRONT OF GROUP BDREG6: CAMN P3,T1 ;CAN IT BE ADDED TO THE END? JRST BDREG7 ;YES ;HERE TO TEST NEXT RTP BDREG5: AOBJN P4,BDREG2 ;SHOULD ALWAYS JUMP ;HERE TO ADD A NEW RTP BDREG3: MOVEI T2,1 ;ONE CLUSTER DPB T2,STYCNP##(P2) ;STORE CLUSTER COUNT DPB P3,STYCLP##(P2) ;STORE CLUSTER ADDRESS PJRST SATRBS ;PUT RTP IN RIB ;SUBROUTINE TO CONVERT NUMBER OF LOGICAL BLOCKS TO NUMBER OF CLUSTERS ;ARG T1=NUMBER OF LOGICAL BLOCKS ;VALUE T1=NUMBER OF CLUSTERS LBNCLS: SUBI T1,1 IDIV T1,J AOJA T1,CPOPJ## ;SUBROUTINE TO ALLOCATE SPACE FOR A UFD NEAR THE CENTER OF A PACK ;ARGS/VALUES SAME AS FOR UFDALC HIALCU: PUSH P,T2 SETO T2, ;ASK FOR MAX POSSIBLE MOVE T1,[JRST ONCWAT##] ;SET UP WAIT ROUTINE MOVEM T1,PWAIT1## ; IN CASE TAKBLK CHANGES SATS MOVE T1,UNIBPU(U) LSH T1,-1 ;START AT MIDDLE OF PACK PUSHJ P,TAKBLK## ;(IT WILL FAIL, BUT RIGHT SAT BLOCK WILL JFCL ; BE SET FOR FOLLOWING ALLOCATION) POP P,T2 ;RESTORE REAL AMOUNT TO GET LDB J,UNYBPC## ;RESET J PUSHJ P,UFDALC ;ALLOCATE BLOCKS IN MIDDLE OF PACK PUSH P,T1 ;SAVE BLOCK NUMBER MOVEI T1,1 MOVEI T2,1 ;RESET TO ALLOCATE AT START OF PACK PUSHJ P,TAKBLK## ;(THIS WILL FAIL TOO) JFCL LDB J,UNYBPC## JRST TPOPJ## ;SUBROUTINE TO ALLOCATE SPACE FOR A UFD ;ARG T2=NUMBER OF BLOCKS TO ALLOCATE ;VALUE T1=LOGICAL BLOCK NUM OF 1ST RIB UFDALC: ADDI T2,2 ;2 BLOCKS FOR RIBS HRLI T2,-1 ;EXACTLY THIS MANY BLOCKS PUSHJ P,CATKBA ;TRY TO ALLOCATE SPACE MOVEM T2,MFDPTR ;REMEMBER RETRIEVAL PTR LDB T1,STYCLP##(P2) ;1ST CLUSTER IMUL T1,J ;LOGICAL BLOCK OF 1ST RIB MOVEM T1,MFDRBD POPJ P, ;SUBROUTINE TO SET UP A UFD WHICH HAS ALREADY BEEN ALLOCATED ;ARGS T1=UFD NAME ; P1=NUMBER OF DATA WORDS TO BE WRITTEN ; P3=1ST RETRIEVAL POINTER UFALST: MOVSI T2,(SIXBIT .UFD.) MOVE T3,MFDPPN## MOVE T4,SATRBA MOVEI P4,RIPDIR## ;SET DIRECTORY BIT IN STATUS ADD P4,NDNCNF ;NO DELETE, NO FAILSAFE BITS PUSHJ P,RIBSET ;SET UP RIB IN CORE MOVEM T4,SATRBP ;SAVE POINTER TO RETRIEVAL PTRS MOVE T2,UFDBKS ;NUMBER OF BLOCKS ALLOCATED IN CURRENT UFD MOVE T4,SATRBA ;POINTER TO RIB MOVEM T2,RIBUSD##+1(T4) ;STORE BLOCKS ALLOCATED IN RIB SETZM UFDBKS ;AND CLEAR FOR NEXT UFD PUSHJ P,STNWUN MOVE T2,P3 ;FIRST RETRIEVAL POINTER PUSH P,SATRBP ;PTR TO RETRIEVAL PTRS PUSHJ P,SATRBS ;STORE RETRIEVAL PTR POP P,T1 LDB T3,STYCLP##(P2) ;1ST CLUSTER IMUL T3,J ;T3=LOG BLOCK OF 1ST RIB PJRST FILST1 ;SUBROUTINE TO CREATE A FILE OF CONTIGUOUS DISK SPACE AND WRITE ZEROS IN DATA BLOCKS ;ARGS T1=FILE NAME ; T2=EXT ; T3=PPN ; T4=NUMBER OF DATA BLOCKS TO ALLOCATE ; P1=NUMBER OF WORDS WHICH WILL BE WRITTEN ; P4=BITS TO SET IN RIB STATUS WORD ;VALUES P1=LOGICAL BLOCK NUMBER OF 1ST RIB ; P3=LOGICAL BLOCK NUMBER OF 2ND RIB ;ENTER AT UFDSET FOR UFD'S, AT FILDO FOR STANDARD SYS FILES FILDO: MOVE T3,SYSPPN## MOVEI P1,BLKSIZ## IMUL P1,T4 PJRST FILSET UFDSET: MOVSI T2,(SIXBIT .UFD.) ;EXT MOVE T3,MFDPPN## ;PPN - FALL INTO FILSET MOVEI T4,1 ;ALLOCATE 1 DATA BLOCK SETZ P1, ;NUMBER OF WORDS TO WRITE MOVEI P4,RIPDIR## ;DIRECTORY BIT FOR STATUS ADD P4,NDNCNF ;NO DELETE, NO FAILSAFE BITS FILSET: ADDI T4,2 ;+2 BLOCKS FOR RIBS PUSHJ P,FIL1RB ;ALLOCATE SPACE AND SET UP RIB IN CORE FILST1: SETZ T2, ;T2=FIRST RELATIVE BLOCK IN GROUP=0 FOR RIB EXCH P1,T3 ;P1=LOG BLOCK OF 1ST RIB,T3=DATA WORDS MOVE T4,SATRBA MOVEM T3,RIBSIZ##+1(T4) ;STORE SIZE IN WORDS IN RIB ADDI T3,BLKSIZ##-1 IDIVI T3,BLKSIZ## ;CONVERT OT BLOCKS ADDI T3,1 ;+1 FOR 2ND RIB PUSHJ P,SCNPTR## ;FIND BLOCK NUM FOR 2ND RIB STOPCD .,STOP,NSR,DIEUNI##, ;++NO SECOND RIB LDB J,UNYBPC## ;J CLOBBERED IN SCNPTR - RESET MOVE P3,DEVBLK##(F) ;DEVBLK=LOG BLOCK OF 2ND RIB MOVE T4,SATRBA ;PTR TO RIB MOVE T1,RIBSTS##+1(T4) ;GET STATUS WORD TRNE T1,RIPDIR## ;SKIP IF NOT DIRECTORY FILE PUSHJ P,QUOSET ;SET UP QUOTAS FOR DIRECTORIES MOVE T4,U PJRST WRTRIB ;WRITE OUT BOTH RIBS ;SUBROUTINE TO COMPUTE SIZE OF FILE IN WORDS=BLOCKS WRITTEN*BLOCK SIZE ;(BEFORE 2ND RIB HAS BEEN ALLOCATED) ;ARGS T4=ADDR-1 OF RIB CMPSIZ: MOVE T4,SATRBA ;ADDR-1 OF SAT RIB - FALL INTO COMSIZ COMSIZ: MOVE T1,RIBALC##+1(T4) ;NUMBER OF CLUSTERS ALLOCATED IMUL T1,J ;CONVERT TO BLOCKS SUBI T1,1 ;-1 FOR FIRST RIB IMULI T1,BLKSIZ## ;TIMES WORDS PER BLOCK MOVEM T1,RIBSIZ##+1(T4) POPJ P, ;SUBROUTINE TO SET UP QUOTAS FOR UFDS ;ARG T4=ADDR OF RIB IN CORE -1 QUOSET: MOVE T1,QUOTAR ;RESERVED QUOTA MOVEM T1,RIBQTR##+1(T4) MOVE T1,QUOTAF ;FIRST COME, FIRST SERVED QUOTA MOVEM T1,RIBQTF##+1(T4) MOVE T1,QUOTAO ;LOGGED OUT QUOTA MOVEM T1,RIBQTO##+1(T4) POPJ P, ;SUBROUTINE TO COMPUTE CHECKSUM FOR 1ST DATA BLOCK OF FILE ;ARGS T1=1ST WORD OF 1ST DATA BLOCK OF FILE ; MFDPTR=1ST RETRIEVAL POINTER FOR FILE ;VALUES P3=MFDPTR=1ST RETRIEVAL POINTER FOR FILE WITH CHECKSUM STORED FILCHK: MOVE T2,MFDPTR ;T2=PTR PUSHJ P,CHEKS1 ;DO THE CHECKSUM MOVE P3,T2 ;P3=PTR WITH CHECKSUM MOVEM P3,MFDPTR ;AND BACK INTO MFDPTR POPJ P, ;SUBROUTINE TO SET UP A FILE, SET UP RIB, ALLOCATE 1ST RIB ;ARGS T1=FILE NAME ; T2=EXT ; T3=PPN ; T4=NUMBER OF BLOCKS TO ALLOCATE ; P4=BITS TO SET IN STATUS WORD ;VALUES T1=AOBIN PTR TO RETRIEVAL POINTERS ; T2=LAST RETRIEVAL POINTER ; T3=LOGICAL BLOCK NUMBER OF FIRST RIB FIL1RB: MOVEM T4,BLKNED ;SAVE NUMBER OF BLOCKS TO ALLOCATE MOVE T4,SATRBA ;ADDR OF RIB IN CORE PUSH P,P4 ;SAVE FLAGS FOR .RBSTS TRZ P4,RIPDMP## ;TURN OFF POSSIBLE "NON-CONTIGUOUS" FLAG PUSHJ P,RIBSET POP P,P4 ;RESTORE FLAGS MOVEM T4,SATRBP ;POINTER TO RETRIEVAL POINTERS PUSHJ P,STNWUN PUSH P,SATRBP ;SAVE PTR TO RETRIEVAL PTRS FIL1R1: HRRO T2,BLKNED ;BLOCKS NEEDED TRNE P4,RIPDMP## ;SKIP IF WE MUST FIND EXACT FIT IN ONE PASS TLZ T2,-1 ;TURN OFF "FIND EXACTLY" FLAG FOR TAKBLK MOVEI T3,ADJALC## ;DEFAULT FOR "FIND SUPERCLUSTERS" MOVE T1,SATRBP ;GET POINTER TO WHERE RETRIEVAL POINTERS GO CAME T1,(P) ;SKIP IF FIRST TRIP THROUGH ALLOCATION LOOP MOVEI T3,TAKBLK## ;ALLOW "REGULAR CLUSTERS" IF NOT FIRST TRIP PUSHJ P,CATKBB ;ALLOCATE MORE SPACE (OR FIRST) TO THE FILE MOVE T1,CHECK0 ;0 CHECKSUM DPB T1,STYCKP##(P2) PUSHJ P,SATRBS ;STORE RETRIEVAL POINTER LDB T1,STYCNP##(P2) ;CLUSTERS ACTUALLY ALLOCATED IMUL T1,J ;BLOCKS ALLOCATED SUB T1,BLKNED ;MINUS NEEDED JUMPGE T1,FIL1R2 ;JUMP IF HAVE ENOUGH MOVNM T1,BLKNED ;RESET AMOUNT STILL NEEDED JRST FIL1R1 ;AND LOOP FOR THOSE FIL1R2: POP P,T1 ;AOBJN PTR TO RETRIEVAL PTRS MOVE T2,1(T1) ;1ST PTR LDB T3,STYCLP##(P2) ;1ST CLUSTER ALLOCATED IMUL T3,J ;1ST BLOCK POPJ P, ;SUBROUTINE ALLOCATE 2ND RIB AND WRITE BOTH RIBS ;ARGS T3=LOGICAL BLOCK NUMBER OF 1ST RIB ; T4=ADDR OF UNIT FOR 1ST RIB FIL2RB: MOVE P1,T3 ;P1=LOG BLOCK NUM OF 1ST RIB MOVE P3,T4 ;P3=ADDR OF UNIT FOR 1ST RIB PUSHJ P,C1TKB ;GET A BLOCK FOR 2ND RIB MOVE T1,SATRBA ;CHECKSUM PUSHJ P,CHEKSM PUSHJ P,SATRBS ;STORE RETRIEVAL POINTER LDB T4,STYCLP##(P2) ;1ST CLUSTER IMUL T4,J ;T4=LOGICAL BLOCK NUM OF 2ND RIB EXCH T4,P3 ;P3=LOG BLK NUM OF 1ST RIB - FALL INTO WRTRIB ;SUBROUTINE TO WRITE RIBS ;ARGS P1=LOGICAL BLOCK NUM OF 1ST RIB ; P3=LOGICAL BLOCK NUM OF 2ND RIB ; T4=ADDR OF UNIT FOR 1ST RIB WRTRIB: EXCH T4,U ;SET U FOR 1ST UNIT PUSH P,T4 MOVE T1,SATRBA ;IOWD FOR RIB MOVE T2,J ;T2=BLOCKS PER CLUSTER IMULB T2,RIBALC##+1(T1) ;CONVERT CLUSTERS ALLOCATED TO BLOCKS ADDM T2,UFDBKS ;KEEP COUNT OF BLOCKS ALLOCATED IN CURRENT UFD MOVE T2,P1 ;LOGICAL BLOCK NUM FOR 1ST RIB MOVEM T2,RIBSLF##+1(T1) ;LOGICAL BLOCK OF THIS RIB PUSHJ P,BLKWRT ;WRITE IT OUT POP P,U ;RESTORE U TO CALLING VALUE FOR 2ND RIB MOVE T2,P3 ;LOGICAL BLOCK NUM FOR 2ND RIB MOVEM T2,RIBSLF##+1(T1) ;LOGICAL BLOCK OF 2ND RIB PJRST BLKWRT ;WRITE OUT SECOND RIB AND EXIT ;SUBROUTINE TO COMPUTE CHECKSUM ON T1 AND SAVE T2 ;ARG T1=ADDR-1 OF WORD TO BE CHECKSUMMED ;VALUES T1=CHECKSUM, STORED IN CHECKSUM FIELD OF T2 ;USES T4 CHEKSM: MOVE T1,1(T1) ;T1=WORD TO CHECKSUM CHEKS1: PUSH P,T2 ;SAVE T2 MOVE T2,T1 ;T2=WORD TO CHEKSUM PUSHJ P,CHKST1## ;CALL FILSER TO COMPUTE IT POP P,T2 ;RESTORE T2 DPB T1,STYCKP##(P2) ;STORE IN T2 CHECKSUM FIELD POPJ P, ;SUBROUTINE TO ALLOCATE 1 BLOCK BY CALLING TAKBLK ;VALUE T2=RETRIEVAL POINTER FOR BLOCK ALLOCATED C1TKB: MOVEI T3,TAKBLK## ;CALL TAKBLK HRROI T2,1 ;GET THE BLOCK ANYWHERE JRST CATKBB ;SUBROUTINE TO TAKE 1 BLOCK AT BEGINNING OF SUPER CLUSTER FOR 1ST RIB ;ENTER CATKB TO TAKE EXACTLY 1 BLOCK ;ENTER CATKBA TO TAKE NUM BLOCKS IN RH(T2) LH(T2)=-1 FOR EXACT NUM BLOCKS ;VALUE T2=RETRIEVAL POINTER FOR BLOCKS ALLOCATED CATKB: HRROI T2,1 ;EXACTLY 1 BLOCK CATKBA: MOVEI T3,ADJALC## ;GET BLOCKS AT BEGINNING OF SUPER CLUSTER CATKBB: MOVE T1,[JRST ONCWAT##] MOVEM T1,PWAIT1## ;SET UP WAIT IN CASE HAVE TO SWITCH SATS SETZ T1, ;TAKE BLOCKS ANYWHERE PUSH P,J ;IN CASE FILIO DOES IO PUSHJ P,(T3) ;DO IT JRST NOROOM ;COULDNT GET ANY BLOCKS JRST JPOPJ## ;RESTORE J AND RETURN BADHOM: SKIPA T1,[[ASCIZ / bad block in HOME.SYS space/]] FEWSAT: MOVEI T1,[ASCIZ / not enough SAT blocks/] PUSH P,T1 ;SAVE ADDR OF MESSAGE MOVEI T1,[ASCIZ /% Unit /] PUSHJ P,ICONM## ;START MESSAGE MOVE T2,UDBNAM(U) ;GET UNIT NAME PUSHJ P,PRNAME## ;PRINT IT POP P,T1 ;RESTORE ADDR OF MESSAGE JRST PMSHLT ;TYPE MESSAGE AND HALT NOROOM: ;POP P,J ;CLEANING STACK NOT NECESSARY NOROO1: PUSHJ P,OTSET## ;INITIALIZE CTY BUFFER MOVEI T1,[ASCIZ /% Structure /] PUSHJ P,ICONM## ;START MESSAGE MOVE T2,STRNAM##(P2) ;GET STRUCTURE NAME PUSHJ P,PRNAME## ;PRINT IT MOVEI T1,[ASCIZ / is full, suggest reducing swapping space/] ;PJRST PMSHLT ;FALL INTO PMSHLT ;SUBROUTINE TO TYPE A MESSAGE ON CTY AND HALT ;ARGS T1=ADDR OF MESSAGE ;OTSET MUST ALREADY HAVE BEEN CALLED PMSHLT: PUSHJ P,CONMES## ;PUT CHARS IN CTY BUFFER PUSHJ P,CRLFOP## ;APPEND CRLF AND OUTPUT CTY BUFFER JRST REFERR ;TAKE ERROR RETURN FROM REFSTR ;SUBROUTINE TO COMPUTE AND STORE NEW UNIT POINTER FOR SAT.SYS STNWUN: LDB T2,UNYLUN## ;LOGICAL UNIT NUMBER IN STR TRO T2,RIPNUB## ;SET BIT TO MAKE SURE NON-0, FALL INTO SATRBS ;SUBROUTINE TO STORE RETRIEVAL POINTER IN SAT.SYS RIB ;ARG T2=RETRIEVAL POINTER ;PRESERVES T2,T3,T4, USES T1 SATRBS: MOVE T1,SATRBP AOBJN T1,SATRS1 STOPCD .,STOP,TMR,DIEUNI##, ;++TOO MANY RETIREVAL POINTERS SATRS1: MOVEM T1,SATRBP PUSHJ P,SAVT## ;SAVE T2,T3,T4 MOVE T3,SATRBA JRST HOMRS2 ;SUBROUTINE TO STORE A RETRIEVAL POINTER IN HOME.SYS RIB ;ARG T2=RETRIEVAL POINTER ;PRESERVES T2,T3,T4, USES T1 HOMRBS: MOVE T1,HOMRBP AOBJN T1,HOMRS1 STOPCD .,STOP,ERP,DIEUNI##, ;++TOO MANY RETRIEVAL POINTERS HOMRS1: MOVEM T1,HOMRBP PUSHJ P,SAVT## MOVE T3,HOMRBA HOMRS2: MOVEM T2,(T1) LDB T1,STYCNP##(P2) ;NUMBER OF CLUSTERS ADDM T1,RIBALC##+1(T3) ;COUNT TOTAL CLUSTER ALLOCATED FOR THIS FILE POPJ P, ;SUBROUTINE TO WRITE OUT DATA IN ALL BUT 1ST BLOCK OF A CLUSTER ;ARG T2=1ST BLOCK OF CLUSTER ; DATA IN SAT BLOCK (SATBKA=IOWD) FINCLS: PUSHJ P,SAVE1## ;SAVE P1 MOVE P1,J ;P1=BLOCKS PER CLUSTER SOJE P1,CPOPJ## MOVE T1,SATBKA FINCL1: ADDI T2,1 PUSHJ P,BLKWRT SOJG P1,FINCL1 POPJ P, ;SUBROUTINE TO SET UP RIB IN CORE ;ARGS T1=NAME OF FILE ; T2=EXT ; T3=PPN ; T4=ADDR OF BUFFER IN CORE-1 ; P4=BITS TO SET IN STATUS WORD ; MFDFDB=1ST DATA BLOCK OF UFD IN WHICH FILE IS BEING WRITTEN ;VALUES T4=POINTER FOR RETRIEVAL POINTERS TO BE STORED IN RIB RIBSET: MOVEI T4,1(T4) ;T4=ADDR OF BUFFER MOVEM T1,RIBNAM##(T4) MOVEM T3,RIBPPN##(T4) ;STORE PPN HRR T2,THSDAT## ;SET ACCESS DATE MOVEM T2,RIBEXT##(T4) ;STORE EXT AND ACCESS DATE SUB T1,CRSFNM ;SEE IF THIS FILE IS CRASH.EXE JUMPE T1,RIBST1 ;IF YOU DON'T STORE CREATION TIMES OR DATE ;SO FILEX CAN STORE THE DATE OF A CRASH MOVE T1,TIME## IDIV T1,TICMIN## ;CONVERT TO TIME IN MINUTES LSH T1,^D12 ;SHIFT TIME LDB T2,[POINT 12,THSDAT##,35] ;GET LOW ORDER 12 BITS OF DATE ADD T1,T2 ;PUT INTO FUTURE RIBPRV LDB T2,[POINT 3,THSDAT##,23] ;GET HIGH ORDER 3 BITS OF DATE DPB T2,[POINT 3,RIBEXT##(T4),20] ;STORE IN PROPER PLACE RIBST1: ADD T1,CURPRT ;CURRENT ACCESS CODE MOVEM T1,RIBPRV##(T4) ;STORE PRIVS WORD MOVE T1,[XWD MRIBLN##,RIBENT##+1] ;GET AOBJN WORD TO FIRST RET PTR MOVEM T1,RIBFIR##(T4) ;SALT AWAY IN RIB SETZM RIBPRV##+1(T4) ;CLEAR REMAINDER OF RIB HRLZI T1,RIBPRV##+1(T4) HRRI T1,RIBPRV##+2(T4) BLT T1,RIBCOD##-1(T4) ; UP THROUGH RIBCOD MOVE T1,[EXP CODRIB##] MOVEM T1,RIBCOD##(T4) ;UNLIKELY CODE FOR RIB HLLZ T1,CNFDVN## ;GET MAJOR MONITOR VERSION NUMBER HRRI T1,VREFST ;INCLUDE REFSTR'S VERSION NUMBER MOVEM T1,RIBVER##(T4) ;STORE VERSION NUMBER OF FILE MOVE T1,[MACTSL##,,RIBACS##] MOVEM T1,RIBACT##(T4) ;POINTER TO NULL ACCT STRING MOVE T1,MFDRBD MOVEM T1,RIBUFD##(T4) ;UFD BLOCK THIS WILL BE FOUND IN IORM P4,RIBSTS##(T4) ;SET ANY STATUS BITS DESIRED ADD T4,RIBFIR##(T4) ;MAKE T4 POINTER TO RETRIEVAL POINTERS SOJA T4,CPOPJ## ;-1 TO ALLOW FOR INCREMENTING AND STORING PTRS ;SUBROUTINE TO SET UP AND STORE AN ENTRY IN A UFD ; P3=INDEX OF FILE IN OUR TABLES ; P4=LAST DATA BLOCK TO WRITE UFDSTO: SKIPN T1,FSTUNW(P3) ;SET UP UNIT OF 1ST RIB POPJ P, MOVE T2,FSTBK(P3) ;LOGICAL BLOCK NUM OF 1ST RIB PUSHJ P,COMCFP ;COMPUTE CFP MOVE T1,FSTFL(P3) ;FILE NAME HRLI T2,(SIXBIT .SYS.) ;MOST EXTENSIONS ARE SYS CAMN T1,CRSFNM ;CRASH.EXE HAS A STRANGE EXTENSTION HRLI T2,(SIXBIT .EXE.) CAIL T1,0 ;SKIP IF ASCII NAME, NOT OCTAL NUMBER HRLI T2,(SIXBIT .UFD.) ;OCTAL NUMBERS ARE UFDS SKIPL T4,UFDSTP ;SKIP IF STILL ROOM IN THIS BLOCK PUSHJ P,NWBKUF ;WRITE OUT THIS BLOCK AND SET UP FOR NEXT MOVEM T1,1(T4) ;STORE FILE NAME MOVEM T2,2(T4) ;AND EXT AND CFP ADD T4,[XWD 2,2] ;BUMP POINTER MOVEM T4,UFDSTP ;RESTORE POINTER POPJ P, ;SUBROUTINE TO WRITE OUT A UFD BLOCK AND SET UP FOR NEXT ;ARGS P1=LOGICAL BLOCK NUM-1 TO WRITE OUT ; P4=LAST LOGICAL BLOCK TO WRITE ;VALUES T4=POINTER TO NEW BUFFER, UFDSTP SET UP ;PRESERVES T1,T2 NWBKUF: PUSH P,T2 PUSH P,T1 AOS T2,P1 ;T2=LOGICAL BLOCK NUM TO WRITE MOVE T1,SATBKA ;IOWD FOR DATA CAMLE P1,P4 ;NO SKIP IF NO MORE BLOCKS JRST NOROO1 PUSHJ P,BLKWRT ;WRITE OUT THE BLOCK MOVE T4,T1 ;SAVE IT IN T4 EXCH T1,UFDSTP ;RESET POINTER HLRES T1 ADDI T1,BLKSIZ## ;LENGTH OF MONITOR BUFFER ADDM T1,UFDWRD MOVE T1,T4 PUSHJ P,CORZER ;CLEAR THE BUFFER POP P,T1 JRST T2POPJ## ;SUBROUTINE TO ZERO OUT A BLOCK OF CORE ;ARGS T1=ADDR-1 OF CORE BLOCK ;ENTER AT CORONZ IF VALUE TO STORE ALREADY SET IN FIRST LOCATION CORZER: SETZM 1(T1) ;CLEAR FIRST WORD OF BLOCK CORONZ: HRLI T1,1(T1) ;LH=ADDR ADDI T1,2 ;RH=ADDR+1, FORMING BLT POINTER MOVEI T2,BLKSIZ##-2(T1) ;ADDR OF LAST WORD IN BUFFER BLT T1,(T2) ;DO THE WHOLE BUFFER POPJ P, ;SUBROUTINE TO COMPUTE A CFP ;ARG T1-ADDR OF UNIT ON WHICH 1ST RIB IS WRITTEN ; T2=LOGICAL BLOCK NUMBER ; P3=INDEX OF FILE IN OUR TABLES ;VALUE T2=CFP COMCFP: EXCH T1,U ;T1 WAS UNIT WE WANTED LDB T3,UNYLUN## ;LOGICAL UNIT NUMBER HRRZ T4,UNISTR(U) ;ADDR OF STR DB MOVE U,T1 ;RESTORE U HRRZ T1,STRSCU##(T4) ;NUM SUPER CLUSTERS PER UNIT IMUL T1,T3 ;SUPER CLUSTER NUM OF BLOCK 0 THIS UNIT HLRZ T4,STRBSC##(T4) ;BLOCKS PER SUPER CLUSTER IDIV T2,T4 SKIPE T3 ;MUST COME OUT EVEN STOPCD .+1,DEBUG,CIO, ;++CFP IS ODD ADD T2,T1 ;COMPLETE COMPUTATION OF SUPER CLUSTER POPJ P, ;SUBROUTINE TO WRITE OUT A BLOCK ;ARGS T1=IOWD ; T2=LOGICAL BLOCK NUM ; U=ADDR OF UNIT ;PRESERVES T1,T2 BLKWRT: MOVEM T1,@ONCMBF## ;OMNWRT TAKES IOWD FROM .UPMBF PUSHJ P,OMNWRT## ;CALL ROUTINE IN ONCE.MOD TO WRITE OUT BLOCK STOPCD .+1,DEBUG,EWB,DIEUNI##, ;++ERROR WRITING BLOCK LDB J,UNYBPC## ;RESET BLOCKS PER CLUSTER MOVE T1,@ONCMBF## ;AND IOWD POPJ P, SUBTTL DATA STORAGE REPEAT 0,< MNSBLA==^D21 ;SIZE OF BLOCK ADDRESS FIELD MNNBLA==^D35 ;RIGHTMOST BIT OF BLOCK ADDRESS FIELD MNSCNT==^D10 ;SIZE OF BLOCK COUNT FIELD MNNCNT==^D14 ;RIGHTMOST BIT OF BLOCK COUNT FIELD MNLEFT==^D36-MNSCNT-MNSBLA ;NUMBER OF BITS LEFT IN WORD (UNUSED) MNYCNT: POINT MNSCNT,(P1),MNNCNT MNYBLA: POINT MNSBLA,(P1),MNNBLA MNTLST: XWD UTYP01,UTYP00 ;KONTROLLER TYPE 0 XWD UTYP11,UTYP10 ;KONTROLLER TYPE 1 - FIXED HEAD DISK XWD UTYP21,UTYP20 ;KONTROLLER TYPE 2 - DISK PACK XWD UTYP31,UTYP30 ;KONTROLLER TYPE 3 - MASS FILE UTYP20: ;RP02 UTYP21: ;RP01 UTYP01: ;DRUM UNIT TYPE 1 UTYP00: ;DRUM UNIT TYPE 0 UTYP11: ;FIXED HEAD DISK UNIT TYPE 1 UTYP10: ;FIXED HEAD DISK UNIT TYPE 0 UTYP31: ;MASS FILE UNIT TYPE 1 UTYP30: 0 ;MASS FILE UNIT TYPE 0 > QUOTAR: EXP QR QUOTAF: EXP QF QUOTAO: EXP QO ;NAMES OF FILES WE CREATE FSTFL:! SATFNM: SIXBIT .SAT. ;SAT FILE HOMFNM: SIXBIT .HOME. ;HOME BLOCK FILE SWPFNM: SIXBIT .SWAP. ;FILE OF SWAPPING SPACE ON STR IFN FTMAINT,< MNTFNM: SIXBIT .MAINT. ;FILE OF MAINTENANCE TRACKS >; END IFN FTMAINT BADFNM: SIXBIT .BADBLK. ;FILE OF BAD REGIONS ON STR CRSFNM: SIXBIT .CRASH. ;FILE FOR SAVING MONITOR CRASHES SNPFNM: SIXBIT .SNAP. ;FILE FOR PERIODIC SNAPSHOTS OF MONITOR RCVFNM: SIXBIT .RECOV. ;FILE FOR SCRATCH SPACE FOR RECOVERY PROGRAMS SIXBIT .FE. ;FRONT-END FILE SYSTEM LSTFL==.-FSTFL SYSUFD: BLOCK 1 PRTUFD: BLOCK 1 XPNUFD: BLOCK 1 ALPUFD: BLOCK 1 XSYUFD: BLOCK 1 OLDUFD: BLOCK 1 MFDUFD: BLOCK 1 LSTUF==.-LSTFL-FSTFL ;*** THIS LIST MUST BE IN THE SAME ORDER AS FILE NAMES FSTBK:! SATRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR SAT.SYS HOMRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR HOME.SYS SWPRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR SWAP.SYS IFN FTMAINT,< MNTRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR MAINT.SYS >; END IFN FTMAINT BADRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR BADBLK.SYS CRSRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR CRASH.EXE SNPRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR SNAP.SYS RCVRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR RECOV.SYS FERBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR FE.SYS SYSRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR SYS UFD PRTRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR PRINT UFD XPNRBD: BLOCK 1 ALPRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR 1,2 XSYRBD: BLOCK 1 OLDRBD: BLOCK 1 MFDRBD: BLOCK 1 ;LOGICAL BLOCK NUMBER OF 1ST RIB FOR MFD (=1,1 UFD) MFDPTR: BLOCK 1 ;FIRST RETRIEVAL POINTER FOR MFD ;*** THIS LIST MUST BE IN THE SAME ORDER AS FILE NAMES FSTUNW:! SATUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR SAT.SYS HOMUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR HOME.SYS SWPUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR SWAP.SYS IFN FTMAINT,< MNTUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR MAINT.SYS >; END IFN FTMAINT BADUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR BADBLK.SYS CRSUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR CRASH.EXE SNPUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR SNAP.SYS RCVUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR RECOV.SYS FEUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR FE.SYS SYSUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR SYS UFD PRTUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR PRT UFD XPNUN: BLOCK 1 ALPUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR 1,2 XSYUN: BLOCK 1 OLDUN: BLOCK 1 MFDUN: BLOCK 1 ;LOGICAL UNIT OF 1ST RIB FOR MFD LSTUNW==.-FSTUNW SATRBA: BLOCK 1 ;ADDRESS OF 1ST RIB IN CORE FOR SAT.SYS HOMRBA: BLOCK 1 ;ADDRESS OF RIB IN CORE FOR HOME.SYS BATBKA: BLOCK 1 ;ADDRESS OF PLACE IN CORE TO READ BAT BLOCKS SATBKA: BLOCK 1 ;ADDRESS OF PLACE IN CORE TO CREATE SAT BLOCKS FERBA: BLOCK 1 CORN==.-SATRBA ;NUMBER OF CORE BLOCKS NEEDED LBNLST: BLOCK 3 LBNLEN=.-LBNLST FSTLEN:! ;THIS TABLE CONTAINS NUMBER OF DATA BLOCKS TO ALLOCATE CRSBKN: BLOCK 1 SNPBKN: BLOCK 1 RCVBKN: BLOCK 1 ZERLEN==.-FSTLEN ;FILES ABOVE MAY HAVE 0 LENGTH, BELOW MAY NOT SYUFSZ: BLOCK 1 BLOCK 1 MFDSIZ: BLOCK 1 LSTLEN==.-FSTLEN FELEN: BLOCK 1 ;NO OF BLOCKS IN FE.SYS SATRBP: BLOCK 1 ;POINTER TO SPACE IN SAT.SYS RIB FOR RETRIEVAL PTRS HOMRBP: BLOCK 1 ;POINTER TO SPACE IN HOME.SYS RIB FOR POINTERS UFDSTP: BLOCK 1 ;POINTER TO SPACE IN UFD RIB FOR POINTERS UFDWRD: BLOCK 1 ;WORDS WRITTEN IN THIS UFD BEGSAT: BLOCK 1 SVSBTL: BLOCK 1 FSTUNI: BLOCK 1 ;RH=ADDR OF FIRST UNIT IN STR LSTUNI==FSTUNI ;LH=ADDR OF LAST UNIT IN STR LCLSAT: BLOCK 1 ;LAST CLUSTER IN CURRENT SAT NDNCNF: BLOCK 1 ;NO DELETE, CHANGE NAME, FAILSAFE BITS IN UFD RIB NDCFAB: BLOCK 1 ;ABOVE + ALWAYS BAD CHECKSUM CHECK0: BLOCK 1 ;CHECKSUM OF WORD OF 0 UFDBKS: BLOCK 1 ;NUMBER OF BLOCKS ALLOCATED IN CURRENT UFD MAXALC: BLOCK 1 ;MAXIMUM NUMBER OF CLUSTERS CAN ALLOCATE IN 1 PTR CURPRT: BLOCK 1 ;CURRENT ACCESS CODE SATIND==BADUN ;USED AS A TEMPORARY HOMSR2==BADUN ;USED AS A TEMPORARY BLKNED: BLOCK 1 ;TEMP SAVEP: BLOCK 1 ;SAVED PDL ON ENTRY (FOR ERRORS) ERRRET: BLOCK 1 ;FLAG NON-ZERO IF ERROR OCCURRED ; (STRUCTURE NOT REFRESHED SUCCESSFULLY) REFEND::END