1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-01-31 13:52:00 +00:00
Files
PDP-10.stacken/files/stacken-tape-backup/dskb:10_7/mon/refstr.mac
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

1837 lines
62 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,<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
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