Trailing-Edge
-
PDP-10 Archives
-
bb-bt99q-bb
-
refstr.x23
There is 1 other file named refstr.x23 in the archive. Click here to see a list.
TITLE REFSTR - ROUTINE TO REFRESH A FILE STRUCTURE - V153
SUBTTL D BLACK 11 APR 89
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,153
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,<XJRST [MCSEC1+.+1]> ;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,<XJRST [MCSEC0+.+1]> ;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
MOVE T3,T4 ;AND BAYNBR NEEDS IT IN T3
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
MOVE T1,CNFDVN## ;GET MONITOR VERSION
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