Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93d-bb - 7,6/ap017/oncmod.x17
There is 1 other file named oncmod.x17 in the archive. Click here to see a list.
TITLE	ONCMOD LEVEL D OPTIONAL & MANDATORY ONCE ONLY CODE V1130
SUBTTL	C. WHITE/DJB/RCC/EVS/WRS/GMU/DPM	  17 JUN 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,1130
;SPECIAL SHORT DIALOG OPTIONS BY ERNIE SOCCI

ENTRY ONCMOD

ONCMOD::
ND	UNTPLN,^D5		;UNITS/LINE TYPED BY TYPUNS/TYPNMU
MXSADA==^D118
	SUBTTL	MULTI-PROCESSING MACRO DEFINITIONS


;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
		   <IFIW SUB>+<FLAGS>]
> ;;END IFN FTMP
> ;;END DEFINE XCTCPU

	XC.ASY==1B1		;ASYNCH REQUEST FLAG
	XC.SHT==1B2		;SHORT TIMEOUT FLAG
	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
	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
	MOVEI	T2,CPUMSK##	;MASK FOR ALL CPU BITS
	TDNE	T2,UNICAM##(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,UNICAM##(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,SAVE1##	;SAVE P1
	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,XC.SHT) ;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
	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 CI20 AND NIA20
;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
				;INITIALIZE WILL FINISH.
> ;END FTMP
	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##
;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##
IFE FTAUTC,<
	SETZM	SYSGEN##	;START UNIGEN'S AFRESH
>; END IFE FTAUTC
	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
	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:
IFE FTAUTC,<
	AOS	T1,SYSGEN##	;GET A UNIQUE UNIT GENERATION NUMBER
	HRRM	T1,UNIGEN##(U)
>; END IFE FTAUTC
	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,<
	PUSHJ	P,MATUN##	;ANY OTHER DRIVE WITH SAME SERIAL NUMBER?
	  JRST	KONTO3		;NO
	HLRZ	T1,UNISYS##(U)	;GET LINK TO NEXT UNIT BEFORE CALLING LN2ND
	PUSH	P,T1		;(CAN'T TRUST UNISYS AFTER UNIT UNLINKED)
	PUSHJ	P,LN2ND##	;SETUP UNI2ND LINKS FOR THIS DRIVE
				;  AND UNLINK SECOND PORT FROM UNISYS CHAIN
	POP	P,U		;NEW UNIT TO RESUME WITH
	JRST	NXTUNU		;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
NXTUNU:	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,HOMBSC##(P1)
	HRLM	T1,STRBSC##(P2)
	MOVE	T1,HOMSCU##(P1)
	HRRM	T1,STRSCU##(P2)
	MOVE	T1,HOMSRC##(P1)
	MOVEM	T1,STRSRC##(P2)
	SKIPL	T1,HOMSDL##(P1)
	SUBI	T1,1
	MOVEM	T1,STRSDL##(P2)
	MOVE	T1,HOMCRS##(P1)
	MOVEM	T1,STRCRS##(P2)
	HLLZ	T1,HOMCNP##(P1)
	TLZ	T1,77
	HLLM	T1,STYCNP##(P2)
	HLLZ	T1,HOMCKP##(P1)
	TLZ	T1,77
	HLLM	T1,STYCKP##(P2)
	HLLZ	T1,HOMCLP##(P1)
	TLZ	T1,770077
	HLLM	T1,STYCLP##(P2)
	MOVE	T2,HOMPT1##(P1)	;GET FIRST RETRIEVAL POINTER TO MFD
	SETZ	T1,		;GET A ZERO
	DPB	T1,STYCNP##(P2)	;ZERO THE COUNT FIELD IN FIRST POINTER
	MOVEM	T2,STRPT1##(P2)	; SO UFDNXT WILL GET FIRST POINTER FROM MFD RIB
	MOVE	T1,HOMREF##(P1)
	HLLM	T1,STRREF##(P2)
	MOVE	T1,STRUN1##(P2)
	MOVE	T2,HOMUN1##(P1)
	DPB	T2,UN1PTR##
	MOVEM	T1,STRUN1##(P2)
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 STR AFTER THE ONE WHICH WAS JUST DISSOLVED?
	JRST	FIXSS1		;NO
	XCT	P4		;YES, MOVE IT DOWN ONE PLACE
	PUSHJ	P,CHGALL	;FLAG UNITS AS NEEDING THEIR HOME BLOCKS REWRITTEN
	JRST	FIXSS1		;LOOP FOR MORE
;ROUTINE TO SETUP THE DEFAULT STRUCTURE DATA BASE FOR THE DESTROY
;OPTION.  USES THE FOLLOWING TABLES IN COMMOD TO DRIVE THE ALGORITHM:
;	ONC'XX'S - LIST OF STRUCTURE NAMES FOR KONTROLLER TYPE XX.
;	ONC'XX'Z - NUMBER OF UNITS TO PUT INTO SPECIFIED STRUCTURE.
;CALL:
;	JSP	T2,SVOTAC	;SAVE AC'S
;	PUSHJ	P,DMKSTR
;	RETURN HERE ALWAYS

DMKSTR:	PUSHJ	P,KILSTR	;CLEAR OUT ALL STRS BEFORE YOU BEGIN
	MOVEI	J,0		;INIT INDEX INTO CONTROLLER TABLES
DSTR1:	SKIPN	KONTBL(J)	;END OF TABLE?
	POPJ	P,		;YES--RETURN
	MOVEI	T4,0		;INITIALIZE ONC'XX'S OFFSET
	MOVEI	U,DIFUSY##	;START AT THE FIRST UDB IN SYSTEM
DSTR2:	PUSHJ	P,FNDUTP	;FIND NEXT UDB OF THIS TYPE
	  AOJA	J,DSTR1		;NONE FOUND, TRY NEXT TYPE
DSTR3:	SKIPE	MUSDEF(J)	;ADD THIS UNIT TYPE TO A STR?
	SKIPN	T1,SSNDEF(J)	;YES--GET 1ST STR NAME ADDRESS (IF ANY)
	AOJA	J,DSTR1		;NO TABLE, OR ZERO ENTRY IN TABLE
	MOVE	T2,T4		;GET INCREMENT
	PUSHJ	P,GENSTR	;GENERATE A STRUCTURE NAME
	  AOJA	J,DSTR1		;ATTEMPT TO GENERATE AN ILLEGAL STR NAME
	PUSH	P,T1		;SAVE STR NAME
	PUSHJ	P,FNSTR		;SET UP PREDECESSOR AND OTHER THINGS
	  CAIA			;ALWAYS SKIP
	STOPCD	.,STOP,AHS,	;++ALREADY HAVE STRUCTURE
	PUSHJ	P,GETSTR	;CREATE SDB AND ZERO IT OUT
	  STOPCD .,STOP,CGS,	;++CAN'T GET STR DATA BLOCK
	POP	P,STRNAM##(P2)	;PUT IN NAME
	HLLOS	STRUNI##(P2)	;SET NEEDS REFRESHING
	MOVEI	P3,STRUNI##(P2)	;MAKE 1ST UNIT PREDECESSOR
	MOVEI	P1,0		;INITIALIZE CALL TO INSUNI
	SETZM	UNITS		;CLEAR UNITS COUNT.
DSTR4:	PUSH	P,T4		;SAVE TABLE OFFSET
	PUSHJ	P,INSUNI	;ADD UNIT TO STR
	  STOPCD .,STOP,UIF,	;++UNIT ALREADY IN FILE STR
	POP	P,T4		;RESTORE TABLE OFFSET
	AOS	T1,UNITS	;BUMP UNITS IN CURRENT STR COUNT
	CAML	T1,MUSDEF(J)	;PUT ENOUGH INTO THIS STRUCTURE?
	JRST	[PUSHJ	P,COMPDF ;YES, CLOSE IT OFF
		 AOJA	T4,DSTR2] ; AND DO NEXT STRUCTURE
	PUSHJ	P,FNDUTP	;FIND NEXT UNIT OF THIS TYPE
	  CAIA			;NONE LEFT
	JRST	DSTR4		;FOUND ONE, PROCESS IT
	PUSHJ	P,COMPDF	;CLOSE OFF THE STRUCTURE
	AOJA	J,DSTR1		;TRY NEXT TYPE
;ROUTINE TO FIND THE NEXT UNIT OF A SPECIFIED CONTROLLER TYPE.
;CALL:	RH(J)=DESIRED TYPE
;	U=UDB AT WHICH TO START SEARCH
;	PUSHJ	P,FNDUTP
;	RETURN HERE IF NO MORE OF SPECIFIED TYPE
;	RETURN HERE WITH U=UDB ADDRESS OF NEXT

FNDUTP:	MOVSI	T2,UNPWPO##	;OFF-LINE AND WRITE PROTECT BITS
FNDUT1:	HLRZ	U,UNISYS##(U)	;STEP TO NEXT UDB
	JUMPE	U,CPOPJ##	;NON-SKIP IF NO MORE
	LDB	T1,UNYKTP##	;GET KONTROLLER TYPE
	TDNN	T2,UNIDES##(U)	;UNIT IN REASONABLE SHAPE?
	CAIE	T1,(J)		;YES, MATCH THE DESIRED TYPE?
	JRST	FNDUT1		;NO, LOOP
	JRST	CPOPJ1##	;GIVE SKIP RETURN WITH U=UDB


;ROUTINE TO CLOSE OFF A STRUCTURE WHEN THE LAST UNIT HAS BEEN
;INSERTED BY DMKSTR.
;CALL:	P1=UDB ADDRESS OF SMALLEST UNIT IN STR (SETUP BY INSUNI)
;	P2=STRUCTURE DATA BLOCK ADDDRESS
;	PUSHJ	P,COMPDF
;	RETURN HERE ALWAYS

COMPDF:	PUSH	P,U		;SAVE U
	HLRZ	U,STRUNI##(P2)	;SETUP FIRST UDB IN STR
	PUSHJ	P,HGHSIZ	;COMPUTE STRHGH AND STRSIZ
	PUSH	P,T4		;SAVE TABLE OFFSET
	PUSHJ	P,PARSET	;SET UP DEFAULTS
	POP	P,T4
	JRST	UPOPJ##		;RESTORE U AND RETURN.
; ROUTINE TO GENERATE A STRUCTURE NAME FOR THE DESTROY OPTION
; CALL:	MOVE	T1, BASE STR NAME
;	MOVE	T2, INCREMENT
;	PUSHJ	P,GENSTR
;	  <ERROR>		;ILLEGAL STR NAME (SUPPLIED OR GENERATED)
;	<NORMAL>		;T1:= UPDATE STR NAME
;
GENSTR:	PUSHJ	P,SAVE4##	;SAVE SOME ACS
	TRZE	T1,7777		;NO JUNK
	POPJ	P,		;CAN'T HAVE THAT
	MOVE	P1,[POINT 6,T1]	;BYTE POINTER TO STR NAME
	MOVEI	P2,0		;INIT COUNTER
GENST1:	ILDB	P3,P1		;GET A CHARACTER
	JUMPE	P3,GENST2	;END OF STR NAME?
	PUSHJ	P,GENSTX	;CHECK CHARACTER
	  POPJ	P,		;NO GOOD
	MOVE	P4,P1		;SAVE BYTE POINTER
	AOJA	P2,GENST1	;LOOP
GENST2:	LDB	P3,P4		;GET LAST GOOD CHARACTER
	ADDI	P3,(T2)		;INCREMENT
	PUSHJ	P,GENSTX	;CHECK THE NEW CHARACTER
	  POPJ	P,		;NO GOOD
	DPB	P3,P4		;AND SAVE IT AWAY
	MOVEI	P3,0		;GET A NUL
GENST3:	IDPB	P3,P4		;CLEAR OUT CHARACTER
	CAIGE	P2,5		;ZAPPED THE REST OF THE WORD?
	AOJA	P2,GENST3	;NO--DO ANOTHER CHARACTER
	JRST	CPOPJ1		;RETURN


; CHECK FOR A LEGAL CHARACTER
GENSTX:	CAIL	P3,'0'		;ALLOW ONLY
	CAILE	P3,'9'		; 0 THROUGH 9
	CAIL	P3,'A'		;  AND
	CAILE	P3,'Z'		;   A THROUGH Z
	POPJ	P,		;JUNK CHARACTER
	JRST	CPOPJ1		;RETURN
BPCSTO:	MOVE	T1,[DPB	P1,UNYBPC##];GET INSTR. TO BE EXECUTED BY STOUNI
	PUSHJ	P,STOUNI	;STORE VALUE IN EVERY UNIT IN STR
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	LDB	T1,UNYBPC##	;GET CURRENT # BLOCKS PER CLUSTER FOR THIS UNIT
	PUSHJ	P,TRFCHS
	PUSHJ	P,COMLCA	;COMPUTE LAST CLUSTER ADR. ON UNIT
	JFFO	T2,.+2		;FIND POSITION OF 1ST. 1 BIT
	MOVEI	T3,^D35		;NONE - BUT BYTE FIELD MUST BE AT LEAST 1 BIT WIDE
	MOVN	P1,T3		;NEGATE FOR ADDI INSTR.
	ADDI	P1,^D36		;COMPUTE FIELD WIDTH FOR CLUSTER ADR.
	LDB	T1,[POINT 6,STYCLP##(P2),11]
	PUSHJ	P,TRFCHS
	DPB	P1,[POINT 6,STYCLP##(P2),11]	;PUT IT IN BYTE POINTER
	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	LDB	T3,UNYBPC##	;GET # BLOCKS/CLUSTER
	MOVE	T1,STRHGH##(P2)	;HIGHEST BLOCK IN STR
	ADDI	T1,-1(T3)
	IDIVI	T1,(T3)
	HLRZ	P1,T1		;DIVIDE BY 2**18
	ADDI	P1,1		;AND ROUND UP
	IMUL	P1,T3		;COMPUTE # BLOCKS PER SUPER CLUSTER
	HLRZ	T1,STRBSC##(P2)	;GET CURRENT # BLOCKS PER SUPER CLUSTER
	PUSHJ	P,TRFCHS
	HRLM	P1,STRBSC##(P2)	;STORE IT
	MOVE	T2,STRBPU##(P2)	;GET # BLOCKS PER UNIT
	SUBI	T2,1
	IDIV	T2,P1		;DIVIDE BY # BLOCKS PER SUPER CLUSTER
	ADDI	T2,1
	MOVE	P1,T2		;GET NEW VALUE INTO A KOSHER AC FOR 'TRFCHG'
	HRRZ	T1,STRSCU##(P2)	;GET CURRENT # SUPER CLUSTERS PER UNIT
	PUSHJ	P,TRFCHS
	HRRM	P1,STRSCU##(P2)	;STORE # SUPER CLUSTERS PER UNIT
	POPJ	P,

CNPSTO:	DPB	P1,[POINT 6,STYCNP##(P2),11]
	PUSHJ	P,REFCHS	;UNIT NEEDS "HOME" BLOCKS REWRITING, STR REFRESHING
	ADD	P1,T3
	MOVNS	P1
	ADDI	P1,^D36
	LDB	T1,[POINT 6,STYCKP##(P2),11]
	PUSHJ	P,TRFCHS
	DPB	P1,[POINT 6,STYCKP##(P2),11]
	ADD	P1,T3
	LDB	T1,[POINT 6,STYCNP##(P2),5]
	PUSHJ	P,TRFCHS
	DPB	P1,[POINT 6,STYCNP##(P2),5]
	MOVE	P1,T3
	LDB	T1,[POINT 6,STYCKP##(P2),5]
	PUSHJ	P,TRFCHS
	DPB	P1,[POINT 6,STYCKP##(P2),5]
	POPJ	P,
;SUBROUTINE TO DETERMINE IF ANY UNITS ARE NOT IN STR'S
;SKIP RETURN IF YES, NO SKIP IF NO

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

;SUBROUTINE TO COMPUTE SIXBIT LOGICAL UNIT NUMBER WITHIN STR

CMPLOG:	PUSH	P,P3
	MOVE	P3,T1
	LSH	P3,-^D3
	ADDI	P3,20
	LSH	P3,^D6
	ANDI	T1,7
	ADDI	P3,20(T1)
	MOVE	T1,STRNAM##(P2)
	PUSHJ	P,MSKUNI##
	SETCA	T2,0
	JFFO	T2,.+2
	STOPCD	.+1,DEBUG,JDJ,	;++JFFO DIDN'T JUMP
	MOVEI	T2,^D24
	TRNE	P3,700
	JRST	INSUN2
	TRZ	P3,7700
	MOVEI	T2,^D30
INSUN2:	SUB	T2,T3
	LSH	P3,(T2)
	ADD	T1,P3
	MOVEM	T1,UNILOG##(U)
	POP	P,P3
	POPJ	P,
CHGASL:	MOVEI	T1,[ASCIZ .
Do you want to change the active swapping list?
.]
	PUSHJ	P,ASKQUE	;TYPE MSG. & GET USER'S RESPONSE
	  POPJ	P,		;OBVIOUSLY NOT
	SETZM	PREASL##	;FORGET PRESERVED ASL
	MOVEI	U,DIFSWP##	;GET ADR. OF PTR. TO 1ST. UNIT DATA BLOCK IN ASL
	PUSHJ	P,CLRAS1
	JRST	CHGAS3		;JRST AROUND THE ROUTINE

CLRASL:	PUSHJ	P,SETCHG	;FLAG "HOME" BLOCK MUST BE REWRITTEN
	SETOM	UNISUN##(U)	;AS UNIT IS NOW NO LONGER IN ASL
CLRAS1:	HLRZ	T2,UNISWP##(U)	;GET LINK TO NEXT UNIT IN ASL
	HRRZS	UNISWP##(U)	;UNLINK CURRENT UNIT FROM ASL
	MOVE	U,T2
	JUMPN	U,CLRASL	;REPEAT IF THERE IS ONE LEFT
	PJRST	KASL2		;CLEAR OUT SWPTAB AND RETURN

CHGAS3:	MOVEI	T1,[ASCIZ .For each class, type physical unit names
(Extra <CR> when done).]
	PUSHJ	P,SVMOUT	;O/P BUFFER & ADD CRLF
	MOVEI	P3,DIFSWP##
	SETZM	P1		;SET CLASS INITIALLY TO ZERO
	MOVSI	P4,MSWPMX##	;SETUP AOBJN PTR. FOR SWAPPING TABLE LENGTH
	SETOM	TYPONL		;SET TYPE ONLY FLAG
CHGAS1:	MOVEI	T1,[ASCIZ .Class .]
	PUSHJ	P,ASKDEC
	  TLOA	P3,-1		;INDICATE FIRST TIME
	STOPCD	.-4,DEBUG,AR1,	;++ASKDEC RETURNED CPOPJ1
	PUSHJ	P,ASKCHW
	  JRST	CHGAS2
	CAIG	P1,SWCLSN##
	AOJA	P1,CHGAS1
CHGAS2:	SETZM	TYPONL
	POPJ	P,
;ROUTINE TO CLEAR OUT ENTIRE ACTIVE SWAPPING LIST...
;DOES NOT ASSUME ACTIVE SWAPPING LIST IS ALREADY SETUP.

KASL:	SETZM	PREASL##	;FORGET PRESERVED ASL
	MOVEI	U,DIFUSY##
KASL1:	HLRZ	U,UNISYS##(U)
	JUMPE	U,KASL2
	PUSHJ	P,SETCHG	;MARK AS NEEDING HOM BLOCKS REWRITTEN
	SETOM	UNISUN##(U)	;UNIT NO LONGER IN ASL
	HRRZS	UNISWP##(U)	;CLEAR LINK
	JRST	KASL1
KASL2:	MOVE	T1,[XWD SWPTAB##,SWPTAB##+1] ;GET BLT POINTER TO CLEAR OUT
	SETZM	SWPTAB##	;SWPTAB
	BLT	T1,SWPTBE##	;CLEAR TO THE LAST DROP
	POPJ	P,		;RETURN
SAMUNI:	MOVEI	T1,[ASCIZ .?Unit already in active swapping list.]
	PUSHJ	P,SVMOUT

ASKCHW:	PUSHJ	P,GETUNI
	  POPJ	P,
	LDB	T1,UNYK4S##	;GET # K FOR SWAPPING ON THIS UNIT
	JUMPN	T1,ASKCH1	;PRINT MSG. IF NONE
	MOVEI	T1,[ASCIZ .?Unit has no space allocated for swapping
.]
	PUSHJ	P,SVMOUT	;TYPE MSG. & CRLF
	JRST	ASKCHW		;AND WAIT FOR ANOTHER UNIT NAME TO TYPED

ASKCH1:	HLRZ	T1,SWPUNI##
	JUMPE	T1,ASKCH3
ASKCH2:	CAMN	T1,U
	JRST	SAMUNI
	HLRZ	T1,UNISWP##(T1)
	JUMPN	T1,ASKCH2
ASKCH3:	TLZE	P3,-1
	AOS	(P)
	HRLM	U,UNISWP##(P3)
	HRRZS	UNISWP##(U)
	DPB	P1,UNYCFS##
	HRRZM	P4,UNISUN##(U)
	HRRM	U,SWPTAB##(P4)
	PUSHJ	P,SETCHG	;FLAG "HOME" BLOCKS MUST BE REWRITTEN
	HRRZ	P3,U
	AOBJN	P4,ASKCHW	;REPEAT IF ANY ROOM LEFT IN TABLE
	MOVEI	T1,[ASCIZ .
%Active swapping list full.]
	SOS	(P)		;NON-SKIP RETURN IF LIST FULL
	PJRST	SVMOUT
DEFASL:	SETZM	PREASL##	;FORGET PRESERVED ASL
	MOVEI	U,DIFSWP##	;GET ADDR OF PTR TO 1ST UDB IN ASL
	PUSHJ	P,KASL		;CLEAR OUT ASL
	MOVEI	P3,DIFSWP##	;POINTERTO PREDECESSOR
	MOVEI	U,DIFUSY##
	MOVSI	P4,MSWPMX##	;AOBJN POINTER
	SETZ	P1,
DFASL1:	HLRZ	U,UNISYS##(U)	;GET UNIT
	JUMPE	U,CPOPJ##	;FINISHED
	MOVSI	T1,UNPWPO##	;THIS IS CASE OFF DOWN UNITS
	TDNE	T1,UNIDES##(U)
	JRST	DFASL2		;SKIP THIS UNIT...
	LDB	T1,UNYK4S##	;ANY K FOR SWAPPING??
	JUMPE	T1,DFASL1	;NO SWAPPING SPACE-GET NEXT UNIT
	LDB	T1,UNYKTP##	;GET KONTROLLER TYPE
	CAIE	P3,DIFSWP##	;FIRST TIME, IT SKIPS
	CAMN	T1,T3		;HAS UNIT TYPE CHANGED?
	JRST	.+2		;NO-BOP IN CLASS
	AOS	P1		;TYPE HAS CHANGED-BUMP IT UP
	DPB	P1,UNYCFS##	;PUT IN SWAP CLASS
	MOVE	T3,T1		;SAVE OLD UNIT TYPE FOR THE CHECK.
	HRLM	U,UNISWP##(P3)	;CREATE POINTER FROM PREDECSS. TO THS UNIT
	HRRZS	UNISWP##(U)	;CLEAR POINTER TO NEXT UNIT FOR THIS UNIT
	HRRM	U,SWPTAB##(P4)	;ENTER THIS UNIT IN SWPTAB
	HRRZM	P4,UNISUN##(U)	;ENTER LOGICAL UNIT NUMBER
	PUSHJ	P,SETCHG	;FLAG HOME BLOCKS NEED REWRITING
	MOVE	P3,U		;MAKE THIS UNIT PREDECESSOR
	AOBJN	P4,DFASL1	;LOOP FOR MORE IF ANY ROOM LEFT
	POPJ	P,		;NO ROOM LEFT IN ASL
DFASL2:	SETOM	UNISUN##(U)
	HRRZS	UNISWP##(U)
	JRST	DFASL1		;TAKE IT OUT OF ACTIVE SWAPPING LIST
				;IF ITS WRITE PROTECTED OR DOWN.
;SUBROUTINE TO CHANGE THE "SYS" SEARCH LIST

CHGSRC:	MOVEI	T1,[ASCIZ .
Do you want to change the system search list?
.]
	PUSHJ	P,ASKQUE	;TYPE QUSTION & GET USER'S RESPONSE
	  POPJ	P,		;OBVIOUSLY NOT
	SETZM	PRESSL##	;FORGET PRESERVED SSL
	HLRZ	P2,SYSSTR##	;TAKE ALL STRS OUT OF "SYS" SEARCH LIST
CHGSR1:	SETOM	STRSRC##(P2)	;INDICATE STR NOT IN "SYS" SEARCH LIST
	PUSHJ	P,CHGALL	;MAKE SURE ALL HOME BLOCKS GET REWRITTEN
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	JUMPN	P2,CHGSR1	;REPEAT IF ANY LEFT
	MOVEI	T1,[ASCIZ .Type structure names for system search list
(Extra <CR> when done).]
	PUSHJ	P,CONOUT	;TYPE MSG. & ADD CRLF
	MOVSI	P4,-.SLMXS	;AOBJN PTR. FOR MAX. # STRS IN SEARCH LIST
CHGSR2:	PUSHJ	P,ASKST1	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR TYPED - EXIT
	JUMPN	P2,CHGSR3	;WAS "ALL" TYPED
	MOVEI	T1,[ASCIZ .
?"ALL" not allowed.]
	PUSHJ	P,CONOUT	;TYPE MSG. & ADD CRLF
	JRST	CHGSR2		;TRY AGAIN

CHGSR3:	HRRZM	P4,STRSRC##(P2)	;STORE LOG. STR # IN STR DATA BLOCK
	AOBJN	P4,CHGSR2	;GET NEXT STR NAME
	POPJ	P,		;EXIT - MAX. # STRS TYPED
;SUBROUTINE TO CHANGE THE SYSTEM DUMP LIST

CHGSDL:	MOVEI	T1,[ASCIZ .
Do you want to change the system dump list?
.]
	PUSHJ	P,ASKQUE	;TYPE QUSTION & GET USER'S RESPONSE
	  POPJ	P,		;OBVIOUSLY NOT
	SETZM	PRESDL##	;FORGET PRESERVED SDL
	HLRZ	P2,SYSSTR##	;TAKE ALL STRS OUT OF SYSTEM DUMP LIST
CHGSD1:	SETOM	STRSDL##(P2)	;INDICATE STR NOT IN SYSTEM DUMP LIST
	PUSHJ	P,CHGALL	;MAKE SURE ALL HOME BLOCKS GET REWRITTEN
	HLRZ	P2,STRSYS##(P2)	;GET ADR. OF NEXT STR DATA BLOCK IN SYSTEM
	JUMPN	P2,CHGSD1	;REPEAT IF ANY LEFT
	MOVEI	T1,[ASCIZ .Type structure names for system dump list
(Extra <CR> when done).]
	PUSHJ	P,CONOUT	;TYPE MSG. & ADD CRLF
	MOVSI	P4,-.SDMAX	;AOBJN PTR. FOR MAX. # STRS IN DUMP LIST
CHGSD2:	PUSHJ	P,ASKST1	;TYPE MSG. & GET RESPONSE
	  POPJ	P,		;CR TYPED - EXIT
	JUMPN	P2,CHGSD3	;WAS "ALL" TYPED
	MOVEI	T1,[ASCIZ .
?"ALL" not allowed.]
	PUSHJ	P,SVMOUT	;TYPE MSG. & ADD CRLF
	JRST	CHGSD2		;TRY AGAIN
CHGSD3:	HRRZ	T1,STRK4C##(P2)	;GET K FOR CRASH ON THIS STR
	JUMPN	T1,CHGSD4	;MUST HAVE SOME
	MOVEI	T1,[ASCIZ .?Structure has no space allocated for CRASH
.]
	PUSHJ	P,SVMOUT	;TELL HIM
	JRST	CHGSD2		;AND TRY AGAIN

CHGSD4:	HRRZM	P4,STRSDL##(P2)	;STORE LOG. STR # IN STR DATA BLOCK
	AOBJN	P4,CHGSD2	;GET NEXT STR NAME
	POPJ	P,		;EXIT - MAX. # STRS TYPED
;ROUTINE TO SET UP SYS SEARCH LIST DEFAULT
;PUTS ALL STRS IN SYS SEARCH LIST

DEFSSL:	SETZM	PRESSL##	;FORGET PRESERVED SSL
	HLRZ	P2,SYSSTR##	;GET ADDR OF 1ST STR IN SSL
	JUMPE	P2,CPOPJ##	;THROUGH IF NONE
DFSSL1:	SETOM	STRSRC##(P2)	;TAKE IT OUT
	PUSHJ	P,CHGALL	;MAKE SURE ALLHOM BLOCKS ARE REWRITTEN
	HLRZ	P2,STRSYS##(P2)	;GET NEXT STR
	JUMPN	P2,DFSSL1	;JUMP IF ANY LEFT
	MOVSI	P4,-.SLMXS	;AOBJN POINTER
	MOVEI	P2,DIFSTR##
DFSSL2:	HLRZ	P2,STRSYS##(P2)
	JUMPE	P2,CPOPJ##
	SKIPN	STRUNI##(P2)	;IF NO UNITS IN THIS STR
	JRST	DFSSL2		;GO FOR NEXT STR
	HRRZM	P4,STRSRC##(P2)	;PUT STR IN SYS SEARCH LIST
	AOBJN	P4,DFSSL2	;BUMP LOGICAL NUMBER AND CONTINUE
	POPJ	P,		;WE'RE THROUGH


;ROUTINE TO SETUP SYSTEM DUMP LIST DEFAULT.  PUTS ALL STRS IN SYSTEM
;DUMP LIST

DEFSDL:	SETZM	PRESDL##	;FORGET PRESERVED SDL
	HLRZ	P2,SYSSTR##	;START AT FIRST STR DATA BLOCK
	JUMPE	P2,CPOPJ##	;QUIT IF NO STRS
DFSDL1:	SETOM	STRSDL##(P2)	;TAKE THIS ONE OUT OF SDL
	PUSHJ	P,CHGALL	;MAKE SURE HOM BLOCKS GET REWRITTEN
	HLRZ	P2,STRSYS##(P2)	;STEP TO NEXT STR DATA BLOCK
	JUMPN	P2,DFSDL1	;LOOP IF NOT AT END
	MOVSI	P4,-.SDMAX	;SETUP AOBJN POINTER FOR SDL
	MOVEI	P2,DIFSTR##	;MAKE STRSYS OFFSETS WORK
DFSDL2:	HLRZ	P2,STRSYS##(P2)	;STEP TO NEXT STR DATA BLOCK
	JUMPE	P2,CPOPJ##	;EXIT AT END
	HRRZ	T1,STRK4C##(P2)	;GET K FOR CRASH FOR THIS STR
	SKIPE	T1		;IF NONE,
	SKIPN	STRUNI##(P2)	;  OR IF NOT IN A STR,
	JRST	DFSDL2		;  DON'T TOUCH THIS ONE
	HRRZM	P4,STRSDL##(P2)	;INSERT THIS STR IN THE SDL
	AOBJN	P4,DFSDL2	;LOOP FOR MAX NUMBER IN SDL
	POPJ	P,		;RETURN
;ENTER WITH P1 = 0

CANTB0:	JUMPN	P1,CPOPJ1##	;SKIP RETURN IF P1 IS NON ZERO
	MOVEI	T1,[ASCIZ .Cannot be .]
	PJRST	DECLOP		;TYPE MSG. & VALUE

CHKHBS:	CAMLE	P1,MAX		;IS NEW VALUE GT OR EQ MAX?
	JRST	CANTEX		;YES - TYPE CANNOT EXCEED AND VALUE
	JRST	CPOPJ1##	;IT'S NOT - SKIP RETURN


;ENTER AT CANTX1 WITH T2 = VALUE TO BE TYPED, AT CANTEX WITH MAX = VALUE

CANTEX:	MOVE	P1,MAX		;PUT VALUE INTO KOSHER AC
	MOVEI	T1,[ASCIZ .Cannot exceed .]
	PJRST	DECLOP		;TYPE MSG. & VALUE


; T3 IS RESPECTED

TRFCHU:	HLLOS	WHICH
	CAME	T1,P1		;IS OLD VALUE=NEW VALUE?
REFCHU:	SKIPN	WHICH
	POPJ	P,
	SKIPE	P2		;IS UNIT IN AN STR?
	HRROS	STRREF##(P2)	;YES - INDICATE STR NEEDS REFRESHING
	PJRST	SETCHG		;FLAG "HOME" BLOCKS MUST BE REWRITTEN

TRFCHS:	HLLOS	WHICH
	CAME	T1,P1
REFCHS:	SKIPN	WHICH
	POPJ	P,
	HRROS	STRREF##(P2)	;INDICATE STR NEEDS REFRESHING
CHGSTR:	SKIPN	WHICH
	POPJ	P,
CHGALL:	MOVE	T1,[PUSHJ P,SETCHG]	;GET INSTR. TO BE EXECUTED BY STOUNI
;SUBROUTINE TO EXECUTE AN INSTRUCTION FOR ALL UNITS WITHIN AN STR
; USUALLY STORES A BYTE
;T1=INSTRUCTION TO BE EXECUTED, P1=ARG., P2=STR DATA BLOCK ADR.

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

;SUBROUTINE TO COMPUTE # CLUSTERS & WORDS PER SAT

CMCWPS:	PUSHJ	P,SAVE4##	;SAVE P1-P4
	PUSHJ	P,COMLC1	;NOW COMPUTE # CLUSTERS PER SAT
	SOS	T2
	LDB	P1,UNYSPU##	;GET # SATS PER UNIT IN THIS STR
	IDIV	T2,P1
	HRRM	T2,UNICPS##(U)	;STORE COMPUTED VALUE
	AOS	UNICPS##(U)	;MAKE VALUE IN UNIT DATA BLOCK RIGHT
	IDIVI	T2,^D36
	ADDI	T2,1
	DPB	T2,UNYWPS##	;STORE COMPUTED VALUE
	POPJ	P,		;EXIT

ASKDMM:	CAMGE	P1,MIN		;SEE IF BELOW MINIMUM
	MOVE	P1,MIN		;YES -- SET TO MINIMUM
	CAMLE	P1,MAX		;SEE IF ABOVE MAXIMUM
	MOVE	P1,MAX		;YES -- SET TO MAXIMUM
	SKIPGE	TYPONL		;DONT SKIP IF ONLY TYPING PARAMS
	PJRST	ASKDEC		;IN WHICH CASE FORGET ABOUT MIN AND MAX
	JSP	T2,SVOTAC
	MOVE	T2,MIN
	CAMN	T2,MAX
	JRST	SNDMIN		;IF MIN=MAX DONT ASK
	MOVEM	P1,WHICH	;SAVE ORIGINAL VALUE
	PUSHJ	P,DECLOP	;TYPE MESSAGE AND SEND VALUE
	MOVEI	T1,[ASCIZ .Min = .]
	MOVE	P1,MIN
	PUSHJ	P,TYPDEC	;TYPE MIN
	PUSHJ	P,SOPOUT
	MOVEI	T1,[ASCIZ . Max = .]
	MOVE	P1,MAX
	PUSHJ	P,DECLOP	;TYPE MAX, CRLF
	MOVE	P1,WHICH	;RESTORE ORIGINAL VALUE
	PJRST	ASKDC2		;GET RESPONSE
SNDMIN:	MOVE	P1,MIN		;RETURN MIN
	JRST	CPOPJ1##
ASKDEC:	JSP	T2,SVOTAC
	JRST	ASKDC1

ASKDC1:	MOVEM	T1,WHICH
ASKDAG:	PUSHJ	P,DECLOP
	SKIPGE	T1,TYPONL
	POPJ	P,
ASKDC2:	PUSHJ	P,GETLIN##
	  JRST	SIXCH1
	PUSHJ	P,ALTM		;IN CASE OF $ COP OUT
	PUSHJ	P,DECIN##
	  JFCL			;SHOULD NEVER HAPPEN
	  SKIPA
	PJRST	SIXCHK
	MOVEI	T1,[ASCIZ .Invalid character in response, please retype number; <CR> =.]
	JRST	ASKDAG

DECLOP:	JSP	T2,SVOTAC
	PUSHJ	P,TYPDEC
	PJRST	CRLFOP


COMLCA:	HLRZ	U,STRUNI##(P2)	;GET ADR. OF 1ST. UNIT DATA BLOCK IN STR
	JRST	COMLC2		;IS UNIT IN AN STR?

COMLC1:	SKIPA	T2,UNIBPU##(U)	;NO - GET # BLOCKS ON UNIT
COMLC2:	MOVE	T2,STRBPU##(P2)	;YES - GET # BLOCKS PER UNIT
	LDB	T4,UNYBPC##	;GET # BLOCKS PER CLUSTER
	IDIV	T2,T4		;COMPUTE LAST CLUSTER ADR. ON UNIT
	POPJ	P,		;RETURN

TYPMSN:	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	PUSHJ	P,TYPDEC	;PUT MSG. IN THE BUFFER FOLLOWED BY DECIMAL #
	PJRST	OPOUT##		;O/P THE BUFFER

TYPDEC:	PUSHJ	P,ICONM##
	MOVE	T1,P1
	PJRST	RADX10##
ASKSIX:	JSP	T2,SVOTAC
	MOVEM	T1,WHICH
	PUSHJ	P,SIXLOP
	SKIPGE	T1,TYPONL
	POPJ	P,
GETSIX:	PUSHJ	P,GETLIN##
	  JRST SIXCH1
	PUSHJ	P,ALTM		;IN CASE OF $ COP OUT
GETSX1:	PUSHJ	P,CTEXT##
SIXCHK:	EXCH	P1,T2
	CAME	P1,T2
	AOSA	(P)
	SETZM	WHICH
	PUSHJ	P,OTSET##	;INITIALIZE BUFFER
	PUSHJ	P,CRLFOP
	SKIPA	T1,WHICH
SIXCH1:	SETZB	T1,WHICH
	POPJ	P,

SIXLOP:	PUSHJ	P,ICONM##
	MOVE	T2,P1
NAMFLO:	PUSHJ	P,PRNAME##
	PJRST	CRLFOP
RWRSUB:	MOVEI	T1,[ASCIZ .
Type physical units on which to write HOME blocks (Extra <CR> when through)
(<CR> if none, ALL if all; "ALL" is normal case).]
	PUSHJ	P,CONOUT	;TYPE MESSAGE
	MOVSI	P4,UNPCHG##	;BIT SET IF HOME BLOCK MUST BE REWRITTEN
	SETZM	RWRFLG		;CLEAR ANY REWRITTEN FLAGS
RWRSU1:	PUSHJ	P,GETUNI	;GET UNITS TO REWRITE
	  JRST	RWREX		;NO MORE
	AOS	RWRFLG
	JUMPE	U,RWRHUN	;JUMP IF NO UNIT SPECIFIED
	PUSHJ	P,RWRWHM	;REWRITE THE HOME BLOCK
	JRST	RWRSU1		;AND WAIT FOR NEXT
RWRHUN:	HLRZ	U,SYSUNI##	;FIRST UNIT IN SYSTEM
RWRSU2:	PUSHJ	P,RWRWHM	;REWRITE HOME BLOCK
	HLRZ	U,UNISYS##(U)	;NEXT UNIT
	JUMPN	U,RWRSU2	;LOOP FOR ALL IN SYSTEM
RWREX:	SKIPN	RWRFLG		;SKIP IF ANY SPECIFIED
	POPJ	P,		;NO, DON'T TYPE
	MOVEI	T1,[ASCIZ .
HOME blocks written.]
	PJRST	SVMOUT		;ADD CRLF, OUTPUT, AND RETURN
RWRWHM:	TDNE	P4,UNIDES##(U)	;SKIP IF DON'T NEED TO
	PUSHJ	P,UPDHOM	;REWRITE UNIT'S HOME BLOCKS
	ANDCAM	P4,UNIDES##(U)	;CLEAR NEEDS REWRITING FLAG
	POPJ	P,		;RETURN
SVOSET::PUSHJ	P,SVTPAC
	PUSHJ	P,OTSET##
	PJRST	SUPDAT

SAVP4:	0
SAVT2:	0
SAVF:	0
SAVU:	0
SAVK:	0

STRIS::	MOVEI	T1,[ASCIZ .
%Structure .]
	PUSHJ	P,ICONM##
	MOVE	T2,STRNAM##(P2)
	PJRST	PRNAME##

SPSNAM::SKIPA	T2,STRNAM##(P2)
SPUNAM::MOVE	T2,UNINAM##(U)
SPRNAM:	PUSHJ	P,SUPDAT
	PUSHJ	P,PRNAME##
	PJRST	SUPDAT

SOPOUT::PUSHJ	P,SUPDAT
	PUSHJ	P,OPOUT##
	PJRST	SUPDAT

SRDX10:	PUSHJ	P,SUPDAT
	PUSHJ	P,RADX10##
	PJRST	SUPDAT

SCRLFO::PUSHJ	P,SUPDAT
	PUSHJ	P,CRLF##
	PUSHJ	P,OPOUT##
	PJRST	SUPDAT

SCONMS::PUSHJ	P,SUPDAT
	PUSHJ	P,CONMES##
SUPDAT:	EXCH	P4,SAVP4
	EXCH	T3,SAVT2
	EXCH	F,SAVF
	EXCH	U,SAVU
	EXCH	J,SAVK
	POPJ	P,

SVTPAC:	MOVEM	P4,SAVP4
	MOVEM	T3,SAVT2
	MOVEM	F,SAVF
	MOVEM	U,SAVU
	MOVEM	J,SAVK
	POPJ	P,

SVMOTS:	SETOM	SERIUS
SVMOTE:	SETOM	ERRHOM
SVMOUT::JSP	T2,SVOTAC
CONOUT:	PUSHJ	P,ICONM##
CRLFOP::PUSHJ	P,CRLF##
	PJRST	OPOUT##
ASKYCR:	MOVEI	T1,[ASCIZ .
Do you want to change any disk parameters? (<CR> if no)
.]
ASKQUE:	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	PJRST	YESNO##		;GET USER'S RESPONSE - SKIP RETURN IF 1ST. T4="Y"
				; NON SKIP RETURN IF ANYTHING ELSE TYPED

;SUBROUTINE TO TYPE A MSG. - ACCEPT A RESPONSE WHICH SHOULD BE AN STR NAME
; AND SCAN STR DATA BLOCKS FOR A MATCH WITH THE NAME TYPED

ASKSTR:	JSP	T2,SVOTAC	;SAVE P4,T3,F,U & J
	PUSHJ	P,CONOUT	;O/P MSG. & ADD CRLF
	CAIA
ASKST1:	JSP	T2,SVOTAC	;SAVE P4,T3,F,U & J
	PUSHJ	P,GETLIN##	;GET RESPONSE
	  POPJ	P,		;CR TYPED - NON SKIP RETURN
	PUSHJ	P,ALTM		;IN CASE OF $ COP OUT
	PUSHJ	P,CTEXT##	;GET RESPONSE IN SIXBIT
	SETZM	P2		;ASSUME "ALL" TYPED
	CAMN	T2,[SIXBIT .ALL.]	;WAS IT?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	MOVE	T1,T2		;PUT STR NAME INTO T1 FOR FNSTR
	PUSHJ	P,FNSTR		;GET STR DATA BLOCK ADR. IF IT EXISTS
	  SKIPA	T1,[[ASCIZ .?Not a structure - Try again.]]
	JRST	CPOPJ1##	;SKIP RETURN WITH ADR. IN P2
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	JRST	ASKST1		;WAIT FOR NEW NAME TO BE TYPED

;T2 & T3 ARE RESPECTED

SETCHG:	MOVSI	T1,UNPCHG##	;PREPARE TO FLAG "HOME" BLOCKS NEED REWITING
	MOVSI	T4,UNPWPO##
	TDNN	T4,UNIDES##(U)	;IS UNIT WRITE PROTECTED OR OFF-LINE?
	IORM	T1,UNIDES##(U)	;SET UNPCHG FLAG
	POPJ	P,		;RETURN

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

CHKCHG:	MOVSI	P4,UNPCHG##	;SEE IF ANY UNITS NEED THEIR "HOME" BLOCKS REWRITTEN
	HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
CHKCH1:	TDNE	P4,UNIDES##(U)	;IS THE BIT SET?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	HLRZ	U,UNISYS##(U)	;GET ADR. OF NEXT UNIT DATA BLOCK IN SYSTEM
	JUMPN	U,CHKCH1	;REPEAT IF THERE IS ONE LEFT
	POPJ	P,		;NO "HOME" BLOCKS NEED REWRITING - NON SKIP RETURN
GETUNI::PUSHJ	P,GETLIN##	;GET USER'S RESPONSE
	  POPJ	P,		;JUST CR TYPED - NON SKIP RETURN
	PUSHJ	P,ALTM		;IN CASE OF $ COP OUT
	PUSHJ	P,CTEXT##	;GET SIXBIT UNIT NAME
	SETZM	U		;ASSUME "ALL" WAS TYPED
	HLRZ	T1,T2		;MAKE AC LOOK GOOD FOR COMPARE
	CAIN	T1,(SIXBIT .ALL.);WAS "ALL" TYPED?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	PUSHJ	P,FNDUNI	;SEE IF UNIT EXISTS & RETURN WITH UNIT DATA BLOCK
	  SKIPA	T1,[[ASCIZ .?Not a physical unit - Try again.]]
	JRST	CPOPJ1##	;UNIT EXISTS - SKIP RETURN
	PUSHJ	P,SVMOUT	;ADD CRLF & O/P MSG.
	JRST	GETUNI		;TRY AGAIN

FNDUNI::HLRZ	U,SYSUNI##	;GET ADR. OF 1ST. UNIT DATA BLOCK IN SYSTEM
FNDUN1:	CAME	T2,UNIHID##(U)	;ACCEPT MATCH ON UNIT ID
	CAMN	T2,UNINAM##(U)	;MATCH?
	JRST	CPOPJ1##	;YES - SKIP RETURN
	HLRZ	U,UNISYS##(U)	;GET NEXT UNIT DATA BLOCK ADR. IN SYSTEM
	JUMPN	U,FNDUN1	;REPEAT IF THERE IS ONE
	POPJ	P,		;NONE FOUND - NON SKIP RETURN

;SUBROUTINE TO PRESERVE AC'S P4,F,U & J

REFSAV:	HRROS	STRREF##(P2)	;INDICATE STR NEEDS REFRESHING
SVOTAC:	PUSH	P,P4
	PUSH	P,T3
	PUSH	P,F
	PUSH	P,U
	PUSH	P,J
	PUSHJ	P,(T2)
	  CAIA
	AOS	-5(P)
	POP	P,J
	POP	P,U
	POP	P,F
	POP	P,T3
	POP	P,P4
	POPJ	P,
;ROUTINE JUST TO WRITE OUT A HOME BLOCK FOR A UNIT WITHOUT READING IT IN.
;CALLED WITH UNIT DATA BLOCK ADRESS IN U

HOMWRT:	JSP	T2,SVOTAC	;SAVE AC'S
	MOVE	F,DATADR	;FDB ADDRESS
	HRRZ	P1,@ONCMBF	;ADRESS OF MBF
	ADDI	P1,1		;POINT IT PAST FIRST IOWD
	MOVSI	P2,(SIXBIT .HOM.)
	MOVE	P3,[EXP CODHOM##]
	PJRST	HOMWR1

UPDHOM:	JSP	T2,SVOTAC	;SAVE P4,F,U & J
	PUSHJ	P,GTHOM		;GET "HOME" BLOCK INTO CORE
	  JFCL			;IGNORE ERRORS
HOMWR1:	MOVEM	P2,BLKNAM##(P1)	;SAVE SIXBIT "HOME" BLOCK IDENTIFIER
	HRRZ	P2,UNISTR##(U)	;GET STR DATA BLOCK ADR.
	MOVE	T1,UNIHID##(U)	;GET SIXBIT UNIT ID
	MOVEM	T1,HOMHID##(P1)	;SAVE IN "HOME" BLOCK
	SETZM	HOMLEN##+1(P1)
	HRLZI	T1,HOMLEN##+1(P1)
	HRRI	T1,HOMLEN##+2(P1)
	BLT	T1,HOMLEN##+4(P1)
	MOVEI	T1,MFDSIZ##	;MAKE UFD'S FOR [1,1] AND [1,4]
	MOVEM	T1,HOMLEN##+3(P1)	; EXTRA LONG TO MINIMISE DSK READ
	MOVEM	T1,HOMLEN##+5(P1)
	HLRZ	T1,UNISTR##(U)	;GET NEXT UNIT DATA BLOCK ADR. IN STR
	SKIPE	T1		;SAVE 0 IF LAST UNIT IN STR OR NOT IN AN STR
	MOVE	T1,UNIHID##(T1)	;GET ITS ID
	MOVEM	T1,HOMNXT##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,P2		;SAVE 0 STR NAME IF UNIT NOT IN AN STR
	MOVE	T1,STRNAM##(P2)	;GET SIXBIT STR NAME
	MOVEM	T1,HOMSNM##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,P2		;STORE 0 FOR OWNER PPN IF UNIT NOT IN A STR
	MOVE	T1,STRPPN##(P2)	;GET OWNER PPN
	MOVEM	T1,HOMOPP##(P1)	;SAVE IN "HOME" BLOCK
	JUMPE	P2,UPDHM3	;BYPASS ALL REFERENCES TO VALUES IN STR DATA BLOCK
	HLRZ	T1,STRUNI##(P2)	;GET ADR. OF 1ST UNIT DATA BLOCK IN STR
UPDHM1:	JUMPE	T1,UPDHM2	;IF NONE LEFT SAVE 0 IN HOMPRV
	HLRZ	T2,UNISTR##(T1)	;GET ADR. OF NEXT UNIT DATA BLOCK IN STR
	MOVE	T3,UNIHID##(T1)	;GET CURRENT UNIT'S SIXBIT ID
	MOVE	T1,T2		;CURRENT UNIT_NEXT UNIT
	CAME	T2,U		;IS ADR. OF NEXT UNIT DATA BLOCK SAME AS THIS ONE?
	JRST	UPDHM1		;YES - PUT SIXBIT ID INTO THIS UNIT'S "HOME" BLOCK
UPDHM2:	MOVEM	T3,HOMPRV##(P1)	;SAVE IN "HOME" BLOCK
				; 0 OR SIXBIT UNIT ID OF PREVIOUS UNIT IN STR
	HLRZ	T1,STRBSC##(P2)	;GET # BLOCKS PER SUPER CLUSTER
	MOVEM	T1,HOMBSC##(P1)	;SAVE IN "HOME" BLOCK
	HRRZ	T1,STRSCU##(P2)	;GET # SUPER CLUSTERS PER UNIT
	MOVEM	T1,HOMSCU##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STRSRC##(P2)	;GET LOG. STR # OF STR IN "SYS" SEARCH LIST
	MOVEM	T1,HOMSRC##(P1)	;SAVE IN "HOME" BLOCK
	SKIPL	T1,STRSDL##(P2)	;CONVERT POS IN SDL FROM INTERNAL 0...N-1
	ADDI	T1,1		; TO 1...N IN HOME BLOCK BUT LEAVE -1 ALONE
	MOVEM	T1,HOMSDL##(P1)	;STORE IN HOME BLOCK
	MOVE	T1,STYCNP##(P2)	;GET BYTE PTR. FOR CLUSTER COUNT
	MOVEM	T1,HOMCNP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STYCKP##(P2)	;GET BYTE PTR. FOR CHECKSUM
	MOVEM	T1,HOMCKP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STYCLP##(P2)	;GET BYTE PTR. FOR CLUSTER ADR.
	MOVEM	T1,HOMCLP##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STRGAR##(P2)	;GET # BLOCKS GUARANTEED TO USER BY RESERVATION
	MOVEM	T1,HOMGAR##(P1)	;SAVE IN "HOME" BLOCK
	HLLZ	T1,STRREF##(P2)	;GET 'REFRESH' FLAG
	HLLM	T1,HOMREF##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,STROVR##(P2)	;GET -VE # BLOCKS USER IS ALLOWED TO OVERDRAW
	MOVEM	T1,HOMOVR##(P1)	;SAVE IN "HOME" BLOCK
	HRRZ	T1,STRK4C##(P2)	;GET # K FOR CRASH.SAV
	MOVEM	T1,HOMK4C##(P1)	;SAVE IN "HOME" BLOCK
	LSH	T1,BLKSPK##	;CONVERT TO # BLOCKS
	SKIPE	T1		;NO EXE DIRECTORY IF NO FILE
	ADDI	T1,4		;ALLOCATE 1 MORE PAGE FOR EXE DIRECTORY

	MOVEM	T1,HOMLEN##(P1)	;SAVE IN "HOME" BLOCK
IFN FTPSTR,<
	LDB	T1,STYPVS##	;GET PRIVATE STR BIT
	DPB	T1,HOYPVS##	;SAVE IN "HOME" BLOCK
>
IFN FTSETS,<
	LDB	T1,STYSET##	;GET SET NUMBER
	DPB	T1,HOYSET##	;SAVE IN "HOME" BLOCK
>; END IFN FTSETS
UPDHM3:	MOVE	T1,UNILOG##(U)	;GET SIXBIT LOGICAL UNIT WITHIN STR
	MOVEM	T1,HOMLOG##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYLUN##	;GET LOGICAL UNIT # WITHIN STR
	MOVEM	T1,HOMLUN##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNIHOM##(U)	;GET LOG. BLOCK #'S OF BOTH "HOME" BLOCKS
	MOVEM	T1,HOMHOM##(P1)	;SAVE IN "HOME" BLOCK
	HLL	T1,UNIGRP##(U)	;GET # CONSECUTIVE CLUSTERS TRIED FOR ON O/P
	HLRZM	T1,HOMGRP##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYK4S##	;GET # K FOR SWAPPING ON THIS UNIT
	MOVEM	T1,HOMK4S##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYBPC##	;GET # BLOCKS PER CLUSTER
	MOVEM	T1,HOMBPC##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYSIC##	;GET # SAT BLOCKS IN CORE FOR THIS UNIT
	MOVEM	T1,HOMSIC##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNISUN##(U)	;GET LOG. UNIT # IN ASL
	MOVEM	T1,HOMSUN##(P1)	;SAVE IN "HOME" BLOCK
	SKIPE	T1,SWPTAB##+1(T1)	;GET UNIT DATA BLOCK ADR. OF NEXT UNIT IN ASL
	MOVE	T1,UNIHID##(T1)	;GET ITS SIXBIT ID
	MOVEM	T1,HOMSID##(P1)	;SAVE IN "HOME" BLOCK
	MOVE	T1,UNISLB##(U)	;GET 1ST. LOG. BLOCK # FOR SWAPPING
	MOVEM	T1,HOMSLB##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYCFS##	;GET CLASS FOR SWAPPING
	MOVEM	T1,HOMCFS##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYSPU##	;GET # SAT BLOCKS PER UNIT
	MOVEM	T1,HOMSPU##(P1)	;SAVE IN "HOME" BLOCK
	LDB	T1,UNYUTP##	;GET UNIT TYPE
	MOVEM	T1,HOMUTP##(P1)	;SAVE IN 'HOME' BLOCK
;HERE TO CLEAR UNUSED PORTIONS OF HOME BLOCK

	MOVEI	T1,HOMEND##+1(P1)	;FIRST WORD TO CLEAR
	CAILE	T1,HOMCOD##-1(P1)	;SKIP IF AT LEAST ONE WORD
	JRST	UPDHM4
	SETZM	(T1)		;CLEAR THE FIRST WORD
	CAIN	T1,HOMCOD##-1(P1)	;SKIP IF MORE
	JRST	UPDHM4
	HRLZI	T1,HOMEND##+1(P1)
	HRRI	T1,HOMEND##+2(P1)
	BLT	T1,HOMCOD##-1(P1)	;CLEAR UNUSED WORDS
UPDHM4:	PUSHJ	P,WRTVID	;STORE VOLID STUFF IN HOME BLOCK
	MOVEM	P3,BLKCOD##(P1)	;SAVE CODE WORD IN "HOME" BLOCK
	MOVE	P4,UNIHOM##(U)	;GET LOG BLOCK #'S OF 1ST. & 2ND. "HOME" BLOCKS
	PUSHJ	P,WRTRUN	;WRITE OUT BOTH "HOME" BLOCKS
	  JFCL			;IGNORE ERRORS
	MOVSI	T1,UNPCHG##	;CLEAR CHANGED FLAG
	ANDCAM	T1,UNIDES##(U)	; IN UDB
	POPJ	P,		;RETURN
	SUBTTL	VOLUME ID ROUTINES

;SUBROUTINE TO SETUP VOLUME ID FIELDS IN HOME BLOCK
;CALL WITH:
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,WRTVID
;	RETURN HERE
;
WRTVID:	MOVEI	T1,HOMVID##	;GET OFFSET TO VOLUME ID
	LSH	T1,2		;MAKE BYTE ADDRESS
	MOVE	T2,HOMHID##(P1)	;GET PACK NAME
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	ADDI	T1,6		;SKIP AHEAD
	MOVEI	T2,0		;BLANKS
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	MOVEI	T1,HOMVSY##	;GET SYSTEM TYPE
	LSH	T1,2		;CONVERT TO BYTES
	MOVE	T2,[SIXBIT "TOPS-1"]
	PUSHJ	P,VOLIDN	;STORE IN BLOCK
	ADDI	T1,6		;BUMP 1 1/2 WORDS
	MOVSI	T2,'0  '	;ADD IN ZERO
	PUSHJ	P,VOLIDN	;STORE NAME
	DMOVE	T1,[EXP <SIXBIT/SYSTEM/>,0] ;ASSUME NO OWNER PPN
	SKIPE	HOMOPP##(P1)	;IS THERE AN OWNER
	PUSHJ	P,VOLPPN	;YES -GENERATE PPN
	EXCH	T1,T2		;SWAP WORDS
	PUSH	P,T1		;SAVE SECOND WORD
	MOVEI	T1,HOMOWN##
	LSH	T1,2
	PUSHJ	P,VOLIDN
	ADDI	T1,6
	POP	P,T2		;GET SECOND WORD BACK
	PJRST	VOLIDN
; SUBROUTINE TO GENERATE A PPN
; CALL:	PUSHJ	P,VOLPPN
;	RETURN HERE WITH T1&T2 CONTAINING PPN STRING IN SIXBIT
;
VOLPPN:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	SETZB	T1,T2		;CLEAR RESULT
	MOVE	P2,[POINT 6,T1]	;BYTE POINTER TO STORE RESULT
	MOVEI	T3,'['		;GET A BRACKET
	PUSHJ	P,VOLCHR	;STORE IT
	HLRZ	T3,HOMOPP##(P1)	;GET PROJECT #
	CAIN	T3,777777	;WILD?
	JRST	[MOVEI	T3,'*'	;YES
		 PUSHJ	P,VOLCHR ;TYPE *
		 JRST	.+2]	;ONWARD
	PUSHJ	P,VOLOCT	;CONVERT IT
	MOVEI	T3,','		;GET A COMMA
	PUSHJ	P,VOLCHR	;STORE IT
	HRRZ	T3,HOMOPP##(P1)	;GET PROGRAMMER #
	CAIN	T3,777777	;WILD?
	JRST	[MOVEI	T3,'*'	;YES
		 PUSHJ	P,VOLCHR ;TYPE *
		 JRST	.+2]	;ONWARD
	PUSHJ	P,VOLOCT	;CONVERT IT
	MOVEI	T3,']'		;GET A BRACKET
	PJRST	VOLCHR		;STORE IT AND RETURN


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

VOLCHR:	TRNN	T2,77		;12 CHARACTERS MAXIMUM
	IDPB	T3,P2		;STORE CHARACTER
	POPJ	P,		;RETURN
;SUBROUTINE TO STORE 1 SIXBIT WORD IN VOLUME ID
;CALL WITH:
;	T1 = BYTE # WITHIN HOME BLOCK (PDP-11 WISE)
;	T2 = WORD
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,VOLIDN
;	RETURN HERE
;
VOLIDN:	PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,T1
	MOVEI	P1,-1(T1)	;SETUP ADDRESS
	MOVEI	T4,6		;BYTE COUNT
VOLDN1:	MOVEI	T3,0		;CLEAR WORD
	ROTC	T2,6		;COPY BYTE
	ADDI	T3,"0"-'0'	;CONVERT TO ASCII
	AOS	T1,P1		;T1 IS BYTE ADDRESS
	PUSHJ	P,VOLIDP	;GET POINTER
	ADD	T1,-2(P)	;ADD ADDRESS OF BUFFER
	DPB	T3,T1		;STORE IN BUFFER
	SOJG	T4,VOLDN1	;LOOP OVER WHOLE WORD
	JRST	TPOPJ##		;RETURN
;SUBROUTINE TO CHECK VOLUME ID TYPE
;CALL WITH:
;	P1 = ADDRESS OF HOME BLOCK
;	PUSHJ	P,CHKVSY
;	RETURN HERE IF VOLUME ID TYPE IS 'TOPS-10'
;	RETURN HERE IF VOLUME ID TYPE IS NOT 'TOPS-10', WITH
;		T1 = BYTE POINTER TO VOLUME ID TYPE STRING IN ASCIZ

CHKVSY:	PUSHJ	P,SAVE2##	;SAVE P1-P2
	MOVEI	P1,HOMVSY##	;OFFSET TO VOLUME ID
	LSH	P1,2		;MAKE BYTE ADDRESS
	MOVE	T3,[POINT 7,VSYBFR] ;POINTER TO TEMP BUFFER
	MOVEI	T4,3*4		;3 WORDS OF 4 BYTES EACH
CHKVS1:	MOVE	T1,P1		;T1 IS BYTE ADDRESS
	PUSHJ	P,VOLIDP	;GET POINTER
	ADD	T1,-2(P)	;ADD ADDRESS OF BUFFER
	LDB	T2,T1		;GET THE BYTE
	SKIPN	T2		;IF NULL,
	MOVEI	T2," "		; MAKE A BLANK
	IDPB	T2,T3		;STUFF IN TEMP BUFFER
	CAIE	T2," "		;NON-BLANK?
	MOVE	P2,T3		;YES, SAVE POINTER TO END OF SYSTEM TYPE
	SOSLE	T4		;QUIT IF DONE
	AOJA	P1,CHKVS1	;LOOP FOR MORE

	DMOVE	T1,VSYBFR	;GET DECODED SYSTEM TYPE
	MOVE	T3,VSYBFR+2	;3 WORDS WORTH
	CAMN	T1,[ASCII .TOPS-.] ;IS IT 'TOPS-10'?
	CAME	T2,[ASCII .10   .] ;...
	JRST	CHKVS2		;NO
	CAMN	T3,[ASCII .  .]	;LAST WORD HAVE 2 BLANKS?
	POPJ	P,		;YES, SYSTEM TYPE IS VALID
CHKVS2:	AOS	(P)		;SET FOR SKIP RETURN
	CAMN	T1,[ASCII .     .] ;NULL SYSTEM TYPE?
	CAME	T2,[ASCII .     .] ;...
	JRST	CHKVS3		;NO
	CAMN	T3,[ASCII .  .]	;LAST WORD HAVE 2 BLANKS?
	SKIPA	T1,[[ASCIZ .unknown.]] ;GENERIC TEXT
CHKVS3:	MOVEI	T1,VSYBFR	;ADDRESS OF DECODED SYSTEM TYPE TEXT
	SETZ	T2,		;GET A ZERO
	IDPB	T2,P2		;TERMINATE SYSTEM TYPE AS ASCIZ
	POPJ	P,		;RETURN

;BUFFER TO EXTRACT SYSTEM TYPE FIELD FROM VOLUME ID BLOCK

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

VOLPTT:	POINT	7,0,17		;BYTE 0
	POINT	7,0,9		;BYTE 1
	POINT	7,0,35		;BYTE 2
	POINT	7,0,27		;BYTE 3
;SUBROUTINE TO WRITE REDUNDANT BLOCKS(HOM,BAT & RIB)
; ENTER WITH F = FILE DATA BLOCK ADR. U = UNIT DATA BLOCK ADR.
; P1 = ADR. OF BLOCK IN CORE. P4 = XWD 1ST. LOG. BLOCK #,2ND. LOG. BLOCK #
; RETURN WITH S = 0 IF NO ERRORS. OTHERWISE IT HAS STANDARD RH ERROR BITS SET
; T2=0 IF NO ERRORS, OTHERWISE RH=-1 IF ERROR ON 2ND. BLOCK & LH=-1 IF ON 1ST.

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

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

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

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


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


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

DEFINE	SUDEFS,<

	RADIX	10

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

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


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


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


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


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


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


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


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


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


; STARTING STRUCTURE NAME
DEFINE	X	(KON,BSA,BPC,GAR,OVR, K4C ,BCC, K4S ,MUS,NSB,SSN ),<EXP	<SIXBIT /SSN/>>
SSNDEF:	SUDEFS
	SUBTTL	MULTI-CPU I/O PROCESSING


IFN FTMP,<

; KDBS
CPUKDB:	MOVEM	T1,CPUACS+T1	;SAVE T1
	LDB	T1,TKYCPU##	;GET TARGET CPU NUMBER
	JRST	CPUXCT		;ENTER COMMON CODE


; UDBS
CPUUNI:	DMOVEM	T1,CPUACS+T1	;SAVE TEMPS
	DMOVEM	T3,CPUACS+T3	;...
	MOVE	T1,UNICAM##(U)	;GET TARGET CPU NUMBER
	PUSHJ	P,CAMCPU##	;DETERMINE CPU NUMBER TO USE
	MOVE	T1,.C0CPN##(T4)	;GET CPU NUMBER
	DMOVE	T2,CPUACS+T2	;GET TEMPS BACK
	MOVE	T4,CPUACS+T4	;...

CPUCPN:				;CPU NUMBER ALREADY IN T1

CPUXCT:	SKIPN	.UONCE##	;IF TWICE, NO OTHER CPU TO WORRY ABOUT
	CAMN	T1,.CPCPN##	;IS IT US?
	JRST	CPUXC4		;GO HANDLE REQUEST ON OUR CPU
	PUSH	P,T2		;SAVE T2 A SEC
	MOVEI	T2,1		;GET ASYNCH IO PENDING BIT FOR CPU0
	LSH	T2,(T1)		;POSITION IT FOR A TEST OF TARGET CPU
;THE PARANOID MIGHT WANT TO CPUTIM-OUT THIS LOOP...
	TDNE	T2,CPUASF	;SEE IF STILL PROCESSING A PREVIOUS COMMAND
	JRST	.-1		; ON THIS CPU.  WAIT TILL DONE IF SO.
	IORM	T2,CPUASF	;REMEMBER THAT IT IS NOW BUSY
	POP	P,T2		;RESTORE T2
	MOVEM	T1,CPUNUM	;SAVE TARGET CPU NUMBER
	SETZM	CPUFLG		;INITIALLY SET FAILURE FLAG
	MOVE	T1,CPUACS+T1	;RESET T1 SO BLT DOESN'T CLOBBER SAVED COPY
	MOVEM	0,CPUACS+0	;SAVE AC 0
	MOVE	0,[1,,CPUACS+1]	;SET UP BLT
	BLT	0,CPUACS+17	;SAVE THE ACS
	MOVE	0,CPUACS+0	;RELOAD AC 0
	XMOVEI	T1,@(P)		;GET ADDRESS OF SUBROUTINE
	MOVE	T2,CPUNUM	;GET TARGET CPU NUMBER
	MOVE	T3,@T1		;GET SUBROUTINE TO EXECUTE (WITH FLAGS)
	MOVEM	T3,CPUSUB	;SAVE IT'S ADDRESS
	POP	P,(P)		;PRUNE STACK
	MOVEM	P,CPUACS+P	;UPDATE PUSH DOWN LIST POINTER
	MOVE	T1,CPUTMS	;TIME TO WAIT FOR CPU TO START PROCESSING
	TLNE	T3,(XC.SHT)	;SHORT WAIT?
	LSH	T1,-2		;YES, WAIT ONE FOURTH OF THE USUAL TIME
	MOVE	P1,T2		;CPU INDEX
	LSH	P1,.CPSOF##	;POINT TO THE TARGET CPU'S CDB
	HLLOS	ONCCOM##	;MARK REQUEST QUEUED
CPUXC1:	SKIPE	CRSHWD##	;RELOADING SYSTEM BECAUSE OF STOPCD?
	PJRST	REBOOT##	;YES
	TRNN	T1,17		;EVERY 20 TIMES THROUGH THIS
	AOS	.C0OK##(P1)	;BUMP CPU'S OK WORD SO IT WILL WAKE UP
	SKIPE	ONCCOM##	;HAS THE OTHER CPU STARTED PROCESSING YET?
	SOJG	T1,CPUXC1	;NO--WAIT
	MOVE	T2,CPUSUB	;GET ADDRESS OF ROUTINE BEING CALLED
	TLNE	T2,(XC.ASY)	;WAS THIS AN ASYNCHRONOUS REQUEST?
	JRST	[JUMPN	T1,CPUXC3	;YES, JUMP IF CPU STARTED REQUEST
		 MOVE	T1,.C0CPN##(P1)	;ASYNCH REQUEST DIDN'T START, CPU #
		 PUSHJ	P,CPUDSB	;CLEAR I/O PENDING FOR NEXT REQUEST
		 JRST	CPUXC3]		;AND EXIT
	MOVE	P2,T1		;SYNCHRONOUS I/O, SAVE RESPONSE TIME
	MOVE	T1,.C0CPN##(P1)	;GET CPU NUMBER OF TARGET CPU
	PUSHJ	P,CPUDSB	;CLEAR I/O PENDING BIT
	JUMPE	P2,CPUXC3	;NO RESPONSE
	MOVE	T1,CPUTIM	;GET CPU HUNG TIMER
	MOVE	T2,CPUSUB	;GET FLAGS
	TLNE	T2,(XC.SHT)	;SHORT WAIT?
	LSH	T1,-2		;YES, WAIT ONE FOURTH OF THE USUAL TIME

CPUXC2:	SKIPE	CRSHWD##	;RELOADING SYSTEM BECAUSE OF STOPCD?
	PJRST	REBOOT##	;YES
	SKIPL	ONCCOM##	;REQUEST COMPLETED YET?
	SOJG	T1,CPUXC2	;NO--WAIT

CPUXC3:	SETZM	ONCCOM##	;TELL OTHER CPUS TO LOOP IN THE ACS
	MOVEM	P,CPUACS+P	;SO BLT DOESN'T WIPE P
	MOVSI	17,CPUACS	;SET UP BLT
	BLT	17,17		;RESTORE THE ACS
	SKIPE	CPUFLG		;SUCESS?
	AOS	(P)		;YES
	POPJ	P,		;PROPAGATE CPOPJ/CPOPJ1 BACK TO CALLER

CPUXC4:	XMOVEI	T1,@(P)		;GET ADDRESS OF SUBROUTINE
	MOVE	T1,@T1		;GET SUBROUTINE TO EXECUTE
	TLZ	T1,-1		;CLEAR FLAGS
	MOVEM	T1,CPUSUB	;SAVE IT'S ADDRESS
	POP	P,(P)		;TRIM STACK
	MOVE	T1,CPUACS+T1	;RELOAD T1
	PUSHJ	P,@CPUSUB	;DO CPU DEPENDANT STUFF
	  POPJ	P,		;FAILED
	JRST	CPOPJ1##	;RETURN
; STILL UNDER IFN FTMP

CPUDSP::MOVE	T1,.CPCPN##	;GET OUR CPU NUMBER
	CAME	T1,CPUNUM	;SANITY CHECK
	POPJ	P,		;REQUEST IS FOR SOMEONE ELSE
	MOVEM	P,CPUACS+P	;SO BLT DOESN'T WIPE P
	MOVSI	17,CPUACS	;SET UP BLT
	BLT	17,17		;LOAD OUR ACS
	PUSH	P,CPUSUB	;SAVE ROUTINE ADDRESS AND FLAGS
	SETZM	ONCCOM##	;START PROCESSING REQUEST
	EXCH	T1,(P)		;GET ROUTINE ADDRESS AND FLAGS
	TLNE	T1,(XC.ASY)	;SEE IF ASYNCHRNOUS IO
	JRST	CPUDSA		;IF SO, DO DIFFERENTLY
	TLZ	T1,-1		;CLEAR FLAGS
	EXCH	T1,(P)		;PUT ROUTINE ADDRESS BACK - WITHOUT FLAGS
	PUSHJ	P,@(P)		;DO SOMETHING
	  SKIPA			;FAILURE
	SETOM	CPUFLG		;INDICATE SUCESS
	ADJSP	P,-1		;TOSS ROUTINE ADDRESS
	MOVEM	0,CPUACS+0	;SAVE AC 0
	MOVE	0,[1,,CPUACS+1]	;SET UP BLT
	BLT	0,CPUACS+17	;SAVE THE UPDATED ACS
	SETOM	ONCCOM##	;REQUEST COMPLETED
	POPJ	P,		;RETURN

;HERE IF REQUEST IS ASYNCHRONOUS
CPUDSA:	TLZ	T1,-1		;CLEAR FLAGS
	EXCH	T1,(P)		;GET T1 BACK, SAVE ADDRESS WITHOUT FLAGS
	PUSHJ	P,@(P)		;DO WHATEVER WE DO
	  JFCL			;ASYNCHRONOUS I/O DOESN'T EXACTLY SKIP...
	ADJSP	P,-1		;CLEAN SUBROUTINE ADDRESS OFF STACK
	MOVE	T1,.CPCPN##	;NOR DOES IT RETURN ACS.  GET CPU NUMBER
CPUDSB:	MOVEI	T2,1		;GET ASYNCHRONOUS IO BUSY BIT FOR CPU 0
	LSH	T2,(T1)		;POSITION IT FOR THIS CPU
	ANDCAM	T2,CPUASF	;CLEAR IO IN PROGRESS BIT
	POPJ	P,		;RETURN
> ;END IFN FTMP
SUBTTL	CPU DEPENDANT ROUTINES


; CHECK ON/OFF-LINE STATUS OF A KONTROLLER
; CALL:	PUSHJ	P,CHKKON
;	  <NON-SKIP>		;OFF-LINE
;	<SKIP>			;ON-LINE, T1 ZERO IF WRITE-HEADER-LOCKOUT OFF
CHKKON:	PUSHJ	P,@KONUPA##(J)	;IS KONTROLLER UP?
	  POPJ	P,		;NO--DOWN
	JRST	CPOPJ1##	;RETURN


; SUBROUTINE TO CHECK WRITE-LOCKED STATUS OF A UNIT
; RETURNS CPOPJ1 IF WRITE-LOCKED.
;
CHKWLK:	LDB	P2,UNYKTP##	;GET KONTROLLER TYPE
	PUSHJ	P,@ONCHWP(P2)	;CHECK UNIT
	  POPJ	P,		;WRITE-ENABLED
	JRST	CPOPJ1##	;WRITE-LOCKED


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


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


; ROUTINE TO SEE IF THE NON-BOOT CPU(S) ARE ALIVE
; CALL:	PUSHJ	P,CHKCPU
;	  <NON-SKIP>		;NOT RUNNING
;	<SKIP>			;ALIVE AND KICKING
CHKCPU:	JRST	CPOPJ1##	;IF WE GET THIS FAR, IT MUST BE RUNNING
IFN FTCIDSK,<

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

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

RAXHWP:	SKIPE	.UONCE##	;IF USER MODE,
	POPJ	P,		;THEN SAY IT'S WRITE-ENABLED
	SETZM	ONLDON		;START AFRESH
	PUSHJ	P,SAVE4##	;SAVE SOME AC'S AGAINST CORRUPTION
	SE1ENT			;ENSURE WE RUN IN NZS
	HRRZ	P4,J		;GET KDB ADDRESS
	ADD	P4,.CPCPN##	;OFFSET BY OUR CPU NUMBER
	MOVE	P4,RAKCTI##(P4)	;GET THE CONNECT TABLE INDEX
	PUSHJ	P,MSCGBF##	;GET A BUFFER TO USE
	  POPJ	P,		;NONE AVAILABLE?
	LDB	T1,UNYPUN##	;GET THE UNIT NUMBER
	PUSHJ	P,MSCCUS##	;CHECK UNIT STATUS
	MOVSI	T1,3*ONCTIM##	;WAIT A WHILE
	SKIPN	ONLDON		;DID IT COMPLETE YET?
	SOJG	T1,.-1		;NO, WAIT A WHILE LONGER
	JUMPLE	T1,CPOPJ##	;IF IT FAILED, JUST ASSUME WRITE-ENABLE
	MOVE	T1,ONLFLG	;GET THE FLAGS
	TLNE	T1,(UF.WPS!UF.WPH) ;WRITE-PROTECT?
	AOS	(P)		;YES, SET FOR SKIP RETURN
	POPJ	P,		;RETURN

ONLDON::0			;SET NON-ZERO WHEN RAXKON GETS A RESPONSE TO
				; A SET UNIT ONLINE COMMAND TO THE HSC
ONLFLG::0			;FLAGS FROM LAST UNIT ONLINE COMMAND
>; END IFN FTCIDSK
UNITS:	BLOCK	1		;COUNTER LOCATION
MIN:	BLOCK	1
MAX:	BLOCK	1

TMPMIN:	BLOCK	1		;TEMPORARY STORAGE OF MIN
DATADR:	BLOCK	1
RWRFLG:	BLOCK	1
HOMFLG:	0
DOFLOK:	BLOCK	1		;DISK OFF-LINE OK
OPTQIK::BLOCK	1		;QUICK OPTION
ONCMBF::BLOCK	1		;ADDRESS OF MONITOR BUFFER FOR ONCE/TWICE
MONBUF:	BLOCK	200		;STORAGE FOR MONITOR BUFFER
SHUTUP::BLOCK	1		;NON-ZERO IF AVOIDING CTY CHATTER
KON:	BLOCK	1
OFFLOK::BLOCK	1		;DON'T TYPE OFF-LINE MSGS
ERROK::	BLOCK	1		;DON'T TYPE MESSAGES PRECEEDED BY %
ERRHOM:	0			;FLAG FOR ERRORS WHILE READING A "HOME" BLOCK
SERIUS:	0			;-1 WHEN IF START SYSTEM EVEN IF QUICK OPTION

IFN FTCIDSK,<
ONCDRB::BLOCK	15		;DRB FOR USE DURING ONCE
SIZDRB==:.-ONCDRB		;GET MULT DEFINED GLOBAL IF DIFFERS FROM COMMOD
>; END IFN FTCIDSK

IFN FTMP,<
CPUTMS:	XWD	3,0		;TIME TO WAIT FOR A CPU TO START PROCESSING
CPUTIM: XWD	<3*ONCTIM##>,0	;NORMAL HUNG CPU TIMER
CPUSUB::BLOCK	1		;ADDR OF SUBROUTINE TO EXECUTE
CPUNUM::BLOCK	1		;TARGET CPU NUMBER
CPUACS::BLOCK	20		;ACS
CPUFLG::BLOCK	1		;SUCESS/FAILURE FLAG
CPUASF:	EXP	0		;BIT MASK OF CPUS DOING ASYNCHRONOUS ONCE IO
> ;END IFN FTMP


XLIST
LIT
VAR
LIST

ONCMND:	END