Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99T-BB_1990 - 10,7/mon/oncmod.mac
There are 15 other files named oncmod.mac in the archive. Click here to see a list.
TITLE	ONCMOD LEVEL D OPTIONAL & MANDATORY ONCE ONLY CODE V11536
SUBTTL	D. MASTROVITO/DPM	17-APR-90

	SEARCH F,S,DEVPRM
IFN FTCIDSK,<
	SEARCH	KLPPRM,MSCPAR
>; END IFN FTCIDSK
	$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,1990.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1990>

;
XP VONCMD,11536

ONCMOD::ENTRY	ONCMOD

	SALL			;CLEAN LISTINGS
	.DIRECT	FLBLST		;CLEANER LISTINGS
ND	UNTPLN,^D5		;UNITS/LINE TYPED BY TYPUNS/TYPNMU
SUBTTL	ASL PROCESSING -- CHGASL - CHANGE


CHGASL::JRST	DEFASL		;SAME AS DEFINE
SUBTTL	ASL PROCESSING -- CRESST - CREATE SWAPPING SATS


CRESST:	SE1ENT			;ENTER SECTION ONE
IFN FTXMON,<SKIPL UNIPTR(U)>	;ALREADY HAVE?
	SKIPGE	UNISUN(U)	;IS UNIT IN ASL?
	POPJ	P,		;NO--DONE
	LDB	T2,UNYK4S##	;GET # K FOR SWAPPING ON THIS UNIT
	JUMPE	T2,CPOPJ##	;RETURN IF NO SWAPPING SPACE
	LSH	T2,K2PLSH	;DOUBLE SIZE IF SWAPPING PAGES
	MOVEI	T2,^D36(T2)	;INCLUDE EXTRA WORD
	IDIVI	T2,^D36
	MOVN	T1,T2		;MAKE LENGTH -VE FOR AOBJN WORD
	HRLM	T1,UNIPTR(U)	;STORE IT IN UNIT DATA BLOCK
	LSH	T2,1		;DOUBLE ALLOCATION FOR COPY FOR 143 RESTARTS
	PUSHJ	P,CORGRS	;GET CORE
	HRRM	T1,UNIPTR(U)	;STORE IT IN UNIT DATA BLOCK FOR AOBJN WORD
IFN FTXMON,<
	MOVEI	T1,(MS.SAT)	;DATA SECTION 1
	DPB	T1,UNYSNS##	;STORE THAT FOR SWPSER
> ;END IFN FTXMON
	POPJ	P,		;RETURN
SUBTTL	ASL PROCESSING -- DEFASL - DEFINE


DEFASL::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,U		;SAVE U
	MOVEI	T1,ASLTXT	;PROMPT STRING
	MOVE	T2,[IFIW ASLVAL] ;ROUTINE TO VALIDATE RESPONSES
	MOVE	T3,[-SWPMAX##,,SUDTAB] ;AOBJN POINTER TO STORE RESULTS
	PUSHJ	P,PRSLST##	;PROMPT AND FETCH ANSWERS
	MOVE	P1,T1		;GET UPDATED AOBJN POINTER TO TABLE
	SETZ	P2,		;INIT POSITION COUNTER
	MOVEI	U,SYSUNI##-UNISYS## ;SET PREDESSOR

DEFAS1:	HLRZ	U,UNISYS(U)	;LINK TO NEXT UNIT IN SYSTEM
	JUMPE	U,DEFAS2	;DONE?
	SKIPL	UNISUN(U)	;NOT IN THE ASL?
	PUSHJ	P,SETCHG	;THEN HOME BLOCKS WILL CHANGE
	SETOM	UNISUN(U)	;REMOVE FROM THE ASL
	JRST	DEFAS1		;LOOP FOR ALL STRS

DEFAS2:	MOVEI	U,SYSUNI##-UNISYS## ;SET PREDESSOR
	MOVE	T1,(P1)		;GET A UNIT NAME

DEFAS3:	HLRZ	U,UNISYS##(U)	;LINK TO NEXT UNIT
	JUMPE	U,DEFAS4	;SHOULD NEVER BE 0 CUZ UNIT WAS VALIDATED
	CAME	T1,UDBNAM(U)	;DRIVE NAME?
	CAMN	T1,UNIHID(U)	;OR LOGICAL UNIT?
	CAIA			;YES
	JRST	DEFAS3		;TRY ANOTHER UNIT
	MOVEM	P2,UNISUN(U)	;STORE FAKED UP POSITION IN THE ASL
	AOS	P2		;INCREMENT FOR NEXT TIME
	PUSHJ	P,SETCHG	;MARK HOME BLOCKS TO BE REWRITTEN

DEFAS4:	AOBJN	P1,DEFAS2	;LOOP BACK FOR ANOTHER UNIT
	POP	P,U		;RESTORE U
	SETZM	PREASL##	;DON'T BELEIVE BOOT VECTOR
	PJRST	VFCORE		;GO VERIFY INCORE DATA BASE
SUBTTL	ASL PROCESSING -- DELSST - DELETE SWAPPING SATS


DELSST:	SKIPL	UNIPTR(U)	;HAVE SWAPPING SATS?
	POPJ	P,		;NO
	LDB	T1,UNYK4S##	;GET # K FOR SWAPPING ON THIS UNIT
	JUMPE	T1,CPOPJ##	;RETURN IF NO SWAPPING SPACE
	SE1ENT			;ENTER SECTION ONE
	LSH	T1,K2PLSH	;DOUBLE SIZE IF SWAPPING PAGES
	MOVEI	T1,^D36(T1)	;INCLUDE EXTRA WORD
	IDIVI	T1,^D36
	LSH	T1,1		;DOUBLE ALLOCATION FOR COPY FOR 143 RESTARTS
	HRRZ	T2,UNIPTR(U)	;GET SECTION-RELATIVE ADDRESS
IFE FTXMON,<PUSHJ P,GIVWDS##>	;RETURN CORE
IFN FTXMON,<
	HRLI	T2,(MS.SAT)	;INCLUDE SECTION NUMBER
	PUSHJ	P,GVFWDS##	;RETURN CORE
	SETZ	T1,		;GET A ZERO
	DPB	T1,UNYSNS##	;CLEAR OUT SECTION NUMBER
> ;END IFN FTXMON
	SETZM	UNIPTR(U)	;ZERO POINTER TO SATS
	POPJ	P,		;RETURN
SUBTTL	ASL PROCESSING -- DSKASL - BUILD ASL FROM DISK


DSKASL:	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	PUSH	P,U		;SAVE U
	MOVSI	P1,-SWPMAX##	;AOBJN POINTER TO SWPTAB
	MOVEI	P2,SWPUNI##-UNISWP ;SET PREDESSOR
	SETZB	P3,P4		;START WITH CLASS 0 & ZERO K4S TALLY

DSKAS1:	HLRZ	U,SYSUNI##	;GET ADDR OF FIRST UDB IN SYSTEM

DSKAS2:	SKIPGE	UNISUN(U)	;UNIT IN ACTIVE SWAPPING LIST?
	JRST	DSKAS4		;CAN'T LINK THIS UNIT
	LDB	T1,UNYCFS##	;GET SWAPPING CLASS
	CAIE	T1,(P3)		;MATCH?
	JRST	DSKAS4		;NO
	SKIPE	P3		;SLOW SWAPPING CLASS?
	SKIPE	SWPUN2##	;YES--SLOW SWAPPING POINTER SETUP YET?
	JRST	DSKAS3		;JUST LINK INTO THE CHAIN
	HRLM	U,SWPUN2##	;SAVE FIRST SLOW SWAPPING UNIT
	HRRM	T1,SWPUN2##	;AND THE CLASS NUMBER

DSKAS3:	PUSHJ	P,CRESST	;CREATE SWAPPING SATS
	HRRZM	P1,UNISUN(U)	;SET SWAPPING UNIT NUMBER
	HRLM	U,UNISWP(P2)	;LINK THIS UNIT TO PREVIOUS IN SWAP LIST
	MOVE	P2,U		;NOW SET PREDECESSOR FOR NEXT UNIT (IF ANY)
	MOVEM	U,SWPTAB##(P1)	;PUT IN SWAPPER TABLE TOO
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING ON THIS UNIT
	ADD	P4,T1		;ACCUMULATE
	MOVE	T1,UDBNAM(U)	;DRIVE NAME (INCAES OF HWP)
	MOVEI	T2,[ASCIZ /swapping unit is hardware write protected/]
	MOVSI	T3,UNPHWP	;GET HWP BIT
	TDNE	T3,UNIDES(U)	;CAN WE WRITE ON THIS UNIT?
	PUSHJ	P,UWARN		;WARN OPERATOR
	AOBJP	P1,DSKAS5	;DONE THE MAXIMUM YET?

DSKAS4:	HLRZ	U,UNISYS(U)	;LINK TO NEXT UNIT
	JUMPN	U,DSKAS2	;LOOP FOR MORE
	SKIPN	P3		;DONE BOTH CLASSES?
	AOJA	P3,DSKAS1	;NOW PROCESS CLASS 1
	HLRZ	U,SWPUNI##	;GET FIRST SWAPPING UNIT
	JUMPN	U,DSKAS5	;ARE THERE ANY UNITS IN ASL?
	AOS	SERIUS		;CALL THIS A SERIOUS ERROR
	MOVEI	T1,[ASCIZ /% No units in active swapping list/]
	PUSHJ	P,CONOUT##	;PRINT MESSAGE
	JRST	DSKAS6		;AND CONTINUE
DSKAS5:	MOVE	T1,MEMSIZ##	;GET WORDS OF CORE
	LSH	T1,W2KLSH	;CONVERT TO K
	CAML	P4,T1		;ENOUGH FOR THE AMOUNT OF CORE WE HAVE?
	JRST	DSKAS6		;YES
	AOS	SERIUS		;CALL THIS A SERIOUS ERROR
	MOVEI	T1,[ASCIZ /% Insufficient swapping space allocated/]
	PUSHJ	P,CONOUT##	;PRINT TEXT
	MOVEI	T1,[ASCIZ /  Swapping space = /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T1,P4		;GET TOTAL SWAPPING SPACE ALLOCATED
	PUSHJ	P,PRTDIG##	;PRINT IT
	MOVEI	T1,[ASCIZ /K, memory size = /]
	PUSHJ	P,CONMES##	;PRINT IT
	MOVE	T1,MEMSIZ##	;GET AMOUNT OF CORE
	LSH	T1,W2KLSH	;CONVERT TO K
	PUSHJ	P,PRTDIG##	;PRINT IT
	MOVEI	T1,[ASCIZ /K/]	;TERMINATOR
	PUSHJ	P,CONMES##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

DSKAS6:	HLRZ	U,SYSUNI##	;POINT TO FIRST UNIT IN SYSTEM

DSKAS7:	SKIPGE	UNISUN(U)	;IN THE ASL?
	PUSHJ	P,DELSST	;NO--DELETE ANY SWAPPING SATS
	HLRZ	U,UNISYS(U)	;LINK TO NEXT
	JUMPN	U,DSKAS7	;LOOP BACK FOR MORE
	JRST	UPOPJ##		;RESTORE U AND RETURN
SUBTTL	ASL PROCESSING -- SHWASL - SHOW


SHWASL::PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,U		;SAVE U
	MOVEI	T1,SWPTXT	;POINT TO HEADER
	PUSHJ	P,CONOUT##	;PRINT IT
	MOVEI	U,SYSUNI##-UNISYS ;SET PREDESSOR
	SETZ	P1,		;CLEAR "*" FLAG

SHWAS1:	HLRZ	U,UNISYS(U)	;LINK TO NEXT
	JUMPE	U,SHWAS3	;DONE?
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	JUMPE	T1,SHWAS1	;HAVE SOME?

SHWAS2:	PUSHJ	P,OTSET##	;SET UP BUFFER
	MOVEI	T3,11		;TAB
	PUSHJ	P,COMTYO##	; OVER
	MOVEI	T3," "		;LEADING SPACE IF NOT IN LIST
	SKIPL	UNISUN(U)	;IS IT?
	MOVEI	T3,"*"		;YES--CHANGE TO A SPACE
	SKIPL	UNISUN(U)	;CHECK AGAIN
	AOS	P1		;FLAG THE ASTERISK
	PUSHJ	P,COMTYO##	;PRINT THE FLAG
	MOVE	T2,UDBNAM(U)	;DRIVE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T3,11		;TAB
	PUSHJ	P,COMTYO##	; OVER
	MOVE	T2,UNIHID(U)	;UNIT ID
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /	  /]
	PUSHJ	P,CONMES##	;SPACE OVER
	LDB	T1,UNYCFS##	;SWAPPING CLASS
	PUSHJ	P,PRTDI8##	;PRINT IT
	MOVEI	T1,[ASCIZ /  	/]
	PUSHJ	P,CONMES##	;SPACE OVER
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	MOVEI	T2,^D9		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	JRST	SHWAS1		;LOOP BACK FOR MORE

SHWAS3:	POP	P,U		;RESTORE U
	SKIPE	.UONCE##	;USER MODE?
	JRST	SHWAS4		;SKIP THE MEMSIZ STUFF
	MOVEI	T1,[ASCIZ /	     (Memory size = /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T1,MEMSIZ##	;GET WORDS OF CORE
	LSH	T1,W2KLSH	;CONVERT TO K
	PUSHJ	P,PRTDIG##	;PRINT IT
	MOVEI	T1,[ASCIZ /K)/]	;TERMINATOR
	PUSHJ	P,CONMES##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

SHWAS4:	JUMPE	P1,CPOPJ1##	;RETURN IF NO UNITS FLAGGED
	MOVEI	T1,[ASCIZ /
	* indicates unit currently in the ASL/]
	PUSHJ	P,CONOUT##	;PRINT TEXT + CRLF
	JRST	CPOPJ1##	;RETURN

SWPTXT:	ASCIZ	/
Swapping Units:
	 Unit	UnitID	Class	Space (K)
	------	------	-----	---------/
SUBTTL	ASL PROCESSING -- MISCELLANEOUS


;VALIDATE AN ASL ENTRY
ASLVAL:	MOVEI	T2,[ASCIZ /does not exist/] ;INCASE OF ERROR
	MOVEI	T3,SYSUNI##-UNISYS ;SET PREDESSOR
ASLVA1:	HLRZ	T3,UNISYS(T3)	;LINK TO NEXT UDB
	JUMPE	T3,UWARN	;END OF CHAIN?
	CAME	T1,UDBNAM(T3)	;PHYSICAL DRIVE NAME?
	CAMN	T1,UNIHID(T3)	;LOGICAL UNIT ID?
	SKIPA			;YES TO EITHER
	JRST	ASLVA1		;TRY ANOTHER
	EXCH	T3,U		;SWAP ACS
	LDB	T4,UNYK4S##	;GET K FOR SWAPPING
	EXCH	T3,U		;RESTORE ACS
	JUMPN	T4,CPOPJ1##	;RETURN GOODNESS IF OK
	MOVEI	T2,[ASCIZ /has no swapping space allocated/]
	PJRST	UWARN		;WARN OPERATOR AND RETURN

ASLTXT:	ASCIZ /
Enter names of units to appear in the active swapping list,  one
per line.  Terminate list with a blank line./
SUBTTL	DIALOGUE SUBROUTINES -- GETASL - SINGLE UNIT ASL


GETASL:	JUMPE	P2,GETAS1	;UNIT PART OF A STRUCTURE?
	HRRZ	T1,STRUNM##(P2)	;NUMBER OF UNITS IN STR
	SOJG	T1,CPOPJ##	;QUESTION ONLY VALID OF A SINGLE PACK STRUCTURE
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	JUMPE	T1,CPOPJ##	;RETURN IF NONE ALLOCATED
GETAS1:	MOVEI	T1,[ASCIZ /    Make this the only unit in the ASL/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	JUMPE	P2,GETAS2	;UNIT PART OF A STRUCTURE?
	MOVE	T3,['KLAD  ']	;SPECIAL NAME FOR DEC DIAG DISKS
	CAMN	T3,STRNAM##(P2)	;IS THIS A KLAD PACK?
	MOVSI	T2,'YES'	;CHANGE THE DEFAULT
GETAS2:	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	PUSH	P,U		;SAVE U
	MOVEI	U,SYSUNI##-UNISYS ;SET PREDESSOR

GETAS3:	HLRZ	U,UNISYS(U)	;LINK TO NEXT UNIT
	JUMPE	U,GETAS4	;DONE ALL UNITS?
	SKIPL	UNISUN(U)	;IN THE ASL ALREADY?
	PUSHJ	P,SETCHG	;YES--MARK HOME BLOCKS TO BE REWRITTEN
	SETOM	UNISUN(U)	;EMPTY THE ASL
	JRST	GETAS3		;LOOP BACK FOR MORE

GETAS4:	POP	P,U		;RESTORE U
	HRLM	U,SWPUNI##	;SET AS FIRST IN THE ASL
	HRRZS	UNISWP(U)	;MAKE IT THE LAST IN THE CHAIN
	SETZM	UNISUN(U)	;SET POSITION TO ZERO
	MOVSI	T1,-SWPMAX##	;AOBJN POINTER
	MOVEM	U,SWPTAB##(T1)	;STORE IN THE SWAPPER TABLE
	AOBJP	T1,CPOPJ##	;RETURN IF A SHORT TABLE
	SETZM	SWPTAB##(T1)	;CLEAR OUT
	AOBJN	T1,.-1		; THE REMAINDER
	POPJ	P,		;AND RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETBAT - READ BAT BLOCKS


GETBAT:	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	PUSH	P,T1		;SAVE MANDATORY REWRITE FLAG
	PUSHJ	P,GTMNB1	;GET MONITOR BUFFER
	SETZM	BATBAD		;CLEAR "BAT" BLOCK BAD FLAG
	MOVSI	P2,'BAT'	;BLOCK NAME
	MOVE	P3,[CODBAT##]	;SPECIAL CODE
	MOVE	P4,[LBOBAT##,,LBOBAT##] ;FIRST,,SECOND BLOCK OFFSETS
	ADD	P4,UNIHOM(U)	;CONVERT TO BLOCK NUMBERS
	PUSHJ	P,REDRUN	;GO READ & VERIFY BLOCKS
	  JRST	TPOPJ##		;BOTH BAD, SO MUST REWRITE THEM
	SKIPE	REDERR		;ANY ERRORS IN EITHER ONE
	SETOM	BATBAD		;SET BAT BLOCK BAD FLAG
	HRRZ	T1,BAFFIR##(P1)	;GET START OF BAD REGION PAIRS
	CAIL	T2,BLKCOD##	;MAKE SURE IT'S WITHIN THE BLOCK
	JRST	TPOPJ##		;IT ISN'T SO MUST REWRITE THE BLOCKS
	MOVE	T3,P1		;COPY BUFFER ADDRESS FOR LDB
	LDB	P2,BAYNBR##	;GET # BAD REGIONS FOUND BY MAP PROGRAM
	ADD	P2,BAFCNT##(P1)	;ADD IN # FOUND BY MONITOR
	SKIPN	BATFLG		;WANT TO SEE THE BAD REGIONS?
	JRST	TPOPJ1##	;NO
	JUMPN	P2,GETBA1	;GO DISPLAY IF SOME ARE MARKED
	MOVEI	T1,[ASCIZ /[No bad blocks found on unit /]
	PUSHJ	P,ICONM##	;START TEXT FOR THIS UNIT
	MOVE	T2,UDBNAM(U)	;GET UNIT NAME
	PUSHJ	P,PRNAME##	;ADD THAT TO THE TEXT
	PUSHJ	P,PRRBKC##	;RIGHT BRACKET+CRLF
	PUSHJ	P,OPOUT##	;SEND IT TO THE TERMINAL
	JRST	TPOPJ1##	;RETURN WINNINGLY
GETBA1:	MOVE	T1,UDBNAM(U)	;GET DRIVE NAME
	MOVEI	T2,[ASCIZ /bad blocks:/]
	PUSHJ	P,UWARN		;WARN OPERATOR
	MOVEI	T1,[ASCIZ/  First  block  No.   CPU   Cont  Unit  Error/]
	PUSHJ	P,CONOUT##	;PRINT TEXT
	MOVEI	T1,[ASCIZ/  ------------  ---  -----  ----  ----  -----/]
	PUSHJ	P,CONOUT##	;PRINT TEXT
	MOVE	T3,P1		;COPY BLOCK ADDRESS FOR LDB
	LDB	P2,BAYNBR##	;GET # BAD REGIONS FOUND BY MAP PROGRAM
	ADD	P2,BAFCNT##(P1)	;ADD IN # FOUND BY MONITOR
	MOVNS	P2		;NEGATE
	HRLZS	P2		;COUNT IN LH
	HRR	P2,BAFFIR##(P1)	;MAKE AN AOBJN POINTER
	ADDI	P2,(P1)		;RELOCATE TO WITHIN THE BUFFER

GETBA2:	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,ICONM##	; OVER
	MOVE	T1,BAFELB##(P2)	;GET START OF REGION
	TLZ	T1,BATMSK##	;MASK OUT ALL BUT ADDR
	MOVEI	T2,BAPNTP##	;IF OLD STYLE
	TDNN	T2,BAFAPN##(P2)	;CHECK IT
	HRRZS	T1		;ONLY 18 BITS COUNT
	MOVEI	T2,^D12		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT STARTING BLOCK NUMBER
	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,CONMES##	; OVER
	MOVE	T2,P2		;COPY POINTER
	LDB	T1,BAYNBB##	;GET BAD BLOCKS-1 IN THIS REGION
	AOS	T1		;ADJUST SO NUMBER IS PLEASING TO THE EYE
	MOVEI	T2,^D3		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,CONMES##	; OVER
	MOVE	T2,P2		;COPY POINTER
	LDB	T1,BAYAPN##	;GET CPU WHICH DETECED THE ERROR
	MOVEI	T2,^D5		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,CONMES##	; OVER
	MOVE	T2,P2		;COPY POINTER
	LDB	T1,BAYKNM##	;GET KONTROLLER NUMBER
	MOVEI	T2,^D4		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,CONMES##	; OVER
	LDB	T1,UNYKTP##	;GET KONTROLLER TYPE
	CAIN	T1,TYPRA	;CI DISK?
	JRST	GETBA3		;THEN UNIT IS MEANINGLESS
	MOVE	T1,BAFPUB##(P2)	;GET WORD CONTAINING UNIT NUMBER
	LSH	T1,14		;LEFT JUSTIFY MASK
	JFFO	T1,.+1		;FIND FIRST BIT
	MOVEI	T1,7		;HIGHEST LEGAL UNIT IN A BAT BLOCK
	SUBI	T1,(T2)		;COMPUTE ACTUAL UNIT NUMBER
	MOVEI	T2,^D4		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	JRST	GETBA4		;SKIP AROUND

GETBA3:	MOVEI	T1,[ASCIZ /    /]
	PUSHJ	P,CONMES##	;SKIP COLUMN

GETBA4:	MOVEI	T1,[ASCIZ /  /]	;SPACE
	PUSHJ	P,CONMES##	; OVER
	MOVE	T2,BAFERR##(P2)	;GET ERROR WORD
	MOVEI	T1,[ASCIZ /???/]
	TLNE	T2,BAPOTR##	;OTHER?
	MOVEI	T1,[ASCIZ /Other/]
	TLNE	T2,BAPDTR##	;DATA ERROR?
	MOVEI	T1,[ASCIZ /Data/]
	TLNE	T2,BAPHDR##	;SEARCH OR HEADER COMPARE?
	MOVEI	T1,[ASCIZ /Search or header compare/]
	PUSHJ	P,CONMES##	;PRINT TEXT

GETBA5:	PUSHJ	P,CRLFOP##	;END LINE
	AOS	P2		;ACCOUNT FOR TWO WORD ENTRIES
	AOBJN	P2,GETBA2	;LOOP
	POP	P,T1		;GET MANDATORY REWRITE FLAG BACK
	JUMPN	T1,CPOPJ##	;RETURN NOW IF NO OPERATOR OPTION
	MOVEI	T1,[ASCIZ /Initialize BAT blocks/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPN	T1,CPOPJ##	;IF "YES", THEN TAKE THE APPROPRIATE RETURN
	JRST	CPOPJ1##	;ELSE DON'T INIT BAT BLOCKS


NUMTYP:	PUSHJ	P,SAVE1##	;SAVE P1
	MOVEI	P1,(T2)		;COPY COLUMN COUNT
NUMTY1:	IDIVI	T1,12		;DIVIDE BY RADIX
	PUSH	P,T2		;SAVE REMAINDER
	SOS	P1		;COUNT DIGITS
	SKIPE	T1		;DONE?
	PUSHJ	P,NUMTY1	;RECURSE
	SKIPLE	P1		;NEED TO PAD ANY COLUMNS?
	PUSHJ	P,PRSPC##	;PRINT A SPACE
	SOJG	P1,.-1		;PAD OUT
	POP	P,T3		;GET DIGIT BACK
	ADDI	T3,"0"		;MAKE ASCII
	PJRST	COMTYO##	;PRINT IT AND RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETBPC - BLOCKS PER CLUSTER


GETBPC:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /   *Blocks per cluster/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,BPCDEF(T2)	;LOAD UP A RESONABLE DEFAULT
	LDB	T2,UNYBPC##	;USE CURRENT VALUE
	MOVEI	T3,3		;LOW RANGE
	MOVEI	T4,377777	;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	MOVE	P1,T1		;COPY TO UNORTHODOX PLACE
;	PJRST	BPCSTO		;GO STORE RESULTS
BPCSTO:	LDB	T1,UNYBPC##	;GET CURRENT VALUE
	CAME	T1,P1		;SAME A NEW?
	PUSHJ	P,REFCHS	;NO--MUST REFRESH
	MOVE	T1,[DPB	P1,UNYBPC##];GET INSTR. TO BE EXECUTED BY STOUNI
	PUSHJ	P,STOUNI	;STORE VALUE IN EVERY UNIT IN STR
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	PUSHJ	P,COMLCA	;COMPUTE LAST CLUSTER ADR. ON UNIT
	JFFO	T2,.+2		;FIND POSITION OF 1ST. 1 BIT
	MOVEI	T3,^D35		;NONE - BUT FIELD MUST BE AT LEAST 1 BIT WIDE
	MOVN	P1,T3		;NEGATE FOR ADDI INSTR.
	ADDI	P1,^D36		;COMPUTE FIELD WIDTH FOR CLUSTER ADR.
	LDB	T1,[POINT 6,STYCLP##(P2),11]
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	DPB	P1,[POINT 6,STYCLP##(P2),11]	;PUT IT IN BYTE POINTER
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	LDB	T3,UNYBPC##	;GET # BLOCKS/CLUSTER
	MOVE	T1,STRHGH##(P2)	;HIGHEST BLOCK IN STR
	ADDI	T1,-1(T3)
	IDIVI	T1,(T3)
	HLRZ	P1,T1		;DIVIDE BY 2**18
	ADDI	P1,1		;AND ROUND UP
	IMUL	P1,T3		;COMPUTE # BLOCKS PER SUPER CLUSTER
	HLRZ	T1,STRBSC##(P2)	;GET CURRENT # BLOCKS PER SUPER CLUSTER
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	HRLM	P1,STRBSC##(P2)	;STORE IT
	MOVE	T2,STRBPU##(P2)	;GET # BLOCKS PER UNIT
	SUBI	T2,1
	IDIV	T2,P1		;DIVIDE BY # BLOCKS PER SUPER CLUSTER
	ADDI	T2,1
	MOVE	P1,T2		;GET NEW VALUE INTO A KOSHER AC FOR 'TRFCHG'
	HRRZ	T1,STRSCU##(P2)	;GET CURRENT # SUPER CLUSTERS PER UNIT
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	HRRM	P1,STRSCU##(P2)	;STORE # SUPER CLUSTERS PER UNIT
	POPJ	P,
SUBTTL	DIALOGUE SUBROUTINES -- GETCFS - CLASS FOR SWAPPING


GETCFS:	SETZM	ONCTCH##	;DEFEAT PRSCON
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	JUMPE	T1,CPOPJ##	;RETURN IF NOT A SWAPPING UNIT
	MOVEI	T1,[ASCIZ /    Swapping class/]
	SKIPN	CHGFLG##	;CHANGE?
	TDZA	T2,T2		;DEFAULT TO CLASS ZERO
	LDB	T2,UNYCFS##	;ELSE USE CURRENT VALUE
	MOVEI	T3,0		;LOW RANGE
	MOVEI	T4,1		;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	LDB	T2,UNYCFS##	;GET OLD VALUE
	DPB	T1,UNYCFS##	;STORE NEW VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	PUSHJ	P,SETCHG	;NO--MUST REWRITE HOME BLOCKS
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETCNP - BITS PER CLUSTER COUNT


GETCNP:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /   *Bits per cluster count/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,CNPDEF(T2)	;LOAD UP A REASONABLE DEFAULT
	LDB	T2,[POINT 6,STYCNP##(P2),11] ;USE CURRENT VALUE
	MOVEI	T3,1		;LOW RANGE
	LDB	T4,[POINT 6,STYCLP##(P2),11] ;HIGH RANGE
	MOVNS	T4		;NEGATE
	ADDI	T4,^D36		;ROUND UP
	CAILE	T4,LIMCNP##	;MAKE SURE DOESNT EXCEED LIMCMP
	MOVEI	T4,LIMCNP##	;KEEP WITHIN BOUNDS
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	MOVE	P1,T1		;COPY TO UNORTHODOX PLACE
;	PJRST	CNPSTO		;GO STORE RESULTS
CNPSTO:	LDB	T1,[POINT 6,STYCNP##(P2),11] ;GET OLD VALUE
	CAME	P1,T1		;IF CHANGED,
	PUSHJ	P,REFCHS	;STR AND UNITS NEED REFRESHING
	DPB	P1,[POINT 6,STYCNP##(P2),11] ;SAVE NEW ONE
	LDB	T3,[POINT 6,STYCLP##(P2),11]
	ADD	P1,T3
	MOVNS	P1
	ADDI	P1,^D36
	LDB	T1,[POINT 6,STYCKP##(P2),11]
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	DPB	P1,[POINT 6,STYCKP##(P2),11]
	ADD	P1,T3
	LDB	T1,[POINT 6,STYCNP##(P2),5]
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	DPB	P1,[POINT 6,STYCNP##(P2),5]
	MOVE	P1,T3
	LDB	T1,[POINT 6,STYCKP##(P2),5]
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;NO
	DPB	P1,[POINT 6,STYCKP##(P2),5]
	POPJ	P,
SUBTTL	DIALOGUE SUBROUTINES -- GETDSN - DISK-SET NUMBERS


GETDSN:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Disk-set (1 - 36,ALL,NONE)/]
	SKIPN	CHGFLG##	;CHANGE?
	TDZA	T2,T2		;DEFAULT TO "ALL"
	LDB	T2,STYSET##	;USE CURRENT DEFAULT
	SETZ	T4,		;CLEAR RESULT
	CAIN	T2,0		;ZERO?
	MOVSI	T4,'ALL'	;YES
	CAIN	T2,^D37		;NONE?
	MOVE	T4,['NONE  ']	;YES
	JUMPN	T4,GETDS2	;SPECIAL NUMBERS?
GETDS1:	IDIVI	T2,12		;DIVIDE BY RADIX
	ADDI	T3,'0'		;CONVERT TO SIXBIT
	LSHC	T3,-6		;SAVE RESULTS
	JUMPN	T2,GETDS1	;LOOP FOR MORE
GETDS2:	MOVE	T2,T4		;COPY RESULT
	PUSHJ	P,PRSSIX##	;PROMPT AND FETCH ANSWER
	MOVE	T3,T1		;MAKE A COPY
	CAMN	T3,['ALL   ']	;ALL?
	JRST	GETDS4		;YES
	CAMN	T3,['NONE  ']	;NONE?
	JRST	GETDS5		;YES
	SETZ	T1,		;CLEAR RESULT

GETDS3:	LSHC	T2,6		;GET A CHARACTER
	ANDI	T2,77		;MASK OUT JUNK
	CAIL	T2,'0'		;RANGE
	CAILE	T2,'9'		; CHECK
	JRST	GETDS7		;NOT A NUMBER
	IMULI	T1,12		;SHIFT
	ADDI	T1,-'0'(T2)	;ADD IN RESULTS
	JUMPN	T3,GETDS3	;LOOP FOR MORE
	CAIL	T1,0		;RANGE
	CAILE	T1,^D36		; CHECK
	JRST	GETDS7		;NO GOOD
	JRST	GETDS6		;GO STORE RESULTS

GETDS4:	TDZA	T1,T1		;ALL = 0
GETDS5:	MOVEI	T1,^D37		;NONE = 37
GETDS6:	LDB	T2,STYSET##	;GET OLD VALUE
	DPB	T1,STYSET##	;STORE NEW VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	PUSHJ	P,CHGSTX	;REMEMBER FOR LATER
	POPJ	P,		;RETURN

GETDS7:	MOVEI	T1,[ASCIZ /% Bad response, try again/]
	PUSHJ	P,CONOUT##	;PRINT THE MESSAGE
	JRST	GETDSN		;LOOP BACK
SUBTTL	DIALOGUE SUBROUTINES -- GETGAR - GUARANTEED BLOCKS


GETGAR:	POPJ	P,		;UNIMPLEMENTED
	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Sum of blocks guaranteed to users/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,GARDEF(T2)	;LOAD UP A REASONABLE DEFAULT
	MOVE	T2,STRGAR##(P2)	;GET CURRENT VALUE
	MOVEI	T3,0		;LOW RANGE
	MOVE	T4,STRSIZ##(P2)	;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	MOVE	T2,STRGAR##(P2)	;GET OLD VALUE
	MOVEM	T1,STRGAR##(P2)	;STORE NEW VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	PUSHJ	P,CHGSTX	;REMEMBER FOR LATER
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETGRP - BLOCKS TO ALLOCATION ON OUTPUT


GETGRP:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Consecutive blocks tried for on output/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,GRPDEF(T2)	;LOAD UP A REASONABLE DEFAULT
	HLRZ	T2,UNIGRP(U)	;USE CURRENT VALUE
	MOVEI	T3,0		;LOW RANGE
	MOVEI	T4,-1		;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	SETZ	T3,		;CLEAR FLAG

GETGR1:	HLRZ	T2,UNIGRP(U)	;GET OLD VALUE
	HRLM	T1,UNIGRP(U)	;STORE NEW VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	AOS	T3		;NO
	HLRZ	U,UNISTR(U)	;GET NEXT UNIT DATA BLOCK ADR. IN THIS STR
	JUMPN	U,GETGR1	;STORE VALUE IN IT
	SKIPE	T3		;DID ANYTHING CHANGE?
	PUSHJ	P,CHGSTX	;YES
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETK4C - K FOR CRASH.SAV


GETK4C:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ  /   *Number of K for CRASH.EXE/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,K4CDEF(T2)	;LOAD UP A REASONABLE DEFAULT
	HRRZ	T2,STRK4C##(P2)	;USE CURRENT VALUE
	MOVE	T3,['KLAD  ']	;SPECIAL NAME FOR DEC DIAGNOSTIC PACKS
	SKIPN	CHGFLG##	;CHANGE?
	CAME	T3,STRNAM##(P2)	;IS THIS A KLAD PACK?
	SKIPA			;LEAVE DEFAULT ALONE
	MOVEI	T2,10000	;CHANGE DEFAULT TO THE MAXIMUM IF DEFINE
	SKIPGE	T2		;MINUS ONE?
	MOVEI	T2,M.NKC##	;THEN USE DEFAULT FROM MONGEN
	MOVEI	T3,0		;LOW RANGE
	MOVEI	T4,10000	;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	MOVE	P1,T1		;COPY TO UNORTHODOX PLACE
	HRRZ	T1,STRK4C##(P2)	;GET CURRENT VALUE
	CAME	T1,P1		;NEW SAME AS OLD?
	PUSHJ	P,REFCHS	;STR NEEDS REFRESHING, REWRITE HOME BLOCKS
	HRRM	P1,STRK4C##(P2)	;STORE NEW VALUE
	POPJ	P,		;DONE
SUBTTL	DIALOGUE SUBROUTINES -- GETK4S - K FOR SWAPPING


GETK4S:	SETZM	ONCTCH##	;DEFEAT PRSCON
	JUMPN	P2,GETK41	;BRANCH IF UNIT KNOWN TO BE IN STRUCTURE
	MOVEI	T3,LB2HOM##+4	;1ST BLOCK AVAILABLE IF NO STRUCTURE
	JRST	GETK44		;COMPUTE MAX K FOR SWAPPING

GETK41:	MOVEI	T1,LB2HOM##+2	;LAST BLOCK NOT AVAILABLE FOR SWAP THIS UNIT
	LDB	T2,UNYBPC##	;BLOCKS PER CLUSTER
	IDIV	T1,T2		;T1=LAST CLUSTER NOT AVAILABLE
	LDB	T3,UNYSPU##	;COUNT 1 CLUSTER FOR EACH SAT ON UNIT
	ADDI	T3,1(T1)	;PLUS CLUSTERS FOR HOME STUFF
	LDB	T1,UNYLUN##	;LOGICAL UNIT IN STR
	JUMPN	T1,GETK42	;JUMP IF NOT 1ST UNIT IN STR
	ADDI	T3,RB1UN##	;+CLUSTERS FOR RIBS ON 1ST UNIT REFRESHER MAKES
	ADDI	T3,3		;ACCOUNT FOR MFD+SYS+SPL

GETK42:	HRRZ	T1,STRUNM##(P2)	;NUMBER OF UNITS IN STR
	LDB	T2,UNYLUN##	;LOGICAL UNIT IN STR
	CAIE	T1,1(T2)	;SKIP IF THIS IS LAST UNIT IN STR
	JRST	GETK43		;NO
	ADDI	T3,RBLUN##	;COUNT RIBS REFRESHER WRITES ON LAST UNIT
	HRRZ	T1,STRK4C##(P2)	;K FOR CRASH SAV
	LSH	T1,BLKSPK	;CONVERT TO BLOCKS
	ADDI	T1,2+4		;+6 FOR RIBS AND EXE DIRECTORY
	LDB	T2,UNYBPC##	;BLOCKS PER CLUSTER
	ADDI	T1,-1(T2)
	IDIV	T1,T2		;CLUSTERS FOR CRASH EXE
	ADD	T3,T1
	MOVEI	T1,2		;2 BLOCKS FOR SNAP SYS AND RECOV SYS
	LDB	T2,UNYBPC##
	ADDI	T1,-1(T2)
	IDIV	T1,T2		;CLUSTERS FOR SNAP SYS
	LSH	T1,2
	ADD	T3,T1

GETK43:	LDB	T2,UNYBPC##	;BLOCKS PER CLUSTER
	IMUL	T3,T2		;T3=1ST BLOCK AVAILABLE FOR SWAPPING
GETK44:	TRZ	T3,3		;ROUND DOWN (MAYBE WE SHOULD ROUND UP?)
	MOVEM	T3,TMPSWM	;SAVE MINIMUM BLOCK NUMBER TO SWAP ON
	SOJ	T3,		;(T3)=LAST BLOCK NOT AVAILABLE FOR SWAP
	MOVE	T1,UNIBPU(U)	;BLOCKS ON UNIT
	SUB	T1,T3		;T1=BLOCKS AVAILABLE FOR SWAPPING
	HRRZ	T2,UNICPS(U)	;NOW GET CLUSTERS PER SAT
	LDB	T3,UNYBPC##	;AND GET BLOCKS PER CLUSTER
	JUMPE	T3,GETK45	;FORGET IT IF NOT IN A STR
	IMULI	T3,-2(T2)	;MULTIPLY TO GET BLOCKS PER SAT - 2 CLUSTERS
	CAMLE	T1,T3		;WILL 1 SAT BLOCK HOLD MORE THAN THIS STR
	MOVE	T1,T3		;NO, CAN'T USE ALL OF STR FOR SWAPPING

GETK45:	LSH	T1,MBKSPK	;CONVERT TO MAX K FOR SWAPPING
	MOVEI	T2,1
	LSH	T2,LIMK4S##-K2PLSH
	SUBI	T2,1		;MAX THAT FITS IN FIELD
	CAMLE	T1,T2
	MOVE	T1,T2		;MIN OF FIELD, BLOCKS AVAILABLE
	MOVE	T4,T1		;HIGH RANGE
	MOVEI	T1,[ASCIZ /   *K for swapping/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,K4SDEF(T2)	;LOAD UP A RESONABLE DEFAULT
	LDB	T2,UNYK4S##	;USE CURRENT VALUE
	MOVE	T3,['KLAD  ']	;SPECIAL NAME FOR DEC DIAGNOSTIC PACKS
	SKIPN	CHGFLG##	;CHANGE?
	CAME	T3,STRNAM##(P2)	;IS THIS A KLAD PACK?
	SKIPA			;LEAVE DEFAULT ALONE
	MOVE	T2,[EXP ^D4096*2] ;CHANGE DEFAULT TO REASONABLE NUMBER
	MOVEI	T3,0		;LOW RANGE
	CAMLE	T2,T4		;IF DEFAULT NOT IN RANGE,
	MOVE	T2,T4		;KEEP IT THERE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	LSH	T1,BLKSPK	;COMPUTE BLOCKS NEEDED FOR SWAPPING
	MOVE	T3,UNIBPU(U)	;GET BLOCKS ON UNIT
	SUB	T3,T1		;COMPUTE FIRST BLOCK FOR SWAPPING
	LSH	T3,-1		;DIVIDE BY 2 SO SWAP AREA CENTERED ON DISK
	TRZ	T3,3
	CAMGE	T3,TMPSWM	;ABOVE MINIMUM BLOCK FOR SWAPPING?
	MOVE	T3,TMPSWM	;NO, USE MINIMUM BLOCK INSTEAD
	MOVEM	T3,TMPSWB	;SAVE TEMPORARY SWAP BLOCK NUMBER
	LSH	T1,MBKSPK	;CONVERT BLOCKS FOR SWAPPING BACK INTO K
	LDB	T2,UNYK4S##	;GET OLD VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	PUSHJ	P,REFCHU	;NO--MUST REWRITE HOME BLOCKS & REFRESH
	DPB	T1,UNYK4S##	;STORE NEW VALUE
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETOPP - OWNER PPN


GETOPP:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Owner PPN/]
	SKIPE	CHGFLG##	;CHANGE?
	SKIPN	T2,STRPPN##(P2)	;USE CURRENT VALUE IF CHANGE
	MOVE	T2,['NONE  ']	;ASSUME NONE FOR DEFINE
	MOVE	T3,[-1,,['NONE  ']] ;ACCEPT "NONE" IN ANY CASE
	PUSHJ	P,PRSPPN##	;PROMPT AND FETCH ANSWER
	MOVE	T2,STRPPN##(P2)	;GET CURRENT VALUE
	MOVEM	T1,STRPPN##(P2)	;SET/CLEAR PPN
	CAME	T1,T2		;ANY CHANGE?
	PUSHJ	P,CHGSTX	;REMEMBER FOR LATER
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETOVR - OVERDRAW


GETOVR:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Blocks allowed for overdraw per user/]
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,OVRDEF(T2)	;LOAD UP A REASONABLE DEFAULT
	MOVM	T2,STROVR##(P2)	;USE CURRENT VALUE
	MOVEI	T3,0		;LOW RANGE
	MOVE	T4,STRSIZ##(P2)	;HIGH RANGE
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	MOVM	T2,STROVR##(P2)	;GET CURRENT VALUE
	MOVNM	T1,STROVR##(P2)	;STORE NEW VALUE
	CAME	T1,T2		;ANY CHANGE?
	PUSHJ	P,CHGSTX	;REMEMBER FOR LATER
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETPRV - PRIVATE STRUCTURE


GETPRV:	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Private structure/]
	SKIPN	CHGFLG##	;CHANGE?
	TDZA	T2,T2		;LOAD UP A REASONABLE DEFAULT
	LDB	T2,STYPVS##	;USE CURRENT VALUE
	MOVE	T2,[EXP <'NO    '>,<'YES   '>](T2) ;SET DEFAULT TEXT
	PUSHJ	P,PRSYNQ##	;GET YES/NO RESPONSE
	LDB	T2,STYPVS##	;GET CURRENT SETTING
	DPB	T1,STYPVS##	;STORE NEW SETTING
	CAME	T1,T2		;DID IT CHANGE?
	PUSHJ	P,CHGSTX	;YES, NOTE THAT
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETSDL - SINGLE STRUCTURE SDL


GETSDL:	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Make this the only structure in the SDL/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	MOVE	T3,['KLAD  ']	;SPECIAL NAME FOR DEC DIAG DISKS
	CAMN	T3,STRNAM##(P2)	;IS THIS A KLAD PACK?
	MOVSI	T2,'YES'	;CHANGE THE DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	PUSH	P,U		;SAVE U
	PUSH	P,P2		;SAVE P2
	PUSH	P,STRSDL##(P2)	;SAVE CURRENT POSITION
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

GETSD1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STR
	JUMPE	P2,GETSD2	;DONE?
	SKIPL	STRSDL##(P2)	;IN THE SDL ALREADY?
	PUSHJ	P,CHGSTX	;YES--MARK HOME BLOCKS TO BE REWRITTEN
	SETOM	STRSDL##(P2)	;EMPTY THE SDL
	JRST	GETSD1		;LOOP BACK FOR MORE

GETSD2:	POP	P,T1		;GET OLD POSITION BACK
	POP	P,P2		;RESTORE P2
	POP	P,U		;RESTORE U
	SETZM	STRSDL##(P2)	;MAKE IT THE FIRST STRUCTURE IN THE SDL
	CAME	T1,STRSDL##(P2)	;SAME AS BEFORE?
	PUSHJ	P,CHGSTX	;MARK HOME BLOCKS TO BE REWRITTEN
	POPJ	P,		;AND RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETSIC - SATS IN CORE


GETSIC:	SETZM	ONCTCH##	;DEFEAT PRSCON
	MOVEI	T1,[ASCIZ  /    SAT blocks in core/]
	LDB	T2,UNYSPU##	;LOAD UP A REASONABLE DEFAULT
	SKIPE	CHGFLG##	;CHANGE?
	LDB	T2,UNYSIC##	;USE CURRENT VALUE
	MOVEI	T3,1		;LOW RANGE
	LDB	T4,UNYSPU##	;HIGH RANGE
	CAIE	T2,0		;SKIP IF NO SATS IN CORE
	CAMLE	T2,T4		;SKIP IF NOT TOO MANY SATS IN CORE
	MOVE	T2,T4		;USE MAX IF NONE OR TOO MANY
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	LDB	T2,UNYSIC##	;GET OLD VALUE
	CAMN	T1,T2		;SAME AS BEFORE?
	POPJ	P,		;THEN ALL DONE
	PUSH	P,T1		;SAVE NEW VALUE
	PUSHJ	P,DELSAB	;DELETE EXISTING SAB RING AND SPT TABLE
	POP	P,T1		;GET NEW VALUE BACK
	DPB	T1,UNYSIC##	;STORE NEW VALUE
	PUSHJ	P,CRESAB	;CREATE A NEW SAB RING AND SPT TABLE
	PJRST	SETCHG		;NEED TO REWRITE HOME BLOCKS
SUBTTL	DIALOGUE SUBROUTINES -- GETSNM - GET STRUCTURE NAME/STR DB


GETSNM:	MOVEI	T1,[ASCIZ /Structure to define/]
	SETZ	T2,		;NO DEFAULT STRUCTURE NAME
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	JUMPE	T1,CPOPJ##	;GIVE UP IF NO RESPONSE
	PUSHJ	P,CHKSN0	;CHECK OUT PROPOSED NAME
	  JRST	GETSNM		;LET OPR TRY AGAIN
	PUSH	P,T1		;SAVE STR NAME
	PUSHJ	P,GETSTR	;CREATE STR DATA BLOCK
	  JRST	GETSNE		;TOO MANY STRUCTURES
	POP	P,T1		;GET STRUCTURE NAME BACK
	MOVEM	T1,STRNAM##(P2)	;SAVE IT
	POPJ	P,		;RETURN WITH STR DB SETUP

GETSNE:	POP	P,(P)		;PHASE STACK
	MOVEI	T2,[ASCIZ /No room for additional structures/]
	PUSHJ	P,SWARN		;WARN OPERATOR
	SETZ	T1,		;SAY NO STRUCTURE
	POPJ	P,		;AND RETURN
CHKSNM:	PUSHJ	P,SAVE4##	;SAVE SOME ACS
CHKSN0:	TRNE	T1,7777		;CHECK THE NAME NOW
	JRST	CHKSND		;SINCE FNSTR WILL TRIM IT SILENTLY
	PUSHJ	P,FNSTR		;ALREADY EXIST?
	  JRST	CHKSN1		;NO
	MOVE	T1,STRNAM##(P2)	;GET OFFENDING NAME
	MOVEI	T2,[ASCIZ /already exists/]
	PJRST	SWARN		;GIVE UP ON HIM

CHKSN1:	MOVSI	T2,-SDVLEN##	;AOBJN POINTER
CHKSN2:	HLLZ	T3,SDVTBL##(T2)	;GET AN ERSATZ DEVICE NAME
	CAMN	T1,T3		;MATCH?
	JRST	CHKSNA		;CAN'T HAVE THAT
	AOBJN	T2,CHKSN2	;SEARCH TABLE
	HRLI	P1,PHONLY##	;FLAG FOR UUOCON TO CHECK
	MOVEI	J,1_CTXLSH##!1	;FOR JCH 1.1
	SKIPE	.UONCE##	;UNLESS IN USER MODE,
	PUSHJ	P,DEVPHU##	;THEN CALL KROCK ROUTINE
	 PUSHJ	P,DEVPHY##	;CONFLICT WITH A DDB NAME?
	  JRST	CPOPJ1##	;SPECIFIED NAME IS OK
	CAIN	F,DSKDDB##	;GENERIC DISK NAME?
	JRST	CHKSNC		;YES
	JRST	CHKSNB		;DDB CONFLICT

CHKSNA:	MOVEI	T2,[ASCIZ /conflicts with ersatz device name/]
	PJRST	SWARN
CHKSNB:	MOVEI	T2,[ASCIZ /conflicts with DDB name/]
	PJRST	SWARN
CHKSNC:	MOVEI	T2,[ASCIZ /conflicts with generic disk/]
	PJRST	SWARN
CHKSND:	MOVEI	T2,[ASCIZ /has more than four characters in name/]
	PJRST	SWARN
SUBTTL	DIALOGUE SUBROUTINES -- GETSPU - SATS PER UNIT


GETSPU:	SETZM	ONCTCH##	;DEFEAT PRSCON
	MOVE	T2,UNIBPU(U)	;NUMBER BLOCKS ON UNIT
	LDB	T4,UNYBPC##	;AND BLOCKS PER CLUSTER
	IDIV	T2,T4		;COMPUTE LAST CLUSTER ADDRESS ON UNIT
	MOVE	T1,T2		;COPY RESULTS
	IDIVI	T2,<MXSADA==^D118>*^D36
	AOS	T3,T2		;LOW RANGE
	IDIVI	T1,^D36		;COMPUTE GREATEST # SATS POSSIBLE ON THIS UNIT
	ADDI	T1,1		;MAX # OF SATS BASED ON USING ONE WORD PER SAT
	MOVEI	T4,1		;ASSUME AT LEAST 1 UNIT PER STR
	SKIPE	P2		;SKIP IF NO STR AFTER ALL
	HRRZ	T4,STRUNM##(P2)	;ONE UNIT CHANGE POINTER REQUIRED PER UNIT
	SUBI	T4,RIBLEN##-3	;SUBTRACT THESE PLUS (2 RIBS + EOF)
	MOVNS	T4		;MAX # OF SATS WHICH CAN FIT IN ONE RIB
	CAILE	T1,(T4)		;LESS THAN THIS?
	MOVE	T1,T4		;NO--PUT IN AS NEW MAX
	MOVE	T4,T1		;HIGH RANGE
	MOVEI	T1,[ASCIZ  /   *SAT blocks per unit/]
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,T3		;USE LOW RANGE VALUE AS DEFAULT
	LDB	T2,UNYSPU##	;GET CURRENT VALUE
	CAMLE	T3,T2		;SKIP IF DEFAULT ISN'T TOO LOW
	MOVE	T2,T3		;IF TOO LOW, MAKE DEFAULT THE MINIMUM
	CAMLE	T2,T4		;SKIP IF DEFAULT ISN'T TOO HIGH
	MOVE	T2,T4		;IF TOO HIGH, MAKE DEFAULT THE MAXIMUM
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	LDB	T2,UNYSPU##	;GET OLD VALUE
	CAMN	T1,T2		;SAME AS BEFORE?
	POPJ	P,		;THEN ALL DONE
	PUSH	P,T1		;SAVE NEW VALUE
	PUSHJ	P,CKUSTR	;JUST TO BE SURE
	  JRST	TPOPJ##		;DON'T WORRY ABOUT IT
	PUSHJ	P,DELSAB	;DELETE EXISTING SAB RING AND SPT TABLE
	POP	P,T1		;GET NEW VALUE BACK
	DPB	T1,UNYSPU##	;STORE NEW VALUE
	PUSHJ	P,CRESAB	;CREATE A NEW SAB RING AND SPT TABLE
	PJRST	REFCHU		;MUST REWRITE HOME BLOCKS & REFRESH
SUBTTL	DIALOGUE SUBROUTINES -- GETSSL - SINGLE STRUCTURE SSL


GETSSL:	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Make this the only structure in the SSL/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	MOVE	T3,['KLAD  ']	;SPECIAL NAME FOR DEC DIAG DISKS
	CAMN	T3,STRNAM##(P2)	;IS THIS A KLAD PACK?
	MOVSI	T2,'YES'	;CHANGE THE DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	PUSH	P,U		;SAVE U
	PUSH	P,P2		;SAVE P2
	PUSH	P,STRSRC##(P2)	;SAVE CURRENT POSITION
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

GETSS1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STR
	JUMPE	P2,GETSS2	;DONE?
	SKIPL	STRSRC##(P2)	;IN THE SSL ALREADY?
	PUSHJ	P,CHGSTX	;YES--MARK HOME BLOCKS TO BE REWRITTEN
	SETOM	STRSRC##(P2)	;EMPTY THE SSL
	JRST	GETSS1		;LOOP BACK FOR MORE

GETSS2:	POP	P,T1		;GET OLD POSITION BACK
	POP	P,P2		;RESTORE P2
	POP	P,U		;RESTORE U
	SETZM	STRSRC##(P2)	;MAKE IT THE FIRST STRUCTURE IN THE SSL
	CAME	T1,STRSRC##(P2)	;SAME AS NEW POSITION?
	PUSHJ	P,CHGSTX	;MARK HOME BLOCK TO BE REWRITTEN
	POPJ	P,		;AND RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETSTN - STRUCTURE NAME


GETSTN:	SETZM	ONCTCH##	;DEFEAT PRSCON
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	MOVEI	T1,[ASCIZ /    Structure name/]
	MOVE	T2,STRNAM##(P2)	;GET OLD NAME FOR DEFAULT
	PUSHJ	P,PRSSIX##	;PROMPT AND FETCH ANSWER
	CAMN	T1,STRNAM##(P2)	;SAME AS BEFORE?
	POPJ	P,		;ALL DONE
	PUSHJ	P,CHKSNM	;VALIDATE PROPOSED NEW NAME
	  JRST	GETSTN		;NO GOOD, TRY AGAIN
	MOVEM	T1,STRNAM##(P2)	;UPDATE POSSIBLY NEW NAME
	MOVE	T1,[PUSHJ P,GETSTX] ;SET UP CALL TO STOUNI
	PJRST	STOUNI		;LOOP THROUGH ALL UNITS IN STRUCTURE

;HELPER ROUTINE EXECUTED FROM STOUNI TO MARK HOME BLOCKS NEED TO BE
;REWRITTEN AND TO UPDATE UNILOG FOR ALL UNITS IN THE STRUCTURE.

GETSTX:	LDB	T1,UNYLUN##	;GET LOGICAL UNIT NUMBER OF THIS UNIT
	PUSHJ	P,CMPLOG	;COMPUTE AND STORE UNILOG
	PJRST	SETCHG		;MARK THIS UNIT NEEDS HOME BLOCKS REWRITTEN
SUBTTL	DIALOGUE SUBROUTINES -- GETSWB - FIRST SWAPPING BLOCK NUMBER


GETSWB:	SETZM	ONCTCH##	;DEFEAT PRSCON
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	JUMPE	T1,CPOPJ##	;RETURN IF NOT A SWAPPING UNIT
	LDB	T4,UNYK4S##	;GET # K FOR SWAPPING
	LSH	T4,BLKSPK	;COMPUTE # BLOCKS FOR SWAPPING ON UNIT
	MOVE	T2,UNIBPU(U)	;GET # BLOCKS ON UNIT
	SUB	T2,T4		;COMPUTE HIGHEST 1ST. LOG. BLOCK # POSSIBLE
	HRRZ	T1,UNICPS(U)	;GET CLUSTERS/SAT
	LDB	T3,UNYSPU##	;GET SATS/UNIT
	SUBI	T3,1		;MINUS 1
	IMUL	T1,T3		;COMPUTE CLUSTERS IN ALL BUT LAST SAT
	LDB	T3,UNYBPC##	;GET BLOCKS/CLUSTER
	IMUL	T1,T3		;COMPUTE BLOCKS IN ALL BUT LAST SAT
	ADD	T1,T4		;ADD IN BLOCKS FOR SWAPPING ON UNIT
	CAMLE	T1,UNIBPU(U)	;GREATER THAN UNIT SIZE?
	SUB	T2,T3		;YES, RESERVE A CLUSTER IN LAST SAT FOR THE SAT
	TRZ	T2,3
	PUSH	P,T2		;SAVE HIGHEST LEGAL BLOCK
	MOVE	T1,UNISLB(U)	;GET FIRST BLOCK FOR SWAPPING
	CAILE	T1,LB2HOM##+1	;IS IT BETWEEN 0 & SECOND BAT BLOCK?
	JRST	GETSW1		;NO
	MOVE	T1,TMPSWB	;GET COMPUTED VALUE
	MOVE	T2,UNISLB(U)	;AND PREVIOUS
	CAME	T1,T2		;SEE IF THE SAME AS BEFORE
	PUSHJ	P,REFCHU	;NO, SO MUST REFRESH
	MOVEM	T1,UNISLB(U)	;SAVE NEW VALUE

GETSW1:	MOVEI	T1,[ASCIZ /   *First logical block for swapping/]
	MOVE	T2,UNISLB(U)	;GET COMPUTED (OR CURRENT) VALUE
	MOVE	T3,TMPSWM	;LOW RANGE
	POP	P,T4		;HIGH RANGE
	CAMG	T2,T4		;IF OUT OF RANGE,
	CAMGE	T2,T3		;IN EITHER DIRECTION,
	MOVE	T2,TMPSWB	;TRY COMPUTED (NOT PREVIOUS)
	CAMG	T2,T4		;IF STILL OUT OF RANGE,
	CAMGE	T2,T3		;IN EITHER DIRECTION,
	MOVE	T2,T3		;GO WITH THE LOWEST
	PUSHJ	P,PRSDEC##	;PROMPT AND FETCH ANSWER
	TRZ	T1,3
	MOVE	T2,UNISLB(U)	;GET OLD VALUE
	CAME	T1,T2		;SAME AS BEFORE?
	PUSHJ	P,REFCHU	;NO--MUST REWRITE HOME BLOCKS & REFRESH
	MOVEM	T1,UNISLB(U)	;STORE NEW VALUE
	POPJ	P,		;RETURN
SUBTTL	DIALOGUE SUBROUTINES -- GETUID - UNIT ID


GETUID:	SETZM	ONCTCH##	;DEFEAT PRSCON
	MOVEI	T1,[ASCIZ  /    Unit ID/]
	SKIPN	CHGFLG##	;CHANGE?
	SKIPA	T2,UNILOG(U)	;DEFAULT UID IS SAME AS LOGICAL UNIT NAME
	MOVE	T2,UNIHID(U)	;USE CURRENT VALUE
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	JUMPN	T1,GETUI1	;CONTINUE IF HAVE SOMETHING
	MOVE	T1,UDBNAM(U)	;DRIVE NAME
	MOVEI	T2,[ASCIZ /requires a name/]
	PUSHJ	P,UWARN		;WARN OPERATOR
	JRST	GETUID		;TRY AGAIN

GETUI1:	CAMN	T1,UNIHID(U)	;ARE WE LEAVING THIS UNCHANGED?
	POPJ	P,		;YES--GET OUT WHILE WE STILL CAN
	HLRZ	T2,SYSUNI##	;GET FIRST UDB IN SYSTEM
GETUI2:	CAMN	T1,UNIHID(U)	;THIS ONE ALREADY IN USE?
	JRST	GETUI3		;CAN'T HAVE THAT
	HLRZ	T2,UNISYS(T2)	;LINK TO NEXT UDB
	JUMPN	T2,GETUI2	;KEEP SEARCHING
	JRST	GETUI4		;NOT A DUPLICATE

GETUI3:	MOVEI	T3,[ASCIZ /Unit id /]
	MOVEI	T2,[ASCIZ /already exists/]
	PUSHJ	P,XWARN		;WARN OPERATOR
	JRST	GETUID		;TRY AGAIN

GETUI4:	MOVEM	T1,UNIHID(U)	;STORE NEW VALUE
	PJRST	SETCHG		;MUST REWRITE HOME BLOCKS
SUBTTL	DIALOGUE SUBROUTINES -- TABLES OF STRUCTURE & UNIT DEFAULTS


; MACROS TO BUILD DEFAULT TABLES FOR STRUCTURE AND UNIT DATA BLOCKS.
; EACH TABLE IS INDEXED BY CONTROLLER TYPE, TAKEN FROM UNYKTP.  THE
; CONTROLLER TYPE CODES ARE:
;	0=DR, 1=FH, 2=DP, 3=MF, 4=FS, 5=RP, 6=RN, 7=RA
;
; CONTROLLER CODES FOR "DR" (FUTURE DRUM ON AN ???? CONTROLLER) AND
; "MF" (MASS FILE UNIT ON AN MD10 "MOBY DISK" CONTROLLER) WERE NEVER
; SUPPORTED BY TOPS10, BUT TABLE ENTRIES EXIST BECAUSE THOSE CODES HAD
; BEEN RESERVED IN ANTICIPATION OF FUTURE HARDWARE.
;
; ARGUMENTS TO THE SUDEFS MACRO ARE:
;	KON = CONTROLLER NAME
;	BSA = NUMBER OF BLOCKS FOR SEQUENTIAL OUTPUT
;	BPC = BLOCKS PER CLUSTER
;	GAR = NUMBER OF BLOCKS GUARANTEED
;	OVR = NUMBER OF BLOCKS OVERDRAW
;	K4C = K FOR CRASH.SAV
;	BCC = BITS PER CLUSTER COUNT
;	K4S = K FOR SWAPPING
;	MUS = MAXIMUM NUMBER OF UNITS PER STRUCTURE
;	NSB = NUMBER OF STRUCTURES TO BUILD
;	SSN = STARTING STRUCTURE NAME

DEFINE	SUDEFS,<

	RADIX	10

;	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN )
X	(DR ,  0,  0,  0,  0,    0, 12,    0,  0,  0,    )
X	(FH , 10,  1,  0,200,    0, 12,    0,  0,  0,    )
X	(DP , 30,  5,  0,500,   -1, 12,    0, 32,  1,DSKE)
X	(MF , 30, 10,  0,500,  256, 12,    0,  0,  0,    )
X	(FS , 10,  1,  0,100,    0, 12,  200, 32,  1,DSKA)
X	(RP , 30, 10,  0,500,   -1, 12, 1000, 16,  3,DSKB)
X	(RN , 30, 50,  0,500,    0, 12,    0, 16,  3,DSKF)
X	(RA , 30, 10,  0,500,    0, 12,    0,  8,  3,DSKI)

	RADIX	8
>
; CONTROLLER NAME
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<SIXBIT /KON/>
KONTBL:	SUDEFS
	EXP	0		;TERMINATE TABLE


; BLOCKS TO TRY FOR ON SEQUENTIAL ALLOCATION
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	BSA>
GRPDEF:	SUDEFS


; BLOCKS PER CLUSTER
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	BPC>
BPCDEF:	SUDEFS


; BLOCKS GUARANTEED TO ALL USERS
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	GAR>
GARDEF:	SUDEFS


; OVERDRAW
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	OVR>
OVRDEF:	SUDEFS


; K FOR CRASH.SAV
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	K4C>
K4CDEF:	SUDEFS


; BITS FOR CLUSTER COUNT FIELD
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	BCC>
CNPDEF:	SUDEFS


; K FOR SWAPPING
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	K4S>
K4SDEF:	SUDEFS


; MAXIMUM NUMBER OF UNITS PER STRUCTURE
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	MUS>
MUSDEF:	SUDEFS


; STARTING STRUCTURE NAME
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	<SIXBIT /SSN/>>
SSNDEF:	SUDEFS
SUBTTL	DIALOGUE SUBROUTINES -- XWARN - GENERATE WARNING MESSAGES


;ROUTINE TO PRINT A WARNING MESSAGE ON THE CTY
;CALL:	MOVE	T1, SIXBIT NAME
;	MOVE	T2, TEXT STRING ADDRESS
;	PUSHJ	P,KWARN		;FOR KONTROLLERS
;	PUSHJ	P,SWARN		;FOR STRUCTURES
;	PUSHJ	P,UWARN		;FOR UNITS
;	<RETURN>

KWARN:	MOVEI	T3,[ASCIZ /Controller /]
	JRST	XWARN		;ENTER COMMON CODE

SWARN::	MOVEI	T3,[ASCIZ /Structure /]
	JRST	XWARN		;ENTER COMMON CODE

UWARN:	MOVEI	T3,[ASCIZ /Unit /]
;	JRST	XWARN		;ENTER COMMON CODE

XWARN:	PUSH	P,T2		;SAVE TEXT
	PUSH	P,T1		;SAVE DEVICE
	PUSH	P,T3		;SAVE PREFIX
	MOVEI	T1,[ASCIZ /% /]	;START OF MESSAGE
	PUSHJ	P,ICONM##	;PRINT IT
	POP	P,T1		;GET PREFIX BACK
	PUSHJ	P,CONMES##	;PRINT IT
	POP	P,T2		;GET DEVICE BACK
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,PRSPC##	;SEPARATOR
	POP	P,T1		;GET TEXT BACK
	PUSHJ	P,CONMES##	;PRINT IT
	PJRST	CRLFOP##	;APPEND A CRLF AND OUTPUT
SUBTTL	DISK READING -- RDDISK - MAIN LOOP


;THIS ROUTINE IS THE FIRST OF THE THREE MAJOR SECTIONS OF THE OPTIONAL
;DISK DIALOGUE.  ITS PURPOSE IS TO READ THE DISKS AND BUILD THE IN-CORE
;DATA BASE OF STRUCTURES, UNITS, AND SYSTEM LISTS.
;CALL:	PUSHJ	P,RDDISK
;	  <NON-SKIP>		;SOME ERRORS DETECTED
;	<SKIP>			;DATA BASE BUILT CORRECTLY
;
;ON THE ERROR RETURN, WARNINGS HAVE BEE ISSUED TO THE OPERATOR FOR ALL
;INCONSISTANCIES DETECTED DURING THIS PROCESS.  AT THIS POINT, THE CALLER
;SHOULD DO WHATEVER CLEANUP IS NECESSARY AND RETURN TO THE "STARTUP OPTION"
;PROMPT.  THIS WILL ALLOW THE OPERATOR TO CORRECT THE ERRORS IN QUESTION.

RDDISK::PUSHJ	P,RDINIT	;RESET FLAGS, RETURN OLD CORE, ETC.
	MOVEI	T1,[ASCIZ \
[Reading HOM blocks]\]
	SKIPE	.UONCE##	;IF AN IMPATIENT USER,
	PUSHJ	P,CONOUT##	;LET HIM KNOW WE'RE ALIVE
	HLRZ	U,SYSUNI##	;GET ADDR OF FIRST UNIT IN SYSTEM
	SETZM	ERRHOM		;NO ERRORS READING THS DISK YET

RDDIS1:	AOS	T1,SYSGEN##	;GET A UNIQUE UNIT GENERATION NUMBER
	HRRM	T1,UNIGEN(U)	;SET INITIAL VALUE
	MOVE	J,UDBKDB(U)	;GET ADDR OF KDB FOR UNIT
	PUSHJ	P,TRYKON	;SEE IF KONTROLLER IS ALIVE
	  JRST	RDDIS7		;DOWN SO FLAG UNIT AS OFFLINE
	PUSHJ	P,TRYUNI	;CHECK OUT UNIT
	  JRST	RDDIS7		;OFFLINE OR UNUSABLE FOR SOME REASON
	  JRST	RDDIS9		;SKIP THE REST FOR SECONDARY PORTS

;CHECK HOME BLOCKS
RDDIS2:	MOVEI	T1,UNVPIM	;IF WE READ HOME BLOCKS
	DPB	T1,UNYUST##	;A PACK MUST BE MOUNTED
	PUSHJ	P,TRYHOM	;TRY READING THE HOME BLOCKS
	  JRST	RDDIS7		;CALL IT OFFLINE FOR SOME REASON

;CHECK BAT BLOCKS
RDDIS3:	JRST	RDDIS8		;CONTINUE SCAN OF NEXT UNIT

;HERE TO FLAG UNIT AS OFFLINE AND NO PACK MOUNTED
RDDIS7:	MOVEI	T1,UNVNPM	;SET STATUS TO NO PACK MOUNTED
	DPB	T1,UNYUST##	;STORE UNIT STATUS
	MOVSI	T1,UNPOFL	;BIT TO TEST
	IORM	T1,UNIDES(U)	;MARK UNIT OFFLINE
	SETZB	T1,UNILOG(U)	;MAKE SURE NOT IN STR FLAG CLEARED
	DPB	T1,UNYSIC##	;MAKE SURE NO SATS IN CORE
	MOVEI	T1,O2COD	;IF DEVICE DOES POSITIONS,
	SKIPL	KONPOS(J)	; WE'LL GET AN INTERRUPT WHEN IT COMES UP,
	MOVEM	T1,UNISTS(U)	; SO MARK IT DOWN FOR NOW
	SETOM	UNISUN(U)	;CAN'T BE  PART OF THE ASL IF OFFLINE
	SETZM	UNISTR(U)	;IN CASE IT WAS UP, <ALT> TYPE

RDDIS8:	HLRZ	U,UNISYS(U)	;GET NEXT UNIT DATA BLOCK
RDDIS9:	JUMPN	U,RDDIS1	;LOOP AROUND AGAIN IF ANY LEFT
	PUSHJ	P,TRYQST	;FIND QUEUE STRUCTURE
	SKIPN	ERRHOM		;ANY ERRORS?
	AOS	(P)		;SKIP TO INDICATE SUCCESSFUL
	POPJ	P,		;RETURN
SUBTTL	DISK READING -- GTHOM - READ THE HOME BLOCKS


;ROUTINE TO READ THE HOME BLOCKS INTO CORE FOR A GIVEN UNIT
;CALL:	MOVE	U, UDB ADDRESS
;	PUSHJ	P,GTHOM
;	  <NON-SKIP>		;ERRORS READING HOME BLOCK
;	<SKIP>			;HOME BLOCKS READ INTO CORE

GTHOM::	MOVSI	P2,'HOM'	;BLOCK NAME
	MOVE	P3,[CODHOM##]	;CODE WORD FOR "HOME" BLOCKS
	MOVE	P4,UNIHOM(U)	;GET HOME BLOCK NUMBERS
	PUSHJ	P,REDRUN	;READ THE HOME BLOCKS
	  JRST	GTHOM1		;BOTH BAD
	MOVE	T1,HOMOKC##(P1)	;GET K FOR CRASH.SAV
	SKIPN	HOMVSY##(P1)	;OLD DISK?
	MOVEM	T1,HOMK4C##(P1)	;YES--PUT IN NEW PLACE
	JRST	CPOPJ1##	;RETURN

GTHOM1:	SETZM   UNILOG(U)	;IN CASE SECOND TIME THROUGH
IFN FTDUAL,<
	SKIPE	T1,UNI2ND(U)	;ALTERNATE PORT?
	SETZM	UNILOG(T1)	;ZAP IT TOO
> ;END IFN FTDUAL
	POPJ	P,		;RETURN INDICATING HOME BLOCKS ARE BAD
SUBTTL	DISK READING -- RDINIT - INITIALIZE DISK READING


;ROUTINE TO ALL FLAGS, RETURN CORE, AND DO GENERAL CLEANUP BEFORE
;READING DATA OFF THE DISKS.
;CALL:	PUSHJ	P,RDINIT
;	<RETURN>

RDINIT:	HLRZ	T1,SYSUNI##	;SEE IF WE FOUND ANY DISK UNITS
	SKIPN	T1		;IF NOT,
	STOPCD	.,STOP,NODISK,	;++ NO DISK UNITS CONFIGURED
	SETOM	BLURBF		;NO DIALOGUE BLURB SEEN YET
	SETOM	PRESSL##	;INIT PRESERVED SSL FLAG
	SETOM	PREASL##	;INIT PRESERVED ASL FLAG
	SETOM	PRESDL##	;INIT PRESERVED SDL FLAG
	SETZM	SYSGEN##	;START UNIGEN'S AFRESH
	SETZM	SYSSTR##	;INITIALLY NO FILE STRUCTURES IN SYSTEM
	MOVE	T1,STRAOB##	;AOBJN POINTER TO STR DATA BLOCKS
	SETZM	TABSTR##(T1)	;CLEAR TABLE ENTRY
	AOBJN	T1,.-1		;ZERO ALL ENTRIES

	HRRZS	SWPUNI##	;INITIALLY NO UNITS IN ASL
	SETZM	SWPUN2##	;SO NO SLOW CLASS SWAPPING SPACE YET
	MOVSI	T1,MSWPMX##	;AOBJN POINTER TO SWAPPING UNITS
	SETZM	SWPTAB##(T1)	;CLEAR TABLE ENTRY
	AOBJN	T1,.-1		;ZERO ALL ENTRIES

	MOVEI	R,.USMBF	;ASSUME ONCE
	SKIPE	.UONCE##	;CHECK FLAG
	MOVEI	R,TWCMBF##	;TWICE
	MOVEM	R,ONCMBF	;ADDRESS OF MONITOR BUFFER TO BE USED
	SKIPE	.UONCE##	;USER MODE (TWICE)?
	JRST	RDINI1		;YES
	PUSHJ	P,RTNCOR	;RETURN SPACE USED FOR SDBS, SATS, AND SPTS
	CONO	PI,PI.ON	;TURN PI SYSTEM ON FOR WAITS

RDINI1:	PUSH	P,F		;SAVE F
	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	MOVE	T1,F		;COPY IT
	POP	P,F		;RESTORE F
	HRRZS	SWPDDB##+DEVSER	;CLEAR LINK SO ONCE WONT LOOP
	PUSHJ	P,SETDDO##	;CREATE A DDB FOR ONCE ONLY I/O
	  STOPCD .,STOP,NMC,	;++NO MORE CORE
	PUSHJ	P,GTMNB1	;GET MONITOR BUFFER FOR READING HOME BLOCKS
	POPJ	P,		;RETURN
SUBTTL	DISK READING -- REDRUN - READ & CHECK SPECIAL BLOCKS


;THIS ROUTINE WILL READ AND CHECK SPECIAL (HOME, BAT, & RIB) DISK BLOCKS.
;CALL:	PUSHJ	P,REDRUN
;	  <NON-SKIP>		;ERRORS ON BOTH BLOCKS
;	<SKIP>			;AT LEAST ONE BLOCK OK

REDRUN::PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	HRRZ	P1,@ONCMBF	;GET ADR. OF MONITOR BUFFER FOR DISK BLOCK
	SKIPN	P1		;SKIP IF WE GOT ONE
	STOPCD	CPOPJ##,DEBUG,ONCMBM, ;++MONITOR BUFFER MISSING
	ADDI	P1,1
	SETZM	REDERR		;CLEAR ERROR FLAG

REDRU1:	SETOM	WHICH		;INDICATE READING 1ST. BLOCK
	HLRZ	T2,P4		;GET ITS BLOCK #
	PUSHJ	P,REDCHK	;READ BLOCK & CHECK FOR ERRORS
	  JRST	REDRU2		;ERROR(S) DETECTED - GO TRY 2ND. BLOCK
	JUMPG	T2,CPOPJ1##	;IF 2ND. BLOCK BAD BUT 1ST. OK - SKIP RETURN

REDRU2:	SETZM	WHICH		;INDICATE READING 2ND. BLOCK
	HRRZ	T2,P4		;GET ITS BLOCK #
	PUSHJ	P,REDCHK	;READ BLOCK & CHECK FOR ERRORS
	  JUMPL	T2,CPOPJ##	;ERROR ON 1ST. BLOCK GIVES ERROR RETURN
	JUMPG	T2,REDRU1	;IF 2ND. BAD BUT 1ST. OK, GO TRY 1ST. AGAIN
	JRST	CPOPJ1##	;GIVE SKIP RETURN
;SUBROUTINE TO READ A SPECIAL BLOCK AND CHECK FOR ERRORS
; ENTER WITH T2 = BLOCK # TO BE READ. F = FILE DATA BLOCK. U = UNIT DATA BLOCK ADR.
; RETURN T2 & S = 0 IF NO ERRORS. NON SKIP RETURN IF ERROR ON EITHER BLOCK
; RETURN RH T2 =-1  IF ERROR ON 2ND. BLOCK
;   "    LH T2 =-1   "   "    " 1ST.   "
; & S HAS APPROPRIATE RH ERROR BITS SET

REDCHK:	PUSHJ	P,OMNRED	;READ THE BLOCK
	  SKIPA	T2,P2		;ERROR--GET BLOCK NAME
	JRST	CONCHK		;NO READ ERRORS - GO MAKE CONSISTANCY CHECKS
	MOVEI	T1,[ASCIZ . block hardware read error.]
	PUSHJ	P,RDNMSG	;PRINT ERROR MSG. FOR BLOCK TYPE
	TRO	S,IODTER	;NOTE DATA ERROR
	JRST	TSTCHK		;DON'T PRINT CONSISTENCY ERROR MESSAGE
CONCHK:	TRNN	P1,777776	;SKIP IF WE GOT A BUFFER
	XCT	ONCMBM		;COMPLAIN IF MONITOR BUFFER NOT ALLOCATED
	CAMN	P2,[SIXBIT /SAT/]	;IS THIS THE SAT.SYS "RIB" BLOCK WE'RE READING?
	CAME	P2,RIBNAM##(P1)	;YES - IS THE NAME IN THE "RIB" = 'SAT'?
	CAMN	P2,BLKNAM##(P1)	;NO - CHECK BLOCK NAME(THIS ALWAYS FAILS WITH "RIB")
	CAME	P3,BLKCOD##(P1)	;OK - CHECK CODE WORD
	SKIPA	T2,P2		;NO CHECK--GET BLOCK NAME
	JRST	TSTCHK		;EXIT CHECKING ERRORS ON THE WAY
	MOVEI	T1,[ASCIZ . block consistency error.]
	PUSHJ	P,RDNMSG	;PRINT ERROR MSG. FOR BLOCK TYPE
	TRO	S,IOIMPM	;SET AN ERROR BIT FOR ERROR CHECK
TSTCHK:	MOVE	T2,REDERR	;PICK UP ERROR WORD FOR CHECKING BY CALLER
	JUMPE	S,CPOPJ1##	;SKIP RETURN IF NO ERRORS
	POPJ	P,
;SUBROUTINE TO PRINT ERROR MESSAGE FOR REDCHK
;CALL:	MOVE	T1, SIXBIT BLOCK NAME
;	MOVE	T2, TEXT STRING ADDRESS
;	PUSHJ	P,RDNMSG
;	<RETURN>

RDNMSG:	PUSH	P,T1		;SAVE BLOCK NAME
	PUSH	P,T2		;SAVE TEXT ADDRESS
	MOVEI	T1,[ASCIZ /% /]	;START OF MESSAGE
	PUSHJ	P,ICONM##	;PRINT IT
	MOVE	T2,UDBNAM(U)	;GET UNIT NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,PRSPC##	;SEPARATOR
	MOVEI	T1,[ASCIZ /first /] ;ASSUME ERROR ON FIRST BLOCK
	SKIPE	WHICH		;SECOND BLOCK?
	JRST	RDNMS1		;NO
	HLLOS	REDERR		;INDICATE ERROR ON SECOND BLOCK
	SKIPA	T1,[[ASCIZ /second /]]

RDNMS1:	HRROS	REDERR		;INDICATE ERROR ON FIRST BLOCK
	PUSHJ	P,CONMES##	;PRINT TEXT
	POP	P,T2		;GET BLOCK NAME
	CAMN	T2,['SAT   ']	;IF THIS WAS A "RIB" BLOCK
	MOVSI	T2,'RIB'	; TYPE "RIB" INSTEAD OF "SAT"
	PUSHJ	P,PRNAME##	;PRINT NAME
	POP	P,T1		;GET TEXT BACK
	PUSHJ	P,CONMES##	;PRINT IT
	PJRST	CRLFOP##	;APPEND A CRLF AND OUTPUT


WHICH:	0			;FLAG TO INDICATE FIRST OR SECOND BLOCK READ
REDERR:	0			;ERROR WORD FOR REDRUN
				; RH=-1 IF ERROR ON SECOND BLOCK
				; LH "  "    "   "  FIRST    "
SUBTTL	DISK READING -- TRYHOM - CHECK HOME BLOCKS


;ROUTINE TO READ AND VERIFY THE HOME BLOCKS, AND SET UP THE
;IN-CORE DATA BASE
;CALL:	PUSHJ	P,TRYHOM
;	  <NON-SKIP>		;OFFLINE OR UNUSABLE
;	<SKIP>			;HOME BLOCKS OK

TRYHOM:	PUSHJ	P,GTHOM		;GET "HOME" BLOCK INTO CORE
	  CAIA			;ERRORS ON BOTH HOME BLOCKS - T2 NON-ZERO
	JRST	TRYHO1		;AT LEAST ONE HOME BLOCK OK
	SETZM	HOMSIC##(P1)	;0 SATS IN CORE (FLAG FOR BAD HOME BLOCKS)
	MOVEI	T1,UNVNPM	;SET STATUS TO NO PACK MOUNTED
	DPB	T1,UNYUST##	;STORE UNIT STATUS
	JRST	CPOPJ1##	;UNIT OK FOR I/O

TRYHO1:	PUSH	P,T2		;SAVE FLAG
	PUSHJ	P,CHKVSY	;DO WE UNDERSTAND THIS PACK?
	  JRST	TRYHO2		;YES
	PUSH	P,T1		;SAVE PACK TYPE
	MOVE	T1,UDBNAM(U)	;GET UNIT NAME
	MOVEI	T2,[ASCIZ /foreign pack mounted (considered offline)/]
	PUSHJ	P,UWARN		;PRINT MESSAGE
	MOVEI	T1,[ASCIZ /  Type = /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	POP	P,T1		;GET PACK TYPE BACK
	PUSHJ	P,CONMES##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	JRST	TPOPJ##		;PHASE STACK AND INDICATE OFFLINE

TRYHO2:	POP	P,T2		;RESTORE HOME BLOCK FLAG
	SKIPE	T2		;EITHER HOME BLOCK BAD?
	PUSHJ	P,SETCHG	;YES, MARK TO REWRITE THEM
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	CAIE	T2,TYPDP	;SKIP IF RP10
	JRST	TRYHO3		;NOT RP10 PROCEED
	LDB	T1,UNYUTP##	;GET UNIT TYPE TO MAKE SURE PACK IS
	CAIN	T1,2		; COMPATIBLE, SKIP IF RP03
	CAMN	T1,HOMUTP##(P1)	;SINCE RP03 DRIVE CAN READ RP02 PACKS
	JRST	TRYHO3		;PACK WRITTEN BY RP03, PROCEED
	MOVE	T1,UDBNAM(U)	;GET UNIT NAME
	MOVEI	T2,[ASCIZ /is an RP03 drive but pack written on an RP02/]
	PUSHJ	P,UWARN		;PRINT MESSAGE
	POPJ	P,		;INDICATE OFFLINE

TRYHO3:	PUSHJ	P,MOVUNI	;MOVE PARAMS FROM HOM BLOCK TO UNIT DATA BLOCK
	MOVEI	P2,0		;SET STR DB ADR. = 0 IN CASE NO STR FOUND
	SKIPN	DSKSET##	;DO WE NOTICE DISK SETS?
	JRST	TRYHO4		;NO, BYPASS CHECKS ON SET NUMBER
	LDB	T1,HOYSET##	;GET SET NUMBER THIS STRUCTURE BELONGS TO
	JUMPE	T1,TRYHO4	;SPECIAL CASE OF THE "ALL" SET
	MOVE	T2,BITTBL##-1(T1) ;GET THE APPROPRIATE BIT
	CAIG	T1,^D36		;IN THE "NO" SET?
	TDNN	T2,DSKSET##	;WANT TO MOUNT THIS STRUCTURE AT ONCE TIME?
	SKIPA			;NO, THEN DON'T SET UP SDB
	JRST	TRYHO4		;PROCEED
	MOVE	T1,HOMSNM##(P1)	;GET STR NAME FROM HOME BLOCK
	CAMN	T1,DDTDSK##	;IF WE WANT THIS DISK FOR DEBUGGING,
	JUMPN	T1,TRYHO4	;IGNORE ITS DISK SET
	MOVSI	T1,UNPNMU	;GET THE TEMPORARY BIT
	IORM	T1,UNIDES(U)	;SET IN THE UNIT DATA BLOCK
	JRST	TRYHO7		;INDICATE NO STRUCTURE MOUNTED

TRYHO4:	MOVE	T1,HOMSNM##(P1)	;GET STR NAME FROM HOME BLOCK
	JUMPE	T1,TRYHO5	;DON'T LOOK FOR OR CREATE A ZERO STR NAME
	PUSHJ	P,FNSTR		;FIND STR(IF IT EXISTS)
	  CAIA			;NOT FOUND--MUST CREATE A NEW STR DB
	JRST	TRYHO5		;FOUND
	PUSHJ	P,GETSTR	;CREATE STR DATA BLOCK IN UPPER CORE
	  JRST	TRYHO6		;ATTEMPT TO CREATE MORE STR'S THAN ALLOWED
	PUSHJ	P,MOVSTR	;MOVE PARAMS FROM HOM BLOCK TO STR DATA BLOCK

TRYHO5:	MOVE	P4,UNIBPU(U)	;UNIT SIZE
	CAMLE	P4,STRBPU##(P2)	;BIGGEST UNIT IN STR?
	MOVEM	P4,STRBPU##(P2)	;YES, SAVE NEW SIZE
	PUSHJ	P,LNKSTR	;LINK ALL UNITS IN THIS STR
	PUSHJ	P,CRESAB	;CREATE SAB RING AND SPT TABLE
	PUSHJ	P,VALMFD	;VALIDATE THE MFD
	JRST	CPOPJ1##	;RETURN

TRYHO6:	SETOM	ERRHOM		;INDICATE ERROR READING HOM BLOCKS
TRYHO7:	SETOM	UNISUN(U)	;INDICATE UNIT NOT IN ASL
	SETZM	UNILOG(U)	;INDICATE UNIT NOT IN AN STR
	JRST	CPOPJ1##	;RETURN
SUBTTL	DISK READING -- TRYKON - CHECK KONTROLLER STATUS


;ROUTINE TO SEE IF KONTROLLER IS OFFLINE, ETC.
;CALL:	PUSHJ	P,TRYKON
;	  <NON-SKIP>		;OFFLINE OR UNUSABLE
;	<SKIP>			;ONLINE AND READY FOR I/O

TRYKON:	MOVSI	T1,KOPDWN	;BIT TO TEST
	TDNE	T1,KONDWN(J)	;ALREADY MARKED AS DOWN?
	POPJ	P,		;YES
	MOVE	J,UDBKDB(U)	;RESET J
	XCTCPU	(UNI,CHKKON)	;GET KONTROLLER ON/OFF-LINE STATUS
	  JRST	TRYKO1		;DOWN
	JUMPN	T1,CPOPJ1##	;KONTROLLER IS OK
	JRST	TRYKO2		;IT'S SET WRONG

TRYKO1:	MOVE	T1,KDBNAM(J)	;GET KONTROLLER NAME
	MOVEI	T2,[ASCIZ /is offline/]
	PUSHJ	P,KWARN		;PRINT WARNING
	MOVSI	T1,KOPDWN	;KONTROLLER DOWN BIT
	IORM	T1,KONDWN(J)	;FLAG KONTROLLER AS DOWN
	POPJ	P,		;RETURN INDICATING DOWN KONTROLLER

TRYKO2:	MOVSI	T1,KOPWHL	;BIT TO TEST
	TDNE	T1,KONUPA(J)	;ALREADY CHECKED WRITE-HEADER-LOCKOUT?
	JRST	CPOPJ1##	;YES--NO MORE CHATTER
	MOVE	T1,KDBNAM(J)	;GET KONTROLLER NAME
	MOVEI	T2,[ASCIZ /write-header-lockout switch allows writing headers/]
	PUSHJ	P,KWARN		;PRINT WARNING
	JRST	CPOPJ1##	;AND RETURN
SUBTTL	DISK READING -- TRYQST - CHECK QUEUE STRUCTURE


TRYQST:	SKIPN	T1,QUESTR##	;GET PRESET STR NAME
	JRST	TRYQS1		;NONE SELECTED
	MOVE	T2,STRAOB##	;SEE IF IT EXISTS
	CAME	T1,@TABSTR##(T2) ;STRNAM IS FIRST WORD
	AOBJN	T2,.-1		;LOOK AT ALL STRS
	JUMPL	T2,CPOPJ##	;RETURN IF A MATCH

TRYQS1:	MOVE	T1,TABST0##	;ADR. OF FASTEST FILE STRUCTURE
	MOVE	T1,STRNAM##(T1)	;FILE STRUCTURE NAME
	MOVEM	T1,QUESTR##	;STORE FOR QUEUEING CUSPS GETTAB UUO
	POPJ	P,		;RETURN
SUBTTL	DISK READING -- TRYUNI - CHECK UNIT STATUS


;ROUTINE TO SEE IF UNIT IS OFFLINE, ETC.
;CALL:	PUSHJ	P,TRYUNI
;	  <NON-SKIP>		;OFFLINE OR UNUSABLE
;	<SKIP>			;ONLINE AND READY FOR I/O

TRYUNI:	MOVSI	T1,UNPOFL	;BIT TO TEST
	TDNE	T1,UNIDES(U)	;IS UNIT OFF-LINE OR DOWN?
	POPJ	P,		;JUST RETURN
	XCTCPU	(UNI,CHKCPY)	;CHECK CAPACITY OF UNIT
	  JRST	TRYUN1		;DON'T DISTURB DATA SETUP BY AUTCON
	MOVEM	T1,UNIBPU(U)	;BLOCKS PER UNIT (REGULAR)
	MOVEM	T2,UNIBPM(U)	;BLOCKS PER UNIT INCL. MAINT CYLS
	MOVEM	T3,UNIBUC(U)	;BLOCKS PER UNIT IN COMPAT. MODE
	DPB	W,UNYBPY##	;BLOCKS PER CYLINDER
	HLRZ	T3,W		;BLOCKS PER TRACK
	DPB	T3,UNYBPT##	;STORE # OF BLOCKS PER TRACK ON THIS UNIT
	DPB	T4,UNYUTP##	;STORE UNIT TYPE #

TRYUN1:
IFN FTDUAL,<
	HRRZ	W,UNIALT(U)	;SAVE UNIALT TO CHECK IF THIS IS FIRST UNIT
	PUSHJ	P,MATUN##	;ANY OTHER DRIVE WITH SAME SERIAL NUMBER?
	  JRST	TRYUN2		;NO
	JUMPE	W,TRYUN2	;IF FIRST UNIT, DON'T NUKE IT, WAIT FOR SECOND
	HLRZ	T1,UNISYS(U)	;GET LINK TO NEXT UNIT BEFORE CALLING LN2ND
	PUSH	P,T1		;(CAN'T TRUST UNISYS AFTER UNIT UNLINKED)
	PUSHJ	P,LN2ND##	;SETUP UNI2ND & UNLINK ALT PORT FROM UNISYS
	POP	P,U		;NEW UNIT TO RESUME WITH
	TLNE	T4,KOPNSU!KOPUHE ;NO SUCH UNIT OR UNIT HAD ERRORS?
	POPJ	P,		;SAY DRIVE IS UNUSABLE
	JRST	CPOPJ1##	;ELSE STOP PROCESSING ON THIS UNIT
> ;END IFN FTDUAL

TRYUN2:	TLNE	T4,KOPNSU!KOPUHE ;NO SUCH UNIT OR UNIT HAD ERRORS?
	POPJ	P,		;SAY DRIVE IS UNUSABLE
	MOVSI	T1,UNPHWP	;GET HWP BIT
	ANDCAM	T1,UNIDES(U)	;CLEAR IT
	DPB	T1,UNYAWL##	;CLEAR SOFTWARE WRITE-LOCKED
	XCTCPU	(UNI,CHKWLK)	;SEE IF UNIT IS WRITE ENABLED
	  JRST	TRYUN3		;IT IS
	MOVEI	T2,[ASCIZ /is hardware write protected/]
	LDB	T1,UNYAWL##	;DID SOFTWARE WRITE-LOCK SET?
	SKIPE	T1		; TEST
	MOVEI	T2,[ASCIZ /is read-only/] ;CHANGE MESSAGE IF SO
	MOVE	T1,UDBNAM(U)	;GET UNIT NAME
	PUSHJ	P,UWARN		;PRINT MESSAGE
	MOVSI	T1,UNPHWP	;HARDWARE WRITE-PROTECT BIT
	IORM	T1,UNIDES(U)	;FLAG UNIT AS WRITE PROTECTED

TRYUN3:	LDB	T1,UNYUST##	;GET CURRENT STATE
	PUSH	P,T1		;SAVE MOMENTARILY
	LDB	T1,UNYKTP##
	CAIE	T1,TYPRP	;IF THIS IS AN RP04
	JRST	TRYUN4		;NOPE
	MOVEI	T1,UNVPIM	;IF WE READ HOME BLOCKS
	DPB	T1,UNYUST##	;A PACK MUST BE MOUNTED
	MOVEI	T2,0		;FORMAT ERROR CAN ONLY BE DETECTED
	PUSHJ	P,OMNRED	; ON SECTOR 0, SO READ IT
	  TRNE	S,IODTER	;IODTER = IODERR = 1
	TRNN	S,IODERR	; MEANS FORMAT ERROR (PDP-11 PACK)
	JRST	TRYUN4		;ALL IS WELL SO FAR
	MOVE	T1,UDBNAM(U)	;GET UNIT NAME
	MOVEI	T2,[ASCIZ /contains a PDP-11 pack (considered offline)/]
	PUSHJ	P,UWARN		;PRINT MESSAGE
	POP	P,T1		;GET OLD STATE BACK
	DPB	T1,UNYUST##	;RESET IT
	POPJ	P,		;INDICATE OFFLINE

TRYUN4:	POP	P,T1		;GET OLD STATE BACK
	DPB	T1,UNYUST##	;RESET IT
	JRST	CPOPJ2##	;UNIT IS READY FOR I/O
SUBTTL	DISK-SET PROCESSING -- CHGSET - CHANGE


CHGSET::PUSHJ	P,SAVE1##	;SAVE P1
	SETZ	P1,		;GET A ZERO INITIALLY (ALL SETS)
	MOVEI	T1,SETTXT	;PROMPT STRING
	PUSHJ	P,ICONM##	;START THE MESSAGE
	PUSHJ	P,OPOUT##	;PUSH OUTPUT OUT

CHGSE1:	PUSHJ	P,GETLIN##	;GET OPERATOR'S RESPONSE
	  JRST	CHGSE3		;DONE
	PUSHJ	P,DECIN##	;READ RESPONSE
	  JRST	CHGSE4		;BAD RESPONSE
	  JRST	CHGSE2		;NOT DECIMAL
	CAIL	T2,^D1		;IN RANGE OF 1
	CAILE	T2,^D36		; TO 36?
	JRST	CHGSE4		;NO
	IOR	P1,BITTBL##-1(T2) ;INCLUDE BIT FOR THIS SET NUMBER
	JRST	CHGSE1		;ASK AGAIN

CHGSE2:	PUSHJ	P,CTEXT1##	;TRY FOR A KEYWORD
	CAME	T2,['ALL   ']	;MOUNT ALL DISK-SETS?
	JRST	CHGSE4		;BAD RESPONSE
	MOVEI	P1,0		;ZERO MEANS ALL

CHGSE3:	EXCH	P1,DSKSET##	;STORE NEW VALUE, SAVE OLD
	CAME	P1,DSKSET##	;IF CHANGED,
	JRST	CHGSE5		;GO EVALUATE THE SAFETY OF THIS
	JRST	CPOPJ1##	;RETURN

CHGSE4:	MOVEI	T1,[ASCIZ /% Bad response, try again/]
	PUSHJ	P,CONOUT##	;PRINT THE MESSAGE
	JRST	CHGSE1		;ASK AGAIN

CHGSE5:	SETZ	T1,		;WE WANT THE FIRST ONE
	PUSHJ	P,RFIND		;SEE IF ANY STR NEEDS REFRESHING
	  TRNA			;NO--LOOK FOR CHANGE-FLAGGED UNITS
	JRST	CHGSE6		;YES--GO MAKE SURE
	PUSHJ	P,CHKCHG	;SEE IF NEED TO REWRITE ANY HOM BLOCKS
	  JRST	CHGSE8		;NO--BUT WE NEED TO RE-READ THEM

CHGSE6:	MOVEI	T1,[ASCIZ /HOM blocks need re-writing./]
	PUSHJ	P,CONOUT##	;TYPE A MESSAGE
	MOVEI	T1,[ASCIZ /Re-write HOM blocks/]
	MOVSI	T2,'YES'	;DEFAULT TO KEEP CURRENT CHANGES
	PUSHJ	P,PRSYNQ##	;SEE WHAT THE OPERATOR WANTS
	JUMPE	T1,CHGSE8	;HE'S A BRAVE FOOL
	PUSHJ	P,VFCORE	;CHECK WHAT WE HAVE NOW
	  SKIPE	IGNORE##	;ERRORS--SEE IF WE CARE
	JRST	CHGSE7		;IT'S OK--GO REWRITE THE HOM BLOCKS
	MOVEI	T1,[ASCIZ /Proceed despite errors/]
	MOVSI	T2,'NO '	;GIVE IT A GO
	PUSHJ	P,PRSYNQ##	;ANOTHER CHANCE AT SANITY
	JUMPN	T1,CHGSE7	;THIS ONE'S CRAZY, TOO
	MOVEM	P1,DSKSET##	;PUT THE DISK SET BACK
	MOVEI	T1,[ASCIZ /% Disk set change aborted/]
	PUSHJ	P,CONOUT##	;LET HIM KNOW
	JRST	CPOPJ1##	;RETURN HAPPY

CHGSE7:	PUSHJ	P,GOHOME	;RE-WRITE ALL HOM BLOCKS

CHGSE8:	MOVEI	T1,[ASCIZ /[Re-reading HOM blocks]/]
	SKIPN	.UONCE##	;EXEC MODE WON'T NORMALLY SAY THIS
	PUSHJ	P,CONOUT##	;BUT WE SHOULD FOR THIS CASE
	SETOM	ALTMFL##	;CLAIM THAT ALTMODE WAS TYPED SO WE WILL RE-READ
	PUSHJ	P,ALTM##	;MAKE SURE
	JRST	CPOPJ1##	;AND SUCCEED

SETTXT:	ASCIZ /
Enter the desired disk-set numbers (1 - 36)  or  "ALL"  for  all
disk-sets, one per line.  Terminate list with a blank line.
/
SUBTTL	DISK-SET PROCESSING -- SHWSET - SHOW


SHWSET::PUSHJ	P,SAVE3##	;SAVE SOME ACS
	MOVEI	T1,[ASCIZ /Disk-sets: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVNI	P3,1		;INIT A FLAG
	MOVE	P1,DSKSET##	;GET DISK-SET
	CAME	P1,[EXP -1]	;BOZO TYPE IN ALL 36 SETS?
	JUMPN	P1,SHWSE1	;JUMP IF NOT ALL
	MOVSI	T2,'ALL'	;ALL DISK-SETS
	PUSHJ	P,PRNAME##	;PRINT TEXT
	PJRST	CRLFOP##	;END LINE AND RETURN

SHWSE1:	JFFO	P1,.+1		;FIND FIRST BIT
	ANDCM	P1,BITTBL##(P2)	;CLEAR BIT
	AOJE	P3,SHWSE2	;FIRST TIME THROUGH?
	MOVEI	T1,[ASCIZ /, /]	;NO
	PUSHJ	P,CONMES##	;SEPARATE FROM PREVIOUS

SHWSE2:	MOVEI	T1,1(P2)	;COPY SET NUMBER
	PUSHJ	P,PRTDIG##	;PRINT IT
	JUMPN	P1,SHWSE1	;LOOP IF MORE SETS
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,CRLFOP##	;AN EXTRA CRLF FOR GOOD MEASURE
	JRST	CPOPJ1##	;RETURN
SUBTTL	FILSER CORE INITIALIZATION


FILMEM::MOVE	T1,SYSSIZ##	;GET SYSTEM SIZE INTO T1
	ADDI	T1,CRWDM1##	;MAKE SURE 4 WORD BLOCKS HAVE BOTTOM 2 BITS = 0
	TRZ	T1,CRWDM1##
	MOVEM	T1,SYSSIZ##	;FAKE OUT CALLS TO INICOR
	MOVE	T1,CORNUM##	;NUMBER OF 4-WORD BLOCKS TO GENERATE
	IMULI	T1,CORWDS##	;CONVERT TO WORDS
	PUSHJ	P,INICOR##	;ALLOCATE CORE
	HRLZM	T2,SYSCOR##	;SAVE STARTING ADDRESS
	MOVE	T1,CORNUM##	;GET BLOCK COUNT BACK
	ADDI	T2,CORWDS##	;ADVANCE POINTER
	HRLZM	T2,CORLNK##-CORWDS##(T2) ;SAVE ADDR OF NEXT BLOCK
	SOJG	T1,.-2		;FINISHED YET?
	SETZM	CORLNK##-CORWDS##(T2) ;ZERO LINK TO SIGNAL END OF LIST
	POPJ	P,		;RETURN
SUBTTL	SDL PROCESSING -- CHGSDL - CHANGE


CHGSDL::JRST	DEFSDL		;SAME AS DEFINE
SUBTTL	SDL PROCESSING -- DEFSDL - DEFINE


DEFSDL::PUSHJ	P,SAVE4##	;SAVE AGAINST FNSTR
	PUSH	P,U		;SAVE U
	MOVEI	T1,SDLTXT	;PROMPT STRING
	MOVE	T2,[IFIW SDLVAL] ;ROUTINE TO VALIDATE RESPONSES
	MOVE	T3,[-^D36,,SUDTAB] ;AOBJN POINTER TO STORE RESULTS
	PUSHJ	P,PRSLST##	;PROMPT AND FETCH ANSWERS
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

DEFSD1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STR IN SYSTEM
	JUMPE	P2,DEFSD2	;DONE?
	SKIPL	STRSDL##(P2)	;NOT IN THE SDL?
	PUSHJ	P,CHGSTX	;THEN HOME BLOCKS WILL CHANGE
	SETOM	STRSDL##(P2)	;REMOVE FROM THE SDL
	JRST	DEFSD1		;LOOP FOR ALL STRS

DEFSD2:	MOVE	P1,T1		;GET UPDATED AOBJN POINTER TO TABLE
	PUSH	P,[-1]		;INIT POSITION COUNTER

DEFSD3:	MOVE	T1,(P1)		;GET A STRUCTURE NAME
	PUSHJ	P,FNSTR		;FIND IT
	  JRST	DEFSD4		;CANNOT HAPPEN SINCE NAME WAS VALIDATED
	AOS	T2,(P)		;GET NEXT POSITION NUMBER
	MOVEM	T2,STRSDL##(P2)	;SET POSITION IN STR DB
	PUSHJ	P,CHGSTX	;MARK HOME BLOCKS TO BE REWRITTEN
DEFSD4:	AOBJN	P1,DEFSD3	;LOOP FOR ALL SPECIFIED STRUCTURES
	ADJSP	P,-1		;TOSS JUNK
	SETZM	PRESDL##	;AND OTHER JUNK TOO
	POP	P,U		;RESTORE U
	PJRST	VFCORE		;GO VERIFY INCORE DATA BASE
SUBTTL	SDL PROCESSING -- SHWSDL - SHOW


SHWSDL::PUSHJ	P,SAVE3##	;SAVE SOME ACS
	MOVEI	T1,[ASCIZ /System dump list: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVNI	P1,1		;INIT A FLAG
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR
	MOVEI	P3,6		;SET A COUNTER

SHWSD1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT
	JUMPE	P2,SHWSD3	;DONE?
	SKIPGE	STRSDL##(P2)	;STRUCTURE IN SSL?
	JRST	SHWSD1		;NO
	MOVEI	T1,[ASCIZ /, /]	;PRINT
	AOSE	P1		;FIRST TIME THROUGH?
	PUSHJ	P,CONMES##	; SEPARATOR
	SOJG	P3,SHWSD2	;ROOM ON THE LINE FOR MORE?
	PUSHJ	P,CRLFOP##	;END THIS LINE
	MOVEI	T1,[ASCIZ /                  /]
	PUSHJ	P,ICONM##	;PRINT BLANKS
	MOVEI	P3,6		;RESET COUNTER

SHWSD2:	MOVE	T2,STRNAM##(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	JRST	SHWSD1		;LOOP FOR MORE

SHWSD3:	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,CRLFOP##	;AN EXTRA CRLF FOR GOOD MEASURE
	JRST	CPOPJ1##	;RETURN
SUBTTL	SDL PROCESSING -- MISCELLANEOUS


;VALIDATE AN SDL ENTRY
SDLVAL:	MOVEI	T2,[ASCIZ /does not exist/] ;INCASE OF ERROR
	MOVEI	T3,SYSSTR##-STRSYS## ;SET PREDESSOR
SDLVA1:	HLRZ	T3,STRSYS##(T3)	;LINK TO NEXT STR DB
	JUMPE	T3,SWARN	;END OF CHAIN?
	CAME	T1,STRNAM##(T3)	;KNOWN STRUCTURE?
	JRST	SDLVA1		;TRY ANOTHER
	SKIPE	STRK4C##(T3)	;DOES IT HAVE CRASH SPACE?
	JRST	CPOPJ1##	;RETURN GOODNESS
	MOVEI	T2,[ASCIZ /has no crash space allocated/]
	PJRST	SWARN		;WARN OPERATOR AND RETURN

SDLTXT:	ASCIZ /
Enter names of structures to appear in the system dump list, one
per line.  Terminate list with a blank line./
SUBTTL	SSL PROCESSING -- CHGSSL - CHANGE


CHGSSL::JRST	DEFSSL		;SAME AS DEFINE
SUBTTL	SSL PROCESSING -- DEFSSL - DEFINE


DEFSSL::PUSHJ	P,SAVE4##	;SAVE AGAINST FNSTR
	PUSH	P,U		;SAVE U
	MOVEI	T1,SSLTXT	;PROMPT STRING
	MOVE	T2,[IFIW SSLVAL] ;ROUTINE TO VALIDATE RESPONSES
	MOVE	T3,[-.FSMAX,,SUDTAB] ;AOBJN POINTER TO STORE RESULTS
	PUSHJ	P,PRSLST##	;PROMPT AND FETCH ANSWERS
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

DEFSS1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STR IN SYSTEM
	JUMPE	P2,DEFSS2	;DONE?
	SKIPL	STRSRC##(P2)	;NOT IN THE SSL?
	PUSHJ	P,CHGSTX	;THEN HOME BLOCKS WILL CHANGE
	SETOM	STRSRC##(P2)	;REMOVE FROM THE SSL
	JRST	DEFSS1		;LOOP FOR ALL STRS

DEFSS2:	MOVE	P1,T3		;GET AOBJN POINTER TO LIST OF ANSWERS
	PUSH	P,[-1]		;INIT POSITION COUNTER

DEFSS3:	MOVE	T1,(P1)		;GET A STRUCTURE NAME
	PUSHJ	P,FNSTR		;FIND IT
	  JRST	DEFSS4		;CANNOT HAPPEN SINCE NAME WAS VALIDATED
	AOS	T2,(P)		;GET NEXT POSITION NUMBER
	MOVEM	T2,STRSRC##(P2)	;SET POSITION IN STR DB
	PUSHJ	P,CHGSTX	;MARK HOME BLOCKS TO BE REWRITTEN
DEFSS4:	AOBJN	P1,DEFSS3	;LOOP FOR ALL SPECIFIED STRUCTURES
	ADJSP	P,-1		;TOSS JUNK
	SETZM	PRESSL##	;AND OTHER JUNK TOO
	POP	P,U		;RESTORE U
	PJRST	VFCORE		;GO VERIFY INCORE DATA BASE
SUBTTL	SSL PROCESSING -- DSKSSL - BUILD SSL FROM DISK


DSKSSL:	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	MOVE	T1,[SUDTAB,,SUDTAB+1] ;SET UP BLT
	SETZM	SUDTAB		;CLEAR FIRST WORD
	BLT	T1,SUDTAB+.FSMAX-1 ;CLEAR OUT TABLE
	SETZB	P1,P3		;INIT STRUCTURE & ERROR COUNTERS
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

DSKSS1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STR
	JUMPE	P2,DSKSS2	;DONE?
	SKIPGE	T1,STRSRC##(P2)	;IS THIS STRUCTURE IN THE SSL?
	JRST	DSKSS1		;NO
	SKIPE	SUDTAB(T1)	;ENTRY ALREADY IN USE?
	AOJA	P3,DSKSS2	;ERROR
	MOVE	T2,STRNAM##(P2)	;GET STR NAME
	MOVEM	T2,SUDTAB(T1)	;STORE IN RESPECTIVE SLOT
	AOJA	P1,DSKSS1	;LOOP THROUGH FOR ALL STRS

DSKSS2:	JUMPN	P3,DSKSS5	;JUMP IF MULTIPLE LOGICAL UNITS
	MOVSI	P3,-.FSMAX	;AOBJN POINTER

DSKSS3:	SKIPE	SUDTAB(P3)	;ENTRY IN USE?
	JRST	DSKSS4		;NO
	MOVEI	T1,[ASCIZ /% Missing logical unit /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	HRRZ	T1,(P3)		;GET NUMBER
	PUSHJ	P,PRTDIG##	;PRINT IT
	MOVEI	T1,[ASCIZ / in the system search list/]
	PUSHJ	P,CONMES##	;PRINT TEXT

DSKSS4:	CAIL	P1,(P3)		;CHECK ALL ENTRIES YET?
	AOBJN	P3,DSKSS3	;LOOP FOR MORE
	JUMPN	P1,CPOPJ##	;NO--RETURN IF FOUND AT LEAST ONE STR
	MOVEI	T1,[ASCIZ/% No structures in system search list/]
	PUSHJ	P,CONOUT##	;PRINT MESSAGE AND RETURN
	AOS	SERIUS		;CALL THIS A SERIOUS ERROR
	POPJ	P,		;AND GIVE UP

DSKSS5:	MOVEI	T1,DSKSST	;POINT TO HEADER
	PUSHJ	P,CONOUT##	;PRINT MESSAGE
	AOS	SERIUS		;CALL THIS A SERIOUS ERROR
	SETZ	P1,		;INIT A COUNTER
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

DSKSS6:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT STRUCTURE
	JUMPE	P2,CPOPJ##	;DONE?
	SKIPGE	STRSRC##(P2)	;IN THE SSL?
	JRST	DSKSS6		;NO
	MOVEI	T1,[ASCIZ /	  /]
	PUSHJ	P,CONMES##	;SPACE OVER
	MOVE	T2,STRNAM##(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /		   /]
	PUSHJ	P,CONMES##	;SPACE OVER
	MOVE	T1,STRSRC##(P2)	;GET POSITION IN THE SSL
	MOVEI	T2,^D2		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	JRST	DSKSS6		;LOOP BACK FOR MORE

DSKSST:	ASCIZ	\
% System search list errors:
	Structure	Position
	---------	--------\
SUBTTL	SSL PROCESSING -- SHWSSL - SHOW


SHWSSL::PUSHJ	P,SAVE3##	;SAVE SOME ACS
	MOVE	T1,[SUDTAB,,SUDTAB+1] ;SET UP BLT
	SETZM	SUDTAB		;CLEAR FIRST WORD
	BLT	T1,SUDTAB+.FSMAX-1 ;CLEAR TABLE
	MOVE	T1,[POSTAB,,POSTAB+1] ;SET UP BLT
	SETZM	POSTAB		;CLEAR FIRST WORD
	BLT	T1,POSTAB+.FSMAX-1 ;CLEAR TABLE
	MOVSI	P1,-.FSMAX	;AOBJN POINTER
	MOVEI	P2,SYSSTR##-STRSYS## ;SET PREDESSOR

SHWSS1:	HLRZ	P2,STRSYS##(P2)	;LINK TO NEXT
	JUMPE	P2,SHWSS2	;DONE?
	SKIPGE	T1,STRSRC##(P2)	;STRUCTURE IN SSL?
	JRST	SHWSS1		;NO
	MOVEM	T1,POSTAB(P1)	;SAVE POSITION
	MOVE	T2,STRNAM##(P2)	;GET STRUCTURE NAME
	MOVEM	T2,SUDTAB(P1)	;STORE IN RESPECTIVE SLOT
	AOBJN	P1,SHWSS1	;LOOP FOR MORE

SHWSS2:	MOVEI	T1,SHWSST	;POINT TO HEADER
	PUSHJ	P,CONOUT##	;PRINT TEXT
	MOVSI	P1,-.FSMAX	;AOBJN POINTER

SHWSS3:	SKIPN	SUDTAB(P1)	;GET A NAME
	JRST	SHWSS4		;EMPTY SLOT
	MOVEI	T1,[ASCIZ /	  /]
	PUSHJ	P,ICONM##	;SPACE OVER
	MOVE	T2,SUDTAB(P1)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /		   /]
	PUSHJ	P,CONMES##	;SPACE OVER
	MOVE	T1,POSTAB(P1)	;GET POSITION
	MOVEI	T2,^D2		;COLUMN COUNT
	PUSHJ	P,NUMTYP	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

SHWSS4:	AOBJN	P1,SHWSS3	;LOOP FOR MORE
	PUSHJ	P,CRLFOP##	;END LINE
	JRST	CPOPJ1##	;RETURN

SHWSST:	ASCIZ	\
System search list:
	Structure	Position
	---------	--------\
SUBTTL	SSL PROCESSING -- MISCELLANEOUS


;VALIDATE AN SSL ENTRY
SSLVAL:	MOVEI	T2,[ASCIZ /does not exist/] ;INCASE OF ERROR
	MOVEI	T3,SYSSTR##-STRSYS## ;SET PREDESSOR
SSLVA1:	HLRZ	T3,STRSYS##(T3)	;LINK TO NEXT STR DB
	JUMPE	T3,SWARN	;END OF CHAIN?
	CAME	T1,STRNAM##(T3)	;KNOWN STRUCTURE?
	JRST	SSLVA1		;TRY ANOTHER
	JRST	CPOPJ1##	;RETURN GOODNESS

SSLTXT:	ASCIZ /
Enter names of structures to appear in the system  search  list,
one per line.  Terminate list with a blank line./
SUBTTL	STARTUP OPTION -- COMMON TEXT


INTRO:	ASCIZ \
In the  following  dialogue,  all  numbers  are  decimal  unless
otherwise  indicated.   Values  within  parenthesis are options.
Values  within  square  brackets  are  defaults  which  will  be
substituted if RETURN is pressed.\


REFPRM:	ASCIZ	\
Any question preceeded with an asterisk indicates changing  that
parameter will require the structure to be refreshed.
\

INIMSG:	ASCIZ	\
                          *** Note ***
HOME blocks will be initialized immediately after all  units  in
the structure have been entered.

\
GETUNM:	MOVEI	P3,STRUNI##(P2)	;SET PREDESSOR UDB
	SETZ	P1,

GETUN1:	PUSHJ	P,PRSSET##	;SET UP SPECIAL BUFFER, .CPTOA, ETC.
	PUSH	P,T1		;SAVE OLD CHARACTER TYPER
	MOVEI	T1,[ASCIZ /Disk drive for logical unit /]
	PUSHJ	P,CONMES##	;STORE IN BUFFER
	MOVE	T1,STRUNM##(P2)	;GET COUNT SO FAR
	PUSHJ	P,PRTDI8##	;STORE IN BUFFER
	POP	P,.CPTOA##	;RESTORE CHARACTER STICKER

GETUN2:	MOVEI	T1,TXTBUF##	;POINT TO PROMPT STRING
	SETZ	T2,		;NO DEFAULT DISK DRIVE
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	SKIPE	T2,T1		;COPY TO A DIFFERENT PLACE
	JRST	GETUN3		;AND GO CHECK IT OUT
	SKIPE	STRUNM##(P2)	;ANY UNITS IN THIS STRUCTURE?
	JRST	CPOPJ1##	;YES--SO ALL DONE
	MOVE	T1,STRNAM##(P2)	;GET STR NAME
	MOVEI	T2,[ASCIZ /has no logical units/]
	PUSHJ	P,SWARN		;WARN OPERATOR
	POPJ	P,		;BUT LET HIM OUT

GETUN3:	HLRZ	U,SYSUNI##	;GET FIRST UNIT DATA BLOCK IN SYSTEM
GETUN4:	CAME	T2,UNIHID(U)	;ACCEPT MATCH ON UNIT ID
	CAMN	T2,UDBNAM(U)	;MATCH?
	JRST	GETUN5		;YES
	HLRZ	U,UNISYS(U)	;GET NEXT UNIT DATA BLOCK ADR. IN SYSTEM
	JUMPN	U,GETUN4	;REPEAT IF THERE IS ONE
	MOVEI	T2,[ASCIZ /does not exist/]
	PUSHJ	P,UWARN		;WARN OPERATOR
	JRST	GETUN2		;TRY AGAIN

GETUN5:	PUSHJ	P,CKUSTR	;MAKE SURE IT'S NOT PART OF A MOUNTED STRUCTURE
	  JRST	GETUN2		;TRY AGAIN IF IT IS
	HRRZ	T1,UNISTR(U)	;SEE IF THIS UNIT IS ALREADY IN AN STR
	JUMPE	T1,GETUN6	;T1 = 0 IF IT ISN'T
	MOVE	T1,UDBNAM(U)	;GET DRIVE NAME
	MOVEI	T2,[ASCIZ /is part of an existing structure/]
	PUSHJ	P,UWARN		;ISSUE WARNING TO OPERATOR
	JRST	GETUN2		;AND TRY AGAIN

GETUN6:	PUSHJ	P,INSUN1	;NO - JUST PUT THIS UNIT INTO THE STR
	  JRST	GETUN2		;UNIT ALREADY IN A STRUCTURE
	PUSHJ	P,HGHSIZ	;COMPUTE STRHGH & STRSIZ FOR THIS STR
	MOVE	T1,STRNAM##(P2)	;GET STRUCTURE NAME
	CAME	T1,['KLAD  ']	;IS IT THE DIAGNOSTICS PACK?
	JRST	GETUN1		;NO - GET THE NEXT UNIT
	JRST	CPOPJ1##	;YES - WE'RE DONE WITH ONE UNIT
;INITIALIZE BAT BLOCKS
INIBAT:	PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,P4		;SAVE P4
	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	PUSHJ	P,GTMNB1	;GET MONITOR BUFFER
	AOS	P1,T1		;SAVE ADDRESS
	HRRZS	P1		;NO JUNK IN LH
	MOVE	T1,P1		;COPY BUFFER ADDRESS
	HRLS	T1		;PUT IN LH TOO
	AOS	T1		;MAKE A BLT POINTER
	SETZM	(P1)		;CLEAR FIRST WORD
	BLT	T1,BLKSIZ##-1(P1) ;CLEAR ENTIRE BUFFER
	MOVSI	T1,'BAT'	;NAME
	MOVEM	T1,BLKNAM##(P1)
	MOVEI	T1,CODBAT	;UNIQUE CODE
	MOVEM	T1,BLKCOD##(P1)
	MOVSI	T1,MBRMAX##	;SETUP AOBJN PTR. TO BE STORED IN BLOCK
	HRRI	T1,BAFREG##	;ORIGIN OF FIRST BAD REGION
	MOVEM	T1,BAFFIR##(P1)
	MOVE	J,UDBKDB(U)	;GET KDB ADDRESS
	MOVE	T1,KDBDVC(J)	;AND DEVICE CODE FOR THE KONTROLLER
	DPB	T1,BAYKDC##	;SAVE IT IN THE BLOCK
	MOVE	P4,[LBOBAT##,,LBOBAT##] ;FIRST,,SECOND BAT BLOCK NUMBERS
	ADD	P4,UNIHOM(U)	;OFFSET TO BAT BLOCKS
	PUSHJ	P,WRTRUN	;WRITE BOTH BAT BLOCKS
	  SETZ	P1,		;INDICATE FAILURE
	PUSHJ	P,GVMNB0	;RETURN MONITOR BUFFER
	PUSHJ	P,GVODDB	;RETURN ONCE DDB
	POP	P,P4		;RESTORE P4
	JUMPE	P1,CPOPJ##	;RETURN ON ERRORS
	MOVEI	T1,[ASCIZ /[BAT blocks initialized on /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET DRIVE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /]/]	;END MESSAGE
	PUSHJ	P,CONMES##	;PRINT IT
	PJRST	CRLFOP##	;END LINE AND RETURN
;INITIALIZE HOME BLOCKS
INIHOM:	PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,T1		;SAVE TYPEOUT FLAG
	PUSH	P,P4		;SAVE P4
	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	PUSHJ	P,GTMNB1	;GET MONITOR BUFFER
	AOS	P1,T1		;SAVE ADDRESS
	HRRZS	P1		;NO JUNK IN LH
	MOVE	T1,P1		;COPY BUFFER ADDRESS
	HRLS	T1		;PUT IN LH TOO
	AOS	T1		;MAKE A BLT POINTER
	SETZM	(P1)		;CLEAR FIRST WORD
	BLT	T1,BLKSIZ##-1(P1) ;CLEAR ENTIRE BUFFER
	MOVSI	T1,'HOM'	;NAME
	MOVEM	T1,BLKNAM##(P1)
	MOVEI	T1,CODHOM	;UNIQUE CODE
	MOVEM	T1,BLKCOD##(P1)
	MOVE	P4,[LBNHOM##,,LB2HOM##] ;FIRST,,SECOND HOME BLOCK NUMBERS
	MOVEM	P4,HOMHOM##(P1)
	SETOM	HOMSUN##(P1)	;INDICATE UNIT NOT IN ASL
	SETOM	HOMSRC##(P1)	;INDICATE STR NOT IN SSL
	SETOM	HOMSDL##(P1)	;INDICATE STR NOT IN SDL
	LDB	T1,UNYUTP##
	MOVEM	T1,HOMUTP##(P1)	;SET RIGHT UNIT IN HOME BLOCK
	PUSHJ	P,WRTVID	;SETUP SYSTEM TYPE IN FUNNY FORMAT
	PUSHJ	P,WRTRUN	;WRITE BOTH "HOME" BLOCKS
	  SETZ	P1,		;INDICATE ERRORS
	PUSHJ	P,GVMNB0	;RETURN MONITOR BUFFER
	PUSHJ	P,GVODDB	;RETURN ONCE DDB
	POP	P,P4		;RESTORE P4
	JUMPE	P1,TPOPJ##	;RETURN ON ERRORS
	POP	P,T1		;GET FLAG BACK
	JUMPE	T1,CPOPJ##	;RETURN IF NO TYPEOUT WANTED
	MOVEI	T1,[ASCIZ /[HOM blocks initialized on /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET DRIVE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /]/]	;END MESSAGE
	PUSHJ	P,CONMES##	;PRINT IT
	PJRST	CRLFOP##	;END LINE AND RETURN
SUBTTL	STARTUP OPTION -- .DESTR - DESTROY


.DESTR::MOVEI	T1,[ASCIZ/
% WARNING:  All structures will be refreshed.  All disk files
will be destroyed.  All information on currently spinning packs
will be lost.  Do not proceed unless you are positive that you
want to do this./]
	PUSHJ	P,CONOUT##	;PRINT WARNING
	MOVEI	T1,[ASCIZ /Proceed/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	HLRZ	U,SYSUNI##	;FIRST UNIT IN SYSTEM

DESTR1:	PUSHJ	P,DELSAB	;DELETE SAB RING AND SPT TABLE
	MOVSI	T1,UNPOFL!UNPHWP ;BITS WHICH MAKE THIS UNIT USELESS
	TDNE	T1,UNIDES(U)	;ANY CHANCE OF USING THIS ONE?
	JRST	DESTR2		;NOPE
	MOVEI	T1,0		;CODE FOR SILENT INITIALIZATION
	PUSHJ	P,INIHOM	;INITIALIZE HOME BLOCKS
	MOVEI	T1,1		;CODE FOR MANDATORY INIT OF BAT BLOCKS
	PUSHJ	P,GETBAT	;CHECK OUT BAT BLOCKS
	  PUSHJ	P,INIBAT	;NEED TO INITIALIZE BAT BLOCKS
	MOVSI	T1,UNPCHG
	ANDCAM	T1,UNIDES(U)	;CLEAR OUT UNPCHG
DESTR2:	HLRZ	U,UNISYS(U)	;NEXT UNIT
	JUMPN	U,DESTR1	;UNITS ARE LEFT-GO FOR MORE
	MOVEI	T1,[ASCIZ /[HOME blocks initialized on all units]/]
	PUSHJ	P,CONOUT##	;PRINT MESSAGE
	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	PUSHJ	P,GVMNB0	;GIVE BACK MONITOR BUFFER
	PUSHJ	P,RDDISK	;READ THE DISKS AGAIN
	  JFCL			;IGNORE ERRORS
	PUSHJ	P,REDBAT	;READ BAT BLOCKS ALSO
	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	JRST	CPOPJ1##	;RETURN
SUBTTL	STARTUP OPTION -- .DISSO - DISOLVE STRUCTURE


.DISSO::MOVEI	T1,[ASCIZ /Structure to dissolve/]
	SETZ	T2,		;NO DEFAULT STRUCTURE NAME
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	JUMPE	T1,VFCORE	;GO VERIFY INCORE DATA BASE IF NO MORE
	PUSHJ	P,FNSTR		;ALREADY EXIST?
	  SKIPA	T2,[[ASCIZ /does not exist/]]
	JRST	DISSO1		;ONWARD
	PUSHJ	P,SWARN		;WARN OPERATOR
	JRST	.DISSO		;TRY AGAIN

DISSO1:	MOVEI	T1,[ASCIZ /All data will be destroyed.  Are you sure/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;ASK THE OPERATOR
	JUMPE	T1,.DISSO	;QUIT THIS ONE NOW IF "NO"
	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE
	JUMPE	U,DISSO2	;JUST UNLINK STR IF IT HAS NO UNITS
	PUSHJ	P,CKUSTR	;SEE IF WE SHOULD ABORT WITH A MOUNTED STR
	  JRST	.DISSO		;YES--LET HIM TRY WITH ANOTHER
	PUSHJ	P,DISSO3	;GO TAKE CARE OF ALL UNITS IN STR

DISSO2:	HLL	T3,STRSYS##(P2)	;GET NEXT STR DB IN SYSTEM
	HLLM	T3,STRSYS##(P3)	;LINK TO PREDESSOR
	SKIPL	T1,STRSRC##(P2)	;WAS THIS STR IN SSL?
	PUSHJ	P,FIXSSL	;YES, CLOSE UP THE SLOT
	SKIPL	T1,STRSDL##(P2)	;WAS THIS STR IN SDL?
	PUSHJ	P,FIXSDL	;YES, CLOSE UP THE SLOT
	PUSHJ	P,KSTR		;KILL OFF THE STR DB
	JRST	.DISSO		;AND LOOP BACK FOR ANOTHER STRUCTURE

DISSO3:	MOVSI	T1,UNPNNA	;USER-MODE TIMESHARED BIT
	ANDCAM	T1,UNIDES(U)	;DISSOLVE MEANS IT'S TOO LATE TO BE SORRY
	SETZM	UNIHID(U)	;CLEAR OUT LOGICAL UNIT NAME
	SETZB	T3,UNILOG(U)	;CLEAR OUT NAME OF LOGICAL UNIT WITHIN STR
	EXCH	T3,UNISTR(U)	;CLEAR OUT LINKS TO STR & NEXT UNIT DATA BLOCKS
	HLRZS	T3		;PUT IN A BETTER HALF-WORD
	PUSH	P,T3		;AND SAVE FROM IMPENDING DISASTER
	HRRZS	UNIGRP(U)	;CLEAR # CLUSTERS TRIED FOR ON O/P
	PUSHJ	P,DELSST	;RETURN SWAPPING SATS
	PUSHJ	P,DELSAB	;DELETE SAB RING AND SPT TABLE
	MOVEI	T1,0		;GET A ZERO
	DPB	T1,UNYBPC##	;CLEAR # BLOCKS PER CLUSTER
	DPB	T1,UNYSPU##	;SET SPU AND SIC TO ZEROES...
	DPB	T1,UNYSIC##	;SO GETSPU AND GETSIC WILL RECREATE THE SAB
				;IF THIS UNIT IS PUT INTO A NEW STRUCTURE
	PUSHJ	P,SETCHG	;HOME BLOCKS MUST BE REWRITTEN
	POP	P,U		;GET NEXT UNIT IN STRUCTURE BACK
	JUMPN	U,DISSO3	;LOOP BACK IF MORE
	POPJ	P,		;ELSE RETURN
SUBTTL	STARTUP OPTION -- .REFRE - REFRESH


.REFRE::SETZ	T1,		;FIND FIRST STRUCTURE TO REFRESH
	PUSHJ	P,RFIND		;...
	  JRST	REFRE4		;THERE ARE NONE SO JUST PROMPT
	PUSHJ	P,CRLFOP##	;START WITH A CRLF
	MOVEI	T1,[ASCIZ /Needs refreshing: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	JRST	REFRE2		;ENTER LOOP
REFRE1:	SKIPN	P4,TABSTR##(P3)	;GET A STR DB
	JRST	REFRE3		;NONE HERE
	HLLZ	T2,STRREF##(P4)	;NEEDS REFRESHING FLAG
	JUMPE	T2,REFRE3	;NOT THIS ONE

REFRE2:	MOVEI	T1,[ASCIZ /, /]	;SEPARATOR
	CAME	P1,STRNAM##(P4)	;THE FIRST STRUCTURE?
	PUSHJ	P,CONMES##	;NO--SEPARATE FROM PREVIOUS
	MOVE	T2,STRNAM##(P4)	;GET STR NAME
	PUSHJ	P,PRNAME##	;PRINT IT

REFRE3:	AOBJN	P3,REFRE1	;LOOP FOR ALL STRS
	PUSHJ	P,CRLFOP##	;TERMINATE LINE

REFRE4:	SETZ	T1,		;WANT FIRST NEEDING TO BE REFRESHED
	PUSHJ	P,RFIND		;LOOK FOR A STR
	  SETZ	T1,		;NONE NEED REFRESHING
	MOVE	T2,T1		;LOAD UP DEFAULT STRUCTURE NAME
	MOVEI	T1,[ASCIZ /Structure to refresh/]
	PUSHJ	P,PRSSIX##	;ASK OPERATOR
	JUMPE	T1,VFCORE	;GO VERIFY INCORE DATA BASE IF NO MORE
REFRE5:	PUSHJ	P,RFIND		;MAKE SURE REQUESTED STR REALLY EXISTS
	  SKIPA	T2,[[ASCIZ /does not exist/]]
	JRST	REFRE6		;ONWARD
	PUSHJ	P,SWARN		;WARN THE OPERATOR
	JRST	REFRE4		;LET THE FOOL TRY AGAIN

REFRE6:	HLLZ	T2,STRREF##(P2)	;IF STR NEEDS REFRESHING
	JUMPN	T2,REFRE7	; DON'T ASK IF HE IS SURE
	MOVEI	T1,[ASCIZ /Structure does not need refreshing.  Are you sure/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;ASK THE OPERATOR
	JUMPE	T1,REFRE4	;CAN'T MAKE UP HIS MIND
	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE
	PUSHJ	P,CKUSTR	;MAKE SURE IT'S NOT MOUNTED
	  JRST	REFRE4		;LET HIM OUT OF THIS ONE
	SKIPGE	STRSDL##(P2)	;STR IN THE SDL?
	SKIPL	STRSRC##(P2)	;OR THE SSL?
	SKIPA	T1,[[ASCIZ /This is a system structure.  Are you positive/]]
	JRST	REFRE7		;NOT IN SYS SEARCH LIST. DO IT
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;ASK THE OPERATOR
	JUMPE	T1,REFRE4	;WIMP

REFRE7:	PUSHJ	P,GTMNB1	;GET A MONITOR BUFFER
	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE

REFR10:	MOVSI	T1,UNPHWP!UNPOFL ;WRITE-PROTECT OR OFFLINE
	TDNN	T1,UNIDES(U)	;CHECK SUCH BADNESS
	JRST	REFR11		;NOT A PROBLEM--KEEP LOOKING
	MOVE	T1,UDBNAM(U)	;GET UNIT NAME
	MOVEI	T2,[ASCIZ /is off-line or hardware write-protected/]
	PUSHJ	P,UWARN		;COMPLAIN ABOUT THE UNIT
	MOVE	T1,STRNAM##(P2)	;GET STR NAME
	MOVEI	T2,[ASCIZ /cannot be refreshed/]
	PUSHJ	P,SWARN		;THEN COMPLAIN ABOUT THE STRUCTURE
	JRST	REFRE4		;TRY FOR ANOTHER

REFR11:	SKIPN	UNISAB(U)	;IF NO SAB CREATED YET,
	PUSHJ	P,CRESAB	;DO IT.  REFSTR NEEDS IT.
	MOVSI	T1,UNPCHG	;THE 'CHANGED' BIT
	TDNN	T1,UNIDES(U)	;DID WE CHANGE ANYTHING?
	JRST	REFR12		;NO--NO NEED TO RE-WRITE HOM BLOCKS
	PUSHJ	P,HOMWRT	;YES--DO IT
	MOVEI	T1,[ASCIZ /[Updated HOM blocks on unit /]
	PUSHJ	P,ICONM##	;SAY WHAT WE DID
	MOVE	T2,UDBNAM(U)	;GET UNIT NAME
	PUSHJ	P,PRNAME##	;SAY TO WHICH UNIT
	PUSHJ	P,PRRBKC##	;END BRACKET AND LINE
	PUSHJ	P,OPOUT##	;FLUSH THE OUTPUT

REFR12:	HLRZ	U,UNISTR(U)	;GET NEXT UNIT IN STRUCTURE
	JUMPN	U,REFR10	;CHECK ALL UNITS IN THE STRUCTURE

	PUSHJ	P,REFSTR##	;REFRESH STR
	  JRST	REFR13		;GO GIVE ERROR MESSAGE
	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE
	PUSH	P,P2		;SAVE STR DB
	PUSH	P,[EXP -1]	;INIT A FLAG

REFRE8:	PUSHJ	P,DELSST	;CLEAR OUT SOME POSSIBLY STALE DATA
	PUSHJ	P,DELSAB	;IN CASE THE REFRESH WAS FLAWED
	PUSHJ	P,GTHOM		;READ THE HOME BLOCKS
	  JRST	REFRE9		;CAN'T HAPPEN (WE THINK)
	MOVE	P2,-1(P)	;GET STR DB BACK
	AOSN	(P)		;FIRST TIME THROUGH?
	PUSHJ	P,MOVSTR	;UPDATE STR DB FROM HOME BLOCKS
	PUSHJ	P,MOVUNI	;UPDATE CHANGES MADE TO HOME BLOCKS IN UDBS
	PUSHJ	P,CRESAB	;RESTORE SAB RING & SPT
	HLRZ	U,UNISTR(U)	;LINK TO NEXT UNIT IN STRUCTURE
	JUMPN	U,REFRE8	;LOOP FOR MORE UNITS

REFRE9:	ADJSP	P,-2		;PHASE STACK
	MOVEI	T1,[ASCIZ /[Structure /]
	PUSHJ	P,ICONM##	;BEGIN OUR MESSAGE
	MOVE	T2,STRNAM##(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;SAY WHICH STRUCTURE
	MOVEI	T1,[ASCIZ / refreshed]/]
	PUSHJ	P,CONMES##	;SAY WHAT WE DID
	PUSHJ	P,CRLFOP##	;FLUSH THE LINE
	JRST	REFRE4		;ASK FOR ANOTHER STR NAME TO BE REFRESHED

REFR13:	MOVE	T1,STRNAM##(P2)	;GET STR NAME
	MOVEI	T2,[ASCIZ /could not be refreshed/]
	PUSHJ	P,SWARN		;COMPLAIN ABOUT THE PROBLEM
	JRST	REFRE4		;ASK FOR ANOTHER VICTIM
;FIND A STRUCTURE WHICH NEEDS TO BE REFRESHED
;CALL:	MOVE	T1, NAME OR ZERO FOR FIRST STR NEEDING TO BE REFRESHED
;	PUSHJ	P,RFIND
;
;RETURNS WITH P1 = STR NAME & P2 = STR DATA BLOCK ADDRESS

RFIND:	MOVE	P3,STRAOB##	;AOBJN POINTER TO STRUCTURE TABLE
	SETZB	P1,P2		;NO STR NAME OR STR DATA BLOCK YET
RFIND1:	SKIPN	P4,TABSTR##(P3)	;ADDR OF NEXT STR DATA BLOCK
	JRST	RFIND5		;NONE HERE
	JUMPE	T1,RFIND2	;JUMP IF WANT FIRST NEEDING REFRESHING
	CAMN	T1,STRNAM##(P4)	;THE ONE WE WANTED?
	JRST	RFIND3		;YES
RFIND2:	HLLZ	T2,STRREF##(P4)	;NEEDS REFRESHING FLAG
	JUMPE	T2,RFIND5	;NOT THIS ONE
	JUMPE	T1,RFIND3	;USE THIS STRUCTURE IF FIRST REQUESTED
	CAME	T1,STRNAM##(P4)	;THE ONE WE WANTED?
	JRST	RFIND5		;NO
RFIND3:	SKIPN	.UONCE##	;USER MODE?
	JRST	RFIND4		;NO--JUST DO REFRESH
	PUSHJ	P,UCKREF##	;SEE IF MOUNTED UNDER TIMESHARING
	  JRST	RFIND5		;CAN'T REFRESH MOUNTED STRUCTURE
RFIND4:	MOVE	P1,STRNAM##(P4)	;SET IT UP
	MOVE	P2,P4		;COPY STR DB ADDRESS
	JRST	CPOPJ1##	;RETURN GOODNESS
RFIND5:	AOBJN	P3,RFIND1	;KEEP SEARCHING
	POPJ	P,		;NO SUCH STR
SUBTTL	STRUCTURE ROUTINES -- CHGSTR - CHANGE


CHGSTR::AOSE	BLURBF		;OPERATOR SEEN THIS TEXT BEFORE?
	JRST	CHGST1		;YES
	PUSHJ	P,PRSCON##	;SEE IF WE WANT THIS CRUFT
	  JRST	CHGST1		;NO--DON'T CLOBBER THE TYPEAHEAD
	MOVEI	T1,INTRO	;INTRODUCTORY TEXT
	PUSHJ	P,CONOUT##	;PRINT IT
	MOVEI	T1,REFPRM	;SPECIAL PARAMETER DISCLAIMER
	PUSHJ	P,CONOUT##	;PRINT IT

CHGST1:	MOVEI	T1,[ASCIZ /Structure to change/]
	SETZ	T2,		;NO DEFAULT
	PUSHJ	P,PRSSIX##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,VFCORE	;GO VERIFY INCORE DATA BASE IF NO MORE
	PUSHJ	P,FNSTR		;FIND STRUCTURE
	  SKIPA	T2,[[ASCIZ /does not exist/]]
	JRST	CHGST2		;FOUND
	PUSHJ	P,SWARN		;WARN OPERATOR
	JRST	CHGSTR		;AND TRY AGAIN

CHGST2:	MOVEI	T1,[ASCIZ /Change unit parameters for this structure/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	MOVEM	T1,UNITFL	;SAVE FLAG
	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE
	PUSHJ	P,CKUSTR	;MAKE SURE WE WANT TO PROCEED IF MOUNTED
	  JRST	CHGSTR		;TRY AGAIN IF NOT
	SKIPN	UNITFL		;IF NOT CHANGING UNITS,
	JRST	CHGST3		;THEN DON'T CHANGE BAT BLOCKS
	MOVEI	T1,[ASCIZ /Do you want to see the BAT blocks/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	MOVEM	T1,BATFLG	;SAVE FOR LATER USE

CHGST3:	MOVEI	T1,[ASCIZ /Parameters for structure /]
	PUSHJ	P,ICONM##	;PRINT MESSAGE
	MOVE	T2,STRNAM(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,GETSTN	;GET NEW NAME
	PUSHJ	P,GETBPC	;GET BLOCKS PER CLUSTER
	PUSHJ	P,GETPRV	;GET PRIVATE STATUS
	PUSHJ	P,GETOPP	;GET OWNER PPN
	PUSHJ	P,GETDSN	;GET DISK-SET NUMBERS
	PUSHJ	P,GETK4C	;GET K FOR CRASH.SAV
	PUSHJ	P,GETOVR	;GET OVERDRAW
	PUSHJ	P,GETGAR	;GET GUARANTEED BLOCKS
	PUSHJ	P,GETGRP	;GET BLOCKS TO TRY FOR ON OUTPUT
	PUSHJ	P,GETCNP	;GET BITS PER CLUSTER COUNT

	SKIPN	UNITFL		;CHANGING UNIT PARAMETERS TOO?
	JRST	CHGST6		;NO
	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
CHGST4:	PUSHJ	P,CRLFOP##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ /Parameters for unit /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,GETUID	;GET UNIT ID
	PUSHJ	P,GETSPU	;GET SATS PER UNIT
	PUSHJ	P,GETSIC	;GET SATS IN CORE
	PUSHJ	P,GETK4S	;GET K FOR SWAPPING
	PUSHJ	P,GETSWB	;GET FIRST SWAPPING BLOCK NUMBER
	PUSHJ	P,GETCFS	;GET CLASS FOR SWAPPING
	SKIPN	BATFLG		;DO WE WANT TO SEE THE BAT BLOCKS?
	JRST	CHGST5		;NO--SKIP THIS
	MOVEI	T1,0		;YES--GET FLAG FOR OPTIONAL INIT OF BAD BLOCKS
	PUSHJ	P,GETBAT	;CHECK AND DISPLAY THE BAF
	  PUSHJ	P,INIBAT	;INITIALIZE IF NEEDED

CHGST5:	HLRZ	U,UNISTR(U)	;LINK TO NEXT UNIT IN STRUCTURE
	JUMPN	U,CHGST4	;LOOP IF MORE

CHGST6:	JRST	CHGST1		;LOOP BACK FOR ANOTHER STRUCTURE
SUBTTL	STRUCTURE ROUTINES -- CHKSTR - MAKE SURE STRS HAVE ALL NEEDED UNITS


CHKSTR:	HLRZ	P2,SYSSTR##	;GET ADDR OF FIRST STR DATA BLOCK IN SYSTEM
	JUMPE	P2,CPOPJ##	;THERE ARE NONE - NON SKIP RETURN
CHKST1:	HRRZ	T1,STRUNM##(P2)
	JUMPN	T1,CHKST3	;WAS THE LAST UNIT IN THIS STR FOUND?
	PUSH	P,STRREF##(P2)	;SAVE STATE OF 'NEEDS REFRESHING' FLAG
	MOVEI	T1,[ASCIZ /
% Last unit wasn't found in structure /]
	PUSHJ	P,MSGSTR	;NO - PRINT MSG. FOLLOWED BY SIXBIT STR NAME
	HLRZ	T1,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
CHKST2:	MOVE	U,T1		;LOAD UP UDB
	HLRZ	T1,UNISTR(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	JUMPN	T1,CHKST2	;REPEAT UNTIL LAST ONE FOUND
	LDB	T1,UNYLUN##	;GET ITS LOG. UNIT # IN STR
	ADDI	T1,1		;MAKE INTO # UNITS IN STR
	HRRM	T1,STRUNM##(P2)	; & STORE IT
	POP	P,T1		;RESTORE STATE OF 'NEEDS REFRESHING' FLAG
	HLLM	T1,STRREF##(P2)	;(RH OF STRREF IS STRUNM, SET ABOVE)
CHKST3:	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN THIS STR
	SETOM	P4		;SETUP FAKE PREVIOUS LOG. UNIT #
	CAIA
CHKST4:	HLLM	T2,UNIGRP(U)	;STORE # CLUSTERS TRIED ON O/P IN EACH UNIT
	LDB	P1,UNYLUN##	;GET LOG. UNIT # OF THIS UNIT WITHIN STR
	EXCH	P1,P4		;PUT THIS & PREVIOUS LOG. UNITS IN PROPER ACS
	CAME	P4,P1		;ARE LOG. UNIT #'S THE SAME?
	JRST	CHKST5		;NO - CHECK FOR MISSING UNITS
	MOVEI	T3,[ASCIZ /
% Two logical unit /]
	MOVEI	T1,[ASCIZ /s found in structure /]
	PUSHJ	P,MSGLNG	;PRINT MSGS FOLLOWED BY SIXBIT STR NAME
	JRST	CHKST6		;CHECK NEXT PAIR OF UNITS
CHKST5:	CAIN	P4,1(P1)	;IS THIS UNIT 1 GREATER THAN LAST ONE?
	JRST	CHKST6		;YES - CHECK NEXT PAIR OF UNITS
	ADDI	P1,1		;INCREMENT TO GET CORRECT MISSING LOG. UNIT #
	MOVEI	T3,[ASCIZ /
% Logical unit /]
	MOVEI	T1,[ASCIZ / missing from structure /]
	PUSHJ	P,MSGLNG
	JRST	CHKST5		;REPEAT UNTIL ALL MISSING ARE TYPED OUT
CHKST6:	MOVE	T1,UNIBPU(U)	;GET # BLOCKS ON THIS UNIT
	ADDM	T1,STRSIZ##(P2)	;ADD TO TOTAL # IN THIS STR
	MOVE	T1,STRBPU##(P2)	;GET # OF BLOCKS ON LARGEST UNIT IN STR
	ADDM	T1,STRHGH##(P2)	;ADD TO TOTAL LOGICAL # IN THIS STR
	HLL	T2,UNIGRP(U)	;GET # OF CONSECUTIVE CLUSTERS TRIED FOR ON O/P
	HLRZ	U,UNISTR(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	JUMPN	U,CHKST4	;JUMP IF MORE TO DO
	SOS	STRHGH##(P2)	;MAKE STRHGH BE HIGHEST LOG. BLOCK # IN STR
	HLRZ	P2,STRSYS##(P2)	;GET NEXT STR DATA BLOCK ADR. WITHIN SYSTEM
	JUMPN	P2,CHKST1	;REPEAT IF THERE IS ONE
	POPJ	P,		;ELSE RETURN
SUBTTL	STRUCTURE ROUTINES -- CRESAB - CREATE SAB AND SPT TABLE


CRESAB:	SE1ENT			;ENTER SECTION ONE
	PUSHJ	P,SAVE4##	;SAVE SOME ACS
CRESA1:	LDB	P1,UNYSIC##	;GET # SATS TO BE IN CORE FOR THIS UNIT
	JUMPLE	P1,CPOPJ##	;DON'T TRY TO SETUP ANYTHING IF 0 OR -VE
	S0PSHJ	CMCWPS		;COMPUTE # CLUSTERS & WORDS PER SAT
	LDB	P3,UNYWPS##	;GET # WORDS PER SAT
	MOVN	P2,P3		;MAKE -VE
	HRLZS	P2		;SETUP LH. OF PTR. FOR SABSCN
	ADDI	P3,SABBIT##	;COMPUTE # WORDS FOR EACH SAB BLOCK
	MOVEI	P4,UNISAB-SABRNG##(U) ;GET LINK TO FIRST SAB BLOCK IN RING
CRESA2:	MOVE	T2,P3		;SETUP ARG. FOR CORE GRABBER
	PUSHJ	P,CORGRS	;GET CORE
	MOVEM	T1,SABRNG##(P4)	;STORE LINK FROM PREVIOUS TO CURRENT SAB
	MOVE	P4,T1		;PREVIOUS SAB _ CURRENT SAB
	HRRI	P2,SABBIT##	;FILL IN RH. OF AOBJN PTR.
	MOVEM	P2,SABSCN##(P4)	;STORE IT IN THIS SAB BLOCK
	SKIPN	UNILOG(U)	;THIS UNIT PART OF A STRUCTURE?
	SETZM	SABFIR##(P4)	;NO
	SOJG	P1,CRESA2	;LOOP IF ANY MORE SATS
	MOVE	T1,UNISAB(U)	;GET ADR. OF 1ST. SAB BLOCK IN RING
	MOVEM	T1,SABRNG##(P4)	;MAKE LAST POINT TO FIRST

CRESPT:	LDB	T2,UNYSPU##	;GET # SATS ON THIS UNIT
	ADDI	T2,SPTFIR##+1	;COMPUTE LENGTH OF SPT TABLE
	MOVEI	P3,(T2)		;SAVE IN P3
	PUSHJ	P,CORGRS	;GET CORE
	MOVEM	T1,UNISPT(U)	;STORE ADR. OF SPT TABLE IN UNIT DATA BLOCK
	ADDI	T1,-1(P3)	;COMPUTE ADR. OF LAST WORD IN SPT TABLE
	SETZM	(T1)		;ZERO IT TO INDICATE END OF TABLE
	POPJ	P,		;RETURN
SUBTTL	STRUCTURE ROUTINES -- DEFSTR - DEFINE


DEFSTR::AOS	BLURBF		;COUNT PASSES THROUGH HERE
	PUSHJ	P,PRSCON##	;SEE IF WE KNOW WHAT WE'RE DOING
	  JRST	DEFST2		;LOOKS LIKE IT--LEAVE USER IN PEACE
	SKIPE	BLURBF		;WAS THIS THE FIRST TIME HERE?
	JRST	DEFST1		;NO--GIVE THE USER SOME PEACE
	MOVEI	T1,INTRO	;INTRODUCTORY TEXT
	PUSHJ	P,CONOUT##	;PRINT IT
	MOVEI	T1,REFPRM	;SPECIAL PARAMETER DISCLAIMER
	PUSHJ	P,CONOUT##	;PRINT IT

DEFST1:	MOVEI	T1,INIMSG	;HOME BLOCK WARNING
	PUSHJ	P,CONOUT##	;PRINT IT

DEFST2:	PUSHJ	P,GETSNM	;GET STRUCTURE NAME AND CREATE STR DB
	JUMPE	T1,VFCORE	;GO VERIFY INCORE DATA BASE IF NO MORE
	PUSHJ	P,GETUNM	;GET AND LINK ALL UNITS
	  JRST	DEFST6		;BRANCH IF NO UNITS SPECIFIED
	MOVEI	T1,[ASCIZ /Do you want to see the bad regions/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	MOVEM	T1,BATFLG	;SAVE FOR LATER

	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
DEFST3:	MOVEI	T1,1		;CODE TO REPORT INITIALIZATION
	PUSHJ	P,INIHOM	;INITIALIZE HOME BLOCKS ON THIS UNIT
	MOVEI	T1,0		;CODE FOR OPTIONAL INIT OF BAT BLOCKS
	PUSHJ	P,GETBAT	;CHECK OUT BAT BLOCKS
	  PUSHJ	P,INIBAT	;NEED TO INITIALIZE BAT BLOCKS
	HLRZ	U,UNISTR(U)	;GET NEXT UNIT IN STRUCTURE
	JUMPN	U,DEFST3	;LOOP BACK FOR MORE
	PUSHJ	P,CRLFOP##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ /Parameters for structure /]
	PUSHJ	P,ICONM##	;PRINT MESSAGE
	MOVE	T2,STRNAM(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,GETBPC	;GET BLOCKS PER CLUSTER
	PUSHJ	P,GETPRV	;GET PRIVATE STATUS
	PUSHJ	P,GETOPP	;GET OWNER PPN
	PUSHJ	P,GETDSN	;GET DISK-SET NUMBERS
	PUSHJ	P,GETK4C	;GET K FOR CRASH.SAV
	PUSHJ	P,GETOVR	;GET OVERDRAW
	PUSHJ	P,GETGAR	;GET GUARANTEED BLOCKS
	PUSHJ	P,GETGRP	;GET BLOCKS TO TRY FOR ON OUTPUT
	PUSHJ	P,GETCNP	;GET BITS PER CLUSTER COUNT
	PUSHJ	P,GETSSL	;GET SINGLE STRUCTURE SSL INFO
	PUSHJ	P,GETSDL	;GET SINGLE STRUCTURE SDL INFO

	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
DEFST4:	PUSHJ	P,CRLFOP##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ /Parameters for unit /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,GETUID	;GET UNIT ID
	PUSHJ	P,GETSPU	;GET SATS PER UNIT
	PUSHJ	P,GETSIC	;GET SATS IN CORE
	PUSHJ	P,GETK4S	;GET K FOR SWAPPING
	PUSHJ	P,GETSWB	;GET FIRST SWAPPING BLOCK NUMBER
	PUSHJ	P,GETCFS	;GET CLASS FOR SWAPPING
	PUSHJ	P,GETASL	;GET SINGLE UNIT ASL INFO
	PUSHJ	P,REFCHZ	;JUST INCASE HE DEFAULTED EVERYTHING
	HLRZ	U,UNISTR(U)	;LINK TO NEXT UNIT IN STRUCTURE
	JUMPN	U,DEFST4	;LOOP IF MORE
	MOVE	T1,[PUSHJ P,CRESAB] ;INSTRUCTION TO EXECUTE PER UNIT
	PUSHJ	P,STOUNI	;TO MAKE THE SAB RINGS FOR THIS STRUCTURE
	MOVE	T1,STRNAM##(P2)	;GET THE STR NAME
	MOVEI	T2,[ASCIZ /must be refreshed before it can be used./]
	PUSHJ	P,SWARN		;MAKE SURE HE KNOWS TO REFRESH IT

DEFST5:	PUSHJ	P,OTSET##	;RESET OUTPUT BYTE POINTER, ETC.
	PUSHJ	P,CRLFOP##	;PUT OUT A BLANK LINE
	JRST	DEFST2		;LOOP BACK FOR ANOTHER STRUCTURE

DEFST6:	HLL	T1,STRSYS##(P2)	;GET NEXT STR, IF ANY
	HLLM	T1,SYSSTR##	;AND MAKE SYSTEM POINT BEYOND US
	PUSHJ	P,KSTR		;KILL OFF STR DB
	JRST	DEFST2		;AND THEN REPROMPT FOR ANOTHER
SUBTTL	STRUCTURE ROUTINES -- DELSAB - DELETE SAB AND SPT TABLE


DELSAB:	SE1ENT			;ENTER SECTION ONE
	PUSHJ	P,SAVE1##	;SAVE P1
	S0PSHJ	CMCWPS		;COMPUTE # CLUSTERS & WORDS PER SAT
	SKIPE	P1,UNISAB(U)	;HAVE A SAB RING?
	LDB	P1,UNYSIC##	;GET SATS IN CORE
	JUMPLE	P1,DELSA2	;NONE
DELSA1:	LDB	T1,UNYWPS##	;GET WORDS PER SAT
	ADDI	T1,SABBIT##	;PLUS OVERHEAD
	MOVE	T2,UNISAB(U)	;GET A SAB ADDRESS
	MOVE	T3,SABRNG##(T2)	;LINK TO NEXT
	MOVEM	T3,UNISAB(U)	;STORE BACK FOR NEXT TIME
IFE FTXMON,<PUSHJ P,GIVWDS##>	;RETURN CORE
IFN FTXMON,<PUSHJ P,GVFWDS##>	;RETURN CORE
	SOJG	P1,DELSA1	;LOOP BACK FOR MORE
DELSA2:	SETZM	UNISAB(U)	;INDICATE NO SABS

DELSPT:	SKIPN	T2,UNISPT(U)	;GET SPT TABLE ADDRESS
	POPJ	P,		;NOTHING THERE??
	LDB	T1,UNYSPU##	;GET # SATS ON THIS UNIT
	ADDI	T1,SPTFIR##+1	;COMPUTE LENGTH OF SPT TABLE
IFE FTXMON,<PUSHJ P,GIVWDS##>	;RETURN CORE
IFN FTXMON,<PUSHJ P,GVFWDS##>	;RETURN CORE
	SETZM	UNISPT(U)	;CLEAR ADDRESS OUT
	POPJ	P,		;AND RETURN
SUBTTL	STRUCTURE ROUTINES -- LNKSTR - LINK UNITS WITHIN A STRUCTURE


LNKSTR:	JUMPE	P2,CPOPJ##	;IF UNIT NOT IN STR SETUP SAB RING & SPT TABLE
	LDB	T2,UNYLUN##	;GET LOGICAL UNIT # WITHIN STR
	SKIPE	HOMNXT##(P1)	;IS THIS LAST UNIT IN STR?
	JRST	LNKST2		;NO - GO LINK UNIT DATA BLOCK INTO STR
	HRRZ	T1,STRUNM##(P2)	;HAVE WE ALREADY SEEN A LAST UNIT FOR THIS STR?
	JUMPE	T1,LNKST1	;NO - NOW WE HAVE
	PUSH	P,T2		;SAVE LOG. UNIT #
	MOVEI	T1,[ASCIZ /
% More than one last unit in structure /]
	PUSHJ	P,MSGSTR	;PRINT MSG FOLLOWED BY SIXBIT STR NAME
	POP	P,T2		;RESTORE LOG. UNIT #
LNKST1:	ANDI	T2,77		;MAX. OF 64 UNITS IN STR
	HRRM	T2,STRUNM##(P2)	;STORE LOG. # OF LAST UNIT IN STR
	AOS	STRUNM##(P2)	;LEAVE T2 ALONE BUT MAKE MEMORY OK
LNKST2:	MOVEI	T4,STRUNI##(P2)	;GET ADDR OF LINK TO FIRST UDB IN STR
	JRST	LNKST4
LNKST3:	LDB	T3,UNYLN1##	;YES - GET LOG. UNIT # OF NEXT UNIT
	CAMLE	T3,T2		;IS IT GREATER THAN UNIT JUST READ?
	JRST	LNKST5		;YES - INSERT UNIT DATA BLOCK HERE
	MOVEI	T4,UNISTR(T1)	;GET ADR. OF LINK TO NEXT UNIT
LNKST4:	HLRZ	T1,(T4)		;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	JUMPN	T1,LNKST3	;MORE DATA BLOCKS?
LNKST5:	HRLM	T1,UNISTR(U)	;SAVE LINKS TO STR & NEXT UNIT DATA BLOCK
	HRRM	P2,UNISTR(U)	; IN THIS UNIT DATA BLOCK
	HRLM	U,(T4)		;SAVE THIS UDB IN PREVIOUS UNIT DATA BLOCK
	POPJ	P,		;RETURN
SUBTTL	STRUCTURE ROUTINES -- SHWSTR - SHOW


SHWSTR::HLRZ	P2,SYSSTR##	;GET FIRST STRUCTURE IN SYSTEM
	JUMPE	P2,[		;MAKE SURE WE HAVE ONE
		MOVEI	T1,[ASCIZ /% No structures found/]
		AOS	(P)	;WRONG, BUT SKIP ANYWAY
		PJRST	CONOUT]	;AFTER GIVING OUR WARNING
	MOVEI	T1,[ASCIZ /Structure/]
	SETZ	T2,		;NO DEFAULT STRUCTURE NAME
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	JUMPE	T1,CPOPJ1##	;GIVE UP IF NO RESPONSE
	PUSHJ	P,FNSTR		;ALREADY EXIST?
	  SKIPA			;NO, SEE IF THIS IS ALL
	JRST	SHWST1		;YES, TYPE OUT INFO AND LOOP BACK
	PUSHJ	P,FNDALL	;DID THE USER TYPE ALL?
	  SKIPA	T2,[[ASCIZ /does not exist/]] ;NO
	JRST	SHWSAL		;SHOW ALL STRUCTURES
	PUSHJ	P,SWARN		;WARN OPERATOR
	JRST	SHWSTR		;TRY AGAIN

SHWST1:	PUSHJ	P,SHWSTU	;SHOW ONE STRUCTURE
	JRST	SHWSTR		;AND ASK FOR ANOTHER

SHWSAL:	HLRZ	P2,SYSSTR##	;GET FIRST STRUCTURE IN SYSTEM
SHWSA1:	PUSHJ	P,SHWSTU	;SHOW A STRUCTURE
	HLRZ	P2,STRSYS##(P2)	;GET THE NEXT STRUCTURE
	JUMPN	P2,SHWSA1	;SHOW THE NEXT STRUCTURE IF MORE.
	JRST	SHWSTR		;LOOP IN CASE HE WANTS TO SEE ONE AGAIN

SHWSTU:	HLRZ	U,STRUNI##(P2)	;POINT TO FIRST UNIT IN STRUCTURE
	PUSHJ	P,CRLFOP##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ /Parameters for structure /]
	PUSHJ	P,ICONM##	;PRINT MESSAGE
	MOVE	T2,STRNAM(P2)	;GET STRUCTURE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /   *Blocks per cluster: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,UNYBPC##	;PICK UP DATA FROM FIRST UNIT IN STR
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Private structure: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,STYPVS##	;GET BIT
	MOVE	T2,[EXP <'NO    '>,<'YES   '>](T1) ;TRANSLATE
	PUSHJ	P,PRNAME##	;PRINT VALUE
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Owner PPN: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVEI	T3,PRNAME##	;ASSUME NOTHING
	SKIPN	T2,STRPPN##(P2)	;GET PPN
	SKIPA	T2,['NONE  ']	;THERE ISN'T ONE
	SKIPA	T3,[IFIW PRTPPN##] ;PPN TYPER
	MOVE	T3,[IFIW PRNAME##] ;SIXBIT TYPER
	PUSHJ	P,(T3)		;CALL SUBR
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Disk-set: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,STYSET##	;GET DISK-SET
	SETZ	T2,		;ASSUME NO KEYWORD
	MOVE	T3,[IFIW PRTDIG##] ;ASSUME A SINGLE SET
	CAIN	T1,0		;ALL?
	MOVSI	T2,'ALL'	;YES
	CAIN	T1,^D37		;NONE?
	MOVE	T2,['NONE  ']	;YES
	SKIPE	T2		;SINGLE DISK-SET?
	HRRI	T3,PRNAME##	;NO
	PUSHJ	P,(T3)		;PRINT SOMETHING
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ  /   *Number of K for CRASH.EXE: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	HRRZ	T1,STRK4C##(P2)	;GET K FOR CRASH.SAV
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Blocks allowed for overdraw per user: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVM	T1,STROVR##(P2)	;GET OVERDRAW
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	JRST	SHWST2		;UNIMPLEMENTED
	MOVEI	T1,[ASCIZ /    Sum of blocks guaranteed to users: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T1,STRGAR##(P2)	;GET GUARANTEED BLOCKS
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

SHWST2:	MOVEI	T1,[ASCIZ /    Consecutive blocks tried for on output: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	HLRZ	T1,UNIGRP(U)	;GET SIZE FROM FIRST UNIT
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /   *Bits per cluster count: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,[POINT 6,STYCNP##(P2),11] ;GET NUMBER OF BITS
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Position in the SSL: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	SKIPGE	T1,STRSRC##(P2)	;IN THE SSL?
	SKIPA	T2,['NONE  ']	;NO
	SKIPA	T3,[IFIW PRTDIG##] ;IF A POSITION
	MOVE	T3,[IFIW PRNAME##] ;IF NONE
	PUSHJ	P,(T3)		;PRINT SOMETHING
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Unit in the SDL: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	SKIPGE	STRSDL##(P2)	;IN THE SDL?
	TDZA	T1,T1		;NO
	MOVEI	T1,1		;YES
	MOVE	T2,[EXP <'NO    '>,<'YES   '>](T1) ;TRANSLATE
	PUSHJ	P,PRNAME##	;PRINT VALUE
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Unit/]
	PUSHJ	P,ICONM##	;PRINT TEXT
	HRRZ	T2,STRUNM##(P2)	;GET # UNITS IN STR
	MOVEI	T1,[ASCIZ /s/]	;POSSIBLE TEXT
	CAIE	T2,1		;IF MULTI-PACK STRUCTURE,
	PUSHJ	P,CONMES##	;MAKE IT PLURAL
	MOVEI	T1,[ASCIZ /:  /]
	PUSHJ	P,CONMES##	;SEPARATION

SHWST3:	MOVE	T2,UDBNAM(U)	;GET THE PHYSICAL UNIT NAME
	PUSHJ	P,PRNAME##	;TYPE IT
	HLRZ	U,UNISTR(U)	;GET NEXT UNIT IN THIS STR
	JUMPE	U,SHWST4	;END LIST IF NO MORE
	MOVEI	T1,[ASCIZ /, /]	;SEPARATION IF MORE
	PUSHJ	P,CONMES##	;TYPE COMMA SPACE
	JRST	SHWST3		;THEN NEXT UNIT NAME

SHWST4:	PUSHJ	P,CRLFOP##	;END THE LINE

	POPJ	P,		;RETURN
SUBTTL	STRUCTURE ROUTINES -- VALMFD - VALIDATE THE MFD


VALMFD:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	SKIPN	UNILOG(U)	;SKIP IF UNIT IS IN A FILE STRUCTURE
	POPJ	P,		;NOT IN A FILE STRUCTURE
	HRRZ	P2,UNISTR(U)	;ADDR OF STR DATA BLOCK
	JUMPE	P2,CPOPJ##	;UNILOG WAS BOGUS
	HLLZ	T1,STRREF##(P2)	;NEEDS REFRESHING FLAG
	JUMPN 	T1,CPOPJ##	;NO MFD IF NEEDS REFRESHING
	HRRZ	P1,@ONCMBF	;ADDR FROM IOWD PTR TO HOME BLOCK
	ADDI	P1,1
	LDB	T2,UNYLUN##	;LOGICAL UNIT IN FILE STRUCTURE
	CAME	T2,HOMUN1##(P1)	;SKIP IF MFD STARTS ON THIS UNIT
	POPJ	P,		;IT DOESN'T
	IMUL	T2,STRBPU##(P2)	;T2=1ST LOGICAL BLOCK ON THIS UNIT
	SUB	T2,HOMMFD##(P1)	;MINUS BLOCK FOR MFD RIB
	MOVNS	T2		;T2=BLOCK ON UNIT FOR MFD RIB
	PUSHJ	P,OMNRED	;READ MFD RIB
	  STOPCD LNKSTR,DEBUG,ERM,DIEUNI##, ;++ERROR READING MFD
	SKIPE	.UONCE##	;IF USER-MODE,
	POPJ	P,		;WE DON'T CARE (AND TWICE.BIN COULD SCREW US)
	HRRZ	T1,P1		;ADDR OF 1ST WORD OF MFD RIB
	ADD	T1,(P1)		;PTR TO 1ST RETRIEVAL PTR
	SKIPE	2(T1)		;SKIP IF ONLY 1 PTR
	POPJ	P,		;DONE
	MOVEI	T1,STP1PT##	;ONLY 1 PTR BIT
	IORM	T1,STR1PT##(P2)	;SAVE
	POPJ	P,		;RETURN
SUBTTL	STRUCTURE ROUTINES -- DSKSDL - BUILD SDL FROM DISK


DSKSDL:	MOVSI	T1,-^D36	;AOBJN POINTER
	MOVEI	T2,SYSSTR##-STRSYS## ;PREDECESSOR OF FIRST STR
	JRST	DSKSD2		;ENTER LOOP FROM THE BOTTOM

DSKSD1:	SKIPGE	STRSDL(T2)	;IN THE SDL?
	JRST	DSKSD2		;NO
	HRRZM	T1,STRSDL(T2)	;SET POSITION IN THE SDL
	AOBJP	T1,CPOPJ##	;RETURN IF ALL FILLED UP

DSKSD2:	HLRZ	T2,STRSYS(T2)	;LINK TO NEXT STR
	JUMPN	T2,DSKSD1	;LOOP BACK FOR ANOTHER
	POPJ	P,		;DONE
SUBTTL	MANDATORY ONCE ONLY CODE -- FILMAN - SETUP FILSER DATA BASE


FILMAN::SETOM	BATMAN		;NOTE IN MANDANTORY PART NOW
	PUSHJ	P,REDBAT	;READ BAT BLOCKS TO SET UP SWAPPING SATS
	MOVEI	P2,SYSSTR##-STRSYS## ;PREDECESSOR TO FIRST STR
	JRST	LSTRT1		;ENTER LOOP FROM THE BOTTOM
NXTSIS:	SETZB	P4,STRTAL##(P2)	;CLEAR FREE BLOCK TALLY & LAST RET. PTR. FLAG
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT IN STR
	PUSHJ	P,GTSRB		;READ SAT.SYS "RIB" BLOCK FOR THIS STR
	  JRST	[MOVE	T1,UDBNAM##(U)
		 MOVEI	T2,[ASCIZ /SAT read errors/]
		 PUSHJ	P,UWARN	;WARN OPERATOR
		 JRST	NXTSIE]	;AND CONTINUE
	HRRZ	T1,P1		;GET ADR. OF "RIB" BLOCK IN CORE
	ADD	T1,RIBFIR##(P1)	;CREATE AOBJN PTR. FOR SCANNING RET. INFO.
	AOBJN	T1,.+2		;SKIP OVER 1ST. PTR. AS IT IS A "RIB"
	STOPCD	NXTSIE,DEBUG,NRS,DIEUNI##,	;++NO RIB IN SAT
	HRRZ	P2,UNISTR(U)	;GET ADR. OF STR - P2 CLOBBERED BY GTSRB
IFN FTXMON,SE1JRS		;MUST BE EXECUTED IN SECTION 1
NXTUIS:	SETZM	UNITAL(U)	;CLEAR FREE BLOCK TALLY FOR THIS UNIT
	PUSH	P,T1		;SAVE PTR.
	LDB	T3,UNYLUN##	;GET LOG. UNIT # OF THIS UNIT IN STR
	SKIPN	T3		;IF THIS UNIT IS LOG. UNIT # 0
	SKIPA	T2,-1(T1)	; SKIP BACK OVER "RIB" TO GET NEW UNIT PTR.
	MOVE	T2,(T1)		;GET NEW UNIT PTR.
	TRNN	T2,RIPNUB##	;IS IT REALLY A NEW UNIT PTR?
	STOPCD	NXTSI1,DEBUG,NNU,DIEUNI##, ;++NOT NEW UNIT
	ANDI	T2,77		;IT SHOULD BE LOG. UNIT # SO MASK OUT EXTRA BITS
	CAME	T2,T3		;IS IT?
	STOPCD	NXTSI1,DEBUG,RPM,DIEUNI##, ;++RET. PTR. MISMATCH
	MOVE	T4,UNISPT(U)	;GET ADR. OF UNIT'S SPT TABLE
MOVPTR:	AOBJP	T1,MOVPT2	;HAVE WE RUN OUT OF RET. INFO?
	MOVE	T2,(T1)		;NO - GET NEXT WORD
	LDB	T3,STYCNP##(P2)	;GET CLUSTER COUNT
	JUMPE	T3,MOVPT1	;IF 0 WE MUST HAVE RUN OUT OF PTRS. FOR THIS UNIT
	LDB	T2,STYCLP##(P2)	;GET CLUSTER ADR.
	DPB	T2,SPYCLA##	;STORE IN SPT TABLE FOR THIS UNIT
	AOJA	T4,MOVPTR	;BUMP SPT TABLE ADR. & RETURN FOR MORE PTRS.

NXTSI1:	POP	P,T1		;RESTORE PTR. TO RET. INFO FROM STACK.
NXTSIE:	MOVEI	T2,1		;GET A BIT
	DPB	T2,UNYAWL##	;SET SOFTWARE WRITE PROTECT FOR ALL JOBS
NXTSI2:	HRRZ	P2,UNISTR(U)	;RESET P2 TO POINT TO STR
	JRST	LSTRT1		;AND GO ON TO NEXT STR

MOVPT1:	MOVEM	T1,(P)		;SAVE PTR. ON STACK FOR NEXT UNIT SCAN
	JUMPN	T2,MOVPT3	;WAS IT 0 ENTRY INDICATING END OF LIST?
MOVPT2:	SUBI	T4,1		;YES - DECREMENT T4 SO THAT LAST ENTRY IN SPT TABLE,
				; WHICH IS A "RIB", GETS CLEARED
	SETOM	P4		;YES - SET END OF LIST FLAG
MOVPT3:	SETZM	(T4)		;ZERO END OF SPT TABLE FOR THIS UNIT
;NOW READ ALL SATS ON THIS UNIT - COMPUTE THE # OF FREE CLUSTERS LEFT IN EACH SAT

	PUSH	P,P2		;SAVE ADR. OF THIS STR
	LDB	P1,UNYSPU##	;GET # SAT BLOCKS ON THIS UNIT
	MOVNS	P1		;MAKE -VE
	HRLZS	P1		;MAKE IT INTO AN AOBJN PTR.
	MOVEI	P2,UNISAB-SABRNG##(U) ;SETUP OFFSET TO POINT TO 1ST. SAB BLOCK ADR.
NXTSAT:	MOVE	P2,SABRNG##(P2)	;GET ADR. OF NEXT SAB BLOCK FOR THIS UNIT
	MOVE	T4,UNISPT(U)	;GET ADR. OF SPT TABLE
	ADDI	T4,(P1)		;ADD IN INDEX FOR LDB SPYCLA
	LDB	T1,SPYCLA##	;GET CLUSTER ADR. OF THIS SAT BLOCK
	LDB	T2,UNYBPC##	;GET # BLOCKS PER CLUSTER
	IMUL	T2,T1		;COMPUTE LOGICAL BLOCK # FOR THIS SAT
	PUSHJ	P,REDSAT	;READ SAT & COMPUTE # FREE CLUSTERS LEFT IN IT
	  STOPCD LSTRT0,DEBUG,SRE,DIEUNI##, ;++SAT READ ERROR
	MOVE	T4,UNISPT(U)	;GET ADR. OF SPT TABLE FOR THIS UNIT
	ADDI	T4,(P1)		;ADD IN INDEX FOR DPB SPYTAL
	DPB	T2,SPYTAL##	;STORE FREE CLUSTERS FOR SAT BLOCK IN SPT TABLE
	LDB	T1,UNYBPC##	;GET # BLOCKS PER CLUSTER FOR THIS UNIT
	IMUL	T1,T2		;COMPUTE # FREE BLOCKS IN THIS SAT BLOCK
	HRRZ	T2,UNISTR(U)	;LOC OF STR DATA BLOCK
	HLLZ	T3,STRREF##(T2)
	JUMPE	T3,NXTSA1	;IF STR NEEDS REFRESHING,
	MOVEI	T3,1		; PRETEND IT'S WRITE-LOCKED
	DPB	T3,UNYAWL##
	JRST	NXTSA2		; AND LEAVE UNITAL=STRTAL=0
NXTSA1:	ADDM	T1,UNITAL(U)	;ADD TO TOTAL FOR THIS UNIT
	ADDM	T1,STRTAL##(T2)	;ADD TO TOTAL FOR THIS STR
NXTSA2:	AOBJN	P1,NXTSAT	;GO READ NEXT SAT IF THERE IS ONE
	MOVE	T2,UNIBPU(U)	;GET NO OF BLOCK ON UNIT
	LDB	T3,UNYK4S##	;K FOR SWAPPING
	LSH	T3,BLKSPK	;CONVERT TO BLOCKS
	SUB	T2,T3		;COMPUTE SAFETY FACTOR
	IDIVI	T2,UNVRSF##	; BLOCKS TO USE WHEN UNIT FULL
	CAILE	T2,^D500	;MAX SAFETY FACTOR = 500 BLOCKS
	MOVEI	T2,^D500
	MOVNS	T2
	ADDM	T2,UNITAL(U)	;SUBTRACT FACTOR FROM UNIT
	HRRZ	T1,UNISTR(U)
	ADDM	T2,STRTAL##(T1)	; AND FROM STR
	POP	P,P2		;POP OFF ADR. OF THIS STR DATA BLOCK FROM STACK
	POP	P,T1		;RESTORE PTR. TO RET. INFO. FROM STACK
	HLRZ	U,UNISTR(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	JUMPL	P4,LSTRTP	;HAS LAST RET. PTR. BEEN SEEN?
	JUMPN	U,NXTUIS	;NO - IS THERE ANOTHER UNIT IN THIS STR TO CHECK
	STOPCD	.,STOP,ROU,DIESTR##, ;++RAN OUT OF UNITS
LSTRTP:	SKIPE	U		;IS THERE ANOTHER UNIT IN THIS STR TO CHECK
	STOPCD	.,STOP,TMU,DIESTR##, ;++TOO MANY UNITS
	JRST	LSTRT1		;ALREADY RESTORED T1 AND P2
LSTRT0:	MOVEI	T1,1		;SET SOFTWARE WRITE PROTECT FOR ALL JOBS
	DPB	T1,UNYAWL##
	POP	P,P2		;POP OFF ADR. OF THIS STR. DATA BLOCK FROM STACK
	POP	P,T1		;RESTORE PTR. TO RE. INFO FROM STACK
LSTRT1:
IFN FTXMON,<XJRST [MCSEC0+.+1]>	;RETURN TO SECTION ZERO
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	JUMPN	P2,NXTSIS	;IF THERE IS ONE REPEAT
	PUSH	P,P2		;INIT TEMP PTR TO SYS. SL.
	MOVE	P2,SYSSRC##
	MOVEM	P2,TEMPTR
	PUSHJ	P,SLINI##	;AND EMPTY THE SYS SL.
	POP	P,P2
	MOVE	P4,[PUSHJ P,DEPCLR]	;SETUP INSTR. FOR XCT IN FNDSRC

	PUSHJ	P,FNDSRC	;GO SETUP "SYS" SEARCH LIST
	PUSHJ	P,SSLBLD##	;LOAD THE SSL INTO THE BOOTSTRAP VECTOR
	  JFCL			;NOT AVAILABLE
	PUSHJ	P,ASLBLD##	;LOAD THE ASL INTO THE BOOTSTRAP VECTOR
	  JFCL			;NOT AVAILABLE
	PUSHJ	P,SDLBLD##	;LOAD THE SDL INTO THE BOOTSTRAP VECTOR
	  JFCL			;NOT AVAILABLE
	MOVEI	P1,SYSSTR##-STRSYS## ;SETUP LINK POINTING TO 1ST. STR IN SYSTEM
	JRST	ADJSR1
ADJSTR:	SETZM	STRMNT##(P1)	;CLEAR MOUNT COUNT(TIMESHARED AS STRSAT)
	SETZM	STRJOB##(P1)	;CLEAR SINGLE ACCESS OWNER(TIMESHARED AS STRSRC)
ADJSR1:	HLRZ	P1,STRSYS##(P1)	;GET ADR. OF NEXT STR IN SYSTEM
	JUMPN	P1,ADJSTR	;REPEAT IF ANY MORE STRS

	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST UNIT DATA BLOCK IN SYSTEM
ADJUNI:	HRRZ	T2,UNISTR(U)	;GET STR ADR. THIS UNIT IS IN
	JUMPE	T2,ADJUN1	;IS IT 0?
IFN FTDUAL,<
	SKIPE	T2,UNI2ND(U)	;DRIVE DUAL PORTED?
	PUSHJ	P,CPYUD##	;COPY INFORMATION TO SECOND PORT
>; END IFN FTDUAL
ADJUN1:	HLRZ	U,UNISYS(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,ADJUNI	;REPEAT IF ANY LEFT
SWPFAC:	PUSHJ	P,GVMNB0	;RETURN MONITOR BUFFER USED FOR "RIB" BLOCK
	PUSHJ	P,TYPNMU	;TYPE UNITS IN STRUCTURES NOT MOUNTED TO THIS SYS


;CALCULATE DATA NEEDED FOR THE MCU FUNCTION.
;SET PROT AND PROT0 ACCORDING TO THE FIRST UNIT
;IN THE ACTIVE SWAPPING LIST USING THE AVERAGE TIME PER PAGE
;FOR PROT AND THE AVERAGE LATENCY TIME FOR PROT0


	MOVEI	P1,BKPMAX	;LAST ENTRY IN UNIT TYPE TABLES
SWPFC1:	MOVEI	T1,PAGSIZ	;GET WORDS PER PAGE
	LSH	T1,-7		;CONVERT TO BLOCKS PER PAGE (128 WORDS PER BLOCK)
	IMUL	T1,MSPREV(P1)	;MULTIPLY BY MICROSECS PER REVOLUTION
	IDIV	T1,BKPREV(P1)	;DIVIDE BY BLOCKS PER REVOLUTION TO
				;GET MICROSECS PER PAGE
	MOVEM	T1,MCUATP##(P1)	;SAVE IN TABLE FOR MCU CALCULATION
	MOVE	T1,AVSEEK(P1)	;GET AVG SEEK TIME IN MICROSECS
	LSH	T1,1		;*2
	ADD	T1,MSPREV(P1)	;ADD IN MICROSECS PER REV
	LSH	T1,-1		;/2 TO GET AVERAGE LATENCY
	MOVEM	T1,MCUALT##(P1)	;IN MICROSECS. SAVE FOR MCU.
	SOJGE	P1,SWPFC1	;LOOP FOR ALL TYPES OF UNIT.


;NOW CALCULATE DEFAULT PROT AND PROT0 WHICH WILL BE USED
;IN THE ABSENCE OF THE MINIMUM CORE USAGE FUNCTION.

	MOVSI	T3,MSWPMX##	;AOBJN POINTER TO SWPTAB
	SKIPN	U,SWPTAB##(T3)	;GET FIRST NON-ZERO ENTRY
	AOBJN	T3,.-1
	LDB	T1,UNYKTP##	;GET KONTROLLER TYPE
	MOVE	T1,TYPTAB##(T1)	;GET OFFSET INTO UNIT TYPE TABLES
	LDB	P1,UNYUTP##	;GET UNIT TYPE
	ADD	P1,T1		;GET FINAL POSITION IN UNIT TYPE TABLES
	MOVE	T1,PRT0TB(P1)	;GET PROT0 FOR THIS DEVICE
	MOVEM	T1,PROT0##	;(MICRO SECONDS)
	IMUL	T1,TICSEC##	;TICS PER SECOND
	IDIV	T1,[^D1000000]	;CONVERT PROT0 TO TICKS
	MOVEM	T1,PROT1##	;AND SAVE AS TICS VERSION OF PROT0
	MOVE	T1,PROTTB(P1)	;GET MULTIPLIER FOR THIS DEVICE
	MOVEM	T1,PROT##	;(MICRO SECONDS)
	MOVE	T1,PRTMTB(P1)	;GET MAXIMUM FOR THIS DEVICE
	MOVEM	T1,PROTM##	;(MICRO SECONDS)
IFN FTNSCHED,<
	MOVE	T1,MCUATP##(P1)	;AVG TIME PER PAGE IN MICROSEC.
	IMULI	T1,PAVJSP##	;PREDICTED AVG JOB SIZE IN PAGES
	ADD	T1,MCUALT##(P1)	;PLUS AVG LATENCY IN MICROSEC.
	IMUL	T1,TICSEC##	;MICROTICS
	IDIV	T1,[^D1000000]	;CONVERT TO TICS
	ADDI	T1,1		;ROUND UP TO NEXT TIC
	MOVEM	T1,SCDSWP##	;CYCLE TIME FOR PQ2 SWAPIN SCAN
>
; NOW SET QUANTUM TABLES
	MOVE	T1,MAXTAB(P1)	;GET MAXIMUM PQ2 QUANTUM RUN TIME
	IMUL	T1,TICSEC	;CONVERT TO TICKS
	IDIV	T1,[^D1000000]
	MOVEM	T1,QMXTAB##+1
	MOVE	T1,ADDTAB(P1)	;GET MINIMUM PQ2 QUANTUM RUN TIME
	IMUL	T1,TICSEC	;CONVERT TO TICKS
	IDIV	T1,[^D1000000]
	MOVEM	T1,QADTAB##+1
	MOVE	T1,MULTAB(P1)	;GET PQ2 QUANTUM RUN TIME MULTIPLIER
	IMUL	T1,TICSEC	;CONVERT TO TICKS
	IDIV	T1,[^D1000000]
	MOVEM	T1,QMLTAB##+1	;AND AS PQ2 MULTIPLIER
				;PQ1 QUANTA ARE INITIALIZED IN COMMON.
				;INSERT ANY NON-STANDARD CODE FOR
				;INITIALIZING PQ1 QUANTA HERE.
	MOVEI	T1,STRSYS##
	HRRM	T1,SYSSTR##

	MOVSI	T1,MSWPMX##	;CAN'T HAVE SWAP SPACE
	MOVNI	T2,4		; START AT BLOCK0,
	SKIPE	T3,SWPTAB##(T1)	; SO DECREMENT UNISLB
	ADDM	T2,UNISLB(T3)	; AND START AT LOGICAL
	AOBJN	T1,.-2		; SWAP BLOCK1
	POPJ	P,		;FINALLY DONE
;BLOCKS PER REVOLUTION TABLE

BKPREV:	0	;NEW DRUM
	0	;DITTO
	^D20	;RD10
	^D30	;RM10B
	^D5	;RP01
	^D10	;RP02
	^D10	;RP03
	^D11	;DUAL POSITIONER MD10
	^D11	;SINGLE POSITIONER MD10
	^D32	;RS04
	^D20	;RP04
	^D20	;RP06
	^D30	;RM03
	^D30	;RP07
	^D25	;RP20
	^D23	;RA80
	^D23	;RA81
	^D19	;RA60
BKPMAX==.-BKPREV-1		;MAXIMUM INDEX TO THESE TABLES

;MICROSECONDS PER REVOLUTION TABLE

MSPREV:	0	;NEW DRUM
	0	;DITTO
	^D33000	;RD10
	^D17000	;RM10B
	^D25000	;RP01
	^D25000	;RP02
	^D25000	;RP03
	^D50000	;DUAL POSITIONER MD10
	^D50000	;SINGLE POSITIONER MD10
	^D17000	;RS04
	^D17000	;RP04
	^D17000	;RP06
	^D17000	;RM03
	^D17000	;RP07
	^D17000	;RP20
	^D17000	;RA80
	^D17000	;RA81
	^D17000	;RA60
AVSEEK:	0	;NEW DRUM
	0	;DITTO
	0	;RD10
	0	;RM10B
	^D50000	;RP01
	^D50000	;RP02
	^D50000	;RP03
	^D110000	;DUAL POSITIONER MD10
	^D110000	;SINGLE POSITIONER MD10
	0	;RS04
	^D27000	;RP04
	^D27000	;RP06
	^D27000	;RM03
	^D23000	;RP07
	^D25000	;RP20
	0	;RA80
	0	;RA81
	0	;RA60


TEMPTR:	0			;ACTUAL PTR. USED
;TABLE OF MINIMUM IN-CORE-PROTECT TIMES FOR VARIOUS DEVICES (PROT0)
PRT0TB:	^D3000000	;NEW DRUM - UNKNOWN
	^D3000000	;DITTO
	^D3000000	;RD10
	^D1500000	;RM10B
	^D7000000	;RP01
	^D5000000	;RP02
	^D5000000	;RP03
	^D8000000	;DUAL POSITIONER MD10
	^D8000000	;SINGLE POSITIONER MD10
	^D1500000	;RS04
	^D2000000	;RP04
	^D2000000	;RP06
	^D2000000	;RM03
	^D2000000	;RP07
	^D2000000	;RP20
	^D2000000	;RA80
	^D2000000	;RA81
	^D2000000	;RA60

;TABLE OF IN-CORE-PROTECT TIME MULTIPLIERS BY DEVICE (PROT)
PROTTB:	0		;NEW DRUM - UNKNOWN
	0		;DITTO
	0		;RD10
	0		;RM10B
	0		;RP01
	0		;RP02
	0		;RP03
	0		;DUAL POSITIONER MD10
	0		;SINGLE POSITIONER MD10
	0		;RS04
	0		;RP04
	0		;RP06
	0		;RM03
	0		;RP07
	0		;RP20
	0		;RA80
	0		;RA81
	0		;RA60
;TABLE OF MAXIMUM IN-CORE-PROTCT TIMES FOR VARIOUS DEVICES (PROTM)
PRTMTB:	^D3000000	;NEW DRUM - UNKNOWN
	^D3000000	;DITTO
	^D3000000	;RD10
	^D1500000	;RM10B
	^D7000000	;RP01
	^D5000000	;RP02
	^D5000000	;RP03
	^D8000000	;DUAL POSITIONER MD10
	^D8000000	;SINGLE POSITIONER MD10
	^D1500000	;RS04
	^D2000000	;RP04
	^D2000000	;RP06
	^D2000000	;RM03
	^D2000000	;RP07
	^D2000000	;RP20
	^D2000000	;RA80
	^D2000000	;RA81
	^D2000000	;RA60

;TABLE OF MINIMUM PQ2 IN QUEUE TIMES BY DEVICE (QADTAB+1)
ADDTAB:	^D3000000/4	;NEW DRUM - UNKNOWN
	^D3000000/4	;DITTO
	^D3000000/4	;RD10
	^D1500000/4	;RM10B
	^D7000000/4	;RP01
	^D5000000/4	;RP02
	^D5000000/4	;RP03
	^D8000000/4	;DUAL POSITIONER MD10
	^D8000000/4	;SINGLE POSITIONER MD10
	^D1500000/4	;RS04
	^D2000000/4	;RP04
	^D2000000/4	;RP06
	^D2000000/4	;RM03
	^D2000000/4	;RP07
	^D2000000/4	;RP20
	^D2000000/4	;RA80
	^D2000000/4	;RA81
	^D2000000/4	;RA60
;TABLE OF PQ2 MULTIPLIERS FOR IN QUEUE TIME BY DEVICE (QMLTAB+1)
MULTAB:	^D3000000/4	;NEW DRUM - UNKNOWN
	^D3000000/4	;DITTO
	^D3000000/4	;RD10
	^D1500000/4	;RM10B
	^D7000000/4	;RP01
	^D5000000/4	;RP02
	^D5000000/4	;RP03
	^D8000000/4	;DUAL POSITIONER MD10
	^D8000000/4	;SINGLE POSITIONER MD10
	^D1500000/4	;RS04
	^D2000000/4	;RP04
	^D2000000/4	;RP06
	^D2000000/4	;RM03
	^D2000000/4	;RP07
	^D2000000/4	;RP20
	^D2000000/4	;RA80
	^D2000000/4	;RA81
	^D2000000/4	;RA60

;TABLE OF MAXIMUM PQ2 IN QUEUE TIMES BY DEVICE (QMXTAB+1)
MAXTAB:	^D3000000/2	;NEW DRUM - UNKNOWN
	^D3000000/2	;DITTO
	^D3000000/2	;RD10
	^D1500000/2	;RM10B
	^D7000000/2	;RP01
	^D5000000/2	;RP02
	^D5000000/2	;RP03
	^D8000000/2	;DUAL POSITIONER MD10
	^D8000000/2	;SINGLE POSITIONER MD10
	^D1500000/2	;RS04
	^D2000000/2	;RP04
	^D2000000/2	;RP06
	^D2000000/2	;RM03
	^D2000000/2	;RP07
	^D2000000/2	;RP20
	^D2000000/2	;RA80
	^D2000000/2	;RA81
	^D2000000/2	;RA60
SUBTTL	MANDATORY ONCE ONLY CODE -- GOHOME - REWRITE HOME BLOCKS


GOHOME::PUSHJ	P,GTMNB1	;GET A MONITOR BUFFER
	HLRZ	U,SYSUNI##	;POINT TO FIRST UNIT IN SYSTEM
	PUSH	P,[EXP 0]	;INIT COUNTER

GOHOM1:	MOVSI	T1,UNPHWP!UNPOFL ;BITS TO TEST
	MOVSI	T2,UNPCHG	;AND MORE
	TDNN	T1,UNIDES(U)	;HARDWARE WRITE PROTECT OR OFFLINE?
	TDNN	T2,UNIDES(U)	;PARAMETERS CHANGE?
	JRST	GOHOM2		;IGNORE THIS UNIT
	PUSHJ	P,HOMWRT	;REWRITE THE HOME BLOCKS
	AOS	(P)		;INDICATE DISK WAS WRITTEN

GOHOM2:	MOVEI	T3,UNVNPM	;NO-PACK-MOUNTED STATE
	MOVSI	T1,UNPNMU	;NOT-OUR-DISK-SET FLAG
	TDNE	T1,UNIDES(U)	;IS IT ON?
	DPB	T3,UNYUST##	;YES--MAKE IT USEABLE
	MOVSI	T1,UNPTSB	;GET TIMESHARED BIT(S) IN UNIDES
	ANDCAM	T1,UNIDES(U)	;CLEAR THEM OUT
IFN FTDUAL,<
	LDB	T3,UNYUST##	;GET STATE TO PROPAGATE
	SKIPE	T2,UNI2ND(U)	;ALTERNATE PORT?
	ANDCAM	T1,UNIDES(T2)	;CLEAR THEM HERE TOO
	EXCH	T2,U		;SWAP FOR BYTE POINTERS
	SKIPE	U		;IF A SECOND PORT,
	DPB	T3,UNYUST##	;PROPAGATE PACK STATE
	EXCH	T2,U		;SWAP BACK
>; END IFN FTDUAL
	HLRZ	U,UNISYS(U)
	JUMPN	U,GOHOM1	;UNITS ARE LEFT-GO FOR MORE
	POP	P,T1		;GET FLAG BACK
	JUMPE	T1,GOHOM3	;NO MESSAGE IF NOTHING HAPPENED
	MOVEI	T1,[ASCIZ /[HOME blocks updated]/]
	PUSHJ	P,CONOUT##	;PRINT MESSAGE

GOHOM3:	PUSHJ	P,GTODDB	;GET ONCE-ONLY DDB ADDRESS
	SETZ	T1,		;FIND FIRST STRUCTURE TO REFRESH
	PUSHJ	P,RFIND		;...
	  SKIPA			;NOTHING TO REFRESH
	PUSHJ	P,.REFRE	;REFRESH SOMETHING
	  JFCL			;IGNORE ERRORS
	POPJ	P,		;RETURN
SUBTTL	MANDATORY ONCE ONLY CODE -- KONCE - KILL OFF ONCE-ONLY DATA BASE


KONCE::	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,U		;SAVE U
	HLRZ	U,SYSUNI##	;POINT TO START OF UNITS

KONCE1:	PUSHJ	P,KUNIT		;KILL OFF UNIT-RELATED PARAMETERS
	HLRZ	U,UNISYS(U)	;LINK TO NEXT UNIT
	JUMPN	U,KONCE1	;LOOP FOR ALL UNITS
	MOVE	P1,STRAOB##	;AOBJN POINTER TO STRUCTURE TABLE

KONCE2:	SKIPE	P2,TABSTR##(P1)	;GET A STR DB
	PUSHJ	P,KSTR		;KILL IT OFF
	AOBJN	P1,KONCE2	;LOOP FOR ALL STRUCTURES
	POP	P,U		;RESTORE U
	POPJ	P,		;RETURN
KSTR:	MOVEI	T1,STRLEN##	;STR DB LENGTH
	MOVE	T2,P2		;STR DB ADDRESS
	PUSH	P,STRFSN##(P2)	;SAVE OUR FSN
	PUSHJ	P,GIVWDS##	;RELEASE CORE
	POP	P,T1		;RESTORE THE FSN
	HRRZS	T1		;ISOLATE FSN
	SETZM	TABSTR##(T1)	;CLEAR TABSTR ENTRY
	POPJ	P,		;RETURN

KUNIT:	SETZM	UNIHID(U)	;CLEAR OUT LOGICAL UNIT NAME
	SETZM	UNILOG(U)	;CLEAR OUT NAME OF LOGICAL UNIT WITHIN STR
	SETZM	UNISTR(U)	;CLEAR OUT LINKS TO STR
	HRRZS	UNIGRP(U)	;CLEAR CLUSTERS TRIED FOR ON O/P
	SETOM	UNISUN(U)	;SAY NOT IN ASL
	PUSHJ	P,DELSAB	;DELETE SAB RING AND SPT TABLE
	MOVEI	T1,0		;GET A ZERO
	DPB	T1,UNYBPC##	;CLEAR BLOCKS PER CLUSTER
	DPB	T1,UNYSIC##	;CLEAR SATS IN CORE
	DPB	T1,UNYSPU##	;CLEAR SATS PER UNIT
	PUSHJ	P,DELSST	;DELETE SWAPPING SATS
	MOVSI	T1,UNPNMU	;WRONG-DISK-SET FLAG
	ANDCAM	T1,UNIDES(U)	;CLEAR IT UNTIL NEXT TIME WE SET IT
	POPJ	P,		;RETURN
SUBTTL	UNIT ROUTINES -- CHGUNI - CHANGE


CHGUNI::AOSE	BLURBF		;OPERATOR SEEN THIS TEXT BEFORE?
	JRST	CHGUN1		;YES--SKIP IT
	PUSHJ	P,PRSCON##	;DOES HE KNOW WHAT HE'S DOING?
	  JRST	CHGUN1		;MAYBE--GIVE HIM A BREAK
	MOVEI	T1,INTRO	;POINT TO INTRODUCTORY TEXT
	PUSHJ	P,CONOUT##	;PRINT IT
	MOVEI	T1,REFPRM	;SPECIAL PARAMETER DISCLAIMER
	PUSHJ	P,CONOUT##	;PRINT IT

CHGUN1:	MOVEI	T1,[ASCIZ /Unit to change/]
	SETZ	T2,		;NO DEFAULT
	PUSHJ	P,PRSSIX##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,VFCORE	;GO VERIFY INCORE DATA BASE IF NO MORE
	HLRZ	U,SYSUNI##	;GET FIRST UNIT DATA BLOCK IN SYSTEM

CHGUN2:	CAME	T1,UNIHID(U)	;MATCH ON UNIT ID
	CAMN	T1,UDBNAM(U)	; OR DRIVE NAME
	JRST	CHGUN3		;FOUND IT
	HLRZ	U,UNISYS(U)	;LINK TO NEXT UNIT IN SYSTEM
	JUMPN	U,CHGUN2	;LOOP BACK AND TRY AGAIN
	MOVEI	T2,[ASCIZ /does not exist/]
	PUSHJ	P,UWARN		;WARN OPERATOR
	JRST	CHGUNI		;AND TRY AGAIN

CHGUN3:	PUSHJ	P,CKUSTR	;MAKE SURE WE ASK ABOUT MOUNTED UNITS
	  JRST	CHGUNI		;HE ABORTED THIS ONE
	HRRZ	P2,UNISTR##(U)	;LOAD UP THE STR POINTER, IF ANY
	MOVEI	T1,[ASCIZ /Do you want to see the BAT blocks/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	MOVEM	T1,BATFLG	;SAVE FOR LATER USE
	MOVEI	T1,[ASCIZ /Parameters for unit /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	PUSHJ	P,GETUID	;GET UNIT ID
	PUSHJ	P,GETSPU	;GET SATS PER UNIT
	PUSHJ	P,GETSIC	;GET SATS IN CORE
	PUSHJ	P,GETK4S	;GET K FOR SWAPPING
	PUSHJ	P,GETSWB	;GET FIRST SWAPPING BLOCK NUMBER
	PUSHJ	P,GETCFS	;GET CLASS FOR SWAPPING
	PUSHJ	P,GETASL	;GET SINGLE UNIT ASL INFO
	SKIPN	BATFLG		;DO WE WANT TO SEE THE BAT BLOCKS?
	JRST	CHGUN4		;NO--SKIP THIS
	MOVEI	T1,0		;YES--GET FLAG FOR OPTIONAL INIT OF BAD BLOCKS
	PUSHJ	P,GETBAT	;CHECK AND DISPLAY THE BAF
	  PUSHJ	P,INIBAT	;INITIALIZE IF NEEDED

CHGUN4:	JRST	CHGUNI		;LOOP BACK FOR ANOTHER UNIT
SUBTTL	UNIT ROUTINES -- ONCBND - BIND CI UNITS


;ROUTINE CALLED BEFORE READING HOM BLOCKS TO BIND UNATTACHED UNITS.
;CALL:
;	PUSHJ	P,ONCBND
;RETURN:
;	CPOPJ ALWAYS

IFN FTCIDSK,<
ONCBND::SKIPE	[M.RAX##]	;SKIP IF RAXKON NOT INCLUDED
	SKIPE	BNDFLG##	;ALREADY BEEN HERE?
	POPJ	P,		;YES
	PUSHJ	P,SAVT##	;SAVE ACS
	MOVEI	T1,[SE1ENT	;LOAD ROUTINE TO EXECUTE
		    SKIPN T2,.CPPCB##-.CPCDB##(P1) ;GET PCB ADDRESS
		    POPJ  P,	;NONE, RETURN
		    MOVE  T2,.PCSTS(T2) ;GET STATUS FLAGS
		    TLNN T2,(ST.DED) ;IS THE KLIPA DEAD?
		    SETO T3,	;NO, REMEMBER WE HAD A RUNNING ONE
		    POPJ  P,]
	SETZ	T3,		;START AFRESH
	PUSHJ	P,CPUAPP##	;DOES ANY CPU HAVE A KLIPA WHICH IS RUNNING?
	JUMPE	T3,CPOPJ##	;IF NOT, DON'T BOTHER WAITING
	MOVEI	T1,[ASCIZ /
[Initializing CI network] /] ;GET MESSAGE
	PUSHJ	P,ICONM##	;TELL THE OPERATOR
	PUSHJ	P,OPOUT##	;FORCE OUTPUT
	MOVE	T1,BNDTIM	;HOW MANY SECONDS TO WAIT
	IMUL	T1,TICSEC##	;CONVERT TO TICKS
	ADD	T1,BNDBEG	;FIND OUT WHEN THE WAIT IS OVER
ONCBN1:	CAMLE	T1,SYSUPT##	;HAVE WE WAITED LONG ENOUGH?
	JRST	[PUSHJ P,APRCHK## ;UPDATE TIME
		 JRST  ONCBN1]	;CHECK AGAIN
	MOVEI	T1,[ASCIZ /

/]
	PUSHJ	P,ICONM##	;START THE MESSAGE
	PUSHJ	P,OPOUT##	;FLUSH THE OUTPUT
ONCBN2:	SETOM	BNDFLG##	;WE'RE READY TO BIND THE UNITS NOW
				; SO FUTURE ONLINES SHOULD BIND THEMSELVES
	MOVEI	J,KDBTAB##+.TYDSK-KDBNXT ;SET UP INITIAL LINK
ONCBN3:	SKIPN	J,KDBNXT(J)	;GET NEXT KDB ADDRESS
	POPJ	P,		;RETURN WHEN DONE
	LDB	T1,KOYKTP##	;GET KONTROLLER TYPE
	CAIE	T1,TYPRA	;CI DISK?
	JRST	ONCBN3		;NO, SKIP IT
	SETZB	P1,ONLFLG	;START WITH CPU0, SET END PACKET FLAGS TO ZERO
ONCBN4:	MOVEI	P2,1		;GET A BIT
	LSH	P2,(P1)		;POSITION FOR CPUN
	TDNN	P2,KDBCAM(J)	;CAN THIS CPU ACCESS THIS KONTROLLER?
	JRST	ONCBN8		;NO, ON TO NEXT CPU
	HLRE	P3,KDBIUN(J)	;GET -VE NUMBER OF UNITS
	SETCA	P3,P3		;START WITH HIGHEST UNIT

ONCBN5:	SKIPN	U,@KONPTR(J)	;GET A UDB ADDRESS
	JRST	ONCBN7		;NOT FOR THIS UNIT NUMBER
	HRRZ	T1,UNIALT(U)	;SEE IF ALTERNATE PORT ALREADY ATTACHED
	JUMPE	T1,ONCBN6	;JUMP IF NO ALTERNATE
	MOVEI	T2,CPUMSK	;MASK FOR ALL CPU BITS
	TDNE	T2,UDBCAM(T1)	;ANY CPU HAVE ALTERNATE PORT ATTACHED?
	JRST	ONCBN7		;YES, DON'T BIND THIS UNIT
	MOVE	T1,UDBKDB(T1)	;ALTERNATE KDB
	MOVE	T1,KONBSY(T1)	;HAVE WE ALREADY PROCESSED ALTERNATE KDB?
	TLNE	T1,KOPBND
	JRST	ONCBN6		;YES, BIND UNIT HERE AS WILL NOT BE BOUND ELSEWHERE
	LDB	T1,KOYKNM##	;GET KONTROLLER NUMBER
	LDB	T2,UNYKOF##	;GET KONTAB OFFSET
	XOR	T1,T2		;TRY TO BIND HALF OF THE UNITS ON EACH KDB
	TRNE	T1,1		;...
	JRST	ONCBN7		;LET ALTERNATE KDB TACKLE THIS ONE
ONCBN6:	TDNE	P2,UDBCAM(U)	;IS THIS UNIT ALREADY BOUND ON THIS CPU?
	JRST	ONCBN7		;YES
	PUSH	P,U		;SAVE UDB ADDRESS
	HRRZ	U,UNIALT(U)	;ALTERNATE UNIT
	SKIPE	U		;IF AN ALTERNATE,
	PUSHJ	P,DETUDB##	; REMOVE FROM UNISYS CHAIN, PUT ON SYSDET CHAIN
	POP	P,U		;RESTORE UDB ADDRESS
	MOVE	T1,P1		;COPY CPU NUMBER
	XCTCPU	(CPN,ONCONL)	;BIND THE UNIT
	  PUSHJ	P,BNDERR	;ERROR, PRINT SOMETHING
ONCBN7:	SOJGE	P3,ONCBN5	;LOOP FOR ALL UNITS
ONCBN8:	CAIGE	P1,M.CPU##-1	;DONE THEM ALL?
	AOJA	P1,ONCBN4	;NO, LOOP FOR OTHER CPUS
	MOVSI	T1,KOPBND	;GET A BIT TO TEST
	IORM	T1,KONBSY(J)	;SHOW WE'VE PROCESSED THIS KDB
	JRST	ONCBN3		;BACK TO NEXT KONTROLLER
;HERE IF ONLINE FAILED

BNDERR:	PUSHJ	P,PRSSET##	;SET UP SPECIAL BUFFER, .CPTOA, ETC.
	PUSH	P,T1		;SAVE OLD CHARACTER TYPER
	MOVEI	T1,[ASCIZ /online failed/]
	PUSHJ	P,CONMES##	;STORE TEXT
IFN FTMP,<
	MOVEI	T1,[ASCIZ / via CPU/]
	PUSHJ	P,CONMES##	;MORE
	MOVEI	T3,"0"(P1)	;GET CPU NUMBER
	PUSHJ	P,COMTYO##	;PRINT DIGIT
>; END IFN FTMP
	POP	P,.CPTOA##	;RESTORE CHARACTER STICKER
	MOVE	T1,UDBNAM(U)	;GET DRIVE NAME
	MOVEI	T2,TXTBUF##	;POINT TO GENERATED TEXT
	PJRST	UWARN		;WARN OPERATOR AND RETURN

BNDBEG::BLOCK	1		;TIME STAMP
BNDTIM:	M.BNDT##		;SECS TO WAIT FOR CI NETWORK TO SETTLE
>; END IFN FTCIDSK

SUBTTL	UNIT ROUTINES -- SHWUNI - SHOW


SHWUNI::HLRZ	U,SYSUNI##	;FIND FIRST UNIT IN SYSTEM
	JUMPE	U,[		;JUMP IF NONE
		MOVEI	T1,[ASCIZ /% No units found/]
		AOS	(P)	;SKIP ANYWAY
		PJRST	CONOUT]	;GIVE WARNING AND RETURN
	MOVEI	T1,[ASCIZ /Unit/]
	SETZ	T2,		;NO DEFAULT STRUCTURE NAME
	PUSHJ	P,PRSSIX##	;GET A SIXBIT QUANTITY
	JUMPE	T1,CPOPJ1##	;GIVE UP IF NO RESPONSE
	HLRZ	U,SYSUNI##	;FIRST UNIT IN SYSTEM
	PUSHJ	P,FNDALL	;DID THE USER ASK FOR ALL?
	  JRST	SHWUN2		;NO, GO FIND THE UNIT

SHWUN1:	PUSHJ	P,SHWUNT	;SHOW A UNIT
	HLRZ	U,UNISYS(U)	;GET THE NEXT UNIT
	JUMPN	U,SHWUN1	;LOOP IF MORE
	JRST	SHWUNI		;LOOP IN CASE HE WANTS TO SEE ONE AGAIN

SHWUN2:	CAME	T1,UDBNAM(U)	;DRIVE NAME?
	CAMN	T1,UNIHID(U)	; OR UNIT ID?
	JRST	SHWUN3		;YES
	HLRZ	U,UNISYS(U)	;LINK TO NEXT
	JUMPN	U,SHWUN2	;KEEP SEARCHING
	MOVEI	T2,[ASCIZ /does not exist/]
	PUSHJ	P,UWARN		;WARN OPERATOR
	JRST	SHWUNI		;TRY AGAIN

SHWUN3:	PUSHJ	P,SHWUNT	;SHOW THE UNIT
	MOVSI	T1,UNPNMU	;WRONG-DISK-SET FLAG
	TDNE	T1,UNIDES(U)	;CHECK IT
	JRST	SHWUN4		;CAN'T DO THIS IF SO
	MOVEI	T1,[ASCIZ /Do you want to see the bad regions/]
	MOVSI	T2,'NO '	;DEFAULT
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,SHWUN4	;NO--SKIP THIS
	MOVEM	T1,BATFLG	;SAVE FOR LATER
	MOVEI	T1,1		;CODE FOR NO OPERATOR OPTION
	PUSHJ	P,GETBAT	;CHECK OUT BAT BLOCKS
	  JFCL			;IGNORE ERRORS

SHWUN4:	JRST 	SHWUNI		;AND LOOP FOR MORE

SHWUNT:	PUSHJ	P,CRLFOP##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ /Parameters for unit /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T2,UDBNAM(U)	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ  /    Unit ID: /]
	PUSHJ	P,ICONM##	;PRINT IT
	MOVE	T2,UNIHID(U)	;GET ID
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /   *K for swapping: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE
	LDB	T1,UNYK4S##	;GET K FOR SWAPPING
	JUMPE	T1,SHWUT1	;NO SWAPPING STUFF IF NO SPACE ALLOCATED

	MOVEI	T1,[ASCIZ /   *First logical block for swapping: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	MOVE	T1,UNISLB(U)	;GET VALUE
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ /    Swapping class: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,UNYCFS##	;GET CLASS
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

SHWUT1:	MOVEI	T1,[ASCIZ  /   *SAT blocks per unit: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,UNYSPU##	;GET SATS PER UNIT
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ  /    SAT blocks in core: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	LDB	T1,UNYSIC##	;GET SATS IN CORE
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

	MOVEI	T1,[ASCIZ  /    Unit in the ASL: /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	SKIPGE	UNISUN(U)	;IN THE ASL?
	TDZA	T1,T1		;NO
	MOVEI	T1,1		;YES
	MOVE	T2,[EXP <'NO    '>,<'YES   '>](T1) ;TRANSLATE
	PUSHJ	P,PRNAME##	;PRINT VALUE
	PUSHJ	P,CRLFOP##	;END LINE

	HRRZ	T1,UNISTR(U)	;GET UPWARD POINTER TO STRUCTURE
	JUMPE	T1,SHWUT2	;NOT IN A STR
	MOVEI	T1,[ASCIZ  /    Unit in structure /]
	PUSHJ	P,ICONM##	;PRINT TEXT
	HRRZ	T2,UNISTR(U)	;GET STR POINTER
	MOVE	T2,STRNAM##(T2)	;AND ITS NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP##	;END LINE

SHWUT2:	MOVSI	T1,UNPNMU	;WRONG-DISK-SET BIT
	TDNN	T1,UNIDES(U)	;IS IT SET?
	JRST	SHWUT3		;NO--DON'T SAY IT IS
	MOVEI	T1,[ASCIZ  /    Unit in a disk set not mounted to this system/]
	PUSHJ	P,CONOUT##	;DUMP THE MESSAGE

SHWUT3:	POPJ	P,		;RETURN


FNDALL:	TRNE	T1,-1		;DOES RESPONSE HAVE MORE THAN 3 CHARACTERS?
	POPJ	P,		;YES, THEN IT'S NOT ALL, RETURN
REPEAT 0,<
	MOVE	T2,[SIXBIT /ALL/] ;SET UP AC FOR COMPARE
	TLNE	T1,77		;DO WE HAVE THREE CHARACTERS EXACTLY?
	JRST	FNDAL1		;YES
	TLNE	T1,7777		;DO WE HAVE TWO OR ONE?
	TLZA	T2,77		;TWO, MASK COMPARE AC
	TLZ	T2,7777		;JUST ONE, FIX COMPARE AC
FNDAL1:	CAMN	T1,T2		;DID THE USER ASK FOR ALL?
> ;END OF REPEAT 0
	CAMN	T1,[SIXBIT /ALL/]	;DID THE USER ASK FOR ALL?
	AOS	(P)		;YES, SKIP RETURN
	POPJ	P,		;RETURN

SUBTTL	VOLUME ID PROCESSING -- CHKVSY - CHECK ID


;SUBROUTINE TO CHECK VOLUME ID TYPE
;CALL WITH:
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,CHKVSY
;	RETURN HERE IF VOLUME ID TYPE IS 'TOPS-10'
;	RETURN HERE IF VOLUME ID TYPE IS NOT 'TOPS-10', WITH
;		T1 = BYTE POINTER TO VOLUME ID TYPE STRING IN ASCIZ

CHKVSY:	PUSHJ	P,SAVE2##	;SAVE P1-P2
	MOVEI	P1,HOMVSY##	;OFFSET TO VOLUME ID
	LSH	P1,2		;MAKE BYTE ADDRESS
	MOVE	T3,[POINT 7,VSYBFR] ;POINTER TO TEMP BUFFER
	MOVEI	T4,3*4		;3 WORDS OF 4 BYTES EACH

CHKVS1:	MOVE	T1,P1		;T1 IS BYTE ADDRESS
	PUSHJ	P,VOLIDP	;GET POINTER
	ADD	T1,-2(P)	;ADD ADDRESS OF BUFFER
	LDB	T2,T1		;GET THE BYTE
	SKIPN	T2		;IF NULL,
	MOVEI	T2," "		; MAKE A BLANK
	IDPB	T2,T3		;STUFF IN TEMP BUFFER
	CAIE	T2," "		;NON-BLANK?
	MOVE	P2,T3		;YES, SAVE POINTER TO END OF SYSTEM TYPE
	SOSLE	T4		;QUIT IF DONE
	AOJA	P1,CHKVS1	;LOOP FOR MORE
	DMOVE	T1,VSYBFR	;GET DECODED SYSTEM TYPE
	MOVE	T3,VSYBFR+2	;3 WORDS WORTH
	CAMN	T1,[ASCII .TOPS-.] ;IS IT 'TOPS-10'?
	CAME	T2,[ASCII .10   .] ;...
	JRST	CHKVS2		;NO
	CAMN	T3,[ASCII .  .]	;LAST WORD HAVE 2 BLANKS?
	POPJ	P,		;YES, SYSTEM TYPE IS VALID

CHKVS2:	AOS	(P)		;SET FOR SKIP RETURN
	CAMN	T1,[ASCII .     .] ;NULL SYSTEM TYPE?
	CAME	T2,[ASCII .     .] ;...
	JRST	CHKVS3		;NO
	CAMN	T3,[ASCII .  .]	;LAST WORD HAVE 2 BLANKS?
	SKIPA	T1,[[ASCIZ /unknown/]] ;GENERIC TEXT

CHKVS3:	MOVEI	T1,VSYBFR	;ADDRESS OF DECODED SYSTEM TYPE TEXT
	SETZ	T2,		;GET A ZERO
	IDPB	T2,P2		;TERMINATE SYSTEM TYPE AS ASCIZ
	POPJ	P,		;RETURN

;BUFFER TO EXTRACT SYSTEM TYPE FIELD FROM VOLUME ID BLOCK

VSYBFR:	BLOCK	3		;12 CHARACTERS OF SYSTEM TYPE
SUBTTL	VOLUME ID PROCESSING -- VOLIDN - STORE ONE SIXBIT WORD


;SUBROUTINE TO STORE 1 SIXBIT WORD IN VOLUME ID
;CALL WITH:
;	T1 = BYTE # WITHIN HOME BLOCK (PDP-11 WISE)
;	T2 = WORD
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,VOLIDN
;	RETURN HERE
;
VOLIDN:	PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,T1
	MOVEI	P1,-1(T1)	;SETUP ADDRESS
	MOVEI	T4,6		;BYTE COUNT

VOLDN1:	MOVEI	T3,0		;CLEAR WORD
	ROTC	T2,6		;COPY BYTE
	ADDI	T3,"0"-'0'	;CONVERT TO ASCII
	AOS	T1,P1		;T1 IS BYTE ADDRESS
	PUSHJ	P,VOLIDP	;GET POINTER
	ADD	T1,-2(P)	;ADD ADDRESS OF BUFFER
	DPB	T3,T1		;STORE IN BUFFER
	SOJG	T4,VOLDN1	;LOOP OVER WHOLE WORD
	JRST	TPOPJ##		;RETURN
SUBTTL	VOLUME ID PROCESSING -- VOLIDP - COMPUTE BYTE POINTERS


;SUBROUTINE TO COMPUTE BYTE POINTER TO BYTE IN VOLID PART
;CALL WITH:
;	T1 = BYTE NUMBER WITHIN HOME BLOCK
;	PUSHJ	P,VOLIDP
;	RETURN HERE WITH POINTER IN T1
;
VOLIDP:	PUSH	P,T2
	IDIVI	T1,4		;T1=WORD #, T2=BYTE #
	ADD	T1,VOLPTT(T2)	;GET CORRECT POINTER
	JRST	T2POPJ##	;RETURN

VOLPTT:	POINT	7,0,17		;BYTE 0
	POINT	7,0,9		;BYTE 1
	POINT	7,0,35		;BYTE 2
	POINT	7,0,27		;BYTE 3
SUBTTL	VOLUME ID PROCESSING -- VOLPPN - GENERATE A PPN


; SUBROUTINE TO GENERATE A PPN
; CALL:	PUSHJ	P,VOLPPN
;	RETURN HERE WITH T1&T2 CONTAINING PPN STRING IN SIXBIT
;
VOLPPN:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	SETZB	T1,T2		;CLEAR RESULT
	MOVE	P2,[POINT 6,T1]	;BYTE POINTER TO STORE RESULT
	MOVEI	T3,'['		;GET A BRACKET
	PUSHJ	P,VOLCHR	;STORE IT
	HLRZ	T3,HOMOPP##(P1)	;GET PROJECT #
	CAIN	T3,777777	;WILD?
	JRST	[MOVEI	T3,'*'	;YES
		 PUSHJ	P,VOLCHR ;TYPE *
		 JRST	.+2]	;ONWARD
	PUSHJ	P,VOLOCT	;CONVERT IT
	MOVEI	T3,','		;GET A COMMA
	PUSHJ	P,VOLCHR	;STORE IT
	HRRZ	T3,HOMOPP##(P1)	;GET PROGRAMMER #
	CAIN	T3,777777	;WILD?
	JRST	[MOVEI	T3,'*'	;YES
		 PUSHJ	P,VOLCHR ;TYPE *
		 JRST	.+2]	;ONWARD
	PUSHJ	P,VOLOCT	;CONVERT IT
	MOVEI	T3,']'		;GET A BRACKET
	PJRST	VOLCHR		;STORE IT AND RETURN


VOLOCT:	IDIVI	T3,10		;DIVIDE BY RADIX
	PUSH	P,T4		;SAVE REMAINDER
	SKIPE	T3		;DONE?
	PUSHJ	P,VOLOCT	;NO - RECURSE
	POP	P,T3		;GET CHARACTER
	ADDI	T3,'0'		;MAKE IT SIXBIT

VOLCHR:	TRNN	T2,77		;12 CHARACTERS MAXIMUM
	IDPB	T3,P2		;STORE CHARACTER
	POPJ	P,		;RETURN
SUBTTL	VOLUME ID PROCESSING -- WRTVID - WRITE VOLUME ID FIELDS


;SUBROUTINE TO SETUP VOLUME ID FIELDS IN HOME BLOCK
;CALL WITH:
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,WRTVID
;	RETURN HERE
;
WRTVID:	MOVEI	T1,HOMVID##	;GET OFFSET TO VOLUME ID
	LSH	T1,2		;MAKE BYTE ADDRESS
	MOVE	T2,HOMHID##(P1)	;GET PACK NAME
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	ADDI	T1,6		;SKIP AHEAD
	MOVEI	T2,0		;BLANKS
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	MOVEI	T1,HOMVSY##	;GET SYSTEM TYPE
	LSH	T1,2		;CONVERT TO BYTES
	MOVE	T2,[SIXBIT "TOPS-1"]
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	ADDI	T1,6		;BUMP 1 1/2 WORDS
	MOVSI	T2,'0  '	;ADD IN ZERO
	PUSHJ	P,VOLIDN	;STORE NAME
	DMOVE	T1,[EXP <SIXBIT/SYSTEM/>,0] ;ASSUME NO OWNER PPN
	SKIPE	HOMOPP##(P1)	;IS THERE AN OWNER
	PUSHJ	P,VOLPPN	;YES -GENERATE PPN
	EXCH	T1,T2		;SWAP WORDS
	PUSH	P,T1		;SAVE SECOND WORD
	MOVEI	T1,HOMOWN##
	LSH	T1,2
	PUSHJ	P,VOLIDN
	ADDI	T1,6
	POP	P,T2		;GET SECOND WORD BACK
	PJRST	VOLIDN
;START OF VERIFY CODE
VFCORE::SETZM	SERIUS		;INIT SERIOUS ERROR FLAG
	SETZM	BATMAN		;ASSUME OPTIONAL FOR VENDING BAT BLOCKS
	PUSHJ	P,CHKSTR	;MAKE SURE ALL STRS HAVE ALL NECESSARY UNITS
	PUSHJ	P,BOOTDB##	;IF DEBUGGING, HACK UP THE SSL/SDL/ASL
	PUSHJ	P,BLDSSL##	;BUILD SYSTEM SEARCH LIST FROM PRESERVED COPY
	  PUSHJ	P,DSKSSL	;USE THE DISK DATA BASE
	PUSHJ	P,BLDASL##	;BUILD ACTIVE SWAPPING LIST FROM PRESERVED COPY
	  JFCL			;IGNORE ERRORS
	PUSHJ	P,DSKASL	;USE THE DISK DATA BASE
	PUSHJ	P,BLDSDL##	;BUILD SYSTEM DUMP LIST FROM PRESERVED COPY
	  PUSHJ	P,DSKSDL	;USE THE DISK DATA BASE
	MOVE	T1,SERIUS	;GET SERIOUS ERROR COUNT
	IOR	T1,ERRHOM	;AND HOME BLOCK ERROR COUNT
	SKIPN	T1		;ANY ERRORS?
	AOS	(P)		;NO - SKIP RETURN
	POPJ	P,		;RETURN
	SUBTTL	SUBROUTINES

;SUBROUTINE TO READ A SAT BLOCK & COUNT THE # OF FREE CLUTERS IN IT

REDSAT:
IFN FTXMON,<
	SE1JRS			;MAKE THE SAB RING ADDRESSABLE
	MOVEI	T1,(MS.SAT)	;WHERE TO READ THE DATA
	HRRM	T1,DEVISN(F)	;STORE SECTION NUMBER FOR MAPIO
>
	HLLZ	T1,SABSCN##(P2)	;GET -VE LENGTH OF THIS SAT BLOCK
	ADDI	T1,-1+SABBIT##(P2)	;MAKE AN IOWD PTR. FOR MONRED
IFN FTXMON,<
	JRST	@[0,,.+1]	;OMNRED CAN'T HACK IT IN SECTION 1
>
	PUSH	P,@ONCMBF	;PRESERVE CURRENT MON. BUFFER ADR.
	MOVEM	T1,@ONCMBF	;STORE NEW IOWD FOR SAT BLOCK
	PUSHJ	P,OMNRED	;GO READ IN "SAT" BLOCK
	  JRST	REDST1		;ERROR WHILE READING SAT BLOCK - NON SKIP RETURN
	AOS	T1,@ONCMBF	;MAKE IOWD BACK INTO AN AOBJN PTR.
	PUSH	P,R		;SAVE R
IFN FTXMON,<
	SE1JRS			;BACK TO SECTION 1
	MOVSI	R,(MS.SAT)	;DATA SECTION
>
IFE FTXMON,<
	SETZ	R,
>
	PUSHJ	P,SATCN##	;COUNT 0 BITS IN SAT BLOCK
	POP	P,R		;RESTORE R
	HRRZM	T2,SABTAL##(P2)	;STORE FREE CLUSTERS IN THIS SAT
	SETOM	SABHOL##(P2)	;DONT KNOW SIZE OF LARGEST HOLE
	HRRZS	T2		;CLEAR OUT LH
	MOVSI	T1,SAPDOB##	;CLEAR SAT BAD & SAT IN CORE DIFFERENT FROM ON DISK
	ANDCAM	T1,SABFIR##(P2)
	DPB	P1,SAZNDX##	;STORE SAT BLOCK INDEX # IN IN SAB BLOCK
	HRRZ	T1,UNICPS(U)	;GET # CLUSTERS PER SAT FOR THIS UNIT
	IMULI	T1,(P1)		;TIMES SAT BLOCK INDEX
	DPB	T1,SAYCLA##
	AOS	-1(P)		;SKIP RETURN
REDST1:
IFN FTXMON,<
	HLLZS	DEVISN(F)	;I/O IS NOW TO SECTION ZERO
>
	POP	P,@ONCMBF	;RESTORE ORIGINAL MON BUFFER ADR.
	POPJ	P,		;RETURN
;SUBROUTINE TO READ THE "RIB" BLOCK FOR SAT.SYS

GTSRB:	MOVE	P4,STRSAT##(P2)	;GET LOG. BLOCK #'S OF 1ST. & 2ND. "RIB" BLOCKS
	MOVE	P3,[EXP CODRIB##]	;GET CODE WORD FOR "RIB" BLOCKS
	MOVSI	P2,(SIXBIT .SAT.)
	PJRST	REDRUN		;READ & VERIFY "RIB" BLOCKS

;SUBROUTINE TO GET ONCE-ONLY DDB
GTODDB:	PUSH	P,T1
	PUSH	P,T2
	MOVEI	T1,DDBLEN##	;WORDS REQUIRED
	SKIPN	T2,ONCDDB	;ALREADY HAVE DDB?
	PUSHJ	P,INICOR##	;ALLOCATE CORE
	MOVEM	T2,ONCDDB	;SAVE ADDRESS
	MOVE	F,T2		;SET UP F
	JRST	TTPOPJ##	;RESTORE ACS AND RETURN

;SUBROUTINE TO RETURN ONCE-ONLY DDB
GVODDB:	MOVEI	T1,DDBLEN##	;LENGTH
	SKIPE	T2,ONCDDB	;FETCH ADDRESS
	PUSHJ	P,GIVWDS##	;GIVE BACK CORE
	SETZM	ONCDDB		;ZAP ADDRESS
	POPJ	P,		;RETURN

;SUBROUTINE TO GIVE THE MONITOR BUFFER TO A DDB
;RETURNS AN IOWD FOR THE MON BUF IN .UPMBF
GTMNB1:	MOVE	T1,[MBLKSZ##,,MONBUF-1]
	MOVEM	T1,@ONCMBF
	POPJ	P,

;SUBROUTINE TO RETURN THE MONITOR BUFFER
GVMNB0:	SETZM	@ONCMBF
	POPJ	P,
;SUBROUTINE TO MOVE PARAMETERS FROM "HOME" BLOCK TO UNIT DATA BLOCK

MOVUNI:	MOVE	T1,HOMLOG##(P1)
	MOVEM	T1,UNILOG(U)
	MOVE	T1,HOMHID##(P1)
	MOVEM	T1,UNIHID(U)
	MOVE	T1,HOMSID##(P1)
	MOVEM	T1,UNISID(U)
	MOVE	T1,HOMLUN##(P1)
	DPB	T1,UNYLUN##
	SKIPLE	T1,HOMHOM##(P1)
	MOVEM	T1,UNIHOM(U)
	MOVE	T1,HOMGRP##(P1)
	HRLM	T1,UNIGRP(U)
	MOVE	T1,HOMBPC##(P1)
	DPB	T1,UNYBPC##
	MOVE	T1,HOMSUN##(P1)
	MOVEM	T1,UNISUN(U)
	MOVE	T1,HOMSLB##(P1)
	MOVEM	T1,UNISLB(U)
	MOVE	T1,HOMK4S##(P1)
	DPB	T1,UNYK4S##
	MOVE	T1,HOMCFS##(P1)
	DPB	T1,UNYCFS##
	MOVE	T1,HOMSIC##(P1)
	DPB	T1,UNYSIC##
	MOVE	T1,HOMSPU##(P1)
	DPB	T1,UNYSPU##
	MOVSI	T2,UNPMSB
	ANDCAM	T2,UNIDES(U)
	CAIE	T1,1
	IORM	T2,UNIDES(U)
	POPJ	P,
;SUBROUTINE TO FIND AN STR DATA BLOCK GIVEN A SIXBIT NAME
; ENTER WITH T1 = SIXBIT STR NAME TO BE SEARCHED FOR
; IF NO STR DATA BLOCK FOUND - RETURN WITH:
;   P2 = 0. P3 = LAST STR DATA BLOCK ADR.(DIFSTR IF NO STRS)
; IF FOUND - SKIP RETURN WITH:
;   P2 = ADR. OF THE STR DATA BLOCK. P4= SYSTEM STR # OF THIS STR
;   P3 = ADR. OF PREVIOUS STR DATA BLOCK (OR DIFSTR IF THE ONLY STR)
; IN BOTH CASES THE LEADING 4 SIXBIT CHS. IN T1 ARE RESPECTED

FNSTR::	TRZ	T1,7777		;STR NAMES CAN BE NO LONGER THAN 4 CHS.
	MOVE	P4,STRAOB##	;POINT AT FIRST ENTRY IN STR TABLE
FNSTR1:	SKIPE	P2,TABSTR##(P4)	;SKIP IF AN UNUSED SLOT
	CAME	T1,STRNAM##(P2)	;SKIP IF USED SLOT MATCHES
	AOBJN	P4,FNSTR1	;LOOP IF EMPTY SLOT OR SLOT DOESN'T MATCH
	JUMPL	P4,FNSTR2	;BRANCH AHEAD IF WE FIND A MATCHING STR
	SETZ	P2,		;MAKE SURE P2 RETURNS A ZERO IF WE FAIL
	POPJ	P,		;GIVE NONSKIP RETURN IF WE FAIL

;HERE IF WE FIND IT. SCAN LIST IN FORWARD DIRECTION FOR PREDECESSOR
FNSTR2:	HRRZS	P4		;RETURN FSN ONLY
	MOVEI	P3,DIFSTR##	;SET (SYSSTR-STRSYS) AS 1ST PREDECESSOR
FNSTR3:	HLRZ	T2,STRSYS(P3)	;LOOK AT POSSIBLE PREDECESSOR SUCCESOR
	CAIN	T2,(P2)		;SKIP IF HIS SUECCESOR IS NOT US
	JRST	CPOPJ1##	;EXIT WITH P2=STR, P3=PRED, P4=FSN
	MOVE	P3,T2		;STEP TO NEXT PREDECESSOR
	JUMPN	P3,FNSTR3	;LOOP IF THERE IS ANOTHER STR IN THE LIST
	SETZ	P2,		;WE CAN'T GET HERE, BUT FORGET MATCH IF WE DO
	POPJ	P,		;...AND GIVE ERROR RETURN

;SUBROUTINE TO CREATE AN STR DATA BLOCK IN UPPER CORE & ZERO IT OUT
; P2 IS RETURNED WITH ADR. OF THIS STR DATA BLOCK

GETSTR:	MOVE	P4,STRAOB##	;GET AOBJN POINTER INTO TABSTR
	SKIPE	TABSTR##(P4)	;SKIP IF WE FOUND A FREE FSN
	AOBJN	P4,.-1		;LOOP UNTIL WE FIND A FREE FSN, OR WE RUN OUT
	JUMPGE	P4,CPOPJ##	;PASS ALONG ERROR IF NO FREE FSNS
	MOVEI	T2,STRLEN##	;GET SIZE OF STR DATA BLOCK
	PUSHJ	P,CORGRB	;GET CORE FOR STR DATA BLOCK
	HRRZ	P2,T1		;GET ADR. OF NEW STR INTO A KOSHER AC
	HRLI	T1,STRDB##	;PUT AD. OF PROTOTYPE STR DATA BLOCK IN RH
	BLT	T1,-1(T2)	;ZERO IT (T2 SET TO LAST LOC. +1 BY CORGRB)
	MOVEM	P2,TABSTR(P4)	;STORE ADR. OF STR IN TABLE BY ITS LOG. #
	HRRM	P4,STRFSN##(P2)	;INSERT FSN# INTO THE NEW STR DB
	SETOM	STRSRC##(P2)	;NOT IN SSL YET
	HLRZ	T1,SYSSTR##	;GET 1ST STR IN SYSTEM FROM BEFORE THIS ONE
	HRLM	T1,STRSYS##(P2)	;NOW MAKE US POINT AT THAT OLD ONE
	HRLM	P2,SYSSTR##	;AND POINT THE SYSTEM AT US
	JRST	CPOPJ1##	;PASS ALONG GOOD RETURN
;SUBROUTINE TO GRAB CORE FOR THE ONCE ONLY CODE
; ENTER WITH T2 = # WORDS TO GRAB
; RETURN WITH T1 = ADR. OF THE GRABBED CORE
; & T2 = ADR. OF 1ST. FREE WORD

IFE FTXMON,<
CORGRS:				;HERE TO GET CORE FOR SATS
>
CORGRB:	MOVEI	T1,(T2)		;COPY WORDS NEEDED
	PUSHJ	P,INICOR##	;ALLOCATE CORE
	EXCH	T1,T2		;T1=ADDR, T2=WORD COUNT
	ADDI	T2,(T1)		;PUT FIRST FREE ADDR IN T2
	POPJ	P,		;AND RETURN
;SUBROUTINE TO GRAB CORE FROM THE FIRST MONITOR DATA SECTION FOR THE ONCE ONLY CODE
; ENTER WITH T2 = # WORDS TO GRAB IN UPPER CORE
; RETURN WITH T1 = ADR. OF THE GRABBED CORE
; & T2 = ADR. OF 1ST. FREE WORD

IFN FTXMON,<
CORGRS:	PUSH	P,T2		;SAVE AMOUNT DESIRED
	MOVEI	T1,(MS.SAT)	;SECTION NUMBER TO ALLOCATE FROM
	PUSHJ	P,GFWNZN##	;ALLOCATE THE SPACE
	  STOPCD .,STOP,NOCSAT,	;++NO CORE FOR SATS
	POP	P,T2		;RESTORE SIZE
	ADD	T2,T1		;LIKE ADVERTISED
	PUSHJ	P,SAVE3##	;SAVE XBLT ACS
	MOVE	P1,T2		;COMPUTE WORD
	SUB	P1,T1		; COUNT FOR BLT
	SOS	P1		;NEED NUMBER OF WORDS -1
	AOS	P3,T1		;SET UP
	SOS	P2,T1		; BLT ACS
	SETZM	(T1)		;ZERO FIRST WORD
	EXTEND	P1,[XBLT]	;ZERO CORE
	POPJ	P,		;RETURN
>; END IFN FTXMON
;SUBROUTINE TO MOVE PARAMETERS FROM "HOME" BLOCK TO STR DATA  BLOCK

MOVSTR:	MOVE	T1,HOMSNM##(P1)
	MOVEM	T1,STRNAM##(P2)
	MOVE	T1,HOMOPP##(P1)
	MOVEM	T1,STRPPN##(P2)
	MOVE	T1,HOMK4C##(P1)
	HRRM	T1,STRK4C##(P2)
	MOVE	T1,HOMSAT##(P1)
	HRLS	T1
	MOVEM	T1,STRSAT##(P2)
	MOVE	T1,UNIBPU(U)
	CAMLE	T1,STRBPU##(P2)
	MOVEM	T1,STRBPU##(P2)
	MOVE	T1,HOMGAR##(P1)
	MOVEM	T1,STRGAR##(P2)
	MOVE	T1,HOMOVR##(P1)
	MOVEM	T1,STROVR##(P2)
	MOVE	T1,HOMBSC##(P1)
	HRLM	T1,STRBSC##(P2)
	MOVE	T1,HOMSCU##(P1)
	HRRM	T1,STRSCU##(P2)
	MOVE	T1,HOMSRC##(P1)
	MOVEM	T1,STRSRC##(P2)
	SKIPL	T1,HOMSDL##(P1)
	SUBI	T1,1
	MOVEM	T1,STRSDL##(P2)
	MOVE	T1,HOMCRS##(P1)
	MOVEM	T1,STRCRS##(P2)
	HLLZ	T1,HOMCNP##(P1)
	TLZ	T1,77
	HLLM	T1,STYCNP##(P2)
	HLLZ	T1,HOMCKP##(P1)
	TLZ	T1,77
	HLLM	T1,STYCKP##(P2)
	HLLZ	T1,HOMCLP##(P1)
	TLZ	T1,770077
	HLLM	T1,STYCLP##(P2)
	MOVE	T2,HOMPT1##(P1)	;GET FIRST RETRIEVAL POINTER TO MFD
	SETZ	T1,		;GET A ZERO
	DPB	T1,STYCNP##(P2)	;ZERO THE COUNT FIELD IN FIRST POINTER
	MOVEM	T2,STRPT1##(P2)	; SO UFDNXT WILL GET FIRST POINTER FROM MFD RIB
	MOVE	T1,HOMREF##(P1)
	HLLM	T1,STRREF##(P2)
	MOVE	T1,STRUN1##(P2)
	MOVE	T2,HOMUN1##(P1)
	DPB	T2,UN1PTR##
	MOVEM	T1,STRUN1##(P2)
	LDB	T1,HOYPVS##
	DPB	T1,STYPVS##
	LDB	T1,HOYSET##	;GET SET NUMBER
	DPB	T1,STYSET##	;STORE IN SDB
	POPJ	P,
MSGLNG:	HRROS	STRREF##(P2)	;INDICATE STR NEEDS REFRESHING
	PUSH	P,T1		;SAVE 2ND. MSG ADR. IN T1
	MOVE	T1,T3		;GET ADR OF 1ST. MSG
	PUSHJ	P,ICONM##
	MOVE	T1,P1
	PUSHJ	P,RADX10##
	PUSHJ	P,OPOUT##	;O/P BUFFER
	POP	P,T1		;RESTORE 2ND. MSG ADR.
	CAIA

MSGSTR:	HRROS	STRREF##(P2)	;INDICATE STR NEEDS REFRESHING
	PUSHJ	P,ICONM##	;PUT MSG. IN BUFFER
	SETOM	ERRHOM		;INDICATE ERROR READING HOM BLOCKS
	SETOM	SERIUS		;SERIOUS ERROR - CAN'T START SYSTEM
	MOVE	T2,STRNAM##(P2)	;GET SIXBIT STR NAME
	PUSHJ	P,PRNAME##	;PRINT NAME
	PJRST	CRLFOP##	;END LINE
;SUBROUTINE TO READ & VERIFY ALL "BAT" BLOCKS IN THE SYSTEM
;AND SET UP SWAPPING SAT TABLES.

REDBAT:	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN THE SYSTEM
CHKBT1:	MOVSI	T1,UNPOFL	;GET OFFLINE FLAG
	TDNE	T1,UNIDES(U)	;UNIT OFFLINE?
	JRST	CHKBT2		;YES, GO READ NEXT BAT BLOCK
	PUSHJ	P,CHKBAT	;NO - GO CHECK "BAT" BLOCKS FOR THIS UNIT
	  JFCL			;IGNORE ERRORS
	SKIPN	BATMAN		;IN MANDATORY ONCE-ONLY?
	JRST	CHKBT2		;NO POINT SETTING UP SWAPPING SAT IF OPTIONAL
	SE1ENT			;ENTER SECTION ONE
	HRRZ	T3,P1		;LOC OF BAT BLOCK
	LDB	T1,BAYNBR##	;NO OF REGION FOUND BY MAPPER
	ADD	T1,BAFCNT##(T3)	;+ NO FOUND BY MONITOR
	HLRE	T3,BAFFIR##(T3)	;- TOTAL NO OF SLOTS
	ASH	T3,-1		;2 WORDS PER ENTRY
	ADD	T3,T1		;+ NO OF ENTRIES LEFT
	MOVNS	T3
	DPB	T3,UNYBCT##	;SAVE IN UDB
	MOVE	T2,UNIPTR(U)	;T2=AOBJN PTR TO SWAPPING SAT FOR THIS UNIT
	SKIPGE	UNISUN(U)	;IN ACTIVE SWAPPING LIST?
	JRST	CHKBT2		;NO, NO SWAPPING SAT
	HLRE	T1,T2		;T1=-LENGTH OF SWAPPING SAT
	SUB	T2,T1		;T2=ADDR OF SECOND COPY (-T1=+LENGTH)
	MOVE	T1,T2		;T1=PTR TO SECOND COPY
	LDB	T3,UNYK4S##	;T3=K FOR SWAPPING ON UNIT
	LSH	T3,K2PLSH	;DOUBLE SIZE IF SWAPPING PAGES
	ADDI	T3,1		;+1 BECAUSE 0 WAS THROWN AWAY
	IDIVI	T3,^D36		;T3=FULL WORDS
	JUMPE	T4,FULSST	;JUMP IF NO WASTED BITS
	ADDI	T2,(T3)		;T2=ADDR OF LAST WORD
	MOVNI	T3,-1(T4)	;T3=-BITS TO SET TO 0 +1
	MOVSI	T4,400000	;SET SIGN BIT
	ASH	T4,(T3)		;SET BITS TO BE 0 TO 1
	SSX	T2,MS.SAT	;SECTION CONTAINING SWAPPING SATS
	SETCAM	T4,(T2)		;COMPLEMENT AND STORE
FULSST:	AOBJP	T1,NOSST	;JUMP IF 0 OR 1 WORD IN SWAPPING SAT
IFE FTXMON,<
	SETZM	-1(T1)		;CLEAR FIRST WORD OF SECOND COPY
	HRLI	T1,-1(T1)	;LH=ADDR OF FIRST WORD
	MOVEI	T3,(T1)		;1ST ADDR +1 = LAST ADDR? ONLY IF EXACTLY 2 WORDS
	CAIGE	T3,(T2)		;SKIP IF YES, NO MORE LOCATIONS TO CLEAR
	BLT	T1,-1(T2)	;CLEAR REST OF SECOND COPY
>
IFN FTXMON,<
	HLL	T1,T2		;SECTION NUMBER
	SETZM	-1(T1)		;ZERO WORD 0
	MOVE	T3,T1		;FIRST WORD TO ZERO
	SUBM	T2,T1		;NUMBER OF WORDS TO ZERO
	JUMPLE	T1,NOSST	;JUMP IF THE SAT IS ONLY 2 WORDS LONG
	MOVE	T2,T3		;ADDRESS OF THE 0
	SUBI	T2,1
	EXTEND	T1,[XBLT]	;ZERO THE REST
>
				;FALL INTO NOSST
NOSST:	MOVEI	T1,-1(P1)	;T1=ADDR OF BAT BLOCK IN CORE -1
	MOVE	T2,[PUSHJ P,SETSST];T2=INSTRUCTION TO EX FOR BAD BLOCKS
	PUSHJ	P,SCNBAT##	;SCAN BAT BLOCK, CALL SETSST FOR BAD BLOCKS
	MOVE	T1,UDBKDB(U)	;KONTROLLER FOR THIS UNIT
	SKIPGE	KONPOS(T1)	;DOES IT POSITION?
	JRST	CHKBT2		;NO--GO ON
	PUSH	P,P1		;MAKE P1 AVAILABLE
	TDZA	P1,P1		;ZERO IT AND HOP OVER NEXT INSTRUCTION
CHKCYL:	PUSHJ	P,SETSST	;MARK OUT PAGE IN SWAP SAT
CHKCY1:	LDB	T3,UNYBPY	;BLKS/CYL FOR UNIT
	ADD	P1,T3		;COMPUTE NEXT LBN ON CYL BOUNDARY
	CAMLE	P1,UNIBPU(U)	;PAST END OF UNIT?
	JRST	CHKCY2		;YES--ALL DONE
	MOVE	T2,P1		;COPY OF THIS LBN
	SUB	T2,UNISLB(U)	;COMPUTE RELATIVE BLK NO. IN SWAP SPACE
	IDIVI	T2,SWBKPP##	;IS A SWAP PAGE SPLIT ACROSS CYL BOUNDARY?
	JUMPE	T3,CHKCY1	;NO IF SWBKPP DIVIDES EVENLY
	MOVE	T1,P1		;YES--THIS PAGE WILL NOW BE MARKED
	JRST	CHKCYL		; AS UNAVAILBLE IN THE SWAP SAT
				; BECAUSE FILSER/VMSER DOESN'T LIKE THIS
CHKCY2:	POP	P,P1		;RESTORE P1
CHKBT2:	HLRZ	U,UNISYS(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
IFN FTXMON,<XJRST [MCSEC0+.+1]>
	JUMPN	U,CHKBT1	;REPEAT IF THERE IS ONE
	POPJ	P,		;NONE LEFT - EXIT
CHKBAT:	SETZM	BATBAD		;CLEAR "BAT" BLOCK BAD FLAG
	SETZM	BTHBAD		;CLEAR BOTH BAD FLAG
	PUSHJ	P,GTBAT		;READ BOTH BAT BLOCKS & VERIFY
	  SETOM	BTHBAD		;BOTH BAD--REMEMBER
	SKIPE	REDERR		;IF READ ERRORS
	AOS	BATANY		;ALSO FLAG THAT SOME UNIT HAS ERRORS
	SKIPE	REDERR		;ANY ERRORS IN EITHER ONE
	SETOM	BATBAD		;SET BAT BLOCK BAD FLAG
	SKIPN	BATMAN		;SKIP IF MANDATORY
	JRST	CKBAT1
	SKIPN	BATBAD		;ANY ERRORS IN EITHER??
	POPJ	P,		;NO, GO TO NEXT UNIT
	HRRZ	T3,P1		;ADDR OF BAT BLOCK IN CORE
	SKIPE	BTHBAD		;BOTH BAD??
	PJRST	INTBAT		;YES-MAY AS WELL REWRITE THEM
	MOVEI	T2,LBOBAT##	;ONE IS GOOD & SITTING IN MBF
	HLRZ	T3,UNIHOM(U)
	SKIPL	REDERR		;SKIP IF BLOCK 2 IS GOOD & 1 IS BAD
	HRRZ	T3,UNIHOM(U)
	ADD	T2,T3		;BLOCK 2 IS BAD-WRITE GOOD ONE ON IT
	MOVEM	T2,BLKSLF##(P1)	;THIS BLOCK MUST KNOW WHAT IT IS
	PUSHJ	P,OMNWRT	;WRITE PROPER BLOCK
	  PUSHJ	P,WRTCHK	;ERROR-TELL OPR ABOUT IT
	POPJ	P,
CKBAT1:	HRRZ	T3,P1		;GET ADR. OF "BAT" BLOCK INTO A BETTER AC
	LDB	T2,BAYNBR##	;GET # BAD REGIONS FOUND BY MAP PROGRAM.
	ADD	T2,BAFCNT##(T3)	;ADD IN # FOUND BY MONITOR
	ADDM	T2,BATANY	;ALSO FLAG THAT SOME UNIT HAS ERRORS
	SKIPN	BATBAD		;LIKEWISE IF ANY BAD REGIONS OR ERRORS DETECTED
	POPJ	P,		;EXIT
;	JRST	INTBAT		;GO INITIALIZE
INTBAT:	MOVE	T1,UDBNAM(U)	;GET DRIVE NAME
	MOVEI	T2,[ASCIZ /- both BAT blocks are bad/]
	SKIPE	BTHBAD		;BOTH BLOCKS BAD?
	PUSHJ	P,UWARN		;WARN OPERATOR
	MOVSI	T1,UNPHWP	;BIT TO TEST
	TDNE	T1,UNIDES(U)	;HARDWARE WRITE PROTECT TURNED ON?
	POPJ	P,		;THEN CAN'T INIT BAT BLOCKS
	MOVEI	T1,[ASCIZ /Initialize BAT blocks/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	MOVEI	T1,[ASCIZ /This is not normally done.  Are you sure/]
	MOVSI	T2,'NO '	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ##	;PROMPT AND FETCH ANSWER
	JUMPE	T1,CPOPJ##	;RETURN IF HE SAID "NO"
	PUSHJ	P,SETBAT	;SETUP "BAT" BLOCK PARAMETERS
	HRRZ	T3,P1		;GET BUFFER ADDRESS IN BETTER AC
	MOVSI	T1,(T3)		;SETUP BLT PTR. TO CLEAR "BAT" BLOCK
	HRRI	T1,1(T3)
	SETZM	(T3)		;CLEAR OUT 1ST. WORD
	BLT	T1,BLKSLF##(T3)	;CLEAR OUT THE REST OF THE BLOCK
	MOVEM	P2,BLKNAM##(T3)	;PUT SIXBIT 'BAT' IN THE BLOCK
	MOVEM	P3,BLKCOD##(T3)	;SAVE THE CODE FOR "BAT" BLOCKS IN THE BLOCK
	MOVSI	T1,MBRMAX##	;SETUP AOBJN PTR. TO BE STORED IN BLOCK
	HRRI	T1,BAFREG##
	MOVEM	T1,BAFFIR##(T3)	;SAVE IT IN THE BLOCK
	MOVE	J,UDBKDB(U)	;GET UNIT'S KONTROLLER DATA BLOCK ADR.
	MOVE	T1,KDBDVC(J)	;GET DEVICE CODE FOR THE KONTROLLER
	DPB	T1,BAYKDC##	;SAVE IT IN THE BLOCK
	MOVEI	T1,[ASCIZ/Initializing BAT blocks/]
	PUSHJ	P,CONOUT##
	PJRST	WRTRUN		;WRITE BOTH "BAT" BLOCKS

BATBAD:	0			;0 INDICATES VIRGIN "BAT" BLOCKS(INITIALIZED)
				; LH = -1 INDICATES ERROR(S) DETECTED WHILE READING
				; RH = # BAD REGIONS ON UNIT
BTHBAD:	0			;0=NOT BOTH BAD, -1 = BOTH BAD
BATMAN:	0			;0=OPTIONAL, -1=MANDANTORY

BATANY:	0			;NON-ZERO IF ANY BAD REGIONS ON ANY UNITS

LSTBAT:	0			;NON-ZERO IF LIST # BAD REGIONS

GTBAT:	PUSHJ	P,SETBAT	;SETUP "BAT" BLOCK PARAMETERS FOR REDRUN
	PJRST	REDRUN		;GO READ & VERIFY BLOCKS

SETBAT:	MOVSI	P2,(SIXBIT .BAT.)
	MOVE	P3,[EXP CODBAT## ]
	MOVE	P4,[XWD LBOBAT##,LBOBAT ]
	ADD	P4,UNIHOM(U)
	POPJ	P,
;SUBROUTINE TO SET BITS IN SWAPPING SAT TABLE FOR BAD BLOCKS IN SWAPPING SPACE
;ARGS	T1=BLOCK NUMBER WITHIN UNIT

SETSST:	SKIPGE	UNISUN(U)	;UNIT IN A.S.L?
	POPJ	P,		;NO, RETURN
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	SUB	T1,UNISLB(U)	;T1=RELATIVE BLOCK IN SWAPPING SPACE
	JUMPL	T1,CPOPJ##	;EXIT IF BLOCK BELOW SWAPPING SPACE
	LDB	P3,UNYK4S##	;P3=K FOR SWAPPING ON THIS UNIT
	JUMPE	P3,CPOPJ##	;EXIT IF NO SWAPPING SPACE ON UNIT
	MOVE	T2,P3
	LSH	T2,BLKSPK	;CONVERT TO BLOCKS
	CAML	T1,T2		;SKIP IF BLOCK IN SWAPPING SPACE
	POPJ	P,		;NO, PAST END
	MOVEI	P1,SWBKPP##	;8 BLOCKS PER K
	SETZ	P2,		;STARTING AT LOGICAL K 0
	SUBI	P3,1		;LAST LOGICAL J NUMBER
	MOVE	P4,UNIPTR(U)	;PTR TO SWAPPING SAT
	HLRE	T2,P4		;T2=-LENGTH OF SWAPPING SAT
	SUB	P4,T2		;P4=AOBJN PTR TO SECOND COPY
	SUBI	P4,1		;MAKE IOWD PTR
	ADDI	T1,SWBKPP##	;SWAPPING SPACE STARTS AT 1 FOR VM
	SSX	P4,MS.SAT	;SECTION NUMBER FOR SWAPPING SATS
				;ADDRESS OF THE SAT
	PUSHJ	P,CHKBIT##	;FIND BIT
	  ORM	T4,(T1)		;WAS NOT ON, SET IT
	POPJ	P,		;THATS ALL
;SUBROUTINE TO TYPE ALL UNITS IN SYSTEM THAT ARE NOT IN ANY STR
; RETURN WITH P1,P4,F,U & J DESTROYED

TYPUNS:	PUSHJ	P,OTSET##
	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
	PUSH	P,[0]		;INITIALIZE COUNTER
	TDZA	P4,P4		;INDICATE UNIT ID TO BE TYPED IN TYPUNI
TYPNS1:	HLRZ	U,UNISYS(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPE	U,TYPNS4	;EXIT IF NONE LEFT
	SKIPE	UNILOG(U)	;IS THIS UNIT IN AN STR?
	JRST	TYPNS1		;YES - CHECK NEXT UNIT
	MOVEI	P1,[ASCIZ .,.]	;ASSUMUE DEFAULT CASE:NON-FIRST UNIT ON A LINE
	SOSLE	T1,(P)		;FINISHED ON THIS LINE?
	JRST	TYPNS3		;OUTPUT STANDARD CASE
	MOVEI	P1,[ASCIZ .,
.]
	JUMPE	T1,TYPNS2	;AND IF THAT IS TRUE,CHARGE AHEAD
	MOVEI	P1,[ASCIZ .
Units not in a file structure:
.]
TYPNS2:	MOVEI	T1,UNTPLN	;RESET COUNTER
	MOVEM	T1,(P)
TYPNS3:	PUSHJ	P,TYPUN1
	JRST	TYPNS1
TYPNS4:	POP	P,T1
	JUMPLE	T1,OPOUT##	;IF FOUND NO UNITS TO TYPE
	PJRST	CRLFOP##	;IF FOUND AT LEAST ONE
;SUBROUTINE TO TYPE ALL UNITS IN SYSTEM THAT ARE IN AN STR WHICH IS
;NOT MOUNTED TO THIS SYSTEM
; RETURN WITH P1,P4,F,U & J DESTROYED

TYPNMU:	PUSHJ	P,OTSET##
	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
	PUSH	P,[0]		;INITIALIZE COUNTER
	TDZA	P4,P4		;INDICATE UNIT ID TO BE TYPED IN TYPUNI
TYPNM1:	HLRZ	U,UNISYS(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPE	U,TYPNM4	;EXIT IF NONE LEFT
	MOVSI	T1,UNPNMU	;GET THE FLAG
	TDNN	T1,UNIDES(U)	;DOES THIS UNIT GET MOUNTED?
	JRST	TYPNM1		;YES - CHECK NEXT UNIT
	MOVEI	P1,[ASCIZ .,.]	;ASSUMUE DEFAULT CASE:NON-FIRST UNIT ON A LINE
	SOSLE	T1,(P)		;FINISHED ON THIS LINE?
	JRST	TYPNM3		;OUTPUT STANDARD CASE
	MOVEI	P1,[ASCIZ .,
.]
	JUMPE	T1,TYPNM2	;AND IF THAT IS TRUE,CHARGE AHEAD
	MOVEI	P1,[ASCIZ .
Units in a disk-set which is not mounted to this system:
.]
TYPNM2:	MOVEI	T1,UNTPLN	;RESET COUNTER
	MOVEM	T1,(P)
TYPNM3:	PUSHJ	P,TYPUN1
	JRST	TYPNM1
TYPNM4:	POP	P,T1
	JUMPLE	T1,OPOUT##	;IF FOUND NO UNITS TO TYPE
	PJRST	CRLFOP##	;IF FOUND AT LEAST ONE
;SUBROUTINE TO TYPE SIXBIT UNIT NAME FOLLOWED BY (ID/SWAPPING CLASS)
; ENTER WITH U = UNIT DATA BLOCK ADR.
; P4 = 0 TO TYPE UNIT ID. P4 = -VE TO TYPE SWAPPING CLASS

TYPUNI:	MOVEI	P1,[ASCIZ .,.]
TYPUN1:	MOVE	T1,P1		;GET MSG. ADR. INTO KOSHER AC
	PUSHJ	P,CONMES##	;PUT "," OR MSG. IN BUFFER
	JUMPE	U,CPOPJ##	;JUST O/P MSG. IF NO UNITS IN ASL
	MOVE	T1,UDBNAM(U)	;GET DRIVE NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ .(.]
	PUSHJ	P,CONMES##	;PUT "(" IN BUFFER
	JUMPL	P4,TYPUN2	;JUMP IF CLASS FOR SWAPPING TO BE TYPED
	MOVE	T2,UNIHID(U)	;GET SIXBIT UNIT ID - IF ANY
	TLNE	T2,777777	;AVOID 0,,JUNK
	PUSHJ	P,PRNAME##	;PUT IT IN THE BUFFER
	JRST	TYPUN3

TYPUN2:	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	PUSHJ	P,RADX10##	;PUT DECIMALLY IN THE BUFFER
TYPUN3:	MOVEI	T1,[ASCIZ .).]
	PJRST	CONMES##
FNDSRC:	MOVSI	P3,-.SLMXS	;SETUP AOBJN PTR. FOR MAX. # STRS IN SEARCH LIST
FNDSR1:	HLRZ	P2,SYSSTR##	;GET ADR. OF 1ST. STR IN SYSTEM
	JUMPE	P2,CPOPJ##	;QUIT NOW IF NO FILE STRUCTURES
FNDSR2:	MOVE	T1,STRSRC##(P2)	;GET LOG. # OF STR IN SEARCH LIST
	CAIE	T1,(P3)		;IS IT THE ONE WE'RE LOOKING FOR?
	JRST	FNDSR3		;NO - GET NEXT STR
	XCT	P4		;EXECUTE INSTR. SUPPLIED BY CALLER
	AOBJP	P3,CPOPJ##	;EXIT IF MAX. # STRS SEEN
	JRST	FNDSR1

FNDSR3:	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	JUMPN	P2,FNDSR2	;REPEAT IF ANY LEFT
	AOBJN	P3,FNDSR1	;LOOK FOR NEXT LOG. STR #
	POPJ	P,		;EXIT


DEPCLR:	HRRZ	T1,STRFSN##(P2)	;GET # OF THIS STR
	EXCH	P2,TEMPTR	;PUT IT IN SYS SL.
	PUSHJ	P,SLAPD##
	  PUSHJ	P,SLXAES##	;STOPCD AES IF NO ROOM
	PUSH	P,P2		;SAVE CURRENT LOC IN SL.
	MOVEI	T1,.FSFNC	;INSERT A FENCE
	PUSHJ	P,SLAPD##
	  PUSHJ	P,SLXAES##
	POP	P,P2		;BACK UP OVER THE FENCE
	EXCH	P2,TEMPTR
	POPJ	P,		;EXIT
HGHSIZ:	MOVE	T1,UNIBPU(U)	;GET # BLOCKS ON UNIT
	ADDM	T1,STRSIZ##(P2)	;ADD TO TOTAL # BLOCKS IN STR
	MOVE	T1,STRBPU##(P2)	;GET MAX. # BLOCKS PER UNIT IN STR
	ADDM	T1,STRHGH##(P2)	;ADD TO HIGHEST LOG. BLOCK # IN STR
	HLRZ	U,UNISTR(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	JUMPN	U,HGHSIZ	;REPEAT IF ANY LEFT
	SOS	STRHGH##(P2)	;MAKE STRHGH BE HIGHEST LOG. BLOCK # IN STR
	POPJ	P,		;RETURN

INSUNI:	HRRZ	T1,UNISTR(U)	;SEE IF THIS UNIT IS ALREADY IN AN STR
	JUMPE	T1,INSUN1	;T1 = 0 IF IT ISN'T
	MOVEI	T1,[ASCIZ .
?Unit already in file structure
.]
	PJRST	CONOUT##	;TYPE MSG. & EXIT

INSUN1:	HRLM	U,(P3)		;LINK THIS UNIT DATA BLOCK TO PREVIOUS ONE
	HRRZM	P2,UNISTR(U)	;ATTACH THIS UNIT DATA BLOCK TO THIS STR
	HRRZ	T1,STRUNM##(P2)	;GET LOGICAL UNIT # WITHIN STR
	DPB	T1,UNYLUN##	;SAVE IT IN UNIT DATA BLOCK
	PUSHJ	P,CMPLOG	;COMPUTE SIXBIT LOGICAL UNIT NUM, STORE IN UNILOG
	MOVE	T1,UNIBPU(U)
	CAMLE	T1,STRBPU##(P2)
	MOVEM	T1,STRBPU##(P2)
	CAIE	P1,0		;SKIP IF 1ST UNIT
	CAMGE	T1,UNIBPU(P1)	;COMPARE WITH SMALLEST SO FAR
	MOVE	P1,U		;SAVE ADDR OF SMALLEST IN P1
	AOS	STRUNM##(P2)	;INCREMENT # OF UNITS IN STR
	PUSHJ	P,SETCHG	;FLAG THAT UNIT'S "HOME" BLOCKS MUST BE REWRITTEN
	MOVEI	P3,UNISTR(U)	;MAKE CURRENT UNIT PREDECESSOR
	JRST	CPOPJ1##	;SKIP RETURN
;SUBROUTINE TO SET DEFAULTS IN STR DATA BLOCK
;ARGS	P1=ADDR OF SMALLEST UNIT IN STR

PARSET:	MOVE	U,P1		;U=ADDR OF SMALLEST UNIT IN STR
	LDB	P1,UNYKTP##	;CONTROLLER TYPE OF SMALLEST UNIT
	MOVE	T2,GRPDEF(P1)	;UNIGRP DEFAULT
	MOVE	T1,[HRLM T2,UNIGRP(U)]
	PUSHJ	P,STOUNI	;STORE IN ALL UNIT DATA BLOCKS
	PUSH	P,P1		;SAVE CONTROLLER TYPE
	MOVE	P1,BPCDEF(P1)	;P1 IS ARG FOR BPCSTO
	PUSHJ	P,BPCSTO	;STORE BPC AND SET UP BYTE POINTERS
	MOVE	T3,(P)		;CONTROLLER TYPE TO T3
	MOVE	P1,CNPDEF(T3)	;DEFAULT BITS PER CLUSTER COUNT FIELD
	LDB	T3,[POINT 6,STYCLP##(P2),11]	;BITS PER CLUSTER ADDR FIELD
	PUSHJ	P,CNPSTO	;STORE THAT IN BYTE POINTERS
	POP	P,P1		;RESTORE CONTROLLER TYPE
	MOVE	T1,GARDEF(P1)	;DEFAULT RESERVE
	MOVEM	T1,STRGAR##(P2)
	MOVE	T1,OVRDEF(P1)	;DEFAULT OVERDRAW
	MOVNM	T1,STROVR##(P2)	;STORED NEGATIVE
	SKIPGE	T1,K4CDEF(P1)	;GET K FOR CRASH.EXE
	MOVEI	T1,M.NKC##	;-1 MEANS USE DEFAULT FROM MONGEN
	HRRM	T1,STRK4C##(P2)	;K FOR CRASH.SAV
	PJRST	CHGSTX		;SET BIT TO WRITE OUT HOME BLOCKS


;SUBROUTINE TO CLOSE UP SLOTS IN SDL AND SSL WHEN DISSOLVING AN STR
;ARGS	T1=POSITION IN SDL/SSL OF DISSOLVED STR

FIXSSL:	SETZM	PRESSL##	;FORGET PRESERVED SSL
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	DMOVE	P3,[CAML P1,STRSRC##(P2) ;INSTRUCTIONS TO TEST
		    SOS  STRSRC##(P2)] ;...
	JRST	FIXSSD		;ON YOUR WAY
FIXSDL:	SETZM	PRESDL##	;FORGET PRESERVED SDL
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	DMOVE	P3,[CAML P1,STRSDL##(P2) ;INSTRUCTIONS TO TEST
		    SOS  STRSDL##(P2)] ;...
FIXSSD:	MOVE	P1,T1		;COPY POSITION OF DISSOLVED STR
	MOVEI	P2,SYSSTR##-STRSYS## ;SET LINK FOR FIRST STRUCTURE
FIXSS1:	HLRZ	P2,STRSYS##(P2)	;GET NEXT STRUCTURE
	JUMPE	P2,CPOPJ##	;RETURN IF JUST CHECKED LAST STR
	XCT	P3		;THIS STR AFTER THE ONE WHICH WAS JUST DISSOLVED?
	JRST	FIXSS1		;NO
	XCT	P4		;YES, MOVE IT DOWN ONE PLACE
	PUSHJ	P,CHGSTX	;FLAG UNITS AS NEEDING THEIR HOME BLOCKS REWRITTEN
	JRST	FIXSS1		;LOOP FOR MORE
;SUBROUTINE TO DETERMINE IF ANY UNITS ARE NOT IN STR'S
;SKIP RETURN IF YES, NO SKIP IF NO

	HLRZ	U,SYSUNI##	;U=1ST UNIT IN SYSTEM
ALLINS:	JUMPE	U,CPOPJ##	;NO MORE UNITS, ALL MUST BE IN STRS
	SKIPN	UNILOG(U)	;SKIP IF THIS UNIT IS IN AN STR
	JRST	CPOPJ1##
	HLRZ	U,UNISYS(U)	;NEXT UNIT IN SYSTEM
	JRST	ALLINS

;SUBROUTINE TO COMPUTE SIXBIT LOGICAL UNIT NUMBER WITHIN STR

CMPLOG:	PUSH	P,P3
	MOVE	P3,T1
	LSH	P3,-^D3
	ADDI	P3,20
	LSH	P3,^D6
	ANDI	T1,7
	ADDI	P3,20(T1)
	MOVE	T1,STRNAM##(P2)
	PUSHJ	P,MSKUNI##
	SETCA	T2,0
	JFFO	T2,.+2
	STOPCD	.+1,DEBUG,JDJ,	;++JFFO DIDN'T JUMP
	MOVEI	T2,^D24
	TRNE	P3,700
	JRST	INSUN2
	TRZ	P3,7700
	MOVEI	T2,^D30
INSUN2:	SUB	T2,T3
	LSH	P3,(T2)
	ADD	T1,P3
	MOVEM	T1,UNILOG(U)
	POP	P,P3
	POPJ	P,
;ROUTINE TO CLEAR OUT ENTIRE ACTIVE SWAPPING LIST...
;DOES NOT ASSUME ACTIVE SWAPPING LIST IS ALREADY SETUP.

KASL:	SETZM	PREASL##	;FORGET PRESERVED ASL
	MOVEI	U,SYSUNI##-UNISYS
KASL1:	HLRZ	U,UNISYS(U)
	JUMPE	U,KASL2
	PUSHJ	P,SETCHG	;MARK AS NEEDING HOM BLOCKS REWRITTEN
	SETOM	UNISUN(U)	;UNIT NO LONGER IN ASL
	HRRZS	UNISWP(U)	;CLEAR LINK
	JRST	KASL1
KASL2:	MOVE	T1,[XWD SWPTAB##,SWPTAB##+1] ;GET BLT POINTER TO CLEAR OUT
	SETZM	SWPTAB##	;SWPTAB
	BLT	T1,SWPTBE##	;CLEAR TO THE LAST DROP
	POPJ	P,		;RETURN
;ROUTINE TO GIVE UP CORE USED BY SDBS, SATS, AND SPTS

RTNCOR:	PUSHJ	P,SAVE2##	;FREE UP P1 AND P2

;SDBS
	MOVE	P1,STRAOB##	;GET AOBJN POINTER INTO TABSTR
RTNCR1:	MOVEI	T1,STRLEN##	;NUMBER OF WORDS FOR A STRUCTURE DATA BLOCK
	SKIPE	T2,TABSTR##(P1)	;GET ADDRESS, SKIP IF STRUCTURE NOT DEFINED
	PUSHJ	P,GIVWDS##	;RETURN THE SPACE
	SETZM	TABSTR##(P1)	;ZERO THE POINTER
	AOBJN	P1,RTNCR1	;LOOP FOR ALL POSSIBLE STRUCTURES

;LOOP OVER EACH UNIT RETURNING SPACE
	HLRZ	U,SYSUNI##	;GET FIRST UNIT DATA BLOCK
RTNCR2:
IFE FTXMON,<

;SATS
	LDB	P1,UNYSIC##	;GET NUMBER OF SATS IN CORE
	JUMPLE	P1,RTNCR4	;NOTHING TO RETURN IF UNYSIC = 0
	MOVE	P2,UNISAB(U)	;GET ADDRESS OF FIRST SAB IN RING
RTNCR3:	MOVE	T2,P2		;COPY SAB ADDRESS
	MOVE	P2,SABRNG##(P2)	;REMEMBER ADDRESS OF NEXT SAB
	LDB	T1,UNYWPS##	;GET WORDS PER SAT
	ADDI	T1,SABBIT##	;INCLUDE OVERHEAD WORDS
	PUSHJ	P,GIVWDS##	;GIVE BACK THE SPACE
	SOJG	P1,RTNCR3	;LOOP FOR ALL SABS
RTNCR4:	SETZM	UNISAB(U)	;FORGET ABOUT IT

;SPT
	LDB	T1,UNYSPU##	;GET NUMBER OF SATS PER UNIT
	ADDI	T1,SPTFIR##+1	;INCLUDE OVERHEAD WORDS
	HRRZ	T2,UNISPT(U)	;GET ADDRESS OF SPT
	SKIPE	T2		;IF THERE IS ONE,
	PUSHJ	P,GIVWDS##	; RETURN IT
	SETZM	UNISPT(U)	;FORGET ABOUT IT

;SWAPPING SAT
	HLRE	T1,UNIPTR(U)	;GET -VE LENGTH OF SWAPPING SAT
	JUMPE	T1,RTNCR5	;NOTHING TO RETURN IF NO SST
	MOVMS	T1		;GET JUST THE MAGNITUDE
	LSH	T1,1		;ACCOUNT FOR DOUBLE ALLOCATION (SEE CRESST)
	HRRZ	T2,UNIPTR(U)	;GET ADDRESS OF SST
	SKIPE	T2		;IF THERE IS ONE,
	PUSHJ	P,GIVWDS##	; RETURN IT
	SETZM	UNIPTR(U)	;FORGET ABOUT IT

RTNCR5:
IFN FTDUAL,<
	SKIPN	T1,UNI2ND(U)	;GET POINTER TO SECOND PORT
	JRST	RTNCR6		;NONE
	SETZM	UNISAB(T1)	;ZERO OUT COPIED POINTERS
	SETZM	UNISPT(T1)
	SETZM	UNIPTR(T1)
RTNCR6:
>; END IFN FTDUAL
>; END IFE FTXMON

	HLRZ	U,UNISYS(U)	;GET NEXT UNIT
	JUMPN	U,RTNCR2	;LOOP IF MORE UNITS
	POPJ	P,		;RETURN
CKUSTR:	SKIPN	.UONCE##	;IF EXEC MODE,
	JRST	CPOPJ1##	;THEN IT ISN'T MOUNTED IN USER MODE
	PJRST	UCKSTR##	;USER MODE HAS TO CHECK

REFCHU:	SKIPN	.UONCE##	;IF EXEC MODE,
	JRST	REFCHZ		;JUST GO DO IT
	PUSH	P,T2		;SAVE THE OLD VALUE
	PUSHJ	P,UCKSTR##	;SEE IF WE REALLY WANT TO DO THIS
	  JRST	TPOPJ##		;NO--GO BACK TO THE OLD VALUE
	POP	P,T2		;YES--PROCEED TO MAKE THE CHANGE
REFCHZ:	SKIPE	P2		;UNIT PART OF A STRUCTURE?
	HRROS	STRREF##(P2)	;YES - INDICATE STR NEEDS REFRESHING
	PJRST	SETCHG		;FLAG "HOME" BLOCKS MUST BE REWRITTEN

REFCHS:	HLRZ	U,STRUNI##(P2)	;GET FIRST UNIT IN STRUCTURE
	MOVSI	T2,UNPNNA	;AND USER-MODE 'MOUNTED' FLAG
	SKIPE	.UONCE##	;NOT A PROBLEM IN EXEC MODE
	TDNN	T2,UNIDES(U)	;DO WE NEED TO WORRY?
	JRST	REFCHY		;NO--JUST DO IT
	PUSH	P,T1		;YES--SAVE OLD VALUE
	PUSHJ	P,UCKSTR##	;MAKE SURE WE WANT TO PROCEED
	  JRST	P1POPJ##	;NO--GO BACK TO THE OLD VALUE
	POP	P,T1		;YES--PROCEED TO MAKE A DRASTIC CHANGE
REFCHY:	HRROS	STRREF##(P2)	;INDICATE STR NEEDS REFRESHING
CHGSTX:	MOVE	T1,[PUSHJ P,SETCHG]	;GET INSTR. TO BE EXECUTED BY STOUNI
	;JRST	STOUNI		;FALL INTO STOUNI
;SUBROUTINE TO EXECUTE AN INSTRUCTION FOR ALL UNITS WITHIN AN STR
; USUALLY STORES A BYTE
;T1=INSTRUCTION TO BE EXECUTED, P1=ARG., P2=STR DATA BLOCK ADR.

STOUNI:	HLRZ	U,STRUNI##(P2)
	PUSH	P,T1
STOUN1:	XCT	(P)		;EXECUTE INSTRUCTION SUPPLIED IN AC T1
	HLRZ	U,UNISTR(U)
	JUMPN	U,STOUN1
	JRST	TPOPJ##

;SUBROUTINE TO COMPUTE # CLUSTERS & WORDS PER SAT

CMCWPS:	PUSHJ	P,SAVE4##	;SAVE P1-P4
	PUSHJ	P,COMLC1	;NOW COMPUTE # CLUSTERS PER SAT
	SOS	T2
	LDB	P1,UNYSPU##	;GET # SATS PER UNIT IN THIS STR
	IDIV	T2,P1
	HRRM	T2,UNICPS(U)	;STORE COMPUTED VALUE
	AOS	UNICPS(U)	;MAKE VALUE IN UNIT DATA BLOCK RIGHT
	IDIVI	T2,^D36
	ADDI	T2,1
	DPB	T2,UNYWPS##	;STORE COMPUTED VALUE
	POPJ	P,		;EXIT
COMLCA:	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	JRST	COMLC2		;IS UNIT IN AN STR?
COMLC1:	SKIPA	T2,UNIBPU(U)	;NO - GET # BLOCKS ON UNIT
COMLC2:	MOVE	T2,STRBPU##(P2)	;YES - GET # BLOCKS PER UNIT
	LDB	T4,UNYBPC##	;GET # BLOCKS PER CLUSTER
	IDIV	T2,T4		;COMPUTE LAST CLUSTER ADR. ON UNIT
	POPJ	P,		;RETURN
;T2 & T3 ARE RESPECTED
SETCHG:	PUSH	P,T1		;NEED TO SAVE T1 THESE DAYS
	MOVSI	T1,UNPCHG	;PREPARE TO FLAG "HOME" BLOCKS NEED REWITING
	MOVSI	T4,UNPWPO
	TDNN	T4,UNIDES(U)	;IS UNIT WRITE PROTECTED OR OFF-LINE?
	IORM	T1,UNIDES(U)	;SET UNPCHG FLAG
	JRST	TPOPJ##		;RETURN

;SUBROUTINE TO SEE IF ANY UNIT IN THE SYSTEM HAS THE 'UNPCHG' BIT ON

CHKCHG:	MOVSI	T1,UNPCHG	;BIT TO TEST
	HLRZ	U,SYSUNI##	;GET FIRST UNIT DATA BLOCK IN SYSTEM
CHKCH1:	TDNE	T1,UNIDES(U)	;NEED TO REWRITE HOME BLOCKS?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	HLRZ	U,UNISYS(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,CHKCH1	;REPEAT IF THERE IS ONE LEFT
	POPJ	P,		;NO "HOME" BLOCKS NEED REWRITING
;ROUTINE JUST TO WRITE OUT A HOME BLOCK FOR A UNIT WITHOUT READING IT IN.
;CALLED WITH UNIT DATA BLOCK ADRESS IN U

HOMWRT:	PUSHJ	P,GTHOM		;GET "HOME" BLOCK INTO CORE
	  JFCL			;IGNORE ERRORS
	HRRZ	P1,@ONCMBF	;ADRESS OF MONITOR BUFFER
	ADDI	P1,1		;POINT IT PAST FIRST IOWD
	MOVSI	P2,'HOM'	;BLOCK NAME
	MOVE	P3,[CODHOM##]	;IDENTIFYING CODE
	MOVEM	P2,BLKNAM##(P1)	;SAVE SIXBIT "HOME" BLOCK IDENTIFIER
	HRRZ	P2,UNISTR(U)	;GET STR DATA BLOCK ADR.
	MOVE	T1,UNIHID(U)	;GET SIXBIT UNIT ID
	MOVEM	T1,HOMHID##(P1)	;SAVE IN "HOME" BLOCK
	SETZM	HOMLEN##+1(P1)
	HRLZI	T1,HOMLEN##+1(P1)
	HRRI	T1,HOMLEN##+2(P1)
	BLT	T1,HOMLEN##+4(P1)
	MOVEI	T1,MFDSIZ##	;MAKE UFD'S FOR [1,1] AND [1,4]
	MOVEM	T1,HOMLEN##+3(P1)	; EXTRA LONG TO MINIMISE DSK READ
	MOVEM	T1,HOMLEN##+5(P1)
	HLRZ	T1,UNISTR(U)	;GET NEXT UNIT DATA BLOCK ADR. IN STR
	SKIPE	T1		;SAVE 0 IF LAST UNIT IN STR OR NOT IN AN STR
	MOVE	T1,UNIHID(T1)	;GET ITS ID
	MOVEM	T1,HOMNXT##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,P2		;SAVE 0 STR NAME IF UNIT NOT IN AN STR
	MOVE	T1,STRNAM##(P2)	;GET SIXBIT STR NAME
	MOVEM	T1,HOMSNM##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,P2		;STORE 0 FOR OWNER PPN IF UNIT NOT IN A STR
	MOVE	T1,STRPPN##(P2)	;GET OWNER PPN
	MOVEM	T1,HOMOPP##(P1)	;SAVE IN "HOME" BLOCK
	JUMPE	P2,HOMWR3	;BYPASS ALL REFERENCES TO VALUES IN STR
	HLRZ	T1,STRUNI##(P2)	;GET ADR. OF 1ST UNIT DATA BLOCK IN STR

HOMWR1:	JUMPE	T1,HOMWR2	;IF NONE LEFT SAVE 0 IN HOMPRV
	HLRZ	T2,UNISTR(T1)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	MOVE	T3,UNIHID(T1)	;GET CURRENT UNIT'S SIXBIT ID
	MOVE	T1,T2		;CURRENT UNIT_NEXT UNIT
	CAME	T2,U		;ADDR OF NEXT UNIT SAME AS THIS ONE?
	JRST	HOMWR1		;PUT SIXBIT ID INTO THIS UNIT'S "HOME" BLOCK

HOMWR2:	MOVEM	T3,HOMPRV##(P1)	;SAVE IN "HOME" BLOCK
	HLRZ	T1,STRBSC##(P2)	;GET # BLOCKS PER SUPER CLUSTER
	MOVEM	T1,HOMBSC##(P1)	;SAVE IN "HOME" BLOCK
	HRRZ	T1,STRSCU##(P2)	;GET # SUPER CLUSTERS PER UNIT
	MOVEM	T1,HOMSCU##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STRSRC##(P2)	;GET LOG. STR # OF STR IN "SYS" SEARCH LIST
	MOVEM	T1,HOMSRC##(P1)	;SAVE IN "HOME" BLOCK
	SKIPL	T1,STRSDL##(P2)	;CONVERT POS IN SDL FROM INTERNAL 0...N-1
	ADDI	T1,1		; TO 1...N IN HOME BLOCK BUT LEAVE -1 ALONE
	MOVEM	T1,HOMSDL##(P1)	;STORE IN HOME BLOCK
	MOVE	T1,STYCNP##(P2)	;GET BYTE PTR. FOR CLUSTER COUNT
	MOVEM	T1,HOMCNP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STYCKP##(P2)	;GET BYTE PTR. FOR CHECKSUM
	MOVEM	T1,HOMCKP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STYCLP##(P2)	;GET BYTE PTR. FOR CLUSTER ADR.
	MOVEM	T1,HOMCLP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STRGAR##(P2)	;GET # BLOCKS GUARANTEED TO USER BY RESERVATION
	MOVEM	T1,HOMGAR##(P1)	;SAVE IN "HOME" BLOCK
	HLLZ	T1,STRREF##(P2)	;GET 'REFRESH' FLAG
	HLLM	T1,HOMREF##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STROVR##(P2)	;GET -VE # BLOCKS USER IS ALLOWED TO OVERDRAW
	MOVEM	T1,HOMOVR##(P1)	;SAVE IN "HOME" BLOCK
	HRRZ	T1,STRK4C##(P2)	;GET # K FOR CRASH.SAV
	MOVEM	T1,HOMK4C##(P1)	;SAVE IN "HOME" BLOCK
	LSH	T1,BLKSPK	;CONVERT TO # BLOCKS
	SKIPE	T1		;NO EXE DIRECTORY IF NO FILE
	ADDI	T1,4		;ALLOCATE 1 MORE PAGE FOR EXE DIRECTORY
	MOVEM	T1,HOMLEN##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,STYPVS##	;GET PRIVATE STR BIT
	DPB	T1,HOYPVS##	;SAVE IN "HOME" BLOCK
	LDB	T1,STYSET##	;GET SET NUMBER
	DPB	T1,HOYSET##	;SAVE IN "HOME" BLOCK

HOMWR3:	MOVE	T1,UNILOG(U)	;GET SIXBIT LOGICAL UNIT WITHIN STR
	MOVEM	T1,HOMLOG##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYLUN##	;GET LOGICAL UNIT # WITHIN STR
	MOVEM	T1,HOMLUN##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNIHOM(U)	;GET LOG. BLOCK #'S OF BOTH "HOME" BLOCKS
	MOVEM	T1,HOMHOM##(P1)	;SAVE IN "HOME" BLOCK
	HLL	T1,UNIGRP(U)	;GET # CONSECUTIVE CLUSTERS TRIED FOR ON O/P
	HLRZM	T1,HOMGRP##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYK4S##	;GET # K FOR SWAPPING ON THIS UNIT
	MOVEM	T1,HOMK4S##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYBPC##	;GET # BLOCKS PER CLUSTER
	MOVEM	T1,HOMBPC##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYSIC##	;GET # SAT BLOCKS IN CORE FOR THIS UNIT
	MOVEM	T1,HOMSIC##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNISUN(U)	;GET LOG. UNIT # IN ASL
	MOVEM	T1,HOMSUN##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,SWPTAB##+1(T1) ;GET UNIT OF NEXT UNIT IN ASL
	MOVE	T1,UNIHID(T1)	;GET ITS SIXBIT ID
	MOVEM	T1,HOMSID##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNISLB(U)	;GET 1ST. LOG. BLOCK # FOR SWAPPING
	MOVEM	T1,HOMSLB##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	MOVEM	T1,HOMCFS##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYSPU##	;GET # SAT BLOCKS PER UNIT
	MOVEM	T1,HOMSPU##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYUTP##	;GET UNIT TYPE
	MOVEM	T1,HOMUTP##(P1)	;SAVE IN 'HOME' BLOCK

;HERE TO CLEAR UNUSED PORTIONS OF HOME BLOCK
	MOVEI	T1,HOMEND##+1(P1)	;FIRST WORD TO CLEAR
	CAILE	T1,HOMCOD##-1(P1)	;SKIP IF AT LEAST ONE WORD
	JRST	HOMWR4
	SETZM	(T1)		;CLEAR THE FIRST WORD
	CAIN	T1,HOMCOD##-1(P1)	;SKIP IF MORE
	JRST	HOMWR4
	HRLZI	T1,HOMEND##+1(P1)
	HRRI	T1,HOMEND##+2(P1)
	BLT	T1,HOMCOD##-1(P1)	;CLEAR UNUSED WORDS

HOMWR4:	PUSHJ	P,WRTVID	;STORE VOLID STUFF IN HOME BLOCK
	MOVEM	P3,BLKCOD##(P1)	;SAVE CODE WORD IN "HOME" BLOCK
	MOVE	P4,UNIHOM(U)	;GET LOG BLOCK #'S OF 1ST. & 2ND. "HOME" BLOCKS
	PUSHJ	P,WRTRUN	;WRITE OUT BOTH "HOME" BLOCKS
	  JFCL			;IGNORE ERRORS
	MOVSI	T1,UNPCHG	;CLEAR CHANGED FLAG
	ANDCAM	T1,UNIDES(U)	; IN UDB
	POPJ	P,		;RETURN
;SUBROUTINE TO WRITE REDUNDANT BLOCKS(HOM,BAT & RIB)
; ENTER WITH F = FILE DATA BLOCK ADR. U = UNIT DATA BLOCK ADR.
; P1 = ADR. OF BLOCK IN CORE. P4 = XWD 1ST. LOG. BLOCK #,2ND. LOG. BLOCK #
; RETURN WITH S = 0 IF NO ERRORS. OTHERWISE IT HAS STANDARD RH ERROR BITS SET
; T2=0 IF NO ERRORS, OTHERWISE RH=-1 IF ERROR ON 2ND. BLOCK & LH=-1 IF ON 1ST.

WRTRUN::SETZM	REDERR		;CLEAR OUT ERROR SWITCH
	SETOM	WHICH		;INDICATE WRITING 1ST. BLOCK
WRTRN1:	HLRZM	P4,BLKSLF##(P1)	;SAVE THIS BLOCK # IN BLOCK
	HLRZ	T2,P4		;GET LOG. BLOCK # TO WRITE
	HRLZS	P4		;SETUP P3 FOR BLOCK #2
	PUSHJ	P,OMNWRT	;GO WRITE OUT BLOCK
	  PUSHJ	P,WRTCHK	;ERROR - GO PRINT MSG.
	SETZM	WHICH		;INDICATE WRITING 2ND. BLOCK
	JUMPN	P4,WRTRN1	;HAVE WE WRITTEN BOTH BLOCKS?
	MOVE	T2,REDERR	;PICK UP ERROR WORD FOR CHECKING BY CALLER
	JUMPE	S,CPOPJ1##	;SKIP RETURN IF NO ERRORS
	POPJ	P,		;EXIT

WRTCHK:	MOVEI	T1,[ASCIZ .% Hardware write error.]
	MOVE	T2,P2		;COPY BLOCK NAME
	PJRST	RDNMSG		;PRINT MESSAGE AND RETURN
;SUBROUTINE TO READ OR WRITE A BLOCK FOR THE ONCE ONLY & REFRESHER
; ENTER WITH T2 = LOG. BLOCK # TO READ OR WRITE. U = UNIT DATA BLOCK ADR.
; F = FILE DATA BLOCK ADR.
; RETURN WITH S = 0 IF NO ERRORS. OTHERWISE IT HAS STANDARD RH ERROR BITS SET

OMNWRT::SKIPA	T3,[MONWRU##]	;GET ADR. OF WRITE RTNE. IN FILSER

OMNRED::MOVEI	T3,MONRDU##	;GET ADR. OF READ RTNE. IN FILSER
				;(BOTH TO NOT USE THE DISK CACHE)
OMONIO:	MOVEI	S,0		;CLEAR S FOR ERROR STATUS CHECKING
	PUSHJ	P,STORU##	;SETUP DEVUNI FOR MONRED/WRT SINCE IT DOESN'T USE U
	MOVE	T1,[JRST ONCWAT##] ;SETUP A FAKE PWAIT1
	MOVEM	T1,PWAIT1##
	MOVSI	T1,DVDSK	;MAKE SURE THE DDB
	IORM	T1,DEVMOD(F)	; LOOKS LIKE A DISK
	MOVE	J,UDBKDB(U)	;RELOAD J
	MOVE	T1,@ONCMBF	;GET IOWD FOR MONRED/WRT
	XCTCPU	(UNI,ONCIOX)	;DO I/O
	  TRO	S,IODERR	;OTHER CPU DIDN'T RESPOND
	TLZ	S,IO		;FOR JUMPE S,WIN
	TRNN	S,IOIMPM!IODERR!IODTER!IOBKTL	;CHECK FOR ERRORS
	AOS	(P)		;NO ERRORS - SKIP RETURN
RSPWTC::MOVE	T1,PWAITZ##	;RESTORE REAL PWAIT1
	MOVEM	T1,PWAIT1##
	POPJ	P,


IFN FTMP,<
;ROUTINE TO DO THE IO FOR THE REFRESHER
;ALWAYS RETURNS CPOPJ1
REFWRT::SKIPA	T3,[MONWRU##]	;WRITE NOT USING DISK CACHE
REFRED::MOVEI	T3,MONRDU##	;READ NOT USING DISK CACHE
	PUSH	P,@ONCMBF
	MOVEM	T1,@ONCMBF	;T1 HAS IOWD FOR THE OPERATION
	PUSHJ	P,OMONIO	;DO THE IO
	  JFCL
	POP	P,@ONCMBF	;RE@ONCMBF
	PJRST	CPOPJ1##	;AND RETURN
>
SUBTTL	CPU DEPENDANT ROUTINES


; CHECK ON/OFF-LINE STATUS OF A KONTROLLER
; CALL:	PUSHJ	P,CHKKON
;	  <NON-SKIP>		;OFF-LINE
;	<SKIP>			;ON-LINE, T1 ZERO IF WRITE-HEADER-LOCKOUT OFF
CHKKON:	SETZ	T1,		;ASSUME WHL ON
	SKIPE	.UONCE##	;USER MODE?
	AOJA	T1,CPOPJ1##	;KONTROLLER ALWAYS ALIVE
	PUSHJ	P,@KONUPA(J)	;IS KONTROLLER UP?
	  POPJ	P,		;NO--DOWN
	JRST	CPOPJ1##	;RETURN


; SUBROUTINE TO CHECK WRITE-LOCKED STATUS OF A UNIT
; RETURNS CPOPJ1 IF WRITE-LOCKED.
;
CHKWLK:	SKIPE	.UONCE##	;USER MODE?
	JRST	UCKWLK##	;YES
	PUSHJ	P,@KONHWP(J)	;CHECK UNIT
	  POPJ	P,		;WRITE-ENABLED
	JRST	CPOPJ1##	;WRITE-LOCKED


; CHECK THE CAPACITY OF A DISK UNIT
; CALL:	PUSHJ	P,CHKCPY
;	  <NON-SKIP>		;ERRORS: OFF-LINE, NO SUCH UNIT, ILLEGAL SECTOR
;	<SKIP>			;T1 THROUGH T4 LOADED BY KONCPY ROUTINE
;
CHKCPY:	SKIPE	.UONCE##	;USER MODE?
	JRST	UCKCPY##	;DO IT THE HARD WAY
	PUSHJ	P,@KONCPY(J)	;CRANK UP FILSER
	  POPJ	P,		;ERRORS
	JRST	CPOPJ1##	;RETURN


; PERFORM I/O
; CALL:	PUSHJ	P,ONCIOX
;
; *** NOTE *** THIS ROUTINE WILL ALWAYS SKIP!
;
ONCIOX: SKIPN	.UONCE##	;NO PI STUFF IN USER MODE (TWICE)
	CONO	PI,PI.ON	;MAKE SURE THE PI SYSTEM IS ON FOR ONCWAT
	PUSHJ	P,(T3)		;DO I/O
	JRST	CPOPJ1##	;RETURN
IFN FTCIDSK,<

;ROUTINE TO DO AN ONLINE OF A CI DISK
;CALL:
;	J/ KDB ADDRESS
;	U/ UDB ADDRESS
;RETURN:
;	CPOPJ IF ERROR
;	CPOPJ1 IF SUCCESS

ONCONL:	SETZM	ONLDON		;START AFRESH
	PUSHJ	P,SAVE4##	;SAVE SOME AC'S AGAINST CORRUPTION
	SE1ENT			;ENSURE WE RUN IN NZS
	HRRZ	P4,J		;GET KDB ADDRESS
	ADD	P4,.CPCPN##	;OFFSET BY OUR CPU NUMBER
	MOVE	P4,RAKCTI##(P4)	;GET THE CONNECT TABLE INDEX
	PUSHJ	P,MSCGBF##	;GET A BUFFER TO USE
	  POPJ	P,		;NONE AVAILABLE?
	HLLZ	T1,ONLFLG	;GET FLAGS FROM LAST ONLINE END PACKET
	PUSHJ	P,REVFUL##	;PUT THEM BACK AS THE HSC WANTS THEM
	MOVEM	T1,P.UNFL(P2)	;STORE FLAGS
	MOVE	T1,UDBPDN(U)	;PHYSICAL DRIVE NUMBER
	MOVEI	R,.RROON	;RECALL CODE
	PUSHJ	P,MSCUON##	;DO A UNIT ONLINE
	MOVSI	T1,3*ONCTIM##	;WAIT A WHILE
	SKIPN	ONLDON		;DID IT COMPLETE YET?
	SOJG	T1,.-1		;NO, WAIT A WHILE LONGER
	JUMPG	T1,CPOPJ1##	;SKIP RETURN IF IT SUCCEEDED
	POPJ	P,		;RETURN

ONLDON::0			;SET NON-ZERO WHEN RAXKON GETS A RESPONSE TO
				; A SET UNIT ONLINE COMMAND TO THE HSC
ONLFLG::0			;FLAGS FROM LAST UNIT ONLINE COMMAND
>; END IFN FTCIDSK
SUBTTL	DATA STORAGE

TMPSWB:	BLOCK	1		;TEMPORARY SWAP BLOCK NUMBER
TMPSWM:	BLOCK	1		;TEMPORARY MINIMUM SWAP BLOCK NUMBER
ONCMBF::BLOCK	1		;ADDRESS OF MONITOR BUFFER FOR ONCE/TWICE
MONBUF:	BLOCK	200		;STORAGE FOR MONITOR BUFFER
ERRHOM:	0			;FLAG FOR ERRORS WHILE READING A "HOME" BLOCK
SERIUS:	0			;-1 WHEN IF START SYSTEM EVEN IF QUICK OPTION
ONCDDB:	BLOCK	1		;ADDRESS OF ONCE-ONLY DDB
BATFLG:	BLOCK	1		;NON-ZERO WE WANT TO LOOK AT BAD REGIONS
BLURBF:	BLOCK	1		;NON-ZERO IF DIALOGUE BLURB TYPED
UNITFL:	BLOCK	1		;NON-ZERO IF CHANGING UNITS WITH STR
SUDTAB:	BLOCK	^D36		;STRUCTURE/UNIT/DISK-SET NAME TABLE
POSTAB:	BLOCK	^D36		;STRUCTURE/UNIT/DISK-SET POSITION TABLE

	XLIST
	LIT
	VAR
	LIST

ONCEND:	END