Google
 

Trailing-Edge - PDP-10 Archives - BB-F493Z-DD_1986 - 10,7/703mon/oncmod.mac
Click 10,7/703mon/oncmod.mac to see without markup as text/plain
There are 14 other files named oncmod.mac in the archive. Click here to see a list.
TITLE	ONCMOD LEVEL D OPTIONAL & MANDATORY ONCE ONLY CODE V1125
SUBTTL	C. WHITE/DJB/RCC/EVS/WRS/GMU/DPM	  27 JAN 86
	SEARCH F,S
IFN FTCIDSK,<
	SEARCH	KLPPRM,MSCPAR
>; END IFN FTCIDSK
	$RELOC
	$LOW



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.

;
XP VONCMD,1125
;SPECIAL SHORT DIALOG OPTIONS BY ERNIE SOCCI

ENTRY ONCMOD

ONCMOD::
ND	UNTPLN,^D5		;UNITS/LINE TYPED BY TYPUNS/TYPNMU
MXSADA==^D118


	;MACRO TO EXECUTE A SUBROUTINE ON A SPECIFIED CPU.  TYP
	;ALLOWS YOU TO SET UP COMMON DATA STRUCTURE ACS FOR FREE.  SEE
	;CPUXCT FOR DETAILS.  CALLS ARE USUALLY SYNCHRONOUS, EXECUTE
	;WITH ALL AC'S EXCEPT FOR P, AND MAY SKIP (ONCE).  THE ACS OF
	;THE CALLED ROUTINE ARE RETURNED.  HOWEVER, IF XC.ASY IS SET, THE
	;CALL ONLY WAITS FOR THE CPU TO ACCEPT THE COMMAND, MAY NOT
	;SKIP, AND DOES NOT RETURN THE ACS.  CPUASF BIT 35-CPU# WILL CLEAR
	;WHEN THE I/O COMPLETES.  

DEFINE	XCTCPU	(TYP,SUB,FLAGS),<
IFE FTMP,<PUSHJ	P,SUB>
IFN FTMP,<
	PUSHJ	P,[PUSHJ P,CPU'TYP
		   EXP	SUB+IFNB /FLAGS/,<FLAGS>]
> ;;END IFN FTMP
> ;;END DEFINE XCTCPU
	XC.ASY==1B1		;XCTCPU FLAG TO SAY ASYNCH REQUEST
	SUBTTL	BIND UNITS AT ONCE TIME


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

IFN FTCIDSK,<
ONCBND::SKIPE	[M0RAX##]	;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,TIME##	;HAVE WE WAITED LONG ENOUGH?
	JRST	[PUSHJ P,APRCHK## ;NO, UPDATE TIME (PRESERVES T1)
		 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,SYSKON##-KONNXT## ;SET UP INITIAL LINK
ONCBN3:	HLRZ	J,KONNXT##(J)	;GET NEXT KDB ADDRESS
	JUMPE	J,CPOPJ##	;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,KONCAM##(J)	;CAN THIS CPU ACCESS THIS KONTROLLER?
	JRST	ONCBN8		;NO, ON TO NEXT CPU
	MOVSS	P2		;MOVE CPU BIT TO LH OF P2
	HRRZ	P3,KONMUN##(J)	;GET MAXIMUM UNIT NUMBER

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
	MOVSI	T2,CPUMSK##	;MASK FOR ALL CPU BITS
	TDNE	T2,UNIALT##(T1)	;ANY CPU HAVE ALTERNATE PORT ATTACHED?
	JRST	ONCBN7		;YES, DON'T BIND THIS UNIT
	HRRZ	T1,UNIKON##(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,UNIALT##(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,CPUN##-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:	MOVEI	T1,[ASCIZ |%% Online of unit |]
	PUSHJ	P,ICONM##	;START MESSAGE
	PUSHJ	P,SPUNAM	;PRINT UNIT NAME
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
	MOVEI	T1,[ASCIZ | failed|]
	PUSHJ	P,CONMES##	;FINISH MESSAGE
	PJRST	CRLFOP		;APPEND A CRLF AND OUTPUT

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

; ROUTINE TO SEE IF THE OTHER CPU(S) ARE RUNNING AND
; PRINT A WARNING MESSAGE IF NOT

IFN FTMP,<
ONCCPU::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVEI	P2,600000	;A REALLY SHORT TIMER
	EXCH	P2,CPUTIM	;SWAP WITH DISK TIMER
	MOVEI	P1,.C0CDB##	;START WITH CPU0
ONCCP1:	MOVE	T1,.CPCPN##-.CPCDB##(P1) ;GET CPU NUMBER
	CAMN	T1,.CPCPN##	;IS IT ME?
	JRST	ONCCP2		;YES
	XCTCPU	(CPN,CHKCPU)	;TRY TO WAKE HIM OUT OF HIS AC LOOP
	  SKIPA			;NOT RUNNING
	JRST	ONCCP2		;CHECK THE NEXT ONE
	MOVEI	T1,[ASCIZ |%% |]
	PUSHJ	P,ICONM##	;START MESSAGE
	MOVE	T2,.CPLOG##-.CPCDB##(P1) ;GET NAME OF CPU
	PUSHJ	P,SPRNAM	;PUT IN MESSAGE
	MOVEI	T1,[ASCIZ/ serial #/]
	PUSHJ	P,CONMES##	;TYPE TEXT
	MOVE	T1,.CPASN##-.CPCDB##(P1) ;GET SERIAL NUMBER
	PUSHJ	P,RADX10##	;TYPE IT
	MOVEI	T1,[ASCIZ | is not running|]
	PUSHJ	P,CONMES##	;FINISH MESSAGE
	PUSHJ	P,CRLFOP	;APPEND A CRLF AND OUTPUT TO CTY
ONCCP2:	HLRZ	P1,.CPCDB##-.CPCDB##(P1) ;NEXT CDB
	JUMPN	P1,ONCCP1	;LOOP IF ANOTHER CPU TO CHECK
	MOVEM	P2,CPUTIM	;ELSE RESTORE DISK TIMER
	POPJ	P,		;AND RETURN
> ;END IFN FTMP
	SUBTTL	GET DATE/TIME FROM ANY FE WILLING TO TALK

;THIS CODE LIVES HERE BECAUSE WE NEED TO RUN ON SOME SPECIFIED CPU
;RETURNS CPOPJ IF CAN'T FIND A VALID DATE/TIME, CPOPJ1 IF CAN

GFETIM::PUSHJ	P,SAVE1##	;SAVE AN AC
	PUSH	P,T1		;FOR ONCE
	MOVSI	P1,-M.CPU##	;TRY ALL CPUS
GFETM1:	HRRZ	T1,P1		;SET UP CPU NUMBER
	XCTCPU	(CPN,SPCGDT##)	;ASK FE FOR DATE/TIME (DTESER/KSSER)
	 CAIA			;THIS CPU CAN'T HELP
	JRST	TPOPJ1##	;LOCxxx NOW MATCH FE
	AOBJN	P1,GFETM1	;TRY NEXT POSSIBLE CPU
	JRST	TPOPJ##		;NONE WERE HELPFUL, RETURN FAILURE
	SUBTTL	INITIALIZE IPA20 PORTS

;THIS CODE IS CALLED VIA QUEUED PROTOCOL TO INITIALIZE THE CI-20 AND NIA-20
;DEVICE DRIVERS.  QUEUED IO PROTOCOL STARTS BEFORE INITIALIZING THE IPA-20
;DRIVERS BECAUSE ALTHOUGH WE CAN'T DO IO AT THIS POINT, QUEUED PROTOCOL IS
;USED TO GET THE DATE AND TIME FROM -20F ON NON-BOOT CPUS.

IFN FTKL10,<
SPRIPA::MOVEI	T4,.C0CDB##	;POINT TO FIRST CDB
SPRIP1:	MOVSI	T2,(CR.IIP)	;INITIALIZE IPA'S PENDING FOR THIS CPU
	IORM	T2,.CPRUN##-.CPCDB##(T4);SET THE BIT
	MOVE	T1,.CPCPN##-.CPCDB##(T4);GET CPU NUMBER TO INITIALIZE
	PUSH	P,T4		;SAVE ADDRESS OF CURRENT CDB
	CAME	T1,.CPCPN##	;DON'T START BOOT CPU HERE - WE'D WAIT
	XCTCPU	(CPN,SPRIPX##,XC.ASY);START INITIALIZING DRIVERS ON SPECIFIED CPU
	POP	P,T4		;RESTORE CDB ADDRESS
	HLRZ	T4,.CPCDB##-.CPCDB##(T4);POINT TO NEXT CDB
	JUMPN	T4,SPRIP1	;IF MORE CPUS TO DO, LOOP
	;WE'VE STARTED AS MANY OTHER CPUS THINKING AS WE CAN.  TIME FOR US.
	PUSHJ	P,SPRIPX##	;INITIALIZE OUR IPA-20 DRIVERS
IFN FTMP,<
	SKIPE	CPUASF		;SEE IF ANY CPUS ARE STILL INITIALIZING
	JRST	.-1		;THEY ARE, WAIT FOR THEM TO SUCCEED
				;WE ASSUME THAT A CPU WHICH STARTS TO
> ;END FTMP
				;INITIALIZE WILL FINISH.
	POPJ	P,		;DONE
>; END IFN FTKL10
	SUBTTL	SHORT DIALOGUE

;ROUTINE FOR SYSTEM START UP (DESTROY OPTION)

SHRTST::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.

Proceed? (Y or <CR>)/]
	JSP	T2,SVOTAC
	PUSHJ	P,YESNO##	;GET ANSWER
	JRST	ALTM1		;GO BACK TO BEGINNING.(NO).
	SETOM	BATMAN
	SETOM	SHUTUP
	SETOM	KON		;SET STARTUP FLAGS
	PUSHJ	P,REDHOM	;DO WONDDEFUL THINGS
	JFCL			;IGNORE ERRORS
	SETZM	KON		;AND RESET KONTROLLER CHECK FLAG.
	JSP	T2,SVOTAC	;SAVE AC'S
	PUSHJ	P,DMKSTR	;SET UP STRS
	JSP	T2,SVOTAC	;SAVE P4,J,F,AND U AGAIN
	PUSHJ	P,DMKUNI	;SET UP UNIT DEFAULTS
	PUSHJ	P,DEFASL	;AND ACTIVE SWAPPING LIST
	PUSHJ	P,DEFSSL	;AND SYS SEARCH LIST
	PUSHJ	P,DEFSDL	;AND SYSTEM DUMP LIST
	PUSHJ	P,WRTHOM	;WRITE OUT HOM BLOCKS, THEN READ
				;THEM IN AGAIN&SET UP DATA BASE
	MOVEI	T1,[ASCIZ /
Start system? (Y or <CR>)/]
	PUSHJ	P,YESNO##
	  JRST	ALTM1		;NO-ASK LONG DIALOG QUEST AGAIN
	MOVE	F,DATADR	;SET UP FILE DATA BLOCK ADR
	HLRZ	P2,SYSSTR##	;GET ADDR. OF 1ST SDB
	SKIPE	P2
	PUSHJ	P,RFRES2	;REFRESH ALL STRS
	POP	P,(P)		;FIX UP PD LIST

	SKIPN	SYSSTR##	;HAVE ANY STRS?
	PJRST	PVQCK##		;NO--GO DO QUICK STARTUP
	MOVEI	T1,[ASCIZ |
Disk file structures:|]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	PUSHJ	P,TYPSYS	;OUTPUT STRS WE JUST CREATED
	MOVEI	T1,[BYTE (7)15,12,0]
	PUSHJ	P,SVMOUT	;OUTPUT A CRLF
	PJRST	PVQCK##		;AND GO THROUGH QUICK STUFF
	SUBTTL	REFRESH AND CHANGE DIALOGUE

;ROUTINE FOR REFRESH ONLY (REFRESH)

SHRTRF::PUSHJ	P,READ		;GO READ HOME & BAT BLOCKS
	PJRST	RFRESH		;REFRESH YOUR STRS.

;ROUTINE FOR CHANGING PARAMETERS ONLY (CHANGE)

SHRTPM::PUSHJ	P,READ		;READ HOME AND BAT BLOCKS
	PUSHJ	P,CHGSTA	;CHANGE STRS?
	PUSHJ	P,CHGUNA	;UNITS?
	PUSHJ	P,CHGASL	;ACTIVE SWAPPING LIST?
	PUSHJ	P,CHGSRC	;SYS SEARCH LIST?
	PUSHJ	P,CHGSDL	;SYSTEM DUMP LIST?
	PUSHJ	P,CHKCHG	;SEE IF ANYTHING HAS BEEN CHANGED
	  POPJ	P,		;NO-NO NEED FOR FOOLING
	SETOM	SHUTUP		;TELL RWRHOM TO KEEP IT QUIET
	PUSHJ	P,RWRHOM	;GO READ & WRITE NEW HOM BLOCKS
	PJRST	RFRESH		;ONLY STRS THAT NEED IT.
	SUBTTL	UNITID DIALOGUE

SHRTID::MOVE	F,DATADR	;FILE DATA BLOCK ADDR
	SKIPE	SHUTUP		;SKIP IF VIRGIN SYSTEM
	PUSHJ	P,GVMNB0	;GIVE MBF BACK-#1 TOOK IT
	PUSHJ	P,READ		;IN ANY EVENT, SET UP STUFF
	MOVEI	T1,[ASCIZ /Change all unit IDs? (Y or <CR>)/]
	PUSHJ	P,YESNO##	;GET ANSWER
	  PJRST	SOMIDS		;ONLY CHANGE SOME.
ALLIDS:	MOVEI	T1,[ASCIZ /After each unit name, type the ID
/]
	PUSHJ	P,SVMOUT
	HLRZ	U,SYSUNI##	;1ST UNIT IN SYSTEM.
	SKIPA
ALLID2:	HLRZ	U,UNISYS##(U)	;GET NEXT UNIT
	JUMPE	U,SOMID2
	MOVSI	T1,UNPWPO##
	TDNE	T1,UNIDES##(U)
	JRST	ALLID2
ALLID1:	PUSHJ	P,SVOSET	;INITIALIZE BUFFER
	SETZB	P1,P4
	PUSHJ	P,TYPUN1	;TYPE OUT UNINAM AND ID
	MOVEI	T1,[ASCIZ /:/]	;AND COLON
	PUSHJ	P,SCONMS	;PUT IT IN
	PUSHJ	P,SOPOUT	;OUTPUT IT
	MOVE	P1,UNIHID##(U)
	PUSHJ	P,GETSIX
	JRST	ALLID2		;NO CHANGE IN VALUE
	JUMPE	P1,ALLID1	;0 IS NO GOOD, GO BACK AGAIN FOR SAME UNIT
	MOVEM	P1,UNIHID##(U)	;OK, YOU PASS...
	PUSHJ	P,SETCHG	;MARK HOM BLOCKS AS NEEDING REWRITING
	JRST	ALLID2
SOMIDS:	MOVEI	T1,[ASCIZ .
Disk file structures:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	SKIPE	SYSSTR##	;DON'T ASK FOLLOWING QUESTION IF NO STR'S
	PUSHJ	P,TYPSYS	;TYPE ALL STR NAMES & THEIR PHYSICAL UNIT NAMES
	PUSHJ	P,TYPUNS	;TYPE ALL UNIT NAMES THAT ARE NOT IN STR'S
	MOVEI	T1,[ASCIZ/
Type unit name, a comma, and new unit ID for each desired unit.
(Extra <CR> when through)
/]
	PUSHJ	P,SVMOUT	;OUTPUT MESSAGE
SOMID1:	PUSHJ	P,GETUNI	;GET UNIT, SETUP U
	PJRST	SOMID2		;END OF LINE
	JUMPE	U,ALLIDS	;IF U=0, DO ALL
	CAIE	T3,","		;USE EITHER COMMA
	CAIN	T3," "		;OR BLANK
	CAIA
	JRST	SOMIDS		;YOU DIDNT GET THE MESSAGE!!
	MOVE	P1,UNIHID##(U)	;GET OLD ID
	JSP	T2,SVOTAC
	PUSHJ	P,GETSX1
	  JRST	SOMID1		;NO CHANGE IN VALUE
	JUMPE	P1,SOMIDS	;ZERO ID NO GOOD-GO BACK AGAIN
	MOVEM	P1,UNIHID##(U)	;PUT IT IN
	PUSHJ	P,SETCHG	;MARK HOME BLOCKS AS NEEDING REWRITING
	JRST	SOMID1		;LOOP BACK FOR MORE POSSIBLE UNITS
SOMID2:	PUSHJ	P,CHKCHG	;ANY NEED CHANGING??
	  PJRST	RFRESH		;NO-JUST GO BACK
	SETOM	SHUTUP
	PUSHJ	P,RWRHOM	;REWRITE HOM BLOCKS
	PJRST	RFRESH		;GO TO IT..
	SUBTTL	SHORT DIALOGUE

SHRTGO::PUSHJ	P,READ		;READ HOM AND BAT BLOCKS.
	SETOM	SHUTUP		;ONLY TELL IF THEY NEED
	PJRST	RFRESH		;REFRESHING. BYE!

;ROUTINE FOR INITIALIZING KONTROLLER DATA BLOCKS.
SETKON::SETZM	HOMFLG		;INDICATE MUST READ HOME BLOCKS
	MOVSI	T1,UNPWPO##	;SETUP UNIT WRITE PROTECT & OFF-LINE BITS
	MOVSI	T2,KOPDWN##	;SETUP KONTROLLER DOWN BIT
	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
SETKN1:	ANDCAM	T1,UNIDES##(U)	;UNIT INITIALIZED TO BE ON-LINE & WRITE ENABLED
	DPB	T1,UNYUST##	;CLEAR UNIT STATUS(LOW ORDER BITS OF AC T1 = 0)
	HRRZ	J,UNIKON##(U)	;GET UNIT'S KONTROLLER DATA BLOCK ADR.
	ANDCAM	T2,KONDWN##(J)	;KONTROLLER IS ON-LINE
	HLRZ	U,UNISYS##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,SETKN1	;REPEAT IF THERE IS ONE
	POPJ	P,

READ:	SETZM	TYPONL
	SETZM	REFLAG##
	PUSHJ	P,SETKON	;SETUP UNIT WRITE PROTECT AND OFFLINE BITS
	PUSHJ	P,REDHOM	;READ HOM BLOCKS,
	  JFCL			;IGNORING ERRORS
	PUSHJ	P,REDBAT	;AND BAT BLOCKS
	POPJ	P,		;THEN GO BACK.


	SUBTTL	LONG DIALOGUE

FILOPL::SETZM	OPTQIK		;ASK ABOUT OFF-LINE UNITS
FILOPT::PUSHJ	P,SETKON	;SET UP KDBS
	MOVEI	T1,[ASCIZ /
In the following dialog, all numbers are decimal.
Type <CR> if OK, or a new number to change value.
/]
	PUSHJ	P,SVMOUT
	SETZM	TYPONL		;CLEAR TYPE ONLY FLAG
	SETZM	REFLAG##	;CLEAR REFLAG - SET IF REFRESH ANYTHING
	SETZM	BATMAN
FILOP2:	PUSHJ	P,REDHOM	;READ ALL "HOME" BLOCKS ON ALL UNITS IN SYSTEM
	  JFCL			;IGNORE ERRORS
FILCHG:	SETZM	BATANY		;CLEAR NO. OF BAD REGIONS FOR SYSTEM
	PUSHJ	P,REDBAT	;GO READ & VERIFY "BAT" BLOCKS ON ALL UNITS IN SYSTEM
	SKIPE	BATANY		;ANY BAD REGIONS ON ANY UNITS?
	PUSHJ	P,TYPBAT	;YES, ASK IF HE WANTS TO LIST ANY
	MOVEI	T1,[ASCIZ .
Disk file structures:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	SKIPE	SYSSTR##	;DON'T ASK FOLLOWING QUESTION IF NO STR'S
	PUSHJ	P,TYPSYS	;TYPE ALL STR NAMES & THEIR PHYSICAL UNIT NAMES
	PUSHJ	P,TYPUNS	;TYPE ALL UNIT NAMES THAT ARE NOT IN STR'S
	PUSHJ	P,TYPASL	;TYPE ALL UNITS IN ACTIVE SWAPPING LIST
	PUSHJ	P,TYPSRC	;TYPE "SYS" SEARCH LIST
	PUSHJ	P,TYPSDL	;TYPE SYSTEM DUMP LIST
	SKIPE	SYSSTR##	;DON'T ASK FOLLOWING QUESTION IF NO STR'S
	PUSHJ	P,TYPSTA	;ASK FOR STR NAMES TO TYPE PARAMETERS
	PUSHJ	P,TYPUNA	;ASK FOR UNIT NAMES TO TYPE PARAMETERS
	SKIPN	HOMFLG
	PUSHJ	P,CHKCHG	;ANY "HOME" BLOCKS NEED REWRITING AT THIS POINT?
	  JRST	ANYCHG		;NONE DO - SEE IF ANYTHING TO BE CHANGED
	MOVEI	T1,[ASCIZ .
Before HOME blocks are rewritten,
Do you want to change any disk parameters?
.]
	PUSHJ	P,ASKQUE	;ASK QUESTION & GET USER'S RESPONSE
	  JRST	RWRHOM		;THE ANSWER WAS "NO" - JUST REWRITE HOME BLOCKS
	JRST	CHGLUP		;FALL INTO CHANGE DIALOG
ANYCHG:	PUSHJ	P,ASKYCR	;ASK IF ANYTHING TO BE CHANGED
	  JRST	RFRESH		;APPARENTLY NOT - SEE IF ANY STR'S TO BE REFRESHED
CHGLUP:	PUSHJ	P,ASKDIS	;ASK IF ANY STR'S TO BE DISSOLVED-DISSOLVE THEM
	PUSHJ	P,ASKDEF	; "  "   "   "    "  "    DEFINED-  DEFINE  "
	SKIPE	SYSSTR##	;DON'T ASK FOLLOWING QUESTION IF NO STR'S
	PUSHJ	P,CHGSTA	;ASK FOR STR NAMES TO TYPE & CHANGE PARAMETERS
	PUSHJ	P,CHGUNA	;ASK FOR UNIT NAMES TO TYPE & CHANGE PARAMETERS
	PUSHJ	P,TYPASL	;TYPE ACTIVE SWAPPING LIST
	PUSHJ	P,CHGASL	;ASK IF ACTIVE SWAPPING LIST TO BE CHANGED
	PUSHJ	P,TYPSRC	;TYPE "SYS" SEARCH LIST
	PUSHJ	P,CHGSRC	;ASK IF "SYS" SEARCH LIST TO BE CHANGED
	PUSHJ	P,TYPSDL	;TYPE SYSTEM DUMP LIST
	PUSHJ	P,CHGSDL	;ASK IF SYSTEM DUMP LIST TO BE CHANGED
	SKIPE	SHUTUP
	JRST	RWRHM1
	PUSHJ	P,CHKCHG	;SEE IF ANY "HOME" BLOCKS NEED REWRITING
	  JRST	ANYCHG		;NONE DO - SEE IF ANYTHING TO BE CHANGED

;HERE WHEN "HOME" BLOCKS MUST BE REWRITTEN

CHGSOM:	MOVEI	T1,[ASCIZ .
Before HOME blocks are written.]
	PUSHJ	P,CONOUT	;ADD CRLF & O/P MSG.
	PUSHJ	P,TYPSTA	;ASK FOR STR NAMES TO TYPE PARAMETERS
				; ASK EVEN IF THERE ARE NO STR'S JUST AS A REMINDER
	PUSHJ	P,TYPUNA	;ASK FOR UNIT NAMES TO TYPE PARAMETERS
	PUSHJ	P,ASKYCR	;ASK IF ANYTHING TO BE CHANGED
	  CAIA			;NO - SEE IF ANY UNITS NEED "HOME" BLOCKS REWRITTEN
	JRST	CHGLUP		;YES - GO CHANGE THINGS

;HERE TO JUST REWRITE "HOME" BLOCKS

RWRHOM:	PUSHJ	P,RWRSUB	;ASK FOR UNITS TO REWRITE HOME BLOCKS
	MOVE	F,DATADR	;SETUP FILE DATA BLOCK ADR.
	PUSHJ	P,GVMNB0	;RETURN MONITOR BUFFER USED FOR "HOME" BLOCK
	SKIPE	SHUTUP
	JRST	RWRHM1		;IF SHORT DIALOG, DONT GO BACK
	PUSHJ	P,CHKCHG	;DID WE WRITE ALL HOME BLOCKS?
	  JRST	FILOP2		;YES, REREAD THEM AS A CHECK
	SETOM	HOMFLG		;NO, INDICATE DON'T REREAD
	PUSHJ	P,GTMNB1	;GET MON BUF TO READ BAT BLOCKS
	JRST	FILCHG		;GO READ ALL "HOME" BLOCKS & SET UP DATA BASE
RWRHM1:	PUSHJ	P,REDHOM
	  JFCL
	PUSHJ	P,REDBAT
	POPJ	P,		;YES.

;ROUTINE TO JUST WRITE OUT ALL HOME BLOCKS(FOR OPTION NUMBER 1)
;DOESN'T WRITE ON OFF LINE OR WRITE PROTECTED UNITS

WRTHOM:	MOVSI	P4,UNPCHG##
	HLRZ	U,SYSUNI##
WRTHM1:	MOVSI	T1,UNPWPO##	;HARDWARE WRITE PROTECT & OFF LINE BITS
	TDNE	T1,UNIDES##(U)	;IF UNABLE TO WRITE, GO TO NEXT UNIT
	JRST	WRTHM2
	PUSHJ	P,HOMWRT
	ANDCAM	P4,UNIDES##(U)	;CLEAR OUT UNPCHG
WRTHM2:	HLRZ	U,UNISYS##(U)
	JUMPN	U,WRTHM1	;UNITS ARE LEFT-GO FOR MORE
	MOVEI	T1,[ASCIZ .
HOME blocks written on all units.]
	PUSHJ	P,SVMOUT
	MOVE	F,DATADR	;GET FDB ADDRESS
	PUSHJ	P,GVMNB0	;GIVE BACK MONITOR BUFFER
	PUSHJ	P,REDHOM
	  JFCL
	PUSHJ	P,REDBAT	;READ BAT BLOCKS ALSO
	POPJ	P,		;GO AWAY

	SUBTTL	REFRESH FILE STRUCTURE(S)

RFRESH:	SKIPN	HOMFLG
	PUSHJ	P,CHKCHG	;ANY "HOME" BLOCKS NEED REWRITING?
	  CAIA			;NO - GO REFRESH STRS
	JRST	CHGSOM		;YES - WARN USER BEFORE WRITING THEM
	MOVE	P1,STRAOB##	;LH=-NUMBER OF STR'S, RH=INDEX OF 1ST
	SETZ	P3,		;P3=0 FOR 1ST THAT NEEDS REFRESHING
RFRESA:	MOVE	P2,TABSTR##(P1)	;ADDR OF NEXT STR DATA BLOCK
	JUMPE	P2,RFRESB	;JUMP IF NOT AN STR
	HLLZ	T2,STRREF##(P2)	;NEEDS REFRESHING FLAG
	JUMPN	T2,RFRESC	;JUMP IF NEEDS REFRESHING
RFRESB:	AOBJN	P1,RFRESA	;LOOP FOR ALL STRS
	SKIPE	SHUTUP		;IF IN QUIET MODE
	JUMPE	P3,CPOPJ##	;DON'T ASK IF NO STR NEEDS IT
	JUMPE	P3,RFRES3	;ASK WHAT HE WANTS TO REFRESH
	PUSHJ	P,SCRLFO
	JRST	RFRES3
RFRESC:	JUMPN	P3,RFRESD
	PUSHJ	P,SVOSET
	MOVEI	T1,[ASCIZ .
%Need refreshing:
.]
	PUSHJ	P,SCONMS
RFRESD:	PUSHJ	P,TYPSTS	;TYPE STR NAME
	AOJA	P3,RFRESB	;BUMP P3 TO SHOW ONE PRINTED AND KEEP ON
RFRES1:	PUSHJ	P,SOPOUT
RFRES3:	MOVEI	T1,[ASCIZ .Type structure name to be refreshed (<CR> if none).]
	MOVE	F,DATADR	;SETUP FILE DATA BLOCK ADR
	PUSHJ	P,ASKSTR	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR WAS TYPED - EXIT
	JUMPN	P2,RFRES4
	MOVEI	T1,[ASCIZ ."ALL" is not a legal response.]
	PUSHJ	P,SCONMS
	JRST	RFRES3
RFRES4:	HLLZ	T2,STRREF##(P2)	;IF STR NEEDS REFRESHING
	JUMPN	T2,WUNSTR	; DON'T ASK IF HE IS SURE
	MOVEI	T1,[ASCIZ .
Structure does not require refreshing, are you sure?
.]
	PUSHJ	P,ASKQUE
	  JRST	RFRES3		;CHANGED HIS MIND
	SKIPGE	STRSDL##(P2)
	SKIPL	STRSRC##(P2)
	CAIA
	JRST	WUNSTR		;NOT IS SYS SEARCH LIST. DO IT
	MOVEI	T1,[ASCIZ .This is a system structure, are you positive?
.]
	PUSHJ	P,ASKQUE
	  JRST	RFRES3		;CHANGED HIS MIND
				;FALL INTO WUNSTR
WUNSTR:	PUSHJ	P,REFSTR##	;REFRESH STR
	  STOPCD .+1,DEBUG,ERD,DIESTR##, ;++ERROR REFRESHING DISK
	JRST	RFRES3		;ASK FOR ANOTHER STR NAME TO BE REFRESHED


;HERE ON DESTROY
RFRES2:	PUSHJ	P,REFSTR##	;REFRESH STR
	  STOPCD .+1,DEBUG,EWR,DIESTR##, ;++ERROR WHILE REFRESHING
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR IN SYSTEM
	JUMPN	P2,RFRES2	;REPEAT IF ANY LEFT
	POPJ	P,		;CR WAS TYPED - EXIT


;ROUTINE TO SEE IF ALTMODE WAS TYPED IN RESPONSE TO A QUESTION
;IF SO, USE SAVED PDP AND POPJ BACK TO QUICK

ALTM::	JUMPGE	J,CPOPJ##	;JUST GO BACK IF ALT WASN'T TYPED.
ALTM1:	MOVE	F,DATADR	;FILE DATA BLOCK ADR
	MOVE	P,.CPNPD##	;FIX PDP
	PUSH	P,.		;POSITIVE NUMBER ON LIST IS
				; THE ALT-MODE FLAG
	JRST	SHORTD##	;GO BACK TO BEGINNING.
	SUBTTL	MANDATORY ONCE ONLY CODE

FILMAN::SETZM	SERIUS
	SETZM	FSTTIM##	;REALLY DO THINGS
	PUSHJ	P,REDHOM	;READ ALL UNIT'S "HOME" BLOCKS THAT CAN BE
				; & SET UP UPPER CORE DATA BLOCKS
	  JRST	.+2		;ERRORS - CALL OPTIONAL ONCE-ONLY
	JRST	FILMN1		;NO ERRORS IN "HOME" BLOCK-PROCEED
	SKIPN	OPTQIK		;QUICK OPTION?
	SKIPGE	DEBUGF##	; OR DEBUGGING?
	SKIPE	SERIUS		;YES, SERIOUS ERROR
	CAIA			;YES, DO LONG DIAGLOGUE
	JRST	FILMN1		;NO, START UP SYSTEM
	SETZM	BATMAN		;ASSUME OPTIONAL FOR VENDING BAT BLOCKS
FILMN0:	SETZM	SERIUS
	PUSHJ	P,FILCHG	;CALL OPTIONAL ONCE-ONLY
	PUSHJ	P,REDHOM	;MUST READ "HOME" BLOCKS AGAIN-MAY HAVE BEEN CHANGED
	  JFCL			;IGNORE ERRORS
	SKIPE	SERIUS		;SERIOUS ERROR STILL EXIST?
	JRST	FILMN0		;YES, MAKE HIM FIX IT
FILMN1:	SETOM	BATMAN		;NOTE IN MANDANTORY PART NOW
	PUSHJ	P,REDBAT	;READ BAT BLOCKS TO SET UP SWAPPING SATS
	HLRZ	P2,SYSSTR##	;GET ADR. OF 1ST. STR IN SYSTEM
NXTSIS:	SETZB	P4,STRTAL##(P2)	;CLEAR FREE BLOCK TALLY & LAST RET. PTR. FLAG FOR STR
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT IN STR
	PUSHJ	P,GTSRB		;READ SAT.SYS "RIB" BLOCK FOR THIS STR - P2 DESTROYED
	  STOPCD NXTSIE,DEBUG,ERS,DIEUNI##, ;++ERR READING SAT
	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,DIFSAB##(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	;GO 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 IN THIS 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,<
	JRST	@[0,,.+1]	;RETURN TO SECTION 0
>
	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
	MOVE	T4,DDSTAR##	;COMPUTE OFFSET OF HI CORE DATA BLOCKS ETC.
	SUB	T4,SYSSIZ##
	MOVEI	T2,SYSSTR##	;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)
	HRRZ	T3,P1
	SUB	T3,T4		;DECREMENT LH OF PTR. TO NEXT STR BY OFFSET
	HRLM	T3,(T2)
	MOVEI	T2,STRSYS##(P1)	;SETUP LINK POINTING TO NEXT STR IN SYSTEM
ADJSR1:	HLRZ	P1,(T2)		;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:
IFE FTXMON,<
	LDB	T1,UNYSIC##	;GET # SAT BLOCKS IN CORE FOR THIS UNIT
	JUMPE	T1,ADJSA1	;MUST BE A UNIT NOT IN AN STR
	MOVEI	T3,UNISAB##(U)	;SETUP LINK POINTING TO 1ST. SAB BLOCK FOR THIS UNIT
	CAIA
ADJSAB:	MOVEI	T3,SABRNG##(P1)	;SETUP LINK POINTING TO NEXT SAB BLOCK FOR THIS UNIT
	MOVE	P1,(T3)		;GET ADR. OF NEXT SAB BLOCK FOR THIS UNIT
	MOVE	T2,P1
	SUB	T2,T4		;DECREMENT LH OF THIS SAB'S(OR UNIT DATA BLOCK'S)
	MOVEM	T2,(T3)		; PTR. TO NEXT SAB BY OFFSET
	SOJG	T1,ADJSAB	;REPEAT IF ANY MORE SAB BLOCKS FOR THIS UNIT
	MOVE	T2,UNISAB##(U)	;GET ADR. OF 1ST. SAB BLOCK
	MOVEM	T2,SABRNG##(P1)	;MAKE LAST SAB BLOCK POINT TO 1ST.(RING)
	HRRZ	T2,UNIPTR##(U)
	SUB	T2,T4		;DECREMENT RH OF AOBJN PTR. TO SWAPPING SAT TABLE
	HRRM	T2,UNIPTR##(U)
	MOVE	T2,UNISPT##(U)
	JUMPE	T2,ADJSA1	;NO SPT TABLE FOR THIS UNIT?
	SUB	T2,T4		;DECREMENT ADR. OF SPT TABLE IN UNIT DATA BLOCK
	MOVEM	T2,UNISPT##(U)
>
ADJSA1:	HRRZ	T2,UNISTR##(U)	;GET STR ADR. THIS UNIT IS IN
	JUMPE	T2,ADJSA2	;IS IT 0?
	SUB	T2,T4		;NO - DECREMENT ITS ADR.
	HRRM	T2,UNISTR##(U)	;STORE NEW ADR.
IFN FTDUAL,<
	SKIPE	T2,UNI2ND##(U)	;DRIVE DUAL PORTED?
	PUSHJ	P,CPYUD##	;COPY INFORMATION TO SECOND PORT
>
ADJSA2:	HLRZ	U,UNISYS##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,ADJUNI	;REPEAT IF ANY LEFT
	MOVE	T3,STRAOB##	;ADJUST ALL ADRS. IN STR TABLE
ADJSTT:	HRRZ	T2,TABSTR##(T3)	;GET NEXT STR ADR. FROM TABLE
	JUMPE	T2,SWPFAC	;END OF TABLE?
	SUB	T2,T4		;NO - DECREMENT THIS STR ADR.
	HRRM	T2,TABSTR##(T3)	;STORE NEW STR ADR.
	AOBJN	T3,ADJSTT	;REPEAT IF NOT END OF TABLE
SWPFAC:	PUSHJ	P,GVMNB0	;RETURN MONITOR BUFFER USED FOR "RIB" BLOCK
IFN FTSETS,<
	PUSHJ	P,TYPNMU	;TYPE UNITS IN STRUCTURES NOT MOUNTED TO THIS SYS
>; END IFN FTSETS


;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.

	MOVSI	T1,UNPTSB##	;GET TIMESHARED BIT(S) IN UNIDES
	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
SWPFC3:	ANDCAM	T1,UNIDES##(U)	;CLEAR TIMESHARED BIT(S)
IFN FTDUAL,<
	SKIPE	T2,UNI2ND##(U)	;ALTERNATE PORT?
	ANDCAM	T1,UNIDES##(T2)	;YES, CLEAR IT (THEM) HERE TOO
>; END IFN FTDUAL
	HLRZ	U,UNISYS##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,SWPFC3	;REPEAT IF ANY LEFT

	SETZM	DINITF##	;CLEAR FLAG THAT INDICATES ONCE ONLY IN PROGRESS
	MOVEI	T1,STRSYS##
	HRRM	T1,SYSSTR##
	SKIPN	REFLAG##	;AUTOMATIC "LOGIN" WANTED?
	POPJ	P,		;NO - RETURN
	MOVE	T1,FFAPPN##
	MOVEM	T1,REFLAG##
	PJRST	REFLOG##
KONCNI:	JFCL			;(NEW) DRUM
	XCT	FHXCI1##(J)
	XCT	DPXCIT##(J)
	JFCL			;MOBY DISK
	XCT	FSXCI2##(J)
IFE FTKS10,<
	XCT	RPXCI2##(J)
>
IFN FTKS10,<
	JFCL
>
	XCT	RNXCI2##(J)	;RP20
IFE FTCIDSK,<
	JFCL
>; END IFN FTCIDSK
IFN FTCIDSK,<
	JFCL			;CI DISKS
>; END IFN FTCIDSK

KONCNO:	JFCL
	XCT	FHXCO1##(J)
	XCT	DPXCO1##(J)
	JFCL
	XCT	FSXCO2##(J)
IFE FTKS10,<
	XCT	RPXCO2##(J)
>
IFN FTKS10,<
	JFCL
>
	XCT	RNXCO2##(J)	;RP20
IFE FTCIDSK,<
	JFCL
>; END IFE FTCIDSK
IFN FTCIDSK,<
	JFCL			;CI DISKS
>; END IFN FTCIDSK
SKPPIA:	JFCL
	TRNN	T2,7
	TRNN	T1,7
	JFCL
	TRNN	T2,7
IFE FTKS10,<
	TRNN	T2,7
>
IFN FTKS10,<
	SKIPA
>
	TRNN	T2,7		;RP20
IFE FTCIDSK,<
	JFCL
>; END IFE FTCIDSK
IFN FTCIDSK,<
	SKIPA			;CI DISKS
>; END IFN FTCIDSK

SKP22B:	JFCL
	TLNN	T2,40000
	TLNN	T1,20
	JFCL
	TLNN	T2,4000
IFE FTKS10,<
	TLNN	T2,4000
>
IFN FTKS10,<
	SKIPA
>
	SKIPA			;RP20
IFE FTCIDSK,<
	JFCL
>; END IFE FTCIDSK
IFN FTCIDSK,<
	SKIPA			;CI DISKS
>; END IFN FTCIDSK
;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	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 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 READ & VERIFY HOME BLOCKS AT SYSTEM INITIALIZATION
; REDHOM GETS A MONITOR BUFFER(GTMNBF), BUT DOESN'T RELINQUISH IT(GVMNB0)
;CALL	PUSHJ	P,REDHOM
;	  ERROR RETURN	AN ERROR WAS DETECTED WHILE READING THE "HOME" BLOCKS
;			OF 1 OR MORE UNITS AND/OR NO STR'S WERE CREATED
;	OK RETURN	ALL HOME BLOCKS THAT WERE NOT DOWN READ OK

REDHOM::SKIPE	HOMFLG		;HOME BLOCKS SAME IN CORE AND DISK?
	JRST	CPOPJ1##	;NO, LEAVE CORE IMAGE ALONE

	SETZM	DOFLOK		;CLEAR FLAG
	SETZM	SWPUN2##
	SKIPE	.UONCE##	;SKIP IF EXEC MODE
	SKIPA	T1,ONCEND##	;USER MODE, GET ADDR OF FIRST FREE LOC
	MOVEI	T1,ONCEND##	;EXEC MODE, ADDR OF FIRST FREE LOC
	MOVEM	T1,DATADR
	MOVEM	T1,HICORE##
	MOVEI	R,.USMBF	;ASSUME ONCE
	SKIPE	.UONCE##
	MOVEI	R,TWCMBF##	;TWICE
	MOVEM	R,ONCMBF	;ADDRESS OF MONITOR BUFFER TO BE USED
	MOVEI	T2,DDBLEN##	;SETUP LENGTH OF DDB FOR CORE GRABBER
	PUSHJ	P,CORGRB	;GET CORE
	MOVEM	T2,DDSTAR##	;SAVE HIGH CORE START ADR. OF DDB'S ETC.
	SETOM	DINITF##	;SET FLAG THAT INDICATES THAT ONCE ONLY IN PROGRESS
	SKIPE	.UONCE##
	JRST	BUFSE1
;HERE TO INITIALIZE FOR 18/22 BIT CHANNEL
TEST22::JFCL	OK22B		;AVOID
	MOVSI	T1,(JRST)	; REDUNDANT
	HLLM	T1,TEST22	;  TESTS
	SETZ	T4,		;CLEAR 18 BIT CHANNEL FLAG
	HLRZ	J,SYSKON##	;POINT TO FIRST DISK KONTROLLER
LOOP22:	LDB	T3,KOYKTP##	;GET KONTROLLER TYPE
	XCTCPU	(UNI,CHKD22)	;GET 18/22 BIT DISK STATUS
	  PUSHJ	P,DCLR22	;18 BITS (UNLESS AN RH20)
	PUSHJ	P,DSET22	;22 BITS
LOOP2A:	HLRZ	J,KONNXT##(J)	;POINT TO NEXT KONTROLLER
	JUMPN	J,LOOP22	;LOOP
	SKIPN	W,CNFMTK##	;1ST MAGTAPE CONTROLLER
	JRST	CHN18B		;NO TAPES??

MTLP22:	SKIPN	U,TKBUDB##(W)	;GET A UDB ADDRESS
	  JRST	MTLPOK		;NOT THERE--ASSUME 22 BITS
	LDB	T3,TUYKTP##	;GET UNIT TYPE
	XCTCPU	(KDB,CHKT22)	;GET 18/22 BIT TAPE STATUS
	  PUSHJ	P,TCLR22	;18 BITS (UNLESS AN RH20)
MTLPOK:	PUSHJ	P,TSET22	;22 BITS
	HRRZ	W,TKBKDB##(W)	;POINT TO NEXT KONTROLLER
	JUMPN	W,MTLP22	;LOOP 'TIL NO MORE

CHN18B:	SKIPE	FLG256##	;GTR THAN 256K?
	SKIPN	T4		;YES, AN 18-BIT DF?
	JRST	OK22B		;ALL IS OK
;HERE IF AN 18-BIT CHAN AND MORE THAN 256K
	MOVEI	T1,[ASCIZ /%Memory above 256K and an 18-bit DF10
System will only use up to 256K.
/]
	PUSHJ	P,CONOUT
	SETZM	FLG256##	;ONLY USE FIRST 256 K
	JRST	OK22B

;SET/CLEAR KA/KI FLAG

TCLR22:	SKIPA	T2,TKBCDB##(W)	;TAPES
DCLR22:	MOVE	T2,KONCHN##(J)	;DISKS/ETC...
	MOVE	T1,CHB22B##(T2)	;CHAN-TYPE WORD
IFN FTKL10,<
	TLNE	T1,CP.RH2##	;IF AN RH20,
	POPJ	P,		; ALWAYS 22-BIT
>
	TLZ	T1,CP.22B##	;NOT AN RH20, 18-BIT
	MOVEM	T1,CHB22B##(T2)	;CLEAR 22-BIT BIT
	SETO	T4,		;SAY WE'VE SEEN AN 18-BIT CHAN
	JRST	CPOPJ1##	;SKIP RETURN

TSET22:	SKIPA	T2,TKBCDB##(W)
DSET22:	MOVE	T2,KONCHN##(J)
	MOVSI	T1,CP.22B##
	IORM	T1,CHB22B##(T2)	;SET BIT
	POPJ	P,		;RETURN
;TAPE KONTROLLER IOT PNTRS

TAPCNO:	JFCL			;TM10A
	XCT	TTMCOC##(W)	;TM10B
	XCT	TTCCOS##(W)	;TC10C
	XCT	TTXCOS##(W)	;TX01
	XCT	TT2CO1##(W)	;TM02
	JFCL			;RH11
	JFCL			;DX20
	JFCL			;TM78

TAPCIC:	JFCL			;TM10A
	XCT	TTMCIC##(W)	;TM10B
	XCT	TTCCIS##(W)	;TC10C
	XCT	TTXCIS##(W)	;TX01
	XCT	TT2CI2##(W)	;TM02
	JFCL			;RH11
	JFCL			;DX20
	JFCL			;TM78

TAPPIA:	JFCL			;TM10A - NO CHL
	TRNN	T1,70		;TM10B
	TRNN	T1,7		;TC10C
	TRNN	T1,7		;TX01
	TRNN	T2,7		;TM02
	SKIPA			;RH11
	SKIPA			;DX20
	SKIPA			;TM78

TAPCIS:	JFCL			;TM10A
	XCT	TTMCIS##(W)	;TM10B
	XCT	TTCCIS##(W)	;TC10C
	XCT	TTXCIS##(W)	;TX01
	XCT	TT2CI2##(W)	;TM02
	JFCL			;RH11
	JFCL			;DX20
	JFCL			;TM78

TAPSKP:	JFCL			;TM10A
	TLNN	T1,400		;TM10B
	TRNN	T1,40		;TC10C
	SKIPA			;TX01
	TLNN	T2,4000		;TM02
	SKIPA			;RH11
	SKIPA			;DX20 - RH20 IS ALWAYS 22 BIT
	SKIPA			;TM78 - TH20 IS ALWAYS 22 BIT
OK22B:	HRRZ	T1,DSKDSP##+DINI
	PUSHJ	P,(T1)		;SET DISK QUEUES AND CLEAR ALL FLAGS
	CONO	PI,PI.ON	;TURN PI SYSTEM ON FOR WAITS
BUFSE1:	MOVE	T1,DATADR
	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 A MONITOR BUFFER FOR READING "HOME" BLOCKS
	SETZM	SYSSTR##	;INITIALLY THERE ARE NO FILE STRUCTURES IN SYSTEM
	HRRZS	SWPUNI##	;INITIALLY NO UNITS IN ASL
	MOVE	T1,STRAOB##	;CLEAR OUT TABLE OF STR DATA BLOCK ADRS.
	SETZM	TABSTR##(T1)
	AOBJN	T1,.-1
	MOVSI	T1,MSWPMX##	;CLEAR OUT TABLE OF UNIT ADRS. IN ASL
	SETZM	SWPTAB##(T1)
	AOBJN	T1,.-1

	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
	SETZM	ERRHOM		;CLEAR ERROR(S) WHILE READING "HOME" BLOCKS FLAG
SCNUNI:	HRRZ	J,UNIKON##(U)	;GET ADR. OF KONTROLLER DATA BLOCK FOR THIS UNIT
	SKIPGE	KONUPA##(J)	;HAS KONTROLLER BEEN FLAGGED AS DOWN?
	JRST	FLGDWN		;YES - FLAG UNIT AS DOWN ALSO

TRYKON:	HRRZ	J,UNIKON##(U)	;RESET J
	XCTCPU	(UNI,CHKKON)	;GET KONTROLLER ON/OFF-LINE STATUS
	  JRST	KDOWN		;DOWN
	JUMPN	T1,KONTOK	;OK IF WRITE-HEADER LOCKOUT IS ON
	JRST	WHLBAD		;IT'S SET WRONG
KDOWN:	MOVEI	T4,[ASCIZ . is off-line.]
	HLLZ	P1,UNINAM##(U)	;GET SIXBIT CONTROLLER NAME
	MOVEI	T3,[ASCIZ .Do you want it to be 1)On-line, or 2)Down? (Type #)
.]
	PUSHJ	P,MCKKON	;PRINT MSG & GET ANSWER
	  JRST	TRYKON		;ILLEGAL RESPONSE
	CAIE	T2,2		;WAS "2" TYPED?
	JRST	TRYKON		;NO - CHECK AGAIN IF "1" OR ANYTHING ELSE WAS TYPED
KOPSET:	MOVSI	T1,KOPDWN##	;KONTROLLER DOWN BIT(SIGN BIT)
	IORM	T1,KONDWN##(J)	;FLAG KONTROLLER AS DOWN
	JRST	FLGDWN		;FLAG UNIT DOWN AS WELL
;HERE WHEN THE WHL SWITCH IS SET WRONG
WHLBAD:	MOVSI	T1,KOPWHL##	;WE ALREADY ASK ABOUT SWITCH!
	TDNE	T1,KONUPA##(J)
	JRST	KONTOK		;YES, HE SAID IT WAS OK
	MOVEI	T4,[ASCIZ . write-header-lockout switch allows writing headers.]
	HLLZ	P1,UNINAM##(U)	;SIXBIT CONTROLLER NAME
	MOVEI	T3,[ASCIZ .Do you want it to be 1)Set, or 2)Ignored? (Type#).]
	PUSHJ	P,MCKKON	;PRINT MSG, GET ANSWER
	  JRST	TRYKON		;ILLEGAL ANSWER
	CAIE	T2,2		;TRY AGAIN?
	JRST	TRYKON		;YES
	PUSHJ	P,OFFDWN
	AOSG	DOFLOK
	JRST	WHLBD1
	MOVEI	T1,[ASCIZ .
Not normally done, are you sure?
.]
	PUSHJ	P,ASKQUE
	  JRST	TRYKON		;HE ISN'T SURE
WHLBD1:	MOVSI	T1,KOPWHL##	;INDICATE OPR SAID CONTROLLER
	IORM	T1,KONUPA##(J)	; HAS SWITCH WRONG
;HERE IF KONTROLLER ON-LINE - TO CHECK IF UNIT OK

KONTOK:	MOVSI	T1,UNPOFL##
	TDNE	T1,UNIDES##(U)	;IS UNIT OFF-LINE OR DOWN?
	JRST	NXTUNI		;YES - CONTINUE SCAN ON NEXT UNIT
	XCTCPU	(UNI,CHKCPY)	;CHECK CAPACITY OF UNIT
	  JFCL			;IGNORE ERRORS (CATCH THEM BELOW)
	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 #
IFN FTDUAL,<
	HLRZ	T1,J		;SERIAL NUMBER
	PUSHJ	P,MATUN##	;ANY OTHER DRIVE WITH SAME NUMBER?
	  JRST	KONTO3		;NO
	PUSHJ	P,LN2ND##	;SETUP UNI2ND LINKS FOR THIS DRIVE
				;  AND UNLINK SECOND PORT FROM UNISYS CHAIN
	JRST	NXTUNI		;DONT READ HOME BLOCKS, TRY NEXT UNIT
KONTO3:>
	TLNN	T4,KOPUHE##	;UNIT ON-LINE?
	JRST	WCKUNI		;YES, SEE IF IT IS WRITE-ENABLED
	TLNE	T4,KOPNSU##	;WAS THIS NO SUCH UNIT ERROR?
	JRST	FLGDWN		;YES, SKIP QUESTION, FLAG AS DOWN

	MOVEI	T3,[ASCIZ .Do you want it to be 1)On-line, 2)Off-line, or 3)Down? (Type #).]
	PUSHJ	P,OFLUNM	;PRINT MSG & GET ANSWER
	  JRST	TRYKON		;ILLEGAL RESPONSE
	CAIN	T2,2		;WAS "2" TYPED?
	JRST	FLGOFL		;YES - FLAG UNIT AS OFF-LINE
	CAIE	T2,3		;WAS "3" TYPED?
	JRST	TRYKON		;NO - CHECK AGAIN IF "1" OR ANYTHING ELSE WAS TYPED
;HERE TO FLAG UNIT AS DOWN & OFF-LINE

FLGDWD:
FLGDWN:	MOVEI 	T1,UNVDWN##	;VALUE FOR UNIT DOWN
	JRST	FLGOFF		;ALSO SET OFF-LINE STATUS BIT

;HERE TO FLAG UNIT AS OFF-LINE ONLY AND NO PACK MOUNTED
FLGOFL:	MOVEI	T1,UNVNPM##	;SET STATUS TO NO PACK MOUNTED
				; SO RES COMMAND WILL PRINT AS AVAIL.
FLGOFF:	DPB	T1,UNYUST##	;STORE UNIT STATUS(DOWN OR NO PACK MOUNTED)
	MOVSI	T1,UNPOFL##	;OFF-LINE BIT
	IORM	T1,UNIDES##(U)	;SET BIT IN LH. OF UNIDES WORD
	SETZB	T1,UNILOG##(U)	;MAKE SURE NOT IN STR FLAG CLEARED
				;COULD HAVE BEEN SET IF UNIT TURNED
				;OFF AND THE ONCE ONLY RESTARTED
	DPB	T1,UNYSIC##	;MAKE SURE NO SATS IN CORE SO WONT ADJUST
				;SAB'S LATER. COULD ALSO HAPPEN AS ABOVE
	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
	JRST	NXTUNI		;CONTINUE SCAN ON NEXT UNIT
;HERE IF UNIT ON-LINE - TO CHECK IF UNIT WRITE ENABLED

WCKUNI:	MOVSI	T1,UNPHWP##	;GET HWP BIT
	ANDCAM	T1,UNIDES##(U)	;CLEAR IT
	DPB	T1,UNYAWL##	;CLEAR SOFTWARE W/L
	HRRZ	J,UNIKON##(U)	;*** MAYBE REMOVE THIS LATER
	XCTCPU	(UNI,CHKWLK)	;SEE IF UNIT IS WRITE ENABLED
	  JRST	CHKHOM		;IT IS
	MOVEI	T3,[ASCIZ .Do you want it to be 1)Write-enabled, or 2)Write-protected? (Type #)
.]
	PUSHJ	P,WRPUNM	;PRINT MSG & GET ANSWER
	  JRST	TRYKON		;ILLEGAL RESPONSE
	CAIE	T2,2		;WAS "2" TYPED?
	JRST	TRYKON		;NO - CHECK AGAIN
	MOVSI	T1,UNPHWP##	;HARDWARE WRITE-PROTECT BIT
	IORM	T1,UNIDES##(U)	;FLAG UNIT AS WRITE PROTECTED
;HERE IF UNIT ON-LINE & LEGALLY WRITE PROTECTED OR ENABLED - CHECK ITS "HOME" BLOCKS

CHKHOM:	MOVEI	T1,UNVPIM##	;IF WE READ HOME BLOCKS
	DPB	T1,UNYUST##	;A PACK MUST BE MOUNTED
	LDB	T1,UNYKTP##
	CAIE	T1,TYPRP##	;IF THIS IS AN RP04
	JRST	CHKHM1
	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	CHKHM1
	PUSHJ	P,UNITIS
	MOVEI	T1,[ASCIZ . PDP-11 pack mounted - Unit considered off-line
.]
	PUSHJ	P,CONMES##
	PUSHJ	P,CRLFOP
	JRST	FLGOFL
CHKHM1:
	SKIPE	KON		;SKIP IF NOT SHORT DIALOG OPTION 1
	JRST	NXTUNI		;SKIP THIS PART IF IT IS OPTION 1
	PUSHJ	P,GTHOM		;GET "HOME" BLOCK INTO CORE
	  CAIA			;ERROR(S) ON BOTH "HOME" BLOCKS - T2 RETURNED NON 0
	JRST	HMBOK		;AT LEAST ONE "HOME" BLOCK OK
	MOVSI	T2,UNPHWP##
	SETZM	HOMSIC##(P1)	;0 SAT BLOCKS IN CORE FOR THIS UNIT(FOR CRESAB CODE)
	MOVEI	T1,[ASCIZ .
Do you want to initialize the HOME blocks on this unit?
.]
	TDNE	T2,UNIDES##(U)
	JRST	ASIS
	SKIPE	SHUTUP
	JRST	.+3
	PUSHJ	P,ASKQUE
	  JRST	ASIS
	MOVE	T1,P1		;USE ANOTHER AC AS P1 IS NEEDED
	SETZM	(T1)		;CLEAR 1ST. WORD OF IN CORE "HOME" BLOCK
	HRLS	T1		;MAKE A BLT PTR. TO CLEAR ALL OF "HOME" BLOCK
	ADDI	T1,1
	BLT	T1,BLKSLF##(P1)	;CLEAR "HOME" BLOCK
	MOVEM	P2,BLKNAM##(P1)	;STORE SIXBIT "HOM"
	MOVEM	P3,BLKCOD##(P1)	;STORE "HOME" BLOCK CODE
	MOVEM	P4,HOMHOM##(P1)	;STORE LOG. BLOCK #'S OF "HOME" BLOCKS
	SETOM	HOMSUN##(P1)	;INDICATE UNIT NOT IN ASL
	SETOM	HOMSRC##(P1)	;INDICATE STR THIS UNIT WILL BE IN
				; WILL NOT BE IN "SYS" SEARCH LIST
	SETOM	HOMSDL##(P1)	;INDICATE NOT IN SYSTEM DUMP LIST
	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
	  JFCL			;IGNORE ERRORS - FOR THE MOMENT
	JRST	FLGCHG		;GO FLAG MOD BLOCKS MUST BE REWRITTEN
ASIS:	MOVEI	T1,UNVNPM##	;NO PACK MOUNTED
	DPB	T1,UNYUST##	;SET STATUS FOR UNIT
FLGCHG:	PUSHJ	P,SETCHG	;FLAG THAT THIS UNIT'S "HOME" BLOCK MUST BE REWRITTEN
	PUSHJ	P,MOVUNI	;MOVE PARAMS FROM "HOME" BLOCK TO UNIT DATA BLOCK
	JRST	NOSTR		;TRY & SETUP SAB RING & SPT TABE FOR UNIT
OFFDWN:	SKIPE	OPTQIK		;SEE IF QUICK OPTION
	SETOM	DOFLOK		;YES--SET DEFAULT FLAG
	SKIPN	SHUTUP
	SKIPGE	DEBUGF##	;IS SYS PROG DEBUGGING?
	SETOM	DOFLOK		;YES--SET DEFAULT FLAG
	POPJ	P,
;HERE IF "HOME" BLOCK(S) READ INTO CORE OK
; GENERATE STR DATA BLOCK & LINK UNIT DATA BLOCKS CORRECTLY

HMBOK:	AOJE	T2,HMBOK2	;FLAG REWRITE HOME BLOCKS IF ERRORS
	PUSH	P,T2		;SAVE HOME BLOCK FLAG
	PUSHJ	P,CHKVSY	;DO WE UNDERSTAND THIS PACK?
	  JRST	HMBOK1		;YES
	PUSH	P,T1		;NO, SAVE ADDRESS OF SYSTEM TYPE TEXT
	PUSHJ	P,UNITIS
	MOVEI	T1,[ASCIZ . - .] ;SOME NOISE
	PUSHJ	P,CONMES##
	POP	P,T1		;RESTORE ADDRESS OF SYSTEM TYPE TEXT
	PUSHJ	P,CONMES##	;START THE MESSAGE
	MOVEI	T1,[ASCIZ . system pack mounted - Unit considered off-line
.]
	PUSHJ	P,CONMES##
	PUSHJ	P,CRLFOP
	POP	P,T2		;CLEAN STACK
	JRST	FLGOFL
HMBOK1:	POP	P,T2		;RESTORE HOME BLOCK FLAG
	SOSE	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	HMBOK3		;NOT RP10 PROCEED
	LDB	T1,UNYUTP##	;GET UNIT TYPE TO MAKE SURE PACK IS
	CAIE	T1,2		; COMPATIBLE, SKIP IF RP03
	JRST	HMBOK3		;NOT RP03, PROCEED
	CAMN	T1,HOMUTP##(P1)	;SINCE RP03 DRIVE CAN READ RP02 PACKS
	JRST	HMBOK3		;PACK WRITTEN BY RP03, PROCEED
				;WRONG PACK! NOTIFY OPERATOR.
	MOVEI	T3,[ASCIZ . Do you want it to be 1)On-line, 2)Off-line, or 3)Down? (Type #).]
	MOVEI	T4,[ASCIZ . is RP03 drive, Pack written on RP02.]
	MOVE	P1,UNINAM##(U)	;GET SIXBIT UNIT NAME
	MOVEI	T1,[ASCIZ .
%.]
	PUSHJ	P,NASTYP	;PRINT MESSAGE AND GET RESPONSE
	  JRST	TRYKON		;ILLEGAL RESPONSE
	CAIN	T2,2		;WAS "2" TYPED?
	JRST	FLGOFL		;YES, FLAG AS OFF-LINE
	CAIE	T2,3		;WAS "3" TYPED?
	JRST	TRYKON		;NO, CHECK AGAIN IF "1" OR SOMETHING ELSE
	JRST	FLGDWN		;WAS "3", FLAG AS DOWN.
HMBOK2:	PUSHJ	P,SETCHG	;FLAG HOME BLOCKS NEED REWRITING
HMBOK3:	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
IFN FTSETS,<
	SKIPE	.UONCE##	;IS THIS TWICE?
	JRST	HMBOK5		;YES, BYPASS CHECKS ON SET NUMBER
	LDB	T1,HOYSET##	;GET SET NUMBER THIS STRUCTURE BELONGS TO
	JUMPE	T1,HMBOK5	;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##	;DO WE WISH TO MOUNT THIS STRUCTURE AT ONCE TIME?
	SKIPA			;NO, THEN DON'T SET UP SDB
	JRST	HMBOK5		;PROCEED
	MOVSI	T1,UNPNMU##	;GET THE TEMPORARY BIT
	IORM	T1,UNIDES##(U)	;SET IN THE UNIT DATA BLOCK
	JRST	NOSTR1		;BYPASS SETTING UP SDB
>; END IFN FTSETS
HMBOK5:	MOVE	T1,HOMSNM##(P1)	;GET STR NAME FROM HOME BLOCK
	JUMPE	T1,HMBOK4	;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	HMBOK4		;FOUND
	PUSHJ	P,GETSTR	;CREATE STR DATA BLOCK IN UPPER CORE
	  JRST	NOSTR		;ATTEMPT TO CREATE MORE STR'S THAN ALLOWED
	PUSHJ	P,MOVSTR	;MOVE PARAMS FROM HOM BLOCK TO STR DATA BLOCK
HMBOK4:	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	NXTUNI		;ONTO THE NEXT UNIT

NOSTR:	SETOM	ERRHOM		;INDICATE ERROR IN "REDHOM"
NOSTR1:	SETOM	UNISUN##(U)	;INDICATE UNIT NOT IN ASL
	SETZM	UNILOG##(U)	;INDICATE UNIT NOT IN AN STR
NXTUNI:	HLRZ	U,UNISYS##(U)	;GET NEXT UNIT DATA BLOCK ADR. IN SYSTEM
	JUMPN	U,SCNUNI	;AROUND AGAIN IF ANY LEFT
	SKIPE	KON		;SKIP IF NOT OPTION 1 OF SHORT DIALOG
	POPJ	P,		;RETURN , YOU WERE PUSHJ ED TO.
	PUSHJ	P,CHKSTR	;MAKE SURE ALL STRS HAVE ALL NECESSARY UNITS
	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,CHKASL	;MAKE SURE THE ASL LOOKS OK
	PUSHJ	P,BLDSDL##	;BUILD SYSTEM DUMP LIST FROM PRESERVED COPY
	  PUSHJ	P,DSKSDL	;USE THE DISK DATA BASE
	SKIPN	ERRHOM		;ANY ERRORS?
	AOS	(P)		;NO - SKIP RETURN
	POPJ	P,
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 -- VALMFD - VALIDATE THE MFD


VALMFD:	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
	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
	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 -- CRESAB - CREATE SAB AND SPT TABLE


CRESAB:	SKIPE	.UONCE##	;TWICE?
	JRST	CRESA1
IFN FTXMON,<
	SKIPE	UNISAB##(U)	;ALREADY SETUP A SAB RING?
	POPJ	P,
>
	SE1ENT			;ENTER SECTION ONE
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,DIFSAB##(U)	;SETUP ADR. OF LINK TO 1ST. 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 -- 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
	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 -- DSKSSL - BUILD SSL FROM DISK DATA BASE


DSKSSL:	PUSHJ	P,SAVE4##	;SAVE P1-P4
	SETOM	P1		;INITIALIZE HIGHEST STR FOUND IN SSL
	MOVE	P4,[HRRZ P1,P3]	;INSTRUCTION TO EXECTUTE
	PUSHJ	P,FNDSRC	;FIND HIGHEST STR IN SSL
	JUMPGE	P1,DSKSS1	;GO IF FOUND AT LEAST ONE
	MOVEI	T1,[ASCIZ/
?No structures in system search list/]
	PJRST	SVMOTS		;GIVE MESSAGE AND RETURN
DSKSS1:	MOVNI	P4,1(P1)	;BUILD -VE COUNT OF STRS TO SEARCH
	HRLZS	P4		;MAKE IT AN AOBJN POINTER
DSKSS2:	MOVEI	P2,0		;P2 COUNTS NUMBER OF MATCHES
	HLRZ	P3,SYSSTR##	;GET ADDRESS OF FIRST STR DATA BLOCK
DSKSS3:	MOVE	T1,STRSRC##(P3)	;GET POSITION IN SSL OF THIS STR
	CAIN	T1,(P4)		;MATCH WITH CURRENT ONE?
	AOS	P2		;YES, COUNT MATCH
	HLRZ	P3,STRSYS##(P3)	;STEP TO NEXT STR
	JUMPN	P3,DSKSS3	;LOOP FOR ALL
	SOJE	P2,DSKSS5	;GO IF FOUND EXACTLY ONE
	HRRZ	P1,P4		;ERROR ROUTINES WANT NUMBER IN P1
	JUMPL	P2,DSKSS4	;GO IF FOUND NONE
	MOVEI	T1,[ASCIZ/
?Two logical structure /]
	PUSHJ	P,TYPMSN	;TYPE MESSAGE AND NUMBER
	MOVEI	T1,[ASCIZ/ 's found in system search list/]
	PUSHJ	P,SVMOTS	;FINISH MESSAGE
	JRST	DSKSS5		;JOIN COMMON CODE
DSKSS4:	MOVEI	T1,[ASCIZ/
%Logical structure /]
	PUSHJ	P,TYPMSN	;TYPE MESSAGE AND NUMBER
	MOVEI	T1,[ASCIZ/ missing from system search list/]
	PUSHJ	P,SVMOTE	;FINISH MESSAGE
DSKSS5:	AOBJN	P4,DSKSS2	;LOOP FOR ALL POSITIONS IN SSL
	POPJ	P,		;RETURN
SUBTTL	STRUCTURE ROUTINES -- DSKSDL - BUILD SDL FROM DISK DATA BASE


DSKSDL:	PUSHJ	P,SAVE4##	;SAVE P1-P4
	SETOM	P1		;INITIALIZE HIGHEST STR FOUND IN SDL
	MOVE	P4,[HRRZ P1,P3]	;INSTRUCTION TO EXECTUTE
	PUSHJ	P,FNDSDL	;FIND HIGHEST STR IN SDL
	JUMPGE	P1,DSKSD1	;GO IF FOUND AT LEAST ONE
	MOVEI	T1,[ASCIZ/
%No structures in system dump list/]
	PJRST	SVMOTE		;GIVE MESSAGE AND RETURN
DSKSD1:	MOVNI	P4,1(P1)	;BUILD -VE COUNT OF STRS TO SEARCH
	HRLZS	P4		;MAKE IT AN AOBJN POINTER
DSKSD2:	MOVEI	P2,0		;P2 COUNTS NUMBER OF MATCHES
	HLRZ	P3,SYSSTR##	;GET ADDRESS OF FIRST STR DATA BLOCK
DSKSD3:	MOVE	T1,STRSDL##(P3)	;GET POSITION IN SDL OF THIS STR
	CAIN	T1,(P4)		;MATCH WITH CURRENT ONE?
	AOS	P2		;YES, COUNT MATCH
	HLRZ	P3,STRSYS##(P3)	;STEP TO NEXT STR
	JUMPN	P3,DSKSD3	;LOOP FOR ALL
	SOJE	P2,DSKSD5	;GO IF FOUND EXACTLY ONE
	HRRZ	P1,P4		;ERROR ROUTINES WANT NUMBER IN P1
	JUMPL	P2,DSKSD4	;GO IF FOUND NONE
	MOVEI	T1,[ASCIZ/
?Two logical structure /]
	PUSHJ	P,TYPMSN	;TYPE MESSAGE AND NUMBER
	MOVEI	T1,[ASCIZ/ 's found in system dump list/]
	PUSHJ	P,SVMOTS	;FINISH MESSAGE
	JRST	DSKSD5		;JOIN COMMON CODE
DSKSD4:	SKIPGE	DEBUGF##	;SOMEONE DEBUGGING?
	JRST	DSKSD5		;YES, THEY PROBABLY DON'T CARE
	MOVEI	T1,[ASCIZ/
%Logical structure /]
	PUSHJ	P,TYPMSN	;TYPE MESSAGE AND NUMBER
	MOVEI	T1,[ASCIZ/ missing from system dump list/]
	PUSHJ	P,SVMOTE	;FINISH MESSAGE
DSKSD5:	AOBJN	P4,DSKSD2	;LOOP FOR ALL POSITIONS IN SDL
	POPJ	P,		;RETURN
SUBTTL	SWAPPING UNIT ROUTINES -- CRESST - CREATE SWAPPING SATS


CRESST:	SE1ENT			;ENTER SECTION ONE
IFN FTXMON,<			;REALLY WANT TO ALLOCATE THIS TWICE
				;IF FTKLP=0
	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	SWAPPING UNIT ROUTINES -- LNKSWP - LINK UNITS IN THE ASL


LNKSWP:	SKIPL	P4,UNISUN##(U)	;IS UNIT IN ACTIVE SWAPPING LIST?
	CAMLE	P4,MAXSWP##	;ABOVE HIGHEST LEGAL UNIT?
	POPJ	P,		;CAN'T LINK THIS UNIT
	MOVEI	T4,SWPUNI##	;GET ADDR OF LINK TO FIRST UDB IN ASL
	JRST	LNKSW2
LNKSW1:	MOVE	T3,UNISUN##(T1)	;GET LOG. UNIT # OF NEXT UNIT IN ASL
	CAMLE	T3,P4		;IS IT GREATER THAN UNIT JUST READ?
	JRST	LNKSW3		;YES - INSERT UNIT DATA BLOCK HERE
	MOVEI	T4,UNISWP##(T1)	;GET ADR. OF LINK TO NEXT UNIT
LNKSW2:	HLRZ	T1,(T4)		;GET ADR. OF NEXT UNIT DATA BLOCK IN ASL
	JUMPN	T1,LNKSW1	;MORE DATA BLOCKS?
LNKSW3:	HRLM	T1,UNISWP##(U)	;SAVE LINK TO NEXT UNIT DATA BLOCK
	HRLM	U,(T4)		;SAVE THIS UNIT ADDR IN PREVIOUS UDB
	MOVEM	U,SWPTAB##(P4)	;PUT THIS UNIT DATA BLOCK ADR. IN ASL
	SKIPN	T2,SWPUN2##	;SLOW SWAPPING CLASS SET?
	JRST	LNKSW4		;NO, CAUSE THIS TO BE IT
	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	SUBI	T1,(T2)		;YES, THIS UNIT IN LOWER CLASS?
	JUMPL	T1,CPOPJ##	;IF SO IGNORE IT
	JUMPN	T1,LNKSW4	;IF IN HIGER CLASS USE IT
	HLRS	T2		;IF IN SAME CLASS
	CAML	P4,UNISUN##(T2)	;IF LOWER IN ASL USE IT
	POPJ	P,		;ELSE GIVE UP
LNKSW4:	HRLM	U,SWPUN2##	;SAVE UNIT
	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	HRRM	T1,SWPUN2##	;SAVE CLASS
	POPJ	P,		;DONE
SUBTTL	SWAPPING UNIT ROUTINES -- CHKASL - MAKE SURE ASL HAS ALL NEEDED UNITS


CHKASL:	HLRZ	U,SWPUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN ASL
	JUMPN	U,CHKAS1	;ARE THERE ANY UNITS IN ASL?
	MOVEI	T1,[ASCIZ .
?No units in active swapping list.]
	PUSHJ	P,SVMOTS	;O/P MSG. & ADD CRLF & SET ERRHOM
	POPJ	P,		;CAN DO NO MORE
CHKAS1:	MOVE	T1,SWPUNI##	;FIRST UNIT IN ASL
	TLNN	T1,-1		;IS THERE ONE?
	HLRS	SWPUNI##	;NO, ALL SWAPPING IS FAST
	SETOM	P4		;SETUP FAKE PREVIOUS LOGICAL UNIT #
CHKAS2:	MOVE	P1,UNISUN##(U)	;GET LOG. UNIT # IN ASL OF THIS UNIT
	EXCH	P1,P4		;PUT THIS & PREVIOUS LOG. UNITS IN PROPER ACS
	CAME	P4,P1		;ARE LOG. UNIT #'S THE SAME
	JRST	CHKAS3		;NO - SEE IF ANY LOG. UNITS MISSING FROM ASL
	MOVEI	T1,[ASCIZ .
?Two logical unit .]
	PUSHJ	P,TYPMSN	;TYPE MSG. FOLLOWED BY A DECIMAL #
	MOVEI	T1,[ASCIZ .'s found in active swapping list.]
	PUSHJ	P,SVMOTS	;O/P MSG. & ADD CRLF & SET ERRHOM
	JRST	CHKAS4		;CHECK NEXT PAIR OF UNITS
CHKAS3:	SKIPN	ERROK
	CAIN	P4,1(P1)	;IS THIS UNIT 1 GREATER THAN PREVIOUS UNIT
	JRST	CHKAS4		;YES - CHECK NEXT PAIR OF UNITS
	ADDI	P1,1		;INCREMENT TO GET CORRECT MISSING LOG. UNIT #
	MOVEI	T1,[ASCIZ .
%Logical unit .]
	PUSHJ	P,TYPMSN	;TYPE MSG. FOLLOWED BY A DECIMAL #
	MOVEI	T1,[ASCIZ . missing from active swapping list.]
	PUSHJ	P,SVMOTE	;O/P MSG. & ADD CRLF & SET ERRHOM
	JRST	CHKAS3		;REPEAT UNTIL ALL MISSING ARE TYPED OUT
CHKAS4:	HLRZ	U,UNISWP##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN ASL
	JUMPN	U,CHKAS2	;REPEAT IF ANY LEFT
	POPJ	P,		;DONE
SUBTTL	SWAPPING UNIT ROUTINES -- DSKASL - BUILD ASL FROM THE DISK DATA BASE


DSKASL:	HLRZ	U,SYSUNI##	;GET ADDR OF FIRST UDB IN SYSTEM
DSKAS1:	PUSHJ	P,CRESST	;CREATE SWAPPING SATS
	PUSHJ	P,LNKSWP	;LINK SWAPPING UNIT INTO THE ASL
	HLRZ	U,UNISYS##(U)	;POINT TO NEXT UNIT
	JUMPN	U,DSKAS1	;LOOP IF MORE TO DO
	POPJ	P,		;DONE
	SUBTTL	SUBROUTINES

WRPUNM:	HRRZS	OFFLOK		;TYPE MESSAGE
	SKIPA	T4,[[ASCIZ . is write protected.]]
OFLUNM:	MOVEI	T4,[ASCIZ . is off-line.]
	MOVE	P1,UNINAM##(U)	;GET SIXBIT UNIT NAME
	MOVEI	T1,[ASCIZ .
%.]
	PUSHJ	P,OFFDWN	;FOR SPECIAL CASE SETTING OF DOFLOK
	PJRST	NASTYP		;TYPE MSGS. & GET USER'S RESPONSE


;SUBROUTINE TO PRINT "CONTROLLER" FOLLOWED BY A "NAME"
; FOLLOWED BY A MESSAGE ASKING WHAT STATE OF THE KONTROLLER IS DESIRED
; THEN IT WAITS FOR OPERATOR TO TYPE AN OCTAL NUMBER TERMINATED BY CRLF
;CALL	MOVE	P1,SIXBIT KONTROLLER NAME
;	MOVEI	T3,MSG. ADR.
;	PUSHJ	P,MCKKON
;	  ERROR RETURN	MSG. PRINTED BUT RESPONSE WASN'T AN OCTAL #
;	OK RETURN	 "      "    T2 CONTAINS OCTAL # TYPED

MCKKON:	MOVEI	T1,[ASCIZ .
%Controller .]
	PUSHJ	P,OFFDWN	;SET DOFLOK IF APPROPRIATE
NASTYP:	SKIPGE	DOFLOK
	SKIPL	OFFLOK		;DON'T TYPE IF OFF-LINE IS OK
	SKIPGE	DEBUGF##	;SEE IF DEBUGGING
	JRST	NASTY1		;YES--SKIP MESSAGE
	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	PUSH	P,T3		;SAVE 2ND. MSG ADR.
	PUSH	P,T4		;SAVE 1ST. MSG. ADR.
	PUSHJ	P,ICONM##	;PUT MSG IN BUFFER
	MOVE	T2,P1		;GET UNIT/KONTROLLER SIXBIT NAME
	PUSHJ	P,PRNAME##	;PUT IT IN BUFFER
	POP	P,T1		;RESTORE 1ST. MSG. ADR.
	PUSHJ	P,CONMES##	;PUT MSG. IN BUFFER
	PUSHJ	P,CRLFOP	;ADD CRLF & O/P MSG.
	POP	P,T1		;RESTORE 2ND. MSG ADR.
NASTY1:	HRLS	OFFLOK
	MOVEI	T2,2		;PRESET DEFAULT
	AOSG	DOFLOK		;SEE IF NEED DEFAULT
	JRST	CPOPJ1##	;YES--RETURN
	PUSHJ	P,CONOUT	;O/P MSG. & ADD CRLF
	PUSHJ	P,GETLIN##	;GET USER'S RESPONSE
	  POPJ	P,		;CR TYPED
	PUSHJ	P,ALTM		;ALTMODE TYPED? IF SO, NEVER RETURN.
	PUSHJ	P,OCTIN##	;READ IT AS AN OCTAL NO.
	  POPJ	P,		;NOTHING BUT A BREAK CH.
	  POPJ	P,		;ILLEGAL CH.
	JRST	CPOPJ1##	;OK RETURN WITH NO. IN T2
;*** DISPATCH TABLES FOR UNIT ON-LINE & WRITE PROTECT TESTING ***


ONCHWP:	XWD	ZERO5,DRMHWP
	XWD	ZERO5,FHDHWP
	XWD	ZERO5,DPCHWP
	XWD	ZERO5,MDFHWP
	XWD	ZERO5,FSDHWP
	XWD	ZERO5,RPXHWP
	XWD	ZERO5,RNXHWP
	XWD	ZERO5,RAXHWP

DRMHWP:	STOPCD	.,STOP,IDC,	;++IMPOSSIBLE DRUM CONDITION


DPCHWP:	PUSHJ	P,DPXSTS##	;GET STATUS FOR THIS UNIT IN T2
	TLNE	T2,2		;WRITE PROTECT ON?
	AOS	(P)		;YES -SKIP
	POPJ	P,		;RETURN


FHDHWP:
MDFHWP:
RNXHWP:
IFE FTCIDSK,<
RAXHWP:
>; END IFE FTCIDSK
FSDHWP:	POPJ	P,

RPXHWP:
IFN FTKL10,<
	PUSHJ	P,RPXSTW##	;MASSBUS ENABLE IF AN RH20
>
IFE FTKS10,<
	MOVSI	T2,10000	;READ STATUS REGISTER
	PUSHJ	P,DODTI4##
	TRNE	T2,4000
	AOS	(P)		;WRITE LOCKED
	POPJ	P,		;RETURN
>
IFN FTKS10,<
	MOVE	W,RHXBAS##(J)	;SET RH11 BASE ADDRESS
	LDB	T2,UNYPUN##	;GET UNIT NUMBER FROM UDB
	WRIO	T2,10(W)	;SELECT UNIT
	RDIO	T2,12(W)	;GET STATUS REGISTER
	TRNE	T2,4000		;WRITE PROTECTED?
	AOS	(P)		;YES-SKIP RETURN
	POPJ	P,		;RETURN
>
;SUBROUTINE TO GET CORE FOR A UNIT'S "HOME" BLOCK
; & THEN TRY TO READ BOTH BLOCKS SUCCESSFULLY
; ENTER WITH F = FILE DATA BLOCK ADR.  U = UNIT DATA BLOCK ADR.

GTHOM::	MOVSI	P2,(SIXBIT .HOM.)
	MOVE	P3,[EXP CODHOM##]	;CODE WORD FOR "HOME" BLOCKS
	MOVE	P4,UNIHOM##(U)	;GET "HOME" BLOCK NUMBERS - XWD 1ST. BLK,2ND. BLK
	PUSHJ	P,REDRUN
	  JRST	GTHOM1		;BOTH BAD
	MOVE	T1,HOMOKC##(P1)
	SKIPN	HOMVSY##(P1)
	MOVEM	T1,HOMK4C##(P1)
	JRST	CPOPJ1##
GTHOM1:	SETZM   UNILOG##(U)	;IN CASE SECOND TIME THROUGH
IFN FTDUAL,<
	SKIPE	T1,UNI2ND##(U)
	SETZM	UNILOG##(T1)
>
	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) P4 = FIRST FREE SYSTEM STR #
; 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.
	MOVEI	P4,.FSMIN	;CLEAR SYSTEM STR #
	MOVEI	P2,DIFSTR##	;GET (SYSSTR-STRSYS) AS 1ST. STR ADR.
FNSTR1:	MOVE	P3,P2		;SETUP P3 AS PREDECESSOR STR DATA BLOCK ADR.
	HLRZ	P2,STRSYS##(P2)	;GET NEXT STR DATA BLOCK ADR.
	JUMPE	P2,CPOPJ##	;NON SKIP RETURN IF NO STR FOUND
	CAMN	T1,STRNAM##(P2)	;A MATCH BETWEEN NAMES?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	AOJA	P4,FNSTR1	;INCREMENT SYSTEM STR # & REPEAT

;SUBROUTINE TO CREATE AN STR DATA BLOCK IN UPPER CORE & ZERO IT OUT
; ENTER WITH P3=ADR. OF LAST STR DATA BLOCK. P4=SYSTEM STR # FOR THIS STR
; P2 IS RETURNED WITH ADR. OF THIS STR DATA BLOCK

GETSTR:	CAILE	P4,.FSMAX	;SEE IF THE LIMIT OF STR'S CREATED HAS BEEN EXCEEDED
	POPJ	P,		;NON SKIP RETURN IF LIMIT EXCEEDED
	MOVEI	T2,STRLEN##	;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 ADR. OF PROTOTYPE STR DATA BLOCK IN RH
	BLT	T1,-1(T2)	;ZERO IT (T2 SET TO LAST LOC. +1 OF STR BY CORGRB)
	HRLM	P2,STRSYS##(P3)	;PUT ADR. OF NEW STR IN (OLD) LAST STR
	MOVEM	P2,TABSTR##(P4)	;STORE ADR. OF STR IN TABLE BY ITS LOG. #
	MOVEM	P4,STRSYS##(P2)	;PUT SYSTEM STR # & 0 LINK IN THIS STR
	JRST	CPOPJ1##	;SKIP RETURN IF STR CREATED OK
;SUBROUTINE TO GRAB CORE 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

IFE FTXMON,<CORGRS:>
CORGRB::MOVE	T1,HICORE##
	ADDB	T2,HICORE##
	SKIPE	.UONCE##	;SKIP IF EXEC MODE
	CAMG	T2,.JBREL##
	JRST	CORGB1		;GO CLEAR IT OUT
	CORE	T2,
	  JFCL
	MOVE	T2,HICORE##
CORGB1:	PUSH	P,T3		;SAVE T3
	SETZM	(T1)		;CLEAR FIRST WORD
	HRLZ	T3,T1		;GET START ADDR
	HRRI	T3,1(T1)	;MAKE A BLT POINTER
	BLT	T3,-1(T2)	;CLEAR CORE
	POP	P,T3		;RESTORE T3
	POPJ	P,		;AND RETURN
IFN FTXMON,<
;SUBROUTINE TO ALLOCATE NON-ZERO SECTION CORE
;CALL WITH:
;	T1 = STARTING VIRTUAL ADDRESS
;	T2 = HIGHEST VIRTUAL ADDRESS REQUIRED
;RETURNS WITH:
;	T1 = ADDRESS OF CORE ALLOCATED
;	T2 = HIGHEST ADDRESS ALLOCATED + 1
;CALL NZSCGT TO ALLOCATE DATA SPACE (WRITABLE), NZSCGC TO ALLOCATE
;CODE SPACE (WRITE LOCKED AND CACHED).

NZSCGC::SKIPA	T3,[<PM.DCD>B2+PM.WRT+PM.PUB+PM.KPM+PM.CSH] ;GET CODE MAP BITS
NZSCGT::MOVSI	T3,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.KPM+PM.SWB) ;GET DATA MAP BITS
	CONO	PI,PI.OFF	;GUARD AGAINST RACES (KLIPA)
	PUSH	P,T1
	MOVE	T1,T2
	TRZE	T1,PG.BDY##	;ROUND DOWN TO PAGE BOUNDARY
	ADDI	T1,PAGSIZ##	;HIGHEST ADDRESS ALLOCATED + 1
	PUSH	P,T1		;SAVE THAT
	SUBI	T1,1		;HIGHEST ALLOCATED ADDRESS
	XOR	T1,T2		;XOR SECTION NUMBERS TOGETHER
	TLNE	T1,-1		;DON'T KNOW HOW TO ALLOCATE ACROSS A SECTION BDY
	STOPCD	.,STOP,CSB,	;++CROSSES SECTION BOUNDARY
	SUB	T2,-1(P)	;NUMBER OF WORDS REQUIRED
	ADDI	T2,PG.BDY##	;ROUND UP
	LSH	T2,W2PLSH##	;NUMBER OF PAGES
	PUSH	P,T2		;SAVE NUMBER OF PAGES REQUIRED
	PUSH	P,P1		;IT IS A PRESERVED AC AFTER ALL
	HRRZ	P1,-3(P)	;ADDRESS WITHIN THE SECTION
	ADDI	P1,PG.BDY##	;ROUND UP
	LSH	P1,W2PLSH##	;PAGE NUMBER WITHIN THE SECTION
	LDB	T1,[POINT 5,-3(P),17] ;SECTION NUMBER TO ALLOCATE FROM
	MOVE	T2,.CPEPT##	;ADDRESS OF THIS CPU'S EXEC PROCESS TABLE
	ADD	T2,T1		;ADDRESS OF SECTION POINTER
	SKIPN	T2,SECTAB(T2)	;ENTRY FOR THIS SECTION'S MAP
	STOPCD	.,STOP,NSA,	;++NO SECTION ALLOCATED
	MOVE	T1,.CPMAP##	;ADDRESS OF THE MAP
	MOVEM	T2,.EUPMP/PAGSIZ##(T1) ;MAPS THE MAP (ONCMAP CLEARS AM)
	PUSH	P,MONVFF##	;NOT REALLY ALLOCATING SECTION ZERO ADDRESS SPACE
	ADD	P1,-2(P)	;GET FIRST PAGE FOLLOWING OUR RANGE
	SUBI	P1,1		;START AT LAST PAGE IN OUR RANGE SO PAGES ARE
				; PHYSICALLY CONTIGUOUS WITHIN OUR RANGE
	PUSH	P,T3		;SAVE PAGE MAP BITS REQUIRED
NZSCG1:	MOVEI	T1,.ECKSM	;PRETEND THAT WE ARE ALLOCATING THIS VIRTUAL ADDRESS
	MOVEM	T1,MONVFF##	;FOR ONCMAP
	MOVEI	T1,PAGSIZ##	;ONLY ALLOCATE 1 PAGE AT A TIME
	MOVE	T2,(P)		;GET PAGE MAP BITS REQUIRED
	PUSHJ	P,ONCMAP##	;GET A PAGE OF PHYSICAL MEMORY
	MOVE	T1,.CPMAP##	;ADDRESS OF MAP ONCMAP STORED IN
	MOVE	T1,.ECKSM/PAGSIZ##(T1) ;GET POINTER
	MOVEM	T1,.EUPMP(P1)	;STORE IT IN MAP FOR THIS SECTION
	SOSLE	-3(P)		;ALLOCATED ALL PAGES REQUESTED?
	SOJA	P1,NZSCG1	;NO, LOOP FOR MORE
	POP	P,(P)		;POP OFF JUNK
	POP	P,MONVFF##	;AND SECTION 0 ALLOCATION VARIABLE
	POP	P,P1		;RESTORE HONORABLE AC
	POP	P,(P)		;POP OFF JUNK
	POP	P,T2		;RESTORE ACS (CAN'T USE TTPOPJ
	POP	P,T1		; AS IT'S NOT MAPPED ALWAYS)
	CONO	PI,PI.ON	;NOW SAVE TO ALLOW INTERRUPTS (KLIPA)
	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

CORGRS::SKIPE	.UONCE##
	JRST	CORGRB		;NO SECTION 2 CORE IF IN USER MODE
	MOVE	T1,FFMD1##
	ADDB	T2,FFMD1##
	CAMGE	T2,RELMD1##
	JRST	CORGS1		;GO ZERO CORE
	PUSH	P,T2
	PUSHJ	P,NZSCGT
	MOVEM	T2,RELMD1##
	POP	P,T2		;RESTORE T2
CORGS1:	PUSHJ	P,SAVE3##	;SAVE XBLT ACS
	MOVE	P1,T2		;COMPUTE WORD
	SUB	P1,T1		; COUNT FOR BLT
	AOS	P3,T1		;SET UP
	SOS	P2,T1		; BLT ACS
	SETZM	(T1)		;ZERO FIRST WORD
	EXTEND	P1,[XBLT]	;ZERO CORE
	POPJ	P,		;RETURN

>
;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,HOMPT1##(P1)
	MOVEM	T1,STRPT1##(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	T1,HOMREF##(P1)
	HLLM	T1,STRREF##(P2)
	MOVE	T1,STRUN1##(P2)
	MOVE	T2,HOMUN1##(P1)
	DPB	T2,UN1PTR##
	MOVEM	T1,STRUN1##(P2)
IFN FTPSTR,<
	LDB	T1,HOYPVS##
	DPB	T1,STYPVS##
>
IFN FTSETS,<
	LDB	T1,HOYSET##	;GET SET NUMBER
	DPB	T1,STYSET##	;STORE IN SDB
>; END IFN FTSETS
	POPJ	P,
MSGLNG:	JSP	T2,REFSAV	;SAVE P4,T3,F,U & J AND INDICATE STR NEEDS REFRESHING
	PUSH	P,T1		;SAVE 2ND. MSG ADR. IN T1
	MOVE	T1,T3		;GET ADR OF 1ST. MSG
	PUSHJ	P,TYPDEC	;PUT MSG. & UNIT # IN BUFFER
	PUSHJ	P,OPOUT##	;O/P BUFFER
	POP	P,T1		;RESTORE 2ND. MSG ADR.
	CAIA

MSGSTR:	JSP	T2,REFSAV	;SAVE P4,T3,F,U & J AND INDICATE STR NEEDS REFRESHING
	PUSHJ	P,ICONM##	;PUT MSG. IN BUFFER
	SETOM	ERRHOM		;INDICATE ERROR IN "REDHOM"
	SETOM	SERIUS		;SERIOUS ERROR - CAN'T START SYSTEM
	MOVE	T2,STRNAM##(P2)	;GET SIXBIT STR NAME
	PJRST	NAMFLO		;PUT IT IN THE BUFFER FOLLOWED BY CRLF & START O/P


;SUBROUTINE TO ASK IF OPERATOR WANTS TO LIST # OF BAD REGIONS

TYPBAT:	SETOM	LSTBAT		;SET FLAG TO LIST # BAT REGIONS
	MOVEI	T1,[ASCIZ .
Type physical unit name to list number of bad regions
(<CR> if none, ALL if all).]
	PUSHJ	P,CONOUT	;ADD CRLF AND TYPE MSG.
	PUSHJ	P,GETUNI	;GET USER'S RESPONSE
	  POPJ	P,		;JUST TYPED CR - EXIT
	PJUMPE	U,REDBT1	;WAS "ALL" TYPED (YES-READ ALL UNITS)?
	PUSHJ	P,CHKBAT	;NO, JUST READ ONE UNIT
	  JFCL			;IGNORE ERROR RETURN
	JRST	TYPBAT		;ASK QUESTION AGAIN
;SUBROUTINE TO READ & VERIFY ALL "BAT" BLOCKS IN THE SYSTEM
;AND SET UP SWAPPING SAT TABLES.  LSTBAT IS FLAG TO LIST # BAD REGIONS OR NOT.

REDBAT:	SETZM	LSTBAT		;CLEAR FLAG SO DO NOT LIST # BAD REGIONS
REDBT1:	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN THE SYSTEM
	MOVSI	P4,UNPOFL##
CHKBT1:	TDNE	P4,UNIDES##(U)	;UNIT OFF-LINE?
	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, NO POIN SETTING UP SWAPPING SAT IF OPTIONAL
IFN FTXMON,<
	SE1JRS			;SWAPPING SATS ARE IN DATA SECTION 1
>
	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)	;YES, 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
	HRRZ	T1,UNIKON##(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,<
	JRST	@[0,,.+1]
>
	JUMPN	U,CHKBT1	;REPEAT IF THERE IS ONE
	POPJ	P,		;NONE LEFT - EXIT
CHKBAT:	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	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
	JSP	T2,SVOTAC	;SAVE P4,F,U, AND J
	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	P1,BAYNBR##	;GET # BAD REGIONS FOUND BY MAP PROGRAM.
	ADD	P1,BAFCNT##(T3)	;ADD IN # FOUND BY MONITOR
	ADDM	P1,BATANY	;ALSO FLAG THAT SOME UNIT HAS ERRORS
	SKIPN	LSTBAT		;LISTING # BAD REGIONS?
	JRST	CHKBT3		;NO, CHECK IF BAD (SO IF NEVER WRITTEN
				;CAN GET CHANCE TO WRITE)
	HRRM	P1,BATBAD	;STORE # BAD REGIONS ON UNIT FOR PRINTING
	SETZ	P4,		;FLAG UNIT ID WANTED IN TYPUN1
	MOVEI	P1,P4		;NULL MESSAGE
	PUSH	P,T3
	PUSHJ	P,OTSET##
	POP	P,T3
	PUSHJ	P,TYPUN1	;TYPE UNIT NAME AND UNIT ID
	PUSHJ	P,SOPOUT
	MOVEI	T1,[ASCIZ .
# Bad regions = .]
	HRRZ	P1,BATBAD	;NUMBER OF BAD REGIONS
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JUMPE	P1,CHKBT3	;PRINT NO BAD BLOCKS IF 0 BAD REGIONS
	HRRZ	T2,BAFFIR##(T3)	;GET START ADR. OF MONITOR BAD REGION PAIRS
	CAIL	T2,BLKCOD##	;MAKE SURE IT'S WITHIN THE BLOCK
	JRST	INTBAT		;ISN'T - ASK IF "BAT" BLOCKS TO BE INITILAIZED
	MOVN	T1,P1		;GET -VE # OF BAD REGIONS
	MOVEI	P1,0		;CLEAR AC FOR TOTAL # BAD BLOCKS
	HRL	T2,T1		;SETUP T2 FOR AOBJN
	ADD	T2,T3		;ADD IN MBF ADR.
	PUSH	P,T2		;SAVE AOBJN POINTER
BDBLUP:	LDB	T1,BAYNBB##	;GET # BAD BLOCKS IN THIS REGION
	ADDI	P1,1(T1)	;ADD TO TOTAL FOR THIS UNIT
	ADDI	T2,1		;EXTRA INCREMENT AS ENTRIES ARE 2 WORD PAIRS
	AOBJN	T2,BDBLUP	;REPEAT IF MORE REGIONS LEFT
	MOVEI	T1,[ASCIZ .# Bad blocks = .]
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JUMPN	P1,[POP	P,P1	;ALWAYS ASK QUESTION IF ANY BAD BLOCKS ON UNIT
		JRST	ASKBIN]
	POP	P,P1		;RESTORE AOBJN PTR TO BATBLK
CHKBT3:	SKIPN	BATBAD		;LIKEWISE IF ANY BAD REGIONS OR ERRORS DETECTED
	POPJ	P,		;EXIT
ASKBIN:	MOVEI	T1,[ASCIZ/
Do you want a list of bad regions?
/]
	PUSHJ	P,ASKQUE	;MAKE FRIENDLY OFFER
	  JRST	INTBAT		;NOPE
	MOVEI	T1,[ASCIZ/
First block      # Blocks
/]
	PUSH	P,T3
	PUSHJ	P,CONOUT	;TYPE HEADER
	MOVE	T3,P1		;SET UP AOBJN PTR
ASKBLP:	MOVE	T1,BAFELB##(T3)	;GET ADDRESS WORD
	TLZ	T1,BATMSK##	;MASK OUT ALL BUT ADDR
	MOVEI	T2,BAPNTP##	;IF OLD STYLE
	TDNN	T2,BAFAPN##(T3)
	HRRZS	T1		; ONLY 18 BITS COUNT
	PUSHJ	P,SVOSET	;SET UP
	PUSHJ	P,SRDX10	;PLACE IN BUFFER
	PUSHJ	P,SOPOUT	;TYPE MESSAGE
	MOVEI	T1,[ASCIZ/              /]	;SPACE OVER
	MOVEI	T2,(T3)		;SET UP INDEX AC
	LDB	P1,BAYNBB##	;GET COUNT OF BAD BLOCKS IN REGION
	AOJ	P1,		;INCREMENT
	PUSHJ	P,DECLOP	;TYPE SPACE, DECIMAL #, CRLF
	AOJ	T3,		;MUST INC T3 BY 2 FOR BAT PAIRS
	AOBJN	T3,ASKBLP	;LOOP
	POP	P,T3
INTBAT:	MOVEI	T1,[ASCIZ .
Do you want to initialize the BAT blocks on this unit?
.]
	SKIPE	BTHBAD		;BOTH BAD??
	MOVEI	T1,[ASCIZ /
Both BAT blocks are bad.
Do you want to initialize the BAT blocks on this unit?
/]
	MOVSI	T2,UNPHWP##
	TDNN	T2,UNIDES##(U)	;DON'T INIT IF UNIT HARDWARE WRITE-PROTECTED
	PUSHJ	P,ASKQUE	;TYPE QUESTION & GET USER'S RESPONSE
	  POPJ	P,		;HE DOESN'T WANT TO
	MOVEI	T1,[ASCIZ .
Not normally done, are you sure?
.]
	PUSHJ	P,ASKQUE	;ASK AGAIN
	  POPJ	P,		;HE SAVED HIMSELF SOME BOTHER
	PUSHJ	P,SETBAT	;SETUP "BAT" BLOCK PARAMETERS
	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
	MOVSI	T1,MBRMAX##	;SETUP AOBJN PTR. TO BE STORED IN BLOCK
	HRRI	T1,BAFREG##
	MOVEM	T1,BAFFIR##(T3)	;SAVE IT IN THE BLOCK
	HRRZ	J,UNIKON##(U)	;GET UNIT'S KONTROLLER DATA BLOCK ADR.
	LDB	T1,[POINT 7,KONINT##(J),9]	;GET DEVICE CODE FOR THE KONTROLLER
	DPB	T1,BAYKDC##	;SAVE IT IN THE BLOCK
	MOVEM	P3,BLKCOD##(T3)	;SAVE THE CODE FOR "BAT" BLOCKS IN THE BLOCK
	MOVE	P1,T3		;GET ADR. OF "BAT" BLOCK IN CORE INTO P1 FOR WRTRUN
	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 SWAPPPING 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 READ SPECIAL BLOCKS ON THE DISK ["HOME","BAT" & "RIB"]
; ENTER WITH U = UNIT U BLOCK ADR. F = FILE DATA BLOCK ADR.
; OTHER ARGS. SETUP BY 'GTHOM' , 'GTBAT' & 'GTSRB'
; RETURN WITH T2 & S AS 'REDCHK' SETS THEM
; NON SKIP RETURN IF ERRORS ON BOTH BLOCKS

REDRUN::MOVE	F,DATADR	;SETUP FILE DATA BLOCK ADR.
	HRRZ	P1,@ONCMBF	;GET ADR. OF MONITOR BUFFER FOR DISK BLOCK
	ADDI	P1,1
	SETZM	REDERR		;CLEAR ERROR FLAG
FIROK:	SETOM	WHICH		;INDICATE READING 1ST. BLOCK
	HLRZ	T2,P4		;GET ITS BLOCK #
	PUSHJ	P,REDCHK	;READ BLOCK & CHECK FOR ERRORS
	  JRST	REDSEC		;ERROR(S) DETECTED - GO TRY 2ND. BLOCK
	JUMPG	T2,CPOPJ1##	;IF 2ND. BLOCK BAD BUT 1ST. OK - SKIP RETURN

REDSEC:	SETZM	WHICH		;INDICATE READING 2ND. BLOCK
	HRRZ	T2,P4		;GET ITS BLOCK #
	PUSHJ	P,REDCHK	;READ BLOCK & CHECK FOR ERRORS
	  JUMPL	T2,CPOPJ##	;ERROR(S) DETECTED
				; ERROR(S) ON 1ST. BLOCK AS WELL GIVES ERROR RETURN
	JUMPG	T2,FIROK	;IF 2ND. BLOCK 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	T3,UNINAM##(U)	;ERROR - GET SIXBIT UNIT 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:	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	T3,UNINAM##(U)	;NO CHECK - GET SIXBIT UNIT 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 MSG. FOR REDCHK
; ENTER WITH T1 = MSG. ADR. T3 = SIXBIT UNIT NAME
; RETURN LH. OR RH. OF REDERR = -1
; DEPENDING ON WHETHER IST. OR 2ND BLOCK HAD ERROR

RDNMSG:	JSP	T2,SVOTAC	;SAVE T3,F,U & J
	PUSH	P,T1		;SAVE ADDR OF MESSAGE
	PUSHJ	P,SVOSET
	MOVE	T2,T3		;SIXBIT UNIT NAME
	PUSHJ	P,SPRNAM	;PUT NAME IN BUFFER
	MOVEI	T1,[ASCIZ . first .]	;PRESUME ERROR ON 1ST. BLOCK
	SKIPE	WHICH		;2ND. BLOCK WAS READ?
	JRST	FSTERR		;NO - 1ST. BLOCK
	HLLOS	REDERR		;INDICATE ERROR ON 2ND. BLOCK
	SKIPA	T1,[[ASCIZ . second .]]
FSTERR:	HRROS	REDERR		;INDICATE ERROR ON 1ST. BLOCK
	PUSHJ	P,SCONMS	;PUT MSG. IN BUFFER
	MOVE	T2,P2		;GET SIXBIT BLOCK TYPE("HOME" OR "BAT")
	CAMN	P2,[SIXBIT .SAT.]	;IF THIS WAS A "RIB" BLOCK
	MOVSI	T2,(SIXBIT .RIB.)	; TYPE "RIB" INSTEAD OF "SAT"
	PUSHJ	P,SPRNAM	;PUT IT IN BUFFER
	POP	P,T1		;ADDR OF MESSAGE
	PUSHJ	P,SCONMS	;PUT MSG. IN BUFFER
	PJRST	SCRLFO		;CRLF AND TYPE MESSAGE

REDERR:	0			;ERROR WORD FOR REDRUN
				; RH=-1 IF ERROR ON 2ND. BLOCK
				; LH "  "    "   "  1ST.   "
WHICH:	0			;FLAG TO INDICATE WHETHER 2ND. OR 1ST. BLK BEING READ
;SUBROUTINE TO TYPE ALL STR'S & THEIR UNITS IN THE SYSTEM
; RETURN WITH P1,P4,F,U & J DESTROYED

TYPSYS:	PUSHJ	P,OTSET##
	SETZM	P4		;INDICATE UNIT ID TO BE PRINTED IN TYPUNI
	HLRZ	P2,SYSSTR##	;ADR. OF 1ST. STR DATA BLOCK IN SYSTEM
TYPSY1:	JUMPE	P2,SOPOUT	;NONE LEFT - EXIT
	PUSHJ	P,TYPSTR	;TYPE STR NAME & ALL ITS UNITS
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK
	JRST	TYPSY1		; & REPEAT

TYPSTR:
IFN FTPSTR,<
	LDB	T1,STYPVS##
	JUMPE	T1,TYPST0	;JUMP IF PUBLIC
	MOVEI	T1,[ASCIZ .Private: .]
	PUSHJ	P,SCONMS	;TELL HIM ITS PRIVATE
TYPST0:>
	HLLZ	T2,STRREF##(P2)
	JUMPE	T2,NOREF	;DOES STR NEED REFRESHING?
	MOVEI	T1,[ASCIZ .Need refreshing: .]	;YES
	PUSHJ	P,SCONMS	;PUT MSG IN BUFFER
NOREF:	PUSHJ	P,SPSNAM	;PUT SIXBIT STR NAME IN BUFFER
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT IN STR
	JUMPE	U,SCRLFO	;IF NO UNITS IN STR - O/P BUFFER WITH CRLF & EXIT
	MOVEI	P1,[ASCIZ .:.]
	PUSHJ	P,TYPUN1	;TYPE ":" UNIT NAME & (ID) [IST. TIME THRU]
TYPST1:	HLRZ	U,UNISTR##(U)	;GET NEXT UNIT DATA BLOCK IN STR
	JUMPE	U,CRLF##	;IF NO MORE UNITS - ADD CRLF & EXIT
	PUSHJ	P,TYPUNI	;TYPE "," UNIT NAME & (ID)
	JRST	TYPST1		;REPEAT UNTIL NO MORE UNITS IN STR
;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,SOPOUT	;IF FOUND NO UNITS TO TYPE
	JRST	TYPSR1		;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

IFN FTSETS,<
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,SOPOUT	;IF FOUND NO UNITS TO TYPE
	JRST	TYPSR1		;IF FOUND AT LEAST ONE
>; END IFN FTSETS
;SUBROUTINE TO TYPE ALL UNITS IN THE ACTIVE SWAPPING LIST
; RETURN WITH P1,P3,P4,F,U & J DESTROYED

TYPASL:	PUSHJ	P,OTSET##
	MOVSI	P3,MSWPMX##	;-VE LENGTH OF ASL
	HRRZ	U,SWPTAB##(P3)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN ASL
	SETOM	P4		;INDICATE CLASS FOR SWAPPING TO BE TYPED IN TYPUNI
	MOVEI	P1,[ASCIZ .
Units in active swapping list:
.]
	PUSHJ	P,TYPUN1	;TYPE MSG., UNIT NAME & (CLASS FOR SWAPPING)
	JRST	TYPAS2

TYPAS1:	HRRZ	U,SWPTAB##(P3)	;GET ADR. OF NEXT UNIT DATA BLOCK IN ASL
	SKIPE	U		;END OF LIST WHEN ZERO ENTRY FOUND
	PUSHJ	P,TYPUNI	;TYPE "," UNIT NAME & (CLASS FOR SWAPPING)
TYPAS2:	AOBJN	P3,TYPAS1	;REPEAT IF LIST NOT COMPLETELY SCANNED
	PJRST	TYPSR1		;ADD CRLF & EXIT

;SUBROUTINE TO PRINT "UNIT" (NAME)
;ENTER U=UDB
UNITIS::MOVEI	T1,[ASCIZ .
%Unit .]
	PUSHJ	P,ICONM##
	MOVE	T2,UNINAM##(U)
	PJRST	PRNAME##

;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,SCONMS	;PUT "," OR MSG. IN BUFFER
	JUMPE	U,CPOPJ##	;JUST O/P MSG. IF NO UNITS IN ASL
	PUSHJ	P,SPUNAM	;PUT SIXBIT UNIT NAME IN BUFFER
	MOVEI	T1,[ASCIZ .(.]
	PUSHJ	P,SCONMS	;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,SPRNAM	;PUT IT IN THE BUFFER
	JRST	TYPUN3

TYPUN2:	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	PUSHJ	P,SRDX10	;PUT DECIMALLY IN THE BUFFER
TYPUN3:	MOVEI	T1,[ASCIZ .).]
	PJRST	SCONMS
;SUBROUTINE TO TYPE ALL STR NAMES IN "SYS" SEARCH LIST

TYPSRC:	MOVEI	T1,[ASCIZ .
Structures in system search list:.]
	PUSHJ	P,CONOUT
	PUSHJ	P,OTSET##
	MOVE	P4,[PUSHJ P,TYPSTS]	;SETUP INSTR. FOR XCT IN FNDSRC
	PUSHJ	P,FNDSRC	;TYPE ALL STR NAMES IN "SYS" SEARCH LIST
TYPSR1:	PJRST	CRLFOP		;O/P CRLF


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

;SUBROUTINE TO TYPE ALL STR NAMES IN THE SYSTEM DUMP LIST

TYPSDL:	MOVEI	T1,[ASCIZ .
Structures in system dump list:.]
	PUSHJ	P,CONOUT
	PUSHJ	P,OTSET##
	MOVE	P4,[PUSHJ P,TYPSTS] ;SETUP INSTR FOR FNDSDL TO XCT
	PUSHJ	P,FNDSDL	;TYPE STR NAMES
	PJRST	CRLFOP		;END WITH CRLF AND RETURN


;SUBROUTINE TO FIND ALL STRS IN THE SYSTEM DUMP LIST AND EXECUTE
;A CALLER SUPPILED INSTRUCTION FOR EACH.  CALL WITH INSTRUCTION TO
;EXECUTE IN P4

FNDSDL:	MOVSI	P3,-.SDMAX	;AOBJN POINTER FOR MAX STRS IN SDL
FNDSD1:	HLRZ	P2,SYSSTR##	;GET ADDR OF 1ST STR IN SYSTEM
	JUMPE	P2,CPOPJ##	;QUIT IF NO STRS
FNDSD2:	MOVE	T1,STRSDL##(P2)	;GET POSITION OF THIS STR IN SDL
	CAIE	T1,(P3)		;THIS THE ONE WE'RE LOOKING FOR?
	JRST	FNDSD3		;NO, CONTINUE
	XCT 	P4		;EXECUTE CALLER SUPPLIED INSTRUCTION
	JRST	FNDSD4		;ELSE LOOP FOR NEXT
FNDSD3:	HLRZ	P2,STRSYS##(P2)	;STEP TO NEXT STR DATA BLOCK
	JUMPN	P2,FNDSD2	;AND FIND MATCH IF NOT AT END
FNDSD4:	AOBJN	P3,FNDSD1	;LOOK FOR NEXT STR IN SDL
	POPJ	P,		;RETURN


TYPSTS:	JSP	T2,SVOTAC
	MOVEI	T1,[ASCIZ .,.]
	TRNE	P3,-1		;1ST STR?
	PUSHJ	P,SCONMS	;YES - NO COMMA
	PUSHJ	P,SPSNAM	;PUT SIXBIT STR NAME IN BUFFER
	POPJ	P,0
CHGUNA:	MOVEI	T1,[ASCIZ .
Type physical unit name to change its parameters (<CR> if none, ALL if all).]
	PUSHJ	P,CONOUT	;ADD CRLF & O/P MSG.
	PUSHJ	P,GETUNI	;GET USER'S RESPONSE
	  POPJ	P,		;JUST CR TYPED - EXIT
	PUSHJ	P,TYNMSG	;TYPE INSTRUCTIONS & CLEAR THE TYPE ONLY FLAG
	PUSHJ	P,SYSPLP	;TYPE & CHANGE PARAMETERS FOR ONE OR ALL UNITS
	  JRST	CHGUNA		;"ALL" WASN'T TYPED - ASK FOR NEXT UNIT NAME
	POPJ	P,		;EXIT


TYPUNA:	MOVEI	T1,[ASCIZ .
Type physical unit name to list its parameters (<CR> if none, ALL if all).]
	PUSHJ	P,CONOUT	;ADD CRLF & TYPE MSG.
	PUSHJ	P,GETUNI	;GET USER'S RESPONSE
	  POPJ	P,		;JUST CR TYPED - EXIT
	SETOM	TYPONL		;SET TYPE ONLY FLAG
	PUSHJ	P,SYSPLP	;TYPE PARAMETERS FOR ONE OR ALL UNITS IN SYSTEM
	  JRST	TYPUNA		;"ALL" WASN'T TYPED - ASK FOR NEXT UNIT NAME
	POPJ	P,		;EXIT


SYSPLP:	JUMPN	U,TYPUNP	;WAS "ALL" TYPED?
	HLRZ	U,SYSUNI##	;YES - GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
SYSPL1:	PUSHJ	P,SVOSET	;INITIALIZE CTY BUFFER
	PUSHJ	P,SCRLFO	;O/P A CRLF
	PUSHJ	P,SVOSET	;INITIALIZE CTY BUFFER
	PUSHJ	P,SPUNAM	;PUT SIXBIT UNIT NAME IN BUFFER
	PUSHJ	P,SOPOUT	; & O/P IT
	MOVSI	T1,UNPOFL##	;GET THE OFF-LINE BIT
	TDNN	T1,UNIDES##(U)	;IS UNIT OFF-LINE OR DOWN?
	JRST	SYSPL2		;NO
	MOVEI	T1,[ASCIZ | is off-line|]
	PUSHJ	P,SVMOUT	;OUTPUT CHATTER
	JRST	SYSPL3		;AND ON TO THE NEXT UNIT
SYSPL2:	PUSHJ	P,TYPUNP	;TYPE (& CHANGE) PARAMETERS FOR THIS UNIT
SYSPL3:	HLRZ	U,UNISYS##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,SYSPL1	;REPEAT IF ANY LEFT
	JRST	CPOPJ1##	;SKIP RETURN


TYPUNP:	HRRZ	P2,UNISTR##(U)	;GET ADR. OF STR DATA BLOCK UNIT BELONGS TO(IF ANY)
	MOVEI	T1,[ASCIZ .
Parameters that require refreshing:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	MOVE	T1,UNIHOM##(U)	;GET POSITION OF HOM BLOCKS
	CAME	T1,[XWD LBNHOM##,LB2HOM##] ;EITHER ORDER IS FINE
	CAMN	T1,[XWD LB2HOM##,LBNHOM##]
	JRST	ASKSPU		;EVERYTHING IS FINE
	MOVE	T1,[XWD LBNHOM##,LB2HOM##]	;GET CORRECT POSITION OF
					;HOM BLOCKS
	MOVEM	T1,UNIHOM##(U)	;PUT IN UNIT DATA BLOCK
	PUSHJ	P,REFCHU	;MAKE SURE HOM BLOCKS ARE
					;WRITTEN ON THIS UNIT
ASKSPU:	PUSHJ	P,COMLC1	;COMPUTE MIN. # SATS ON UNIT
	MOVE	T1,T2
	IDIVI	T2,MXSADA*^D36
	AOS	P4,T2
	MOVEM	P4,MIN
	IDIVI	T1,^D36		;COMPUTE GREATEST # SATS POSSIBLE ON THIS UNIT
	ADDI	T1,1		;MAX # OF SATS BASED ON USING ONE WORD PER SAT
	HRRZ	T2,STRUNM##(P2)	;ONE UNIT CHANGE POINTER REQUIRED PER UNIT
	SUBI	T2,RIBLEN##-3	;SUBTRACT THESE PLUS (2 RIBS + EOF)
	MOVNS	T2		;MAX # OF SATS WHICH CAN FIT IN ONE RIB
	CAILE	T1,(T2)		;LESS THAN THIS?
	MOVE	T1,T2		;NO--PUT IN AS NEW MAX
	MOVEM	T1,MAX
ASKSP1:	SKIPN	SHUTUP		;SKIP IF SHORT DIALOG
	JRST	.+4		;ELSE CONTINUE WITH NORMAL CODE
	LDB	T3,UNYKTP##	;GET KONTROLLER TYPE
	MOVE	P1,MIN		;NO. OF SAT BLOCKS DESIRED ON THIS UNIT
	JRST	SPUOK		;MAKE IT HAPPEN
	LDB	P1,UNYSPU##	;GET SAT BLOCKS ON UNIT.
	MOVEI	T1,[ASCIZ .Number of SAT blocks on unit = .]
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,TYPCPS	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	CAML	P1,P4		;IS NEW VALUE > THAN MIN. # POSSIBLE?
	JRST	ASKSP2		;YES - SEE IF LT. OR EQ. TO MAX. # SATS ON UNIT
	MOVEI	T1,[ASCIZ /?Too small - Min. # = /]
	MOVE	P1,P4		;GET MIN. # INTO KOSHER AC
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKSP1		;ASK QUESTION AGAIN

ASKSP2:	CAMG	P1,MAX		;LESS THAN MAX. # ON UNIT?
	JRST	SPUOK		;YES - GO STORE VALUE & COMPUTE # CLUSTERS PER SAT
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKSP1		;ASK QUESTION AGAIN
SPUOK:	DPB	P1,UNYSPU##	;STORE NEW VALUE
	PUSHJ	P,REFCHU	;UNIT NEEDS "HOME" BLOCKS REWRITING, STR REFRESHING

TYPCPS:	MOVE	T1,UNIDES##(U)
	TLZ	T1,UNPMSB##	;ASSUME ONLY 1 SAT BLOCK ON UNIT
	CAIE	P1,1		;MORE THAN 1?
	TLO	T1,UNPMSB##	;YES - FLAG THE FACT
	MOVEM	T1,UNIDES##(U)	;SAVE STATE IN UNIT DATA BLOCK
	PUSHJ	P,CMCWPS	;COMPUTE # CLUSTERS & SATS ON UNIT
	SKIPN	SHUTUP
	JRST	.+4
	LDB	T1,UNYSPU##
	DPB	T1,UNYSIC##
	PJRST	REFCHU
	HRRZ	P1,UNICPS##(U)	;GET # CLUSTERS PER SAT
	MOVEI	T1,[ASCIZ .Therefore clusters per SAT = .]
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	LDB	P1,UNYWPS##	;GET # WORDS PER SAT
	MOVEI	T1,[ASCIZ .Therefore words per SAT = .]
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
ASKK4S:	SETZM	MIN		;0 IS ACCEPTABLE
	SKIPE	UNILOG##(U)	;SKIP IF NOT IN A FILE STRUCTURE
	JRST	CK4S1		;YES, FIGURE OUT SPACE AVAILABLE FOR SWAPPING
	MOVEI	T3,LB2HOM##+4	;FIRST BLOCK AVAILABLE FOR SWAPPING
	JRST	CK4SO		;COMPUTE MAX K FOR SWAPPING
CK4S1:	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,CK4S2	;JUMP IF NOT 1ST UNIT IN STR
	ADDI	T3,RB1UN##	;+CLUSTERS FOR RIBS ON 1ST UNIT REFRESHER MAKES
	LDB	T1,UNYBPC##	;BLOCKS PER CLUSTER
	CAIG	T1,2
	MOVEI	T1,3
	LDB	T2,UNYBPC##	;BLOCKS PER CLUSTER
	ADDI	T1,-1(T2)
	IDIV	T1,T2		;CLUSTERS FOR MFD
	IMULI	T1,3		;COUNT SAME FOR SYS AND PRT UFD'S
	ADD	T3,T1		;COUNT CLUSTERS NECESSARY FOR REFRESHER
CK4S2:	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	CK4S3		;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
CK4S3:	LDB	T2,UNYBPC##	;BLOCKS PER CLUSTER
	IMUL	T3,T2		;T3=1ST BLOCK AVAILABLE FOR SWAPPING
CK4SO:	MOVEM	T3,TMPMIN	;SAVE FIRST BLOCK TO SWAP
	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,CK4S6	;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
CK4S6:	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
	MOVEM	T1,MAX		;IS MAX K FOR SWAPPING
	SKIPN	SHUTUP
	JRST	CK4S4
	LDB	T4,UNYKTP##	;KONTROLLER TYPE
	MOVE	P1,K4SDEF(T4)	;GET K4 SWAPPING ON UNIT
	JUMPE	P1,K4SOK	;ZERO SPEC IS ALWAYS GOOD
	CAMLE	P1,MAX		;GREATER THAN MAX ALLOWED?
	MOVE	P1,MAX		;YES--USE MAX
	JRST	K4SOK		;NO-GO ALLOCATE WHAT HE ASKED FOR
CK4S4:	MOVEI	T1,[ASCIZ .Number of K for swapping on unit = .]
	LDB	P1,UNYK4S##
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET RESPONSE IF TYPONL=0)
	  JUMPL	T1,ASKSLB	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	CAMG	P1,MAX		;SWAPPING  MORE BLOCKS THAN ON UNIT?
	JRST	K4SOK		;NO - GO STORE NEW VALUE IN STR DATA BLOCK
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKK4S		;ASK QUESTION AGAIN
K4SOK:	LSH	P1,BLKSPK##	;COMPUTE (# BLOCKS NEEDED FOR SWAPPING)
	MOVE	T3,UNIBPU##(U)	;PUT # BLOCKS ON UNIT INTO T2. RESPECTED BY REFCHG
	SUB	T3,P1		;COMPUTE 1ST. LOG. BLOCK FOR SWAPPING
	LSH	T3,-1		;DIVIDE BY 2 SO SWAP AREA CENTERED ON DISK
	TRZ	T3,3
	CAMGE	T3,TMPMIN	;ABOVE MINIMUM BLOCK FOR SWAPPING?
	MOVE	T3,TMPMIN	;NO, USE MINIMUM BLOCK INSTEAD
	LSH	P1,MBKSPK##	;CONVERT BLOCKS FOR SWAPPING BACK INTO J
	DPB	P1,UNYK4S##	;STORE NEW VALUE
	PUSHJ	P,REFCHU	;UNIT NEEDS "HOME" BLOCKS REWRITING, STR REFRESHING
	JUMPE	P1,TYPUNN	;IF NO SWAPPING SPACE ALLOCATED SKIP QUESTIONS
	MOVE	P1,T3		;SAVE COMPUTED FIRST LBN FOR LATER TYPE OUT
	MOVE	T1,TMPMIN	;GET MIN BLOCK TO SWAP TO
	MOVEM	T1,MIN		;MIN BLOCK FOR SWAPPING SPACE
	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
	MOVEM	T2,MAX		;MAX=HIGHEST LEGAL BLOCK
	MOVE	T1,UNISLB##(U)	;GET 1ST. LOG. BLOCK FOR SWAPPING
	CAILE	T1,LB2HOM##+1	;IS IT BETWEEN 0 & 2ND. BAT BLOCK?
	JRST	K4SOK1		;NO
	PUSHJ	P,TRFCHU	;UNIT NEEDS "HOME" BLOCKS REWRITING, STR REFRESHING
	MOVEM	P1,UNISLB##(U)	;SUBSTITUTE COMPUTED VALUE OF 1ST. LOG. BLOCK
K4SOK1:	SKIPE	SHUTUP		;SKIP IF NOT SHORT DIALOG
	JRST	SLBOK		;JUST USE COMPUTED BLOCK NO.
	MOVEI	T1,[ASCIZ /Computed first logical block for swapping = /]
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKSL1
ASKSLB:	JUMPE	P1,TYPUNN	;DON'T ASK OR TYPE SWAPPING STUFF IF NO SWAPPING SPACE
ASKSL1:	MOVEI	T1,[ASCIZ /The first logical block for swapping = /]
	MOVE	P1,UNISLB##(U)
	SKIPGE	TYPONL		;IF JUST LISTING VALUES,
	MOVEM	P1,MAX		;U MAX ISN'T SET UP
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,TYPUNN	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	PUSHJ	P,CANTB0	;TYPE 'CANNOT BE 0' IF P1 = 0
	  JRST	ASKSL1		;P1 = 0 - ASK QUESTION AGAIN
	CAML	P1,MIN		;IS NEW VALUE IN FORBIDDEN AREA?
	JRST	HGHSLB		;NO
	MOVEI	T1,[ASCIZ .?Must exceed .]
	MOVE	P1,MIN
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKSL1		;ASK QUESTION AGAIN
HGHSLB:	CAMG	P1,MAX		;IS SPECIFIED VALUE GREATER THAN THIS?
	JRST	SLBOK		;NO - GO STORE NEW VALUE
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKSL1		;ASK QUESTION AGAIN

SLBOK:	TRZ	P1,3
	MOVEM	P1,UNISLB##(U)	;STORE NEW VALUE
	PUSHJ	P,REFCHU	;UNIT NEEDS "HOME" BLOCKS REWRITING, STR REFRESHING
;HERE TO CHANGE AND/OR TYPE PARAMETRS THAT DON'T REQUIRE REFRESHING

TYPUNN:	SKIPN	SHUTUP		;SKIP IF SHORT DIALOG
	JRST	TYPUN0		;JUMP IF NOT
	LDB	P1,UNYSPU##	;GET NUMBER OF SATS ON UNIT
	JRST	SICOK		;MAKE INTO #SATS IN CORE
TYPUN0:	MOVEI	T1,[ASCIZ .
Parameters that do not require refreshing:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	MOVEI	P2,0		;PRETEND UNIT HAS NO STR SO CALLS TO REFCHU
				; WILL NOT SET STR NEEDS REFRESHING FLAG(STRREF)
	MOVE	P1,UNIHID##(U)	;GET THE UNIT ID
ASKUID:	MOVEI	T1,[ASCIZ .Zero unit ID - New ID needed.] ;ASSUME NO UNIT ID
	TLNN	P1,777777	;AVOID 0,,JUNK
	TDZA	P1,P1		;CLEAR OUT JUNK
	MOVEI	T1,[ASCIZ .Unit ID is .]
	PUSHJ	P,ASKSIX	;TYPE MSG. & TEXT(GET RESPONSE IF TYPONL=0)
	  JUMPL	T1,ASKNSC	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	JUMPE	P1,ASKUID	;NO - USER MUST SPECIFY NEW ID
	MOVEM	P1,UNIHID##(U)	;STORE NEW VALUE
	PUSHJ	P,REFCHU	;UNIT NEEDS HOME BLOCKS REWRITTEN
ASKNSC:	LDB	T1,UNYSPU##	;GET NUMBER OF SAT BLOCK ON UNIT
	MOVEM	T1,MAX		;CAN'T HAVE MORE THAN THAT IN CORE
	MOVEI	T1,1		;MUST HAVE AT LEAST 1 SAT BLOCK
	MOVEM	T1,MIN		;IN CORE
	MOVEI	T1,[ASCIZ .Number of SAT blocks in core = .]
	LDB	P1,UNYSIC##
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,CPOPJ##		;TYPONL=-1, CR OR NO CHANGE IN VALUE
	LDB	T2,UNYSPU##	;GET # SATS ON UNIT
	CAMG	P1,T2		;# SATS IN CORE SHOULDN'T EXCEED # SATS ON UNIT
	JRST	ZERSIC		;THEY DON'T
	MOVEI	T1,[ASCIZ .?Cannot exceed # SAT blocks on unit = .]
	MOVE	P1,T2		;GET # SATS ON UNIT INTO KOSHER AC
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKNSC		;ASK QUESTION AGAIN

ZERSIC:				;NO SATS IN CORE ISN'T ALLOWED EITHER
	PUSHJ	P,CANTB0	;TYPE 'CANNOT BE 0' IF P1 = 0
	  JRST	ASKNSC		;P1 = 0 - ASK QUESTION AGAIN
SICOK:	DPB	P1,UNYSIC##	;STORE NEW VALUE
	PJRST	REFCHU		;UNIT NEEDS "HOME" BLOCKS REWRITING
DMKUNI:	HLRZ	U,SYSUNI##	;GET 1ST UNIT DATA BLOCK
DMKUN1:	MOVSI	T1,UNPWPO##	;OFF LINE AND WRITE PROTECT BITS
	TDNE	T1,UNIDES##(U)	;SKIP IF ON LINE
	JRST	DMKUN3		;GET NEXT UNIT AND PROCEED
	LDB	J,UNYKTP##	;GET KONTROLLER TYPE IN J
	MOVE	T1,TIME##	;SET UP RANDOM TEMPORARY UNIT ID
	ADD	T1,U		;ADD IN THE UNIT DATA BLOCK ADRESS
	XOR	T1,THSDAT##	;OR THE DATE IN-THIS CREATES UNIQUE NUMBER.
	MOVE	T2,[XWD -1,505050]
	ANDCAM	T2,T1		;GET RID OF ALL BUT 3 NUMBERS
	MOVE	T2,[XWD 'ONC',202020]	;MAKE SURE ALL IS SIXBIT
	IORM	T2,T1		;PUT IT IN
	MOVEM	T1,UNIHID##(U)	;USE IT AS A UNIQUE ID
	MOVE	T1,[XWD LBNHOM##,LB2HOM##]	;STANDARD HOM BLOCKS AT 1 AND 10
	PUSHJ	P,ASKSPU	;GET UP SATS PER UNIT
	PUSHJ	P,ASKK4S	;GO TO THIS SUBROUTINE FOR REST OF STUFF.
DMKUN2:	HLRZ	U,UNISYS##(U)	;GET NEXT UNIT
	JUMPN	U,DMKUN1	;IF IT EXISTS, CONTINUE
	POPJ	P,		;OR ELSE, WERE DONE.
DMKUN3:	SETZ	T1,
	DPB	T1,UNYSIC##	;NO SATS IN CORE FOR DONW UNITS
	JRST	DMKUN2		;GET NEXT UNIT
CHGSTA:	MOVEI	T1,[ASCIZ .
Type structure name to change its parameters (<CR> if none, ALL if all).]
	PUSHJ	P,ASKSTR	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR WAS TYPED - EXIT
	PUSHJ	P,TYNMSG	;TYPE INSTRUCTIONS & CLEAR THE TYPE ONLY FLAG
	PUSHJ	P,DSKPLP	;TYPE & CHANGE PARAMETRS
	  JRST	CHGSTA		;ASK QUESTION AGAIN IF "ALL" WAS NOT TYPED
	POPJ	P,		;"ALL" WAS TYPED - EXIT

TYPSTA:	MOVEI	T1,[ASCIZ .
Type structure name for a list of its parameters (<CR> if none, ALL if all).]
	PUSHJ	P,ASKSTR	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR WAS TYPED - EXIT
	SETOM	TYPONL		;SET TYPE ONLY FLAG
	PUSHJ	P,DSKPLP	;TYPE PARAMETRS
	  JRST	TYPSTA		;ASK QUESTION AGAIN IF "ALL" WAS NOT TYPED
	POPJ	P,		;"ALL" WAS TYPED - EXIT

DSKPLP:	JUMPN	P2,TYPSTP	;WAS "ALL" TYPED?(P2 RETURNED 0 FROM ASKSTR)
	HLRZ	P2,SYSSTR##	;YES - GET ADR. OF 1ST. STR DATA BLOCK IN SYSTEM
	JUMPE	P2,CPOPJ1##	;SKIP RETURN IF THERE ISN'T ONE
DSKPL1:	PUSHJ	P,SVOSET	;INITIALIZE CTY BUFFER
	PUSHJ	P,SCRLFO	;O/P A CRLF
	PUSHJ	P,SVOSET	;INITIALIZE CTY BUFFER
	PUSHJ	P,SPSNAM	;PUT STR NAME IN BUFFER
	PUSHJ	P,SOPOUT	; & O/P IT
	PUSHJ	P,TYPSTP	;TYPE PARAMETERS FOR THIS STR
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	JUMPN	P2,DSKPL1	;REPEAT IF NOT LAST ONE
	JRST	CPOPJ1##	;SKIP RETURN

TYNMSG:	MOVEI	T1,[ASCIZ .
After each printing of current value, type new value or <CR>.]
	SETZM	TYPONL		;CLEAR TYPE ONLY FLAG
	PJRST	SVMOUT		;ADD CRLF & O/P MSG.

TYPONL:	0
TYPSTP:	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	JUMPE	U,CPOPJ##	;IF NO UNITS IN THIS STR - EXIT
	MOVEI	T1,[ASCIZ .
Parameters that do not require refreshing:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	MOVEI	T1,1
	MOVEM	T1,MIN		;MUST HAVE 1 BLOCK TRIED FOR ON OUTPUT
	MOVE	T1,STRSIZ##(P2)
	TLNE	T1,-1
	MOVEI	T1,-1
	MOVEM	T1,MAX		;MAY HAVE WHOLE LEFT HALF
TYPPR1:	MOVEI	T1,[ASCIZ .Number of consecutive blocks tried for on output = .]
	HLRZ	P1,UNIGRP##(U)
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,ASKBGA	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	PUSHJ	P,CANTB0	;TYPE 'CANNOT BE 0' IF P1 = 0
	  JRST	TYPPR1		;P1 = 0 - ASK QUESTION AGAIN
;HERE TO STORE NEW VALUE OF UNIGRP IN ALL UNIT DATA BLOCKS IN THIS STR

TYPPR2:	HRLM	P1,UNIGRP##(U)	;STORE NEW VALUE IN THIS UNIT DATA BLOCK
	HLRZ	U,UNISTR##(U)	;GET NEXT UNIT DATA BLOCK ADR. IN THIS STR
	JUMPN	U,TYPPR2	;STORE VALUE IN IT
	PUSHJ	P,CHGSTR	;SET 'UNPCHG' BIT FOR ALL UNITS IN STR

ASKBGA:	MOVEI	P1,0
REPEAT 0,<
	SETZM	MIN		;MAY HAVE 0 RESERVED
	MOVE	T1,STRSIZ##(P2)	;MAX IS SIZE OF STR
	MOVEM	T1,MAX
	MOVEI	T1,[ASCIZ .Sum of blocks guaranteed to users = .]
	MOVE	P1,STRGAR##(P2)
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,ASKBOU	;TYPONL=-1, CR OR NO CHANGE IN VALUE

	CAMG	P1,STRSIZ##(P2)	;MORE BLOCKS THAN IN STR?
	JRST	ASKBG2		;NO
	MOVEI	T1,[ASCIZ .?Cannot exceed the number of blocks in file structure = .]
	MOVE	P1,STRSIZ##(P2)
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKBGA		;ASK QUESTION AGAIN
>

ASKBG2:	MOVEM	P1,STRGAR##(P2)	;STORE NEW VALUE
	PUSHJ	P,CHGSTR	;SET 'UNPCHG' BIT FOR ALL UNITS IN STR

ASKBOU:	MOVEI	T1,[ASCIZ .Number of blocks allowed for overdraw per user = .]
	MOVM	P1,STROVR##(P2)
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,TYPSTN	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	CAMG	P1,STRSIZ##(P2)	;MORE BLOCKS THAN IN STR?
	JRST	ASKBO1		;NO - GO STORE NEW VALUE
	MOVEI	T1,[ASCIZ .?Cannot exceed # blocks in file structure = .]
	MOVE	P1,STRSIZ##(P2)
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	JRST	ASKBOU		;ASK QUESTION AGAIN
ASKBO1:	MOVNM	P1,STROVR##(P2)	;STORE NEW VALUE
	PUSHJ	P,CHGSTR	;SET 'UNPCHG' BIT FOR ALL UNITS IN STR

TYPSTN:
IFN FTPSTR,<
	SKIPL	TYPONL		;ASKING
	JRST	ASKPRV		;YES, GO ASK
	MOVEI	T1,[ASCIZ .Not private.]
	LDB	T2,STYPVS##
	SKIPE	T2		;PRIVATE
	MOVEI	T1,[ASCIZ .Private structure.]
	PUSHJ	P,SVMOUT	;TELL WHICH
	JRST	TYPPPN

ASKPRV:	MOVEI	T1,[ASCIZ .
Is this a private structure? (Type Y if private, N if no access restrictions)
.]
	PUSHJ	P,ASKQUE	;ASK HIM
	  TDZA	T1,T1		;HE SAID NO
	MOVEI	T1,1		;HE SAID YES
	LDB	T2,STYPVS##	;GET CURRENT SETTING
	DPB	T1,STYPVS##	;STORE NEW SETTING
	CAME	T1,T2		;DID IT CHANGE?
	PUSHJ	P,CHGALL	;YES, NOTE THAT
>
; OWNER PPN
;
TYPPPN:	MOVEI	T1,[ASCIZ |Owner PPN is |]
	SKIPN	STRPPN##(P2)	;IS THERE A PPN
	MOVEI	T1,[ASCIZ |Owner PPN is not set|]
	PUSHJ	P,ICONM##	;TYPE TEXT
	SKIPE	T2,STRPPN##(P2)	;GET PPN
	PUSHJ	P,PPNTYO	;TYPE IT
	PUSHJ	P,CRLFOP	;ADD CRLF
	SKIPGE	TYPONL		;ASKING?
	JRST	TYPSET		;NO
	JRST	ASKPPN		;YES

PPNTYO:	MOVEI	T3,"["		;GET A BRACKET
	PUSHJ	P,COMTYO##	;TYPE IT
	HLRZ	T1,STRPPN(P2)	;GET PROJECT NUMBER
	CAIN	T1,777777	;WILD?
	JRST	[MOVEI	T3,"*"	;GET WILDCARD CHARACTER
		 PUSHJ	P,COMTYO## ;TYPE IT
		 JRST	PPNTY1]	;ONWARD
	PUSHJ	P,PRTDI8##	;TYPE PROJECT NUMBER
PPNTY1:	MOVEI	T3,","		;GET COMMA
	PUSHJ	P,COMTYO##	;TYPE IT
	HRRZ	T1,STRPPN(P2)	;GET PROGRAMMER NUMBER
	CAIN	T1,777777	;WILD?
	JRST	[MOVEI	T3,"*"	;GET WILDCARD CHARACTER
		 PUSHJ	P,COMTYO## ;TYPE IT
		 JRST	PPNTY2]	;ONWARD
	PUSHJ	P,PRTDI8##	;TYPE PROGRAMMER NUMBER
PPNTY2:	MOVEI	T3,"]"		;GET CLOSING BRACKET
	PJRST	COMTYO##	;TYPE IT AND RETURN


ASKPPN:	MOVEI	T1,[ASCIZ |
Do you want to change the owner PPN? (<CR> if no)
|]
	JSP	T2,SVOTAC	;SAVE SOME ACS
	PUSHJ	P,YESNO##	;GET ANSWER
	  JRST	TYPSET		;OPR SAID NO
	MOVEI	T1,[ASCIZ |
Enter PPN as [proj#,prog#] or <CR> to clear it
|]
	PUSHJ	P,GTPPN##	;GET THE PPN
	  SETZ	T1,		;OPR TYPED <CR>
	MOVE	T2,STRPPN##(P2)	;GET ORIGINAL VALUE
	MOVEM	T1,STRPPN##(P2)	;STORE OWNER'S PPN
	CAME	T1,T2		;PPN CHANGE?
	PUSHJ	P,CHGALL	;YES - REMEMBER IT
;	JRST	TYPSET
; SET NUMBER
;
TYPSET:
IFN FTSETS,<
	LDB	P1,STYSET##	;GET SET NUMBER
	CAIL	P1,^D1		;"NONE"
	CAILE	P1,^D36		; OR "ALL"?
	SKIPA			;YES
	JRST	TYPSE1		;NO
	MOVEI	T1,[ASCIZ |Structure belongs to NO set|]
	SKIPN	P1		;TRUE?
	MOVEI	T1,[ASCIZ |Structure belongs to the ALL set|]
	PUSHJ	P,ICONM##	;START MESSAGE
	JRST	TYPSE2		;FINISH IT

TYPSE1:	MOVEI	T1,[ASCIZ |Structure belongs to set number |]
	PUSHJ	P,ICONM##	;START MESSAGE
	MOVE	T1,P1		;GET SET NUMBER
	PUSHJ	P,RADX10##	;PRINT IT
TYPSE2:	PUSHJ	P,CRLFOP	;ADD CRLF AND FORCE OUTPUT
	SKIPGE	TYPONL		;ASKING?
	JRST	TYPNRF		;NO

ASKSET:	MOVEI	T1,[ASCIZ |
Do you want to change the set to which the structure belongs? (<CR> if no)
|]
	JSP	T2,SVOTAC	;SAVE AC'S
	PUSHJ	P,YESNO##	;DO THEY WANT TO CHANGE?
	  JRST	TYPNRF		;NO
	MOVEI	T1,[ASCIZ |
Enter set number, or "ALL", or <CR> for NO set
|]
	PUSHJ	P,GETSET##	;DO IT IN ONCE
	  MOVEI	T1,^D36+1	;JUST <CR>, THAT'S THE "NO" SET
	LDB	T2,STYSET##	;GET OLD SET
	DPB	T1,STYSET##	;SAVE NEW
	CAME	T1,T2		;DID IT CHANGE?
	PUSHJ	P,CHGALL	;YES, FLAG REWRITE HOME BLOCKS
;	JRST	TYPNRF		;FALL INTO TYPNRF
>; END IFN FTSETS
TYPNRF:	MOVEI	T1,[ASCIZ .
Parameters that require refreshing:.]
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	SETZM	MIN		;MINIMUM IS 0 K FOR CRASH.EXE
	MOVEI	T1,^D4096	;MAX K FOR CRASH.SAV IS 4096K IF MORE THAN 256K
				; IS SUPPORTED
IFN FTCIDSK,<
	HLRZ	U,STRUNI##(P2)	;GET ADDRESS OF FIRST UDB IN STRUCTURE
	LDB	T2,UNYKTP##	;GET KONTROLLER TYPE
	CAIN	T2,TYPRA##	;CI DISK?
	SETZ	T1,		;YES, NO CRASH ALLOWED
>; END IFN FTCIDSK
	MOVEM	T1,MAX		;MAX K FOR CRASH.SAV IS 256
ASKK4C:
	MOVEI	T1,[ASCIZ  /Number of K for CRASH.EXE = /]

	HRRZ	P1,STRK4C##(P2)
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET RESPONSE IF TYPONL=0)
	  JUMPL	T1,ASKBP2	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	CAMG	P1,MAX		;SEE IF VALUE EXCEEDS MAX. AMOUNT OF CORE POSSIBLE
	JRST	K4COK		;IT DOESN'T - GO STORE NEW VALUE
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKK4C		;ASK QUESTION AGAIN

K4COK:	HRRZ	T1,STRK4C##(P2)	;GET CURRENT VALUE
	HRRM	P1,STRK4C##(P2)	;STORE NEW VALUE
	PUSHJ	P,TRFCHS	;STR NEEDS REFRESHING, UNIT'S "HOME" BLOCKS REWRITING
ASKBP2:	AOS	T1,MIN		;MUST HAVE 1 BLOCK PER CLUSTER
	LSH	T1,LIMBPC##	;COMPUTE MAX. # OF BLOCKS PER CLUSTER+1
	SUBI	T1,1		;MAXIMUM BLOCKS PER CLUSTER
	MOVEM	T1,MAX
ASKBPC:	HLRZ	U,STRUNI##(P2)	;GET 1ST. UNIT DATA BLOCK ADR. IN THIS STR
	MOVEI	T1,[ASCIZ .Blocks per cluster = .]
	LDB	P1,UNYBPC##
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET RESPONSE IF TYPONL=0)
	  JUMPL	T1,TYPCLT	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	PUSHJ	P,CANTB0	;TYPE 'CANNOT BE 0' IF P1 = 0
	  JRST	ASKBPC		;P1 = 0 - ASK QUESTION AGAIN

	CAMG	P1,MAX		;IS NEW VALUE < LIMIT
	JRST	BPCOK		;YES - GO STORE NEW VALUE IN ALL UNIT DATA BLOCKS
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKBPC		;ASK QUESTION AGAIN

BPCOK:	PUSHJ	P,BPCSTO	;STORE BPC AND SET UP STYCLP
TYPCLT:	MOVEI	T1,[ASCIZ /Therefore bits per cluster adr. = /]
	LDB	P1,[POINT 6,STYCLP##(P2),11]
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	MOVEI	T1,[ASCIZ .Therefore blocks per super-cluster = .]
	HLRZ	P1,STRBSC##(P2)
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	MOVEI	T1,[ASCIZ .Therefore super-clusters per unit = .]
	HRRZ	P1,STRSCU##(P2)
	PUSHJ	P,DECLOP	;TYPE MSG. & VALUE
	PUSHJ	P,SVOSET
	SKIPL	TYPONL		;SKIP IF ONLY TYPING PARAMS
	PUSHJ	P,SCRLFO	;EXTRA CRLF BEFORE NEXT QUESTION

	LDB	T3,[POINT 6,STYCLP##(P2),11]
	MOVN	T2,T3
	ADDI	T2,^D36
	CAILE	T2,LIMCNP##	;MAKE SURE DOESNT EXCEED LIMCMP
	MOVEI	T2,LIMCNP##
	MOVEM	T2,MAX		;THAT MIN IS MAX
ASKBCC:	MOVEI	T1,[ASCIZ .Bits per cluster count = .]
	LDB	P1,[POINT 6,STYCNP##(P2),11]
	PUSHJ	P,ASKDMM	;TYPE MSG. & VALUE(GET NEW VALUE IF TYPONL=0)
	  JUMPL	T1,TYPBCK	;TYPONL=-1, CR OR NO CHANGE IN VALUE
	PUSHJ	P,CANTB0	;TYPE 'CANNOT BE 0' IF P1 = 0
	  JRST	ASKBCC		;P1 = 0 - REPEAT QUESTION

	CAMG	P1,MAX
	JRST	CNPOK
	PUSHJ	P,CANTEX	;TYPE 'CANNOT EXCEED' & VALUE
	JRST	ASKBCC

CNPOK:	PUSHJ	P,CNPSTO
TYPBCK:	MOVEI	T1,[ASCIZ .Therefore bits per checksum = .]
	LDB	P1,[POINT 6,STYCKP##(P2),11]
	PJRST	DECLOP		;TYPE MSG. & VALUE
KILSTR:	HLRZ	U,SYSUNI##
KLSTR2:	SETZM	UNISTR##(U)
	SETZM	UNILOG##(U)
	HRRZS	UNIGRP##(U)
	SETZ	T1,
	DPB	T1,UNYBPC##
	PUSHJ	P,SETCHG
	HLRZ	U,UNISYS##(U)
	JUMPN	U,KLSTR2
	MOVE	T1,STRAOB##	;CLEAR TABSTR
	SETZM	TABSTR##(T1)
	AOBJN	T1,.-1
	POPJ	P,


ASKDIS:	MOVEI	T1,[ASCIZ .Type structure name to be dissolved (<CR> if none, ALL if all).]
	SKIPE	SYSSTR##	;DON'T TYPE MSG. IF NO STR'S
	PUSHJ	P,ASKSTR	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR WAS TYPED - EXIT
	JUMPN	P2,ASKDS2	;WAS "ALL" TYPED?(P2 RETURNED 0 FROM ASKSTR)
	HLRZ	P2,SYSSTR##	;YES - GET 1ST. STR DATA BLOCK ADR. IN SYSTEM
	MOVEI	P3,DIFSTR##	;SETUP P3 AS PREDECESSOR STR DATA BLOCK
ASKDS1:	PUSHJ	P,DISSTR	;DISSOLVE STR
	HLRZ	P2,STRSYS##(P2)	;GET NEXT STR DATA BLOCK ADR. IN SYSTEM
	JUMPN	P2,ASKDS1	;REPEAT IF NOT LAST ONE
	POPJ	P,		;EXIT

ASKDS2:	PUSHJ	P,DISSTR	;DISSOLVE STR
	JRST	ASKDIS		;ASK QUESTION AGAIN

DISSTR:	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	JUMPE	U,DISST2	;JUST UNLINK STR IF IT HAS NO UNITS
	PUSHJ	P,DISST1	;GO TAKE CARE OF ALL UNITS IN STR
DISST2:	HLL	T3,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	HLLM	T3,STRSYS##(P3)	; & LINK IT TO PREDECESSOR DATA BLOCK(OR SYSSTR)
	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
	HRRZ	T1,STRFSN##(P2)	;GET THIS STR'S LOG. #
	SETZM	TABSTR##(T1)	;INDICATE STR NO LONGER EXISTS
	POPJ	P,		;RETURN - DON'T WORRY ABOUT RETURNING CORE
				; AS REDHOM MUST BE CALLED AGAIN
DISST1:	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
	HRRZS	UNIGRP##(U)	;CLEAR # CLUSTERS TRIED FOR ON O/P
	MOVEI	T1,0
	DPB	T1,UNYBPC##	;CLEAR # BLOCKS PER CLUSTER
	PUSHJ	P,SETCHG	;FLAG THAT THIS UNIT'S "HOME" BLOCK MUST BE REWRITTEN
	HLRZ	U,T3		;GET NEXT UNIT DATA BLOCK ADR.
	JUMPN	U,DISST1	;REPEAT IF THERE IS ONE
	POPJ	P,
ASKDEF:	PUSHJ	P,ALLINS	;SKIP IF ANY UNITS NOT IN FILE STRUCTURES
	  POPJ	P,
	MOVEI	T1,[ASCIZ .Type structure name to be defined (<CR> if none).]
	PUSHJ	P,CONOUT	;O/P MSG. & ADD CRLF
	PUSHJ	P,GETLIN##	;GET USER'S RESPONSE
	  JRST	DEMSTR		;JUST CR TYPED - EXIT ONLY IF AT LEAST ONE STR EXISTS
	PUSHJ	P,ALTM		;IN CASE OF $ COP OUT
	PUSHJ	P,CTEXT##	;GET SIXBIT STR NAME
	MOVE	T1,T2		;GET SIXBIT NAME INTO KOSHER AC FOR FNSTR
	PUSHJ	P,FNSTR		;SEE IF STR ALREADY EXISTS
	  JRST	DEFNEW		;IT DOESN'T
	MOVEI	T1,[ASCIZ .?Structure already exists.]
	PUSHJ	P,CONOUT	;ADD CRLF & O/P MSG.
	JRST	ASKDEF		;ASK QUESTION AGAIN

DEMSTR:	SKIPN	SYSSTR##	;DO ANY STR'S EXIST?
	JRST	ASKDEF		;NO - AT LEAST ONE STR MUST BE DEFINED
	POPJ	P,		;EXIT

DEFNEW:	PUSH	P,T1		;SAVE STR NAME
	PUSHJ	P,GETSTR	;CREATE STR DATA BLOCK IN UPPER CORE & ZERO IT OUT
	  SKIPA	T1,[[ASCIZ .
?Too many file structures
.]]
	JRST	DEFNE1
	POP	P,T2		;POP OFF STR NAME
	PJRST	CONOUT		;TYPE MSG.

DEFNE1:	POP	P,STRNAM##(P2)	;RESTORE SIXBIT STR NAME IN STR DATA BLOCK
	HLLOS	STRUNI##(P2)	;INDICATE STR MUST BE REFRESHED
	SETOM	STRSRC##(P2)	;NOT IN SYS SEARCH LIST
	SETOM	STRSDL##(P2)	;NOT IN SYSTEM DUMP LIST

DEFNE2:	MOVEI	T1,[ASCIZ .Type names of physical units in structure
(ALL if all, extra <CR> when done).]
	PUSHJ	P,CONOUT	;O/P MSG. & ADD CRLF
	MOVEI	P3,STRUNI##(P2)	;MAKE ADR. OF LINK TO 1ST. UNIT DATA BLOCK IN STR
				; LOOK LIKE A PREDECESSOR UNIT DATA BLOCK
	SETZ	P1,
GETNXT:	PUSHJ	P,GETUNI	;GET USER'S RESPONSE
	  JRST	NXTPST		;JUST CR TYPED - ASK FOR NEXT STR NAME
	JUMPE	U,ALLUNI	;WAS "ALL" TYPED?
	PUSHJ	P,INSUNI	;NO - JUST PUT THIS UNIT INTO THE STR
	  JRST	DEFNE2		;UNIT ALREADY IN AN STR
	PUSHJ	P,HGHSIZ	;COMPUTE STRHGH & STRSIZ FOR THIS STR
	JRST	GETNXT		;GET THE NEXT UNIT

NXTPST:	PUSHJ	P,PARSET	;SET UP DEFAULTS
	JRST	ASKDEF
ALLUNI:	HLRZ	U,SYSUNI##	;NO - USE ALL UNITS IN THE SYSTEM
ALLUN1:	MOVSI	T1,UNPWPO##	;WRITE PROTECT AND OFFLINE BITS
	TDNN	T1,UNIDES##(U)	;SKIP IF LOCKED OR OFFLINE
	SKIPE	UNISTR##(U)	;SKIP IF ALREADY IN AN STR
	JRST	ALLUN2		;SKIP THIS UNIT
	PUSHJ	P,INSUNI	;PUT THIS UNIT INTO STR
	  JRST	DEFNE2		;UNIT ALREADY IN AN STR
ALLUN2:	HLRZ	U,UNISYS##(U)	;GET NEXT UNIT IN THE SYSTEM
	JUMPN	U,ALLUN1	;REPEAT IF THERE IS ONE
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	PUSHJ	P,HGHSIZ	;COMPUTE STRHGH & STRSIZ FOR THIS STR
	PJRST	PARSET		;SET DEFAULTS AND 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	CHGALL		;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