Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99T-BB_1990 - 10,7/mon/sysini.mac
There are 13 other files named sysini.mac in the archive. Click here to see a list.
TITLE	SYSINI - SYSTEM INITIALIZATION AND ONCE-ONLY DIALOGUE - V2105
SUBTTL	JOSEPH A. DZIEDZIC /JAD		06-FEB-90

	SEARCH	F,S,DEVPRM,NETPRM,BTSPRM
	$RELOC
	$INIT

	.DIREC	FLBLST		;FOR CLEANER LISTINGS

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1969,1970,1971,1972,1973,1974,
; 1975,1976,1977,1978,1979,1980,1982,1984,1986,1988,1990.
;ALL RIGHTS RESERVED.

.CPYRT<1969,1990>

XP	VSYSII,2105		;MODULE VERSION NUMBER

	ENTRY	SYSINI		;SYSTEM INITIALIZATION ROUTINE


;THE MONITOR MODULES SYSINI AND ONCE WERE COMBINED INTO ONE MODULE NAMED
;"SYSINI" IN THE VERSION 7.04 MONITOR.  THE AUTHORS OF THOSE MODULES WERE:
;ONCE	- T. HASTINGS/CHW/RCC/AF/DAL
;SYSINI	- TH/RCC/TL/AF/PH/DAL/BGE/RLD/JBS


;NOTE THAT SYSINI MAY INCLUDE INITIALIZATION ROUTINES WHICH SHOULD NOT
;BE CALLED. THIS HAPPENS IF THE FEATURE TEST SWITCH FOR A FEATURE IS ON,
;BUT THE MODULE IS NOT LOADED BECAUSE OF THE ANSWER TO A MONGEN QUESTION.
;TO SOLVE THIS PROBLEM, COMMON DEFINES SYMBOLS =0 IF THE ROUTINE IS
;NOT TO BE CALLED, = NON-0 IF IT IS TO BE CALLED.


SAVITM=40			;SAVED DEVICE DISPATCH ADDRESS IN IOGO
	SUBTTL	SYSTEM DEBUGGING STARTUP

;CODE TO SET MONITOR FOR DEBUGGING SESSION WITH EXEC DDT
;MAKE STARTUP BE FAST
;SYSTEM PROGRAMMER TYPES DEBUG$G TO START MONITOR
;ALLOW SAME COPY OF MONITOR TO BE USED FOR REGULAR SYSTEM
;SIMPLY BY NOT STARTING AT DEBUG.

DEBUG::
IFN FTXMON,<XJRST [MCSEC0+.+1]>	;ALWAYS STARTUP IN SECTION ZERO
	MOVEI	T1,DDTEND##	;END OF DDT
	HRRM	T1,PATSIZ	;INCLUDE DDT IN SYSTEM SIZE

;PATCH DDTCPU WITH A JFCL TO BYPASS SMP DEBUGGING FEATURES

IFN FTMP,<
	MOVE	T1,BOOTCP##	;GET OUR CPU NUMBER
DDTCPU:	MOVEM	T1,DEBCPU##	;SAVE FOR DEBUGGING SMP
>; END IFN FTMP

	MOVSI	T1,(DF.SBD+DF.NAR) ;FLAG SYSTEM DEBUGGING IN PROGRESS,
				; DISABLE AUTOMATIC SYSTEM RELOAD
	IORM	T1,DEBUGF##	;FLAG DEBUGGING MODE
				; SO WHY RELOAD, LONG DIALOG
				; UNITS OFF-LINE NOT ASKED
				;ALSO, NOTICES 21 NON-ZERO
				;  RETURN IS BY GOBACK$G
	MOVEI	T1,ST.NRT	;TURN OFF REMOTE
	IORM	T1,STATES##	; TTY'S
	JRST	SYSINI		;START UP SYSTEM


;IF PATCHED WITH A SIXBIT STRUCTURE NAME, SAID STRUCTURE WILL BE STUFFED
;INTO THE SDL AND SSL, AND THE LOGICAL UNITID INTO THE ASL.  A MINUS ONE
;MEANS USE THE BOOTSTRAP STRUCTURE.
DDTDSK::EXP	0		;DEFAULT TO NORMAL ASL/SDL/SSL STUFF

;ROUTINE TO SEE IF MONITOR WILL RUN WITH EDDT

DDTCHK:	HRRZ	T1,PATSIZ	;GET START OF PATCH SPACE
	SKIPL	DEBUGF##	;DEBUGGING?
	CAIN	T1,DDTEND##	;KEEPING EDDT?
	JRST	DDTCH2		;YES
	SKIPA	T2,[-$NB##,,0]	;AOBJN POINTER TO DDT'S BREAKPOINTS
DDTCH1:	ADDI	T2,$2B##-$1B##-1 ;OFFSET TO NEXT BREAKPOINT
	SKIPG	$1B##(T2)	;THIS BREAKPOINT SET?
	AOBJN	T2,DDTCH1	;NO, CHECK THE REST
	JUMPGE	T2,CPOPJ##	;NORMAL STARTUP?
DDTCH2:	MOVEI	T1,DDTEND##	;FIX UP PATSIZ
	HRRM	T1,PATSIZ	;...
	JRST	CPOPJ1##	;INDICATE RUNNING WITH EDDT
	SUBTTL	PRIMARY SYSTEM INITIALIZATION

;SYSINI IS BRANCHED TO FROM SYSTRT (COMMON) OR DEBUG (SYSINI) TO
;BEGIN SYSTEM INITIALIZATION.  PAGING HAS BEEN TURNED ON.

SYSINI::CONO	APR,AP.IOR	;IO RESET
	MOVE	P,.CPNPD##	;SET UP A PDL FOR THIS
	SETZM	CLKDDT		;ZERO OUT LOCATIONS
	SETZM	CPNDDT		; WHICH MIGHT CAUSE
	SETZM	CRSHWD		; PROBLEMS DURING
	SETZM	SYSSNP		; INITIALIZATION OR LATER
	MOVE	T1,CRSDTM	;GET DATE/TIME OF LAST CRASH
	MOVEM	T1,CRSSAV	;SAVE FOR AVAIL.SYS

	MOVEI	F,CT.P6		;ASSUME A 166 (PDP-6) PROCESSOR
	JFCL	17,.+1		;CLEAR ALL FLAGS
	JRST	.+1		;SET PC CHANGE FLAG IF CPU IS A 166
	JFCL	1,CPU166	;BRANCH IF PDP-6
	SETZ	T1,		;THE TEST FOR A KL10 PROCESSOR
	BLT	T1,0		;IS A NO-OP BLKT LEAVING AC NON-ZERO
	JUMPE	T1,CPU166	;JUMP IF NOT KL OR KS
	MOVEI	P1,1
	SETZ	P2,		;BIG BINARY INTEGER
	MOVEI	P4,1		;ONE DIGIT BYTE
	EXTEND	P1,[CVTBDO]	;CONVERT WILL ABORT
	TLNN	P4,200000	;TEST EFFECT ON N
	JRST	CPKS10
;	JRST	CPKL10

CPKL10:	SKIPA	F,[CT.KL]	;SET TYPE AS KL10
CPKS10:	MOVEI	F,CT.KS		;SET TYPE AS KS
CPU166:	CAME	F,.CPTYP##	;DO WHAT THE MONITOR WAS BUILT FOR AND
				; THE CURRENT MACHINE AGREE?
	STOPCD	.,HALT,WCT	;++WRONG CPU TYPE
SYSIN1:
IFN FTKL10,<
	APRID	T1		;READ MISCELLANEOUS JUNK
	MOVEI	T2,^D60		;ASSUME NORTH AMERICAN LINE FREQUENCY
	TRNE	T1,ID.50H	;50 CYCLE DYNAMOS?
	MOVEI	T2,^D50		;YES
> ;END IFN FTKL10
IFN FTKS10,<
	MOVEI	T2,M.TPS##	;THERE'S GOT TO BE A BETTER WAY OF DOING THIS
> ;END IFN FTKS10
	MOVEM	T2,TICSEC##	;SAVE TICKS/SECOND FOR CLOCK1, GETTABS, ETC.
	MOVEM	T2,JIFSEC##+1	;SAVE IN DOUBLE-WORD FOR TIME ACCOUNTING
	MOVSI	T3,(ST.CYC)	;SET BIT SIX OF STATES IF 50 HZ POWER
	CAIN	T2,^D50		;50 HERTZ POWER?
	IORM	T3,STATES##	;YES
	IMULI	T2,^D60		;COMPUTE THE NUMBER OF TICKS PER MINUTE
	MOVEM	T2,TICMIN##	;SAVE FOR CURIOUS EYES
	IMULI	T2,^D60*^D24	;NUMBER OF TICS PER DAY
	MOVEM	T2,MIDNIT##	;SAVE THAT FOR MIDNIGHT CHECKING
IFN FTKL10,<
	DMOVE	T2,[M.EBPS##	;ASSUME A MODEL A PROCESSOR
		M.MBPS##]
	TRNE	T1,ID.XKL	;IS IT A MODEL B PROCESSOR?
	DMOVE	T2,[^D30*M.EBPS##/^D25 ;YES, USE DIFFERENT EBOX/MBOX CALABRATION CONSTANTS
		^D30*M.MBPS##/^D25]
	MOVEM	T2,.CPEBS##	;STORE AS EBOX TICS/SEC
	MOVEM	T3,.CPMBS##	;STORE AS MBOX TICS/SEC
	IDIV	T2,TICSEC##	;AND NOW GET EBOX COUNTS/JIFFY
	IMULI	T2,.EBCPT	;MULITPLY BY EBOX COUNTS/TICK
	MOVEM	T2,.CPEBJ##	;STORE IN CDB VARIABLE
	MOVE	T2,.CPMBS##	;GET MBOX TICKS/SECOND
	IDIV	T2,TICSEC##	;GET MBOX COUNTS/JIFFY
	IMULI	T2,.MBCPT	;MULTIPLY BY MBOX COUNTS/TICK
	MOVEM	T2,.CPMBJ##	;SAVE
>;END IFN FTKL10

IFN FTMP,<
	MOVEI	T1,M.CPU##	;SETUP COUNTER
SYSIN2:	MOVNI	T2,(T1)		;MINUS CPU NUMBER
	IMUL	T2,TICSEC##	;COMPUTE INITIAL OK WORD
	MOVEM	T2,COKTAB##-1(T1) ;STORE AWAY
	SOJG	T1,SYSIN2	;FILL THE TABLE
> ;END IFN FTMP
IFN FTKL10,<
	MOVE	T1,.CPCPN##	;FOR THIS CPU
	PUSHJ	P,DTEINI##	;INITIALIZE DTE'S EARLY
	PUSHJ	P,ENTSPC##	;START SECONDARY PROTOCOL ON MASTER DTE
>; END IFN FTKL10
IFN FTKS10,<
	PUSHJ	P,DISKAL##	;DISABLE KEEP-ALIVE COUNTING
	SETZM	CTYIWD		;ZERO OUT 8080 COMMS WORDS
	MOVE	T1,[CTYIWD,,CTYIWD+1]
	BLT	T1,KLIOWD
>; END IFN FTKS10
IFN FTMP,<
	PUSHJ	P,BCOM0##	;ESTABLISH CPU 0
>; END IFN FTMP

	MOVE	T1,[<PM.DCD>B2+PM.WRT+PM.PUB+NUPMPP##] ;SET UP NULL JOB MAPPING
	MOVEM	T1,NLUPMP##+.UMUPT ; FOR UPT
	MOVEM	T1,NLUPMP##+.UMUPM ; FOR S0 MAP
	MOVEM	T1,NLUPMP##+.UMUUP ; FOR CACHED UPMP REFERENCES
	MOVEM	T1,NLUPMP##+.UMJDT ; FOR .JDAT REFERENCES
	CLRPGT			;MAKE SURE CHANGES IN MAPPING ARE VISIBLE

	PUSHJ	P,BOOTNX	;COPY BOOTSTRAP NXMTAB
	PUSHJ	P,BOOTSZ	;FIXUP SYSORG TO ACCOUNT FOR UNMAPPED BOOTSTRAP
	PUSHJ	P,BOOTFX	;FIND OUT WHERE THE MONITOR WAS READ FROM
IFN FTXMON,<PUSHJ P,BOOTMP>	;MAP BOOT INTO THE MONITOR'S ADDRESS SPACE
	PUSHJ	P,PATFIX	;FIXUP "PAT" GLOBAL BEFORE MOVING SYMBOL TABLE
	SUBTTL	MOVE MONITOR PSECTS TO FINAL RESTING PLACES

;THE ORDER IN WHICH THE VARIOUS PIECES OF THE MONITOR ARE MOVED AROUND
;IS VERY IMPORTANT DUE TO THE ORDERING OF THE PSECTS IN THE .EXE FILE.
;DON'T CHANGE THIS ORDER UNLESS YOU KNOW WHAT YOU ARE DOING, AND THEN
;BE SMART AND DON'T CHANGE THE ORDER ANYWAY.
;
;FOR NON-EXTENDED MONITOR:  MOVE HIGH SEGMENT AND THEN SYMBOL TABLE.
;
;FOR EXTENDED MONITOR:  MOVE EXTENDED HIGH SEGMENT, EXTENDED SYMBOL TABLE,
;HIGH SEGMENT, AND THEN COMMON SUBROUTINES PSECT.

;FIRST SETUP MONVFF, SYSLEN, AND CSBLEN (IFN FTXMON)

SETLEN:	MOVE	T1,MONEND##	;GET LAST ADDRESS IN HIGH SEGMENT
	SUBI	T1,MONORG##-1	;SUBTRACT ORIGIN OF HIGH SEGMENT
	TRZE	T1,PG.BDY	;ROUND UP
	ADDI	T1,PAGSIZ	;LENGTH OF THE HIGH SEGMENT IN WORDS
	MOVEM	T1,SYSLEN##	;STORE THE LENGTH OF THE HIGH SEGMENT
	ADDI	T1,MONORG##	;ADD IN START OF HIGH SEGMENT
	MOVEM	T1,MONVFF##	;SET UP HONORABLE (BUT NO LONGER USED) VARIABLE
	MOVEI	T1,HLCSAD##	;HIGHEST LEGAL ADDRESS IN HIGH SEGMENT
	SUB	T1,MONVFF##	;SUBTRACT FIRST ADDRESS FOLLOWING HIGH SEGMENT
	ASH	T1,W2PLSH	;CONVERT TO A NUMBER OF PAGES
	JUMPLE	T1,SETLN1	;QUIT IF NOTHING TO ZERO
	MOVEI	T2,<HLCSAD##/PAGSIZ>-1 ;LAST PAGE TO CLEAR MAPPING FOR
	ADD	T2,.CPMAP##	;ADD IN ADDRESS OF SECTION 0/1 MAP
	SETZM	(T2)		;CLEAR AN ENTRY IN THE MAP
	SOSLE	T1		;QUIT WHEN COUNT EXHAUSTED
	SOJA	T2,.-2		;LOOP FOR ALL MAP SLOTS TO CLEAR
SETLN1:
IFN FTXMON,<
	MOVE	T1,CSBEND##	;GET LAST ADDRESS IN COMMON SUBS PSECT
	SUBI	T1,CSBORG##-1	;SUBTRACT ORIGIN OF COMMON SUBS PSECT
	TRZE	T1,PG.BDY	;ROUND UP
	ADDI	T1,PAGSIZ	;LENGTH OF THE COMMON SUBS PSECT IN WORDS
	MOVEM	T1,CSBLEN##	;STORE THE LENGTH OF THE COMMON SUBS PSECT
	SUBI	T1,<MONORG##-CSBORG##> ;CALCULATE NUMBER OF WORDS NOT IN CSUB
	JUMPGE	T1,SETLN2	;JUMP IF NO LEFT OVER WORDS
	ASH	T1,W2PLSH	;CONVERT TO NUMBER OF PAGES TO CLEAR
	MOVEI	T2,<MONORG##/PAGSIZ>-1 ;LAST PAGE TO CLEAR MAPPING FOR
	ADD	T2,.CPMAP##	;ADD IN ADDRESS OF SECTION 0/1 MAP
	SETZM	(T2)		;CLEAR AN ENTRY IN THE MAP
	AOSGE	T1		;QUIT WHEN COUNT EXHAUSTED
	SOJA	T2,.-2		;LOOP FOR ALL MAP SLOTS TO CLEAR
SETLN2:
>; END IFN FTXMON
;MOVE EXTENDED HIGH SEGMENT

IFN FTXMON,<
MOVXHI:	MOVE	T1,[XHIORG##]	;WHERE EXTENDED HIGH SEGMENT STARTS
	MOVE	T2,XHIEND##	;WHERE IT ENDS
	CAMLE	T1,T2		;IS THERE ANY CODE TO MOVE?
	JRST	MOVXH1		;NO, SKIP OVER SOME CODE
	PUSHJ	P,MOVPSE	;MOVE THE PSECT TO IT'S FINAL RESTING PLACE
IFN FTKL10,<
	MOVE	T1,.CPEPT##	;GET ADDRESS OF THIS CPU'S EPT
	MOVSI	T2,(PM.KPM)	;"KEEP ME" BIT
	SKIPE	.CPKPM##	;IF CPU HAS AN MCA25,
	IORM	T2,<SECTAB+<(MS.HGH)>>(T1) ; LIGHT THE BIT IN XHIGH SEC PTR
>; END IFN FTKL10
MOVXH1:

MOVXST:	PUSHJ	P,SYTBFX	;MOVE SYMBOL TABLE TO SECTION 35
;STILL IN IFN FTXMON

;MAP EXTENDED LOW SEGMENT 1:1 VIA INDIRECT POINTERS TO SECTION 0/1 MAP

MAPXLS:	MOVE	T3,.CPEPT##	;THIS CPU'S EPT
	MOVE	T1,<SECTAB+(MS.HGH)>(T3) ;SECTION POINTER FOR EXTENDED HIGH SEG MAP
	MOVE	T3,.CPMAP##	;THIS CPU'S MAP
	MOVEM	T1,.ECKSM/PAGSIZ(T3) ;TO MAKE THE MAP ADDRESSABLE
	CLRPT	.ECKSM		;MAKE NEW MAPPING VISIBLE
	MOVEI	T1,(<PM.ICD>B2+PM.WRT+PM.PUB+PM.CSH+PM.KPM+PM.SWB)
				; INDIRECT POINTERS TO SECTION 0 MAP
	HRLI	T1,SPTLOW##-SPTTAB## ;SPT SLOT USED FOR MAPPING EXTENDED HIGH SEGMENT
	MOVS	T2,.CPCPN##	;OUR CPU NUMBER
	ADD 	T1,T2		;ADD THAT TO THE SPT INDEX
	MOVEI	T2,0		;STARTING AT PAGE 0
MAPXL1:	SKIPE	(T3)		;IF THE PAGE EXISTS IN THE SECTION 0 MAP,
	MOVSM	T1,.ECKSM(T2)	;POINT AT IT IN THE EXTENDED HIGH SEG MAP
	ADDI	T1,1		;NEXT PAGE
	ADDI	T3,1		; ..
	CAIGE	T2,CSBORG##/PAGSIZ-1 ;UP TO COMMON SUBROUTINES ORIGIN?
	AOJA	T2,MAPXL1	;NO, DO THE NEXT PAGE
	TRZ	T1,(PM.SWB)	;WRITE LOCKED FROM HERE ON OUT
	ADDI	T2,1		;ACCOUNT FOR MISSING AOS AT END OF LOOP ABOVE
	MOVE	T4,CSBEND##	;GET END OF COMMON SUBROUTINES ENTRY
	LSH	T4,W2PLSH	;CONVERT TO HIGHEST PAGE TO MAP
MAPXL2:	MOVSM	T1,.ECKSM(T2)	;POINT AT IT IN THE EXTENDED HIGH SEG MAP
	ADDI	T1,1		;NEXT PAGE
	CAMGE	T2,T4		;THROUGH THE END OF THE COMMON SUBROUTINES?
	AOJA	T2,MAPXL2	;NO, DO THE NEXT PAGE
	ADDI	T2,1		;ACCOUNT FOR MISSING AOS AT END OF LOOP ABOVE
	MOVEI	T1,<XHIORG##&777777> ;IN-SECTION ORIGIN OF EXTENDED HIGH SEG
	MOVEI	T3,CSBORG##	;ORIGIN OF COMMON SUBROUTINES
	ADD	T3,CSBLEN##	;PLUS LENGTH
	SUB	T1,T3		;CALCULATE NUMBER OF PAGES TO ZERO MAPPING FOR
	ASH	T1,W2PLSH
	JUMPLE	T1,MAPXL3	;GO IF SOMETHING FUNNY HAPPENED
	SETZM	.ECKSM(T2)	;ZERO A WORD
	SOSLE	T1		;DECREMENT COUNT, SKIP WHEN DONE
	AOJA	T2,.-2		;LOOP FOR ALL
MAPXL3:	MOVE	T1,.CPMAP##	;NOW SETUP SKIP CPU MAPPING
	MOVE	T1,.EVCDB##/PAGSIZ(T1) ;GET MAPPING FOR FIRST CDB PAGE
	TLO	T1,(PM.SWB)	;WRITE ENABLE
	MOVSI	T2,-CDBPGS##	;NUMBER OF CDB PAGES TO MAP
	MOVEM	T1,.ECKSM+.EVCDB##/PAGSIZ(T2) ;STORE IN XHIGH SEG MAP
	AOBJP	T2,.+2		;LOOP FOR ALL PAGES
	AOJA	T1,.-2		;...
>; END IFN FTXMON
;MOVE .INIT. PSECT (BY HAND - SIGH)

MOVINI:	MOVE	P1,.CPMAP##	;GET ADDRESS OF S0/S1 MAP
	MOVEI	P2,.UPMAP-PAGSIZ ;LAST PAGE IN FUNNY SPACE AREA TO MOVE
	MOVEI	P3,<.UPMAP-PAGSIZ>/PAGSIZ ;INDEX INTO NULL JOB'S PAGE MAP
MOVI.1:	PUSHJ	P,GTPHPG	;GET A PHYSICAL PAGE
	HRLI	T1,(<PM.DCD>B2+PM.WRT) ;ACCESSIBLE AND WRITABLE
	MOVEM	T1,.ECKSM/PAGSIZ(P1) ;VIA ADDRESS .ECKSM
	CLRPT	.ECKSM		;MAKE NEW MAPPING VISIBLE
	MOVS	T2,P2		;COPY SOURCE ADDRESS
	HRRI	T2,.ECKSM	;DESTINATION ADDRESS
	BLT	T2,.ECKSM+PG.BDY ;TRANSFER THE PAGE
	HRRM	T1,NLUPMP##(P3)	;STORE NEW MAPPING
	SUBI	P2,PAGSIZ	;BACK OFF BY ONE PAGE
	CAIL	P2,FYSORG	;DONE THEM ALL?
	SOJA	P3,MOVI.1	;NO, LOOP
	CLRPGT			;MAKE NEW FUNNY SPACE MAPPING VISIBLE

;MOVE HIGH SEGMENT

MOVHGH:	MOVEI	T1,MONORG##	;ORIGIN OF PSECT
	MOVE	T2,MONEND##	;END OF PSECT
	PUSHJ	P,MOVPSE	;MOVE THE PSECT TO IT'S FINAL RESTING PLACE

;MOVE COMMON SUBROUTINES PSECT

IFN FTXMON,<
MOVCSB:	MOVEI	T1,CSBORG##	;GET START OF PSECT
	MOVE	T2,CSBEND##	;GET END OF COMMON SUBROUTINES SEGMENT
	PUSHJ	P,MOVPSE	;MOVE THE PSECT TO IT'S FINAL RESTING PLACE
>; END IFN FTXMON

;FINISH UP WITH LOOSE ENDS

IFE FTXMON,<PUSHJ P,SYTBFX>	;FIXUP SYSORG TO ACCOUNT FOR HIDDEN SYMBOL
				; TABLE, MOVE SYMBOL TABLE TO HIGH MEMORY
IFN FTXMON,<PUSHJ P,SETEDV##>	;SET UP EXEC DATA VECTOR
IFE FTXMON,<PUSHJ P,BOOTMP>	;MAP BOOT INTO THE MONITOR'S ADDRESS SPACE

	PUSHJ	P,BSTRNG	;BUILD BOOTS COMMAND FOR AUTO-RELOAD

IFN FTKL10,<PUSHJ P,CLRSBD##>	;CLEAN MEMORY CONTROLLERS

IFN FTXMON,<XJRST [MCSEC1+HIGHIN]> ;GET INTO SECTION 1 SO CAN LOOK AT THINGS
HIGHIN:
IFN FTXMON,<XJRST [MCSEC0+.+1]>	;RETURN TO SECTION 0
	SUBTTL	INITIALIZE TABLE OF LOWER CORE FOUR WORD BLOCKS FOR I/O

IFN FTKL10,<
SETLOW:	MOVE	T1,LOWPTR##	;ABOJN POINTER TO LOWTAB
	SETOM	(T1)		;SET IT TO ALL ONES
	AOBJN	T1,.-1		; ..
	MOVEI	P1,LTINIT##	;ADDRESS OF TABLE CONTAINING ADDRESSES OF
				;  LOWER CORE FOUR WORD BLOCKS
	HRRZ	P2,LTINIT##	;ADDRESS OF FIRST FOUR WORD BLOCK
	MOVEM	P2,LOWLOC##	;STORE THAT AS ORIGIN OF FOUR WORD IOWD SPACE
SETLO1:	SKIPN	T2,(P1)		;NEXT CHUNK OF FOUR WORD SPACE
	JRST	SETLO2		;ALL DONE
	HLRZ	T1,(P1)		;NUMBER OF FOUR WORD BLOCKS IN THIS CHUNK
	HRRZS	T2		;0,,STARTING ADDRESS OF THIS CHUNK
	SUBI	T2,(P2)		;RELATIVE ADDRESS WITHIN IOWD SPACE
	LSH	T2,-2		;FOUR WORDS PER BLOCK
	IDIVI	T2,^D36		;NUMBER OF BITS REPRESENTING FOUR WORD BLOCKS
	HRLS	T2		;WHERE THEY START IN THE TABLE
	ADD	T2,LOWPTR##	;MAKE AN AOBJN POINTER TO THE TABLE
	PUSHJ	P,SETZRS##	;INDICATE THAT THOSE BLOCKS ARE AVAILABLE
	AOJA	P1,SETLO1	;LOOP UNTIL ALL CHUNKS ARE MARKED IN BIT TABLE
SETLO2:	MOVEI	T1,<<.LMMBL-.LMEBH>+3>/4 ;# OF 4-WORDS BLOCKS (= # OF BITS)
	MOVEI	T2,.LMEBH	;START OF EBOX/MBOX COUNTS IN UPT
	PUSHJ	P,MRKIOW	;MARK THE IOWD(S) IN USE
	MOVEI	T1,<<.EPPAC+1-.EPTMB>+3>/4 ;# 4-WORD BLOCKS (= # BITS)
	MOVEI	T2,.EPTMB	;START OF TIME BASE/PERF COUNT IN EPT
	PUSHJ	P,MRKIOW	;MARK THE IOWD(S) IN USE
>; END IFN FTKL10
	SUBTTL	ALLOCATE SECTION MAPS AND SCA FREE POOL

	SETOM	DINITF##	;TELL AUTCON WHAT KIND OF CORE TO GET
IFN FTXMON,<
	MOVSI	T1,(MS.MEM)	;DATA SECTION FOR PAGTAB/MEMTAB
	PUSHJ	P,ALCSMP	;ALLOCATE A SECTION MAP FOR SECTION 3
	MOVSI	T1,(MS.SCN)	;DATA SECTION FOR SCNSER DATA BASE
	PUSHJ	P,ALCSMP	;ALLOCATE A SECTION MAP FOR SECTION 4
	MOVSI	T1,(MS.SAT)	;DATA SECTION FOR SATS, ETC.
	PUSHJ	P,ALCSMP	;ALLOCATE A MAP FOR THIS SECTION
>; END IFN FTXMON
	SUBTTL	SET UP SPT AND SECTION MAP MAPPINGS

SETSPT:	MOVEI	T1,NUPMPP##	;PAGE NUMBER OF NULL JOB'S UPT
	MOVNI	T2,M.CPU##	;NUMBER OF CPUS
	MOVEI	T3,.E0MAP##/PAGSIZ ;PAGE NUMBER OF CPU0'S MAP

SETSP1:	MOVEM	T1,JBTUPM##(T2)	;SETUP CONTEXT SLOTS IN THE SPT
	MOVEM	T3,SPTLOW##+M.CPU##(T2) ;SPT ENTRIES FOR EXTENDED HIGH SECTION
	ADDI	T3,EPTDIF##/PAGSIZ ;NEXT MAP
	AOJL	T2,SETSP1	;LOOP FOR ALL CPUS
	MOVEM	T1,JBTUPM##+0	;AND JBTUPM FOR THE NULL JOB

IFN FTXMON,<
	MOVSI	T1,-<MXSECN-<(MS.FMD)>> ;-VE NUMBER OF SPTCOM SLOTS
	MOVE	T3,.CPEPT##	;ADDR OF OUR MAPPING PAGE
SETSP2:	SKIPN	T2,SECTAB+<(MS.FMD)>(T3) ;GET COMMON DATA SECTION MAP PAGE
	MOVSI	T2,1		;MAKE ILLEGAL POINTER IF NOT ASSIGNED
	MOVEM	T2,SPTCOM##(T1)	;STORE FOR SPYING USERS
	AOS	T3		;ADVANCE SECTION POINTER INDEX
	AOBJN	T1,SETSP2	;LOOP OVER ALL SUCH SLOTS

	MOVSI	T1,-<(MS.FMD)>-1 ;AOBJN POINTER TO HARDWIRED SECTION MAPS
SETSP3:	HRRZ	T2,T1		;GET SECTION NUMBER
	ADD	T2,.CPEPT##	;PLUS THE EPT ADDRESS
	MOVE	T2,SECTAB(T2)	;FETCH SECTION MAP POINTER
	MOVEM	T2,.CPMMA##(T1)	;MAKE ADDRESSABLE IN SECTION 37
	AOBJN	T1,SETSP3	;LOOP FOR ALL HARDWIRED SECTIONS
>; END IFN FTXMON
	SUBTTL	INITIALIZE CORE ALLOCATION AND PRINT SYSTEM NAME

	MOVE	T1,[NZSFCH##,,NZSFCE##]	;SET UP END TABLE FOR ALLOCATION
	BLT	T1,NZSFCE##+NZSFCL##-1 ;COPY THE HEAD TABLE OVER
	PUSHJ	P,PATSIZ	;SET UP SYSSIZ, CHECK FOR B.P.'S AND NO EDDT
	MOVE	T1,ANFNUM##	;GET CENTRAL SITE STATION NUMBER
	MOVEM	T1,JBTLOC##	;AND SAVE IN JOB LOCATION TABLE
	PUSHJ	P,AUTINI##	;INITIALIZE AUTCON
	CONO	PI,PI.CPI	;CLEAR PI SYSTEM
IFN FTKS10,<PUSHJ P,UBAPIS##>	;ASSIGN PIS TO UNIBUS ADAPTERS
	PUSHJ	P,ONCINT	;START INTERVAL TIMER GIVING CLOCK TICKS
				; FOR ONCE, SET UP ONCKLT SO APRINT AND
				; OPRFIL CAN USE IT TO START UP TIMER AGAIN.

	PUSHJ	P,OTSET		;INITIALIZE OUTPUT BUFFER
	PUSHJ	P,CRLF##	;TYPE CR-LF
	MOVEI	T1,CONFIG##	;POINT AT SYSTEM NAME
	PUSHJ	P,CONMES##	;TYPE IT
	PUSHJ	P,PRSPC##	;SPACE OVER
	MOVEI	T1,SYSDAT##	;POINT AT SYSTEM CREATION DATE
	PUSHJ	P,CONMES##	;TYPE IT
	PUSHJ	P,CRLFOP	;ADD CRLF AND PUSH IT OUT
	SUBTTL	CHECK FOR FULL AMOUNT OF MEMORY ONLINE

CHKMEM:	MOVSI	T1,-NXMTBL##	;AOBJN POINTER
	MOVEI	R,NXMTAB##	;TABLE ADDRESS
	PUSHJ	P,SATCN##	;COUNT UP THE ZERO BITS
	LSH	T2,P2WLSH	;CONVERT TO WORDS
	SKIPL	DEBUGF##	;DEBUGGING?
	CAML	T2,NWCORE##	;OR AT LEAST AS MUCH AS SPECIFIED BY MONGEN?
	JRST	SYSLIM		;YES--SKIP MEMORY CHECK
	TDZA	P2,P2		;FLAG FIRST TIME WE ASKED
CHKME1:	TLO	P2,400000	;FOR CALLS TO A SUBROUTINE IN SYSINI
	SETZB	U,P4		;INITIALIZE HIGHEST LOC TO ZERO
	MOVEI	P1,CORBLK##	;MAXIMUM PAGES OF PHYSICAL MEMORY POSSIBLE

CHKME2:	CONO	APR,AP.NXE##	;CLEAR NXM FLAG

CHKME3:	ADDI	U,PAGSIZ	;TRY NEXT PAGE
	SETZ	T2,		;CLEAR FLAGS
	PUSHJ	P,REFMEM##	;REFERENCE C(U)
	CONSZ	APR,AP.NXM##	;NON-EXISTANT?
	SKIPA			;NXM
	SOJG	P1,CHKME3	;KEEP LOOKING AS LONG AS NOT TOP OF MEMORY
	SKIPN	P4		;FIRST TIME THROUGH?
	MOVE	P4,U		;YES, REMEMBER LOCATION OF LOWEST NON-EX MEM
	SOJL	P1,CHKME5	;ACCOUNT FOR MISSED SOJ AND SEE IF FINISHED
	MOVE	P3,U		;NOW SEE IF ANY MEMORY EXISTS HIGHER UP

CHKME4:	CONO	APR,AP.NXE##	;CLEAR NXM FLAG
	ADDI	P3,PAGSIZ	;TRY NEXT PAGE
	PUSH	P,U		;SAVE U
	MOVE	U,P3		;SET ARG FOR REFMEM
	PUSHJ	P,REFMEM##	;REFERENCE IT
	POP	P,U		;RESTORE U
	CONSZ	APR,AP.NXM##	;IS IT THERE?
	SOJG	P1,CHKME4	;NO, LOOP THROUGH ALL GEN'D MEMORY
	SOJLE	P1,CHKME5	;JUMP IF NO MORE EXISTANT MEMORY
	PUSHJ	P,MEMBAD	;TELL THE OPERATOR HE HAS HOLES IN MEMORY
	  JRST	CHKME1		;HE SAID HE FIXED IT. GO SEE IF HE DID.
	  JFCL			;OFF-LINE
	MOVE	U,P3		;HE SAID ITS BROKEN
	JRST	CHKME2		;GO SEE IF THERE ARE ANY MORE HOLES
CHKME5:	SKIPL	DEBUGF##	;DEBUGGING? (ALREADY REPORTED HOLES)
	CAML	U,NWCORE##	;AS MUCH MEMORY AS SPECIFIED BY MONGEN?
	JRST	CHKME6		;THERE IS SO NO REASON TO COMPLAIN
	MOVE	P3,NWCORE##	;REMIND HIM OF HOW MUCH MONGEN'ED MEMORY
	PUSHJ	P,MEMBAD	;TELL THE OPERATOR THERE'S NOT THAT MUCH THERE
	  JRST	CHKME1		;OPR SAID FIXED, SEE IF HE REALLY DID
	  MOVEM	U,NWCORE##	;OPR SAID DOWN, NO EXTRA CORE FOR PAGTAB, ETC.

;BRING SYSTEM UP WITHOUT ALL OF MEMORY ONLINE
CHKME6:	SKIPE	P2		;IF WE COMPLAINED,
	PUSHJ	P,SUNXMT	; MUST SET NXMTAB UP AGAIN
	SUBTTL	INITIALIZE NXMPTR AND CORE ALLOCATION VARIABLES

;SET UP BYTE POINTER TO NXMTAB AND CORE ALLOCATION VARIABLES

SYSLIM:	MOVEI	T1,CORBLK##	;MAXIMUM # OF PAGES OF MEMORY POSSIBLE
	MOVEI	F,PAGSIZ	;CORE SIZE INCREMENT
	SETZB	U,P1		;CLEAR AMOUNT OF CONTIGUOUS MEMORY DETECTED
				; AND MAXIMUM SIZE OF SINGLE USER
	MOVE	P3,[POINT 1,NXMTAB##] ;GET BYTE POINTER TO NXMTAB
SYSLM1:	ILDB	T4,P3		;GET BYTE FROM NXMTAB
	CAML	U,SYSSIZ##	;STILL IN MONITOR (FIRST LOC NOT USED BY MON)?
	SKIPE	T4		;NO, IS THIS PAGE NON-EXISTANT?
	JRST	SYSLM2		;NOT PAST END OF MONITOR OR NON-EXISTANT PAGE
	MOVEM	U,MEMSIZ##	;SET SIZE OF PHYSICAL MEMORY EVEN HIGHER
	HRRZ	T3,CORLIM##	;MAXIMUM CORE AVAILABLE TO A SINGLE USER.
				; DEFINED BY MONGEN, MODIFIED BY ONCE
	CAMGE	P1,T3		;REACHED MAX YET FOR SINGLE USER?
	ADDM	F,CORMAX##	;NO, INCREASE MAX SIZE CORE AVAIL. TO A USER
	ADDM	F,MAXMAX##	;INCREMENT HIGHEST LEGAL CORMAX
	ADDM	F,RMCMAX##	;REAL MAXIMUM LEGAL CORMAX
	AOS	P1,CORTAL##	;INCREMENT NO. OF FREE 1K BLOCKS
SYSLM2:	ADD	U,F		;INCREMENT MEMORY REF
	SOJG	T1,SYSLM1	;CHECKED EVERY POSSIBLE PAGE YET?
	ADDM	F,MEMSIZ##	;SET SIZE OF PHYSICAL MEMORY SO EQUAL
				; TO THE FIRST NON-EX MEM ADR
	MOVE	T1,MEMSIZ##	;SIZE OF MEMORY =
	LSH	T1,W2PLSH	;PAGE NUMBER OF HIGHEST EXISTANT PAGE
	TRZE	T1,PG.BDY	;ROUND UP TO 256K BOUNDARY
	ADDI	T1,PP256K##
	IDIVI	T1,^D36
	MOVNI	T1,1(T1)	;NUMBER OF WORDS IN NXMTAB
	HRLI	T1,NXMTAB##	;FORM AN AOBJN POINTER
	MOVSM	T1,NXMPTR##	;STORE IT FOR DAEMON AND MONBTS
	SUBTTL	ALLOCATE MEMORY MANAGEMENT TABLES

MMTALC:	MOVE	T1,MEMSIZ##	;HIGHEST ADDRESS + 1
	CAMGE	T1,NWCORE##	;GREATER THAN HIGHEST ADDRESS SYSTEM WAS MONGENED FOR?
	MOVE	T1,NWCORE##	;NO, USE THAT TO SETUP PAGTAB AND MEMTAB
	MOVEM	T1,NWCORE##	;SAVE LARGER AS MAX CORE WHICH CAN BE SET ON LINE

	MOVS	T1,NWCORE##	;GET AMOUNT OF MEMORY SYSTEM WILL SUPPORT
	TLZE	T1,-1		;CHECK IF EXACTLY A MULTIPLE OF 256K
	ADDI	T1,1		;NO, 1 MORE PAGE REQUIRED FOR PAGTAB
	LSH	T1,P2WLSH	;NUMBER OF WORDS FOR EACH OF PAGTAB AND MEMTAB
	MOVEM	T1,MMTSIZ	;SAVE SIZE OF MEMORY MANAGEMENT TABLES
IFE FTXMON,<
	PUSH	P,MONVFF##	;SAVE HIGHEST VIRTUAL ADDRESS USED
	MOVEI	T2,PAGTAB	;VIRTUAL ADDRESS TO ALLOCATE AT
	MOVEM	T2,MONVFF##	;MAP PAGES TO PAGTAB
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.SWB) ;PAGE MAP BITS
	SKIPN	[M.CPU##-1]	;ONLY ONE CPU?
	TLO	T2,(PM.CSH)	;YES, MAKE IT CACHED
	PUSHJ	P,ONCMAR	;ALLOCATE AND MAP IN PAGTAB
	MOVE	T1,MMTSIZ	;NUMBER OF WORDS REQUIRED
	MOVEI	T2,PT2TAB	;VIRTUAL ADDRESS TO ALLOCATE AT
	MOVEM	T2,MONVFF##	;MAP PAGES TO PT2TAB
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.SWB) ;PAGE MAP BITS
	SKIPN	[M.CPU##-1]	;ONLY ONE CPU?
	TLO	T2,(PM.CSH)	;YES, MAKE IT CACHED
	PUSHJ	P,ONCMAR	;ALLOCATE AND MAP IN PAGTAB
	MOVE	T1,MMTSIZ	;NUMBER OF WORDS REQUIRED
	MOVEI	T2,MEMTAB	;VIRTUAL ADDRESS TO ALLOCATE AT
	MOVEM	T2,MONVFF##	;MAP PAGES TO MEMTAB
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.SWB) ;PAGE MAP BITS
	SKIPN	[M.CPU##-1]	;ONLY ONE CPU?
	TLO	T2,(PM.CSH)	;YES, MAKE IT CACHED
	PUSHJ	P,ONCMAR	;ALLOCATE AND MAP IN MEMTAB
	POP	P,MONVFF##	;PUT THINGS BACK
>
IFN FTXMON,<
	XJRST	[MCSEC1+.+1]	;ENTER SECTION ONE
	MOVE	T1,[EXP MS.MEM+PAGTAB] ;EXTENDED VIRTUAL ADDRESS OF PAGTAB
	MOVE	T2,T1		;COPY IT
	ADD	T2,MMTSIZ	;CALCULATE FIRST FREE FOLLOWING PAGTAB
	PUSHJ	P,NZSCGT	;ALLOCATE SPACE FOR PAGTAB
	MOVE	T1,[EXP MS.MEM+PT2TAB] ;EXTENDED VIRTUAL ADDRESS OF PT2TAB
	MOVE	T2,T1		;COPY IT
	ADD	T2,MMTSIZ	;CALCULATE FIRST FREE FOLLOWING PT2TAB
	PUSHJ	P,NZSCGT	;ALLOCATE SPACE FOR PT2TAB
	MOVE	T1,[EXP MS.MEM+MEMTAB] ;EXTENDED VIRTUAL ADDRESS OF MEMTAB
	MOVE	T2,MMTSIZ	;NUMBER OF WORDS REQUIRED
	ADD	T2,T1		;CALCULATE FIRST FREE FOLLOWING MEMTAB
	PUSHJ	P,NZSCGT	;ALLOCATE SPACE FOR MEMTAB
	MOVSI	T1,-MEMPGS	;NUMBER OF PAGES USED BY TABLES
	MOVSI	T2,1		;JUNK MAP SLOT ENTRY

MMTAL1:	HRRZ	T3,T1		;GET PAGE NUMBER
	ADD	T3,[<MS.MAP+MMAPS+<<(MS.MEM)>*PAGSIZ>>+<MEMBEG/PAGSIZ>]
	SKIPN	(T3)		;PAGE IN USE?
	MOVEM	T2,(T3)		;RESERVE IT SO TABLES CAN BE EXPANDED
	AOBJN	T1,MMTAL1	;LOOP FOR ALL PAGES
>; END IFN FTXMON

	MOVE	T1,MMTSIZ	;SIZE OF TABLES IN WORDS
IFE FTXMON,<
	SETZM	PAGTAB		;ZERO THE FIRST WORD OF PAGTAB
	MOVE	T2,[PAGTAB,,PAGTAB+1]
	BLT	T2,PAGTAB-1(T1)	;ZERO ALL OF PAGTAB
	SETZM	PT2TAB		;ZERO THE FIRST WORD OF PT2TAB
	MOVE	T2,[PT2TAB,,PT2TAB+1]
	BLT	T2,PT2TAB-1(T1)	;ZERO ALL OF PT2TAB
	SETOM	MEMTAB		;SET MEMTAB TO -1 SO THAT USE WITHOUT SETUP
	MOVE	T2,[MEMTAB,,MEMTAB+1] ;WILL LIKELY CAUSE A STOPCD
	BLT	T2,MEMTAB-1(T1)	;ZAP, ITS ALL - 1
>; END IFE FTXMON
IFN FTXMON,<
	DMOVE	T2,[EXP MS.MEM+PAGTAB,MS.MEM+PAGTAB+1] ;SET UP XBLT SOURCE/DEST
	SUBI	T1,1		;DECREMENT SIZE OF TABLES (WORDS TO ZERO)
	PUSH	P,T1		;SAVE IT
	SETZM	(T2)		;ZERO THE FIRST WORD OF PAGTAB
	EXTEND	T1,[XBLT]	;ZERO ALL OF PAGTAB
	DMOVE	T2,[EXP MS.MEM+PT2TAB,MS.MEM+PT2TAB+1] ;SET UP XBLT SOURCE/DEST
	MOVE	T1,(P)		;NUMBER OF WORDS TO ZERO
	SETZM	(T2)		;ZERO THE FIRST WORD OF PT2TAB
	EXTEND	T1,[XBLT]	;ZERO ALL OF PT2TAB
	POP	P,T1		;NUMBER OF WORDS TO ZERO
	DMOVE	T2,[EXP MS.MEM+MEMTAB,MS.MEM+MEMTAB+1] ;SET UP XBLT SOURCE/DEST
	SETOM	(T2)		;SET MEMTAB TO -1 SO THAT USE WITHOUT SETUP
	EXTEND	T1,[XBLT]	; WILL LIKELY CAUSE A STOPCD
>; END IFN FTXMON
	SUBTTL	MARK AND LINK MEMORY MANAGEMENT TABLES

;STILL IN SECTION 1 IFN FTXMON

MMTINI:	LDB	T2,[POINT 14,LOWLIM##,26] ;GET NUMBER OF LOW SEGMENT PAGES
	ADDI	T2,1		;SINCE LOWLIM IS THE HIGHEST ADDRESS
	MOVSI	T1,MONTRB	;BIT WHICH SAYS THIS PAGE CONTAINS THE MONITOR
	MOVEI	T3,1		;STARTING AT PAGE 1,
	SSX	T3,MS.MEM	;PAGTAB SECTION
	SETZB	T4,PT2TAB-1(T3)	;FIRST PAGE IN PT2TAB
MMTIN1:	HRRZM	T3,PAGTAB-1(T3)	;TURN IT ON
	HLLM	T1,PAGTAB-1(T3)	;+ MONTRB
	HRRZM	T4,PT2TAB(T3)	;SET UP BACKWARD LINK IN PT2TAB
	AOS	T4		;NEXT PAGE
	CAIE	T2,1(T3)	;FOR ALL PAGES UP TO SYSSIZ
	AOJA	T3,MMTIN1	; ..
	HRRZM	T3,LMPAG##	;SET LAST MONITOR PAGE SEEN
	MOVEI	T1,MONORG##	;WHERE TO START LOOKING
	MOVE	T4,MONVFF##	;FIRST FREE MONITOR VIRTUAL ADDRESS
	SUBI	T4,MONORG##	;MINUS MONITOR ORGIN
	LSH	T4,W2PLSH	;EQUALS NUMBER OF MONITOR HI SEG PAGES
	PUSHJ	P,SETMRB	;MARK PAGES OF MONITOR CODE AND DATA
IFN FTXMON,<
	MOVEI	T1,CSBORG##	;WHERE COMMON SUBROUTINES BEGIN
	MOVE	T4,CSBLEN##	;GET THE LENGTH
	LSH	T4,W2PLSH	;CONVERT TO PAGES
	PUSHJ	P,SETMRB	;MARK OFF THOSE PAGES
>; END IFN FTXMON
IFE FTXMON,<
	MOVEI	T1,PAGTAB	;MARK PAGTAB ITSELF AS TAKEN
	MOVE	T4,MMTSIZ	;NUMBER OF PAGES IN PAGTAB
	LSH	T4,W2PLSH
	PUSHJ	P,SETMRB	;MARK THE ENTRIES IN PAGTAB FOR PAGTAB
	MOVEI	T1,PT2TAB	;MARK PT2TAB
	MOVE	T4,MMTSIZ
	LSH	T4,W2PLSH
	PUSHJ	P,SETMRB	;MARK
	MOVEI	T1,MEMTAB	;AND MEMTAB TOO
	MOVE	T4,MMTSIZ	;SAME SIZE AS PAGTAB
	LSH	T4,W2PLSH
	PUSHJ	P,SETMRB
>; END IFE FTXMON
IFN FTXMON,<
	MOVEI	T4,HLGSNO-3	;NUMBER OF SECTIONS TO CONSIDER
	MOVEI	T1,SECTAB+3	;SECTION 0, 1, AND 37 ARE SPECIAL
	ADD	T1,.CPEPT##	;STARTING ADDRESS IN THE SECTION TABLE
	PUSHJ	P,SETMRP	;MARK PAGES AS IN USE BY THE MONITOR
	MOVEI	J,(MS.FMD)	;AS WAS STATED, SECTIONS 0 AND 1 ARE SPECIAL
MMTIN2:	MOVE	T1,.CPEPT##	;ADDRESS OF OUR PROCESS TABLE
	ADDI	T1,SECTAB(J)	;ADDRESS OF THE ENTRY IN THE SECTION TABLE
	SKIPN	T2,(T1)		;HAS THIS SECTION BEEN ALLOCATED?
	JRST	MMTIN3		;NO, SAVE TIME
	MOVE	T1,.CPMAP##	;ADDRESS OF OUR MAP
	MOVEM	T2,.EUPMP/PAGSIZ(T1) ;SECTION MAP
	CLRPT	.EUPMP		;MAKE SECTION MAP ADDRESSABLE
	MOVEI	T1,.EUPMP	;VIRTUAL ADDRESS OF THE SECTION MAP
	MOVEI	T4,^D512	;NUMBER OF PAGES IN A SECTION
	CAIN	J,(MS.HGH)	;EXTENDED HIGH SEGMENT?
	MOVEI	T4,HLCSAD##/PAGSIZ ;YES, DON'T LOOK AT EXEC VIRTUAL MAPPINGS
	PUSHJ	P,SETMRP	;MARK ALLOCATED PAGES IN THIS SECTION
MMTIN3:	CAIGE	J,HLGSNO-1	;LOOKED AT ALL SECTIONS?
	AOJA	J,MMTIN2	;NO, LOOP OVER ALL
>; END IFN FTXMON
	PUSHJ	P,BTAVAL##	;GET ADDRESS OF BOOTSTRAP VECTOR
	  JRST	MMTIN6		;BOOTSTRAP NOT AVAILABLE
	MOVE	T1,BOOTPA	;GET PHYSICAL ADDRESS OF BOOTSTRAP
	LSH	T1,W2PLSH	;GET STARTING PAGE NUMBER
	HLRE	T2,.BTSIZ(T2)	;GET -VE NUMBER OF PAGES IN BOOTSTRAP
	MOVMS	T2		;GET NUMBER OF PAGES
	PUSHJ	P,SETCTB	;SET THE "PHYSICALLY CONTIGUOUS" BIT IN PAGTAB
MMTIN6:	MOVE	U,[POINT 1,NXMTAB##]
	MOVE	T1,MMTSIZ	;NUMBER OF WORDS IN PAGTAB
	SETZB	T2,T3		;INITIALIZE
	PUSH	P,T3		;SAVE BITS
MMTIN7:	ILDB	T4,U		;NEXT PAGE IN NXMTAB
	JUMPE	T4,MMTIN9	;JUMP IF PAGE EXISTS
	SKIPE	@[IW MS.MEM,PAGTAB(T3)] ;IS THE PAGE FREE?
	STOPCD	.,STOP,MNM,	;++MONITOR IN NON-EXISTANT MEMORY
	TLO	T3,NXMBIT	;INDICATE NON-EXISTANT PAGE
	TLZ	T3,MONTRB
	JUMPE	T2,MMTIN8	;JUMP IF NO PREDECESSOR
	SSX	T2,MS.MEM	;SET SECTION NUMBER IN INDEX
	HLLM	T3,(P)		;SAVE LATEST BITS
	MOVEM	T3,PAGTAB(T2)	;STORE THAT IN PAGTAB
MMTIN8:	HRRZS	T2,T3		;PREDESSOR TO THIS PAGE
MMTIN9:	CAIE	T1,1(T3)	;LOOKED AT EVERY PAGE IN PAGTAB?
	AOJA	T3,MMTIN7	;NO, LOOP OVER ALL PAGES
	POP	P,T4		;RESTORE BITS
	SSX	T2,MS.MEM	;SECTION NUMBER
	TRNE	T2,-1		;ANY NON-EXISTANT PAGES AT ALL
	HLLZM	T4,PAGTAB(T2)	;YES, INDICATE THE LAST ONE
IFN FTKL10,<
	CAIN	T1,CORBLK##	;4 MW OF MEMORY?
	SKIPE	@[IW MS.MEM,PAGTAB(T3)] ;AND IS LAST PAGE FREE?
	JRST	MMIN9A		;NOT 4 MW OR LAST PAGE IN USE
	HRR	T4,T3		;LINK IN THIS NXM PAGE IF PREDECESSOR EXISTS
	TRNE	T2,-1
	MOVEM	T4,PAGTAB(T2)
	TLO	T4,NXMBIT	;MARK LAST PAGE AS NON-EXISTANT BECAUSE
	HLLZM	T4,@[IW MS.MEM,PAGTAB(T3)] ; RH20'S CAUSE PARITY ERRORS WHEN
	SETOM 	T4		; TRYING TO USE LAST PHYSICAL QUADWORD IN 4 MW
	DPB	T4,U		;MARK IN NXMTAB
	LSH	T3,P2WLSH	;MAKE MEMSIZ REFLECT THE CHANGE
	MOVEM	T3,MEMSIZ##
MMIN9A:
>; END IFN FTKL10
	LDB	T1,[POINT 14,MEMSIZ##,26]
	MOVEI	T1,PAGTAB-1(T1)	;HIGHEST PAGE IN THE MONITOR - 1
	SSX	T1,MS.MEM	;PAGTAB SECTION
	MOVEM	T1,CORLST##	;HIGHEST PAGE IN PAGTAB

	MOVEI	T1,1000		;START FREE LIST AT 256K
	SSX	T1,MS.MEM	;SET PAGTAB SECTION
	SETZ	T2,		;NO PREDECESSOR
	SSX	T2,MS.MEM	;SET PAGTAB SECTION
	SETZ	T3,		;NO FREE PAGES SEEN YET
	MOVE	T4,MMTSIZ	;SET UP A LOOP COUNTER
	SUBI	T4,1000		;WE SKIPPED THE FIRST 1000 PAGES
	SETO	P1,		;MARK FIRST PASS THROUGH PAGTAB
MMIN10:	SKIPE	PAGTAB(T1)	;IS THIS PAGE FREE?
	JRST	MMIN13		;NO
	TRNE	T2,-1		;FIRST FREE PAGE?
	JRST	MMIN11		;NO
	HRRZM	T1,PAGPTR##	;YES, STORE ORGIN OF THE FREE CORE LIST
	SETZM	PT2TAB(T1)	;INIT TAIL OF LIST
	JRST	MMIN12		;CONTINUE
MMIN11:	PUSH	P,T1		;SAVE PAGTAB POINTER
	HRLI	T1,FREPAG	;INDICATE A FREE PAGE
	MOVEM	T1,PAGTAB(T2)	;STORE THAT IN PAGTAB
	SSX	T1,MS.MEM
	HRRZM	T2,PT2TAB(T1)	;SET BACKWARDS LINK
	POP	P,T1		;RESTORE PAGTAB POINTER
MMIN12:	MOVE	T2,T1		;SAVE PREDECESSOR
	ADDI	T3,1		;NEXT PAGE
MMIN13:	SOSLE	T4		;LOOKED AT ALL PAGES IN PAGTAB?
	AOJA	T1,MMIN10	;NO
	AOJN	P1,MMIN14	;JUMP IF WE'VE MADE TWO PASSES THROUGH PAGTAB
	SETZ	T1,		;START OVER AT THE BEGINNING
	SSX	T1,MS.MEM	;SET PAGTAB SECTION
	MOVEI	T4,1000		;JUST LOOK AT FIRST 1000 PAGES
	JRST	MMIN10		;NOW DO IT AGAIN

MMIN14:	MOVSI	T1,FREPAG	;LAST FREE PAGE
	HLLZM	T1,PAGTAB(T2)	;TERMINATE LINKED LIST OF FREE PAGES
	MOVEM	T3,BIGHOL##	;STORE THE NUMBER OF EXISTANT PHYSICAL PAGES
	MOVEM	T3,CORTAL##	; OF USER CORE SEEN
	MOVEM	T3,USRCOR##	;TOTAL AMOUNT OF USER CORE
	LSH	T3,P2WLSH	;CONVERT TO NUMBER OF WORDS
	MOVEM	T3,MAXMAX##	;MAX CORMAX CAN BE SET TO
	MOVE	T2,T3
	SUBI	T2,NWMCP+PAGSIZ
	MOVEM	T2,RMCMAX##	;REAL MAXIMUM CORMAX
	HRRZ	T1,CORLIM##	;MAXIMUM NUMBER OF PAGES ALLOWED A SINGLE
				; USER (MONGEN SPECIFIED)
	LSH	T1,P2WLSH	;CONVERT TO NUMBER OF WORDS
	CAMGE	T1,T3		;.GE. THE NUMBER OF PAGES AVAILABLE TO USERS?
	MOVE	T3,T1		;NO, MAXIMUM AVAILABLE TO USERS
	CAMLE	T3,T2
	MOVE	T3,T2
	MOVEM	T3,CORMAX##	;NO ONE CAN GET LARGER THAN THIS (HOPEFULLY)
IFN FTXMON,<
;NOW ZERO OUT THE SECTION ENTRIES FOR WHICH NZS CORE CANNOT BE ALLOCATED
	SETZM	NZSFCH##+<(MCSEC1)>
	SETZM	NZSFCH##+<(MS.HGH)>
	SETZM	NZSFCH##+<(MS.SNP)>
	SETZM	NZSFCH##+<(MS.MAP)>
	XJRST	[MCSEC0+.+1]	;BACK INTO SECTION 0
> ;END IFN FTXMON
	PUSHJ	P,RSTDEF	;RESET DEFAULT TIMEOUT VALUE, ETC. FOR INITIAL
				;PROMPTS WHICH WE WANT TO TIMEOUT IF THE
				;OPERATOR FELL ASLEEP.
	SUBTTL	CHECK AND ASK ABOUT OFF-LINE CPUS

;ROUTINE TO CHECK IF A CPU IS OFF-LINE, AND ASK THE OPERATOR IF
;IT SHOULD BE RUNNING OR NOT, THEN GIVE THEM A CHANCE TO START IT.

ASKCPU:
IFN FTMP,<
	MOVEI	P1,.C0CDB##	;START WITH CPU0
	SETZ	P2,		;INIT COUNT OF NON-RUNNING CPUS
ASKCP1:	MOVE	T1,.CPCPN##-.CPCDB##(P1) ;GET CPU NUMBER
	CAMN	T1,.CPCPN##	;IS IT ME?
	JRST	ASKCP2		;YES
	XCTCPU	(CPN,CPOPJ1##)	;TRY TO WAKE HIM OUT OF HIS AC LOOP
	  AOSA	P2		;FAILED, COUNT ONE NOT RUNNING
	JRST	ASKCP2		;SUCCEEDED

	PUSHJ	P,PRSSET	;SET UP SPECIAL BUFFER, .CPTOA, ETC.
	PUSH	P,T1		;SAVE OLD CHARACTER TYPER
	MOVEI	T1,[ASCIZ /% /]	;STARTING TEXT
	PUSHJ	P,CONMES	;PRINT IT
	MOVE	T2,.CPLOG##-.CPCDB##(P1) ;GET CPU NAME
	PUSHJ	P,PRNAME##	;PUT IN MESSAGE
	MOVEI	T1,[ASCIZ/ #/]
	PUSHJ	P,CONMES##	;TYPE TEXT
	MOVE	T1,.CPASN##-.CPCDB##(P1) ;GET SERIAL NUMBER
	PUSHJ	P,PRTDIG##	;TYPE IT
	MOVEI	T1,[ASCIZ / is not running.  Set CPU status/]
	PUSHJ	P,CONMES##	;PRINT TEXT
	POP	P,.CPTOA##	;RESTORE CHARACTER STICKER
	MOVEI	T1,[ASCIZ //]	;NULL TEXT
	CAIN	P2,1		;FIRST TIME THROUGH?
	PUSHJ	P,CONOUT	;YES--START WITH A CRLF
	MOVEI	T1,TXTBUF	;POINT TO PROMPT STRING
	MOVE	T2,['DOWN  ']	;DEFAULT
	MOVE	T3,[-2,,ASKCPT]	;TABLE OF RESPONSES
	PUSHJ	P,PRSKEY	;PROMPT AND FETCH ANSWER
	  JFCL			;SHOULDN'T HAPPEN
	JUMPN	T1,ASKCP1	;CHECK AGAIN IF "UP" WAS REQUESTED
	MOVSI	T1,(CR.RMV!CR.DET!CR.NRN) ;GET THE BITS
	IORM	T1,.CPRUN##-.CPCDB##(P1) ;SET IN THE RUNNABILITY WORD
	SOS	NCPRUN##	;COUNT DOWN RUNNABLE CPUS
ASKCP2:	HLRZ	P1,.CPCDB##-.CPCDB##(P1) ;GET NEXT CDB
	JUMPN	P1,ASKCP1	;LOOP IF ANOTHER CPU TO CHECK
	JRST	CLRCCB		;ONWARD

ASKCPT:	SIXBIT	/DOWN/
	SIXBIT	/UP/
>; END IFN FTMP
	SUBTTL	CLEAR CACHE BITS FOR LOW SEGMENT PAGES

CLRCCB:
IFN FTXMON,<XJRST [MCSEC1+.+1]>	;GET INTO SECTION 1 FOR PAGTAB REFS
IFN FTMP,<
	SKIPG	[M.CPU##-1]	;MORE THAN ONE CPU?
	JRST	CLRCC3		;NO, TURN OFF CACHE FOR A FEW PAGES
	SETZ	T1,		;ON 1088 SYSTEMS, MUST TURN OFF
	MOVEI	T2,CSBORG##-1	; CACHE FOR ENTIRE LOWSEG
	PUSHJ	P,CCTRNG	;CLEAR
	MOVEI	T1,CSHFIR##	;START UP INTERRUPT LEVEL PDL'S AND STUFF
	MOVEI	T2,CSHLAS##	;CAN CACHE ALL OF THAT
	PUSHJ	P,CSBRNG	;SINCE NOT REALLY SHARED BETWEEN CPUS
IFE FTXMON,<
	MOVE	T2,MMTSIZ	;SIZE OF MEMORY MANAGEMENT TABLES
	MOVEI	T1,PAGTAB	;START OF PAGTAB
	ADDI	T2,-1(T1)	;END OF PAGTAB
	PUSHJ	P,CCTRNG	;CLEAR CACHE BITS FOR PAGTAB
	MOVE	T2,MMTSIZ	;NUMBER OF WORDS AGAIN
	MOVEI	T1,MEMTAB	;START OF MEMTAB
	ADDI	T2,-1(T1)	;END OF MEMTAB
	PUSHJ	P,CCTRNG	;CLEAR CACHE BITS FOR MEMTAB
>; END IFE FTXMON
IFN FTXMON,<
	MOVE	J,.CPEPT##	;GET EPT ADDRESS
	ADDI	J,<(MS.FMD)>+1	;START AT FIRST REAL DATA SECTION
CLRCC1:	SKIPE	T1,SECTAB(J)	;GET SECTION MAP POINTER
	TLNN	T1,(PM.CSH)	;ALLOW FOR UNCACHED SECTION
	JRST	CLRCC2		;SKIP THIS SECTION
	MOVE	T2,.CPMAP##	;GET ADDRESS OF S0 MAP
	MOVEM	T1,.EUPMP/PAGSIZ(T2) ;MAKE SECTION MAP VISIBLE VIA .EUPMP
	CLRPT	.EUPMP		;MAKE NEW MAPPING VISIBLE
	PUSHJ	P,CCTRNS	;MARK PAGES
CLRCC2:	MOVE	T1,.CPEPT##	;GET EPT ADDRESS
	CAIGE	J,MXSECN-1(T1)	;DONE ALL POSSIBLE SECTIONS?
	AOJA	J,CLRCC1	;NO, LOOP FOR MORE
>; END IFN FTXMON
	MOVEI	T1,OUCHTB##	;OUCHTB MUST BE UNCACHED
	MOVEI	T2,OUCHTB##+7
	PUSHJ	P,CCTRNG
CLRCC3:
>; END IFN FTMP

	MOVSI	T1,(ST%LSC)	;LOW SEG IS CACHED BIT
	ANDCAM	T1,CNFST2##	;INITIALLY CLEAR LOW SEG IS CACHED BIT
	MOVE	T2,NCPRUN##	;NUMBER OF RUNNABLE CPUS
	CAIN	T2,1		;ONLY 1 CPU?
	IORM	T1,CNFST2##	;YES, WE CACHED LOW SEGMENT

IFN FTKL10,<
	SETZ	P1,		;CLEAR LTINIT INDEX
CLRCC4:	SKIPN	T1,LTINIT##(P1)	;LTINIT ENDS WITH A ZERO
	JRST	CLRCC5		;DONE
	HLRZ	T2,T1		;GET NUMBER OF 4 WORD BLOCKS
	LSH	T2,2		;MAKE IT NUMBER OF WORDS
	ADDI	T2,-1(T1)	;GET END ADDRESS OF THIS CHUNK
	HRRZS	T1		;CLEAR LEFT HALF FOR CCBRNG
	PUSHJ	P,CCBRNG	;CLEAR CACHE BITS IN EXEC MAP
	AOJA	P1,CLRCC4	;AND GET NEXT ENTRY IN LTINIT

CLRCC5:	MOVEI	T1,DLXFST##	;CLEAR OUT CACHE BITS FOR DC75
	MOVEI	T2,DLXLST##
	CAIN	T1,(T2)		;ANY DL10 WINDOWS DEFINED
	JRST	CLRCC6		;NO, DON'T BOTHER
	PUSHJ	P,CCBRNG
	MOVEI	T1,.C0UPT##	;DC76 LOOKS AT UPTIME FOR CPU0
	MOVE	T2,T1		;UNCACHE JUST THIS
	PUSHJ	P,CCBRNG	;CLEAR OUT CACHE FOR UPTIME
	MOVEI	T1,.CPUPT##	;UNCACHE THE OTHER VIRTUAL MAPPING TOO
	MOVE	T2,T1		;ONLY THE ONE WORD
	SKIPN	.CPCPN##	;UNLESS WE'RE NOT CPU #0.
	PUSHJ	P,CCBRNG	;  (ONLY PLACE A DC76 CAN BE).
CLRCC6:
>; END IFN FTKL10
IFN FTKS10,<			;ONLY KS-10'S HAVE KMC/DUP-11S
	MOVEI	T1,KDLFST##	;GET THE ADDRESS OF THE FIRST KDL PAGE
	MOVEI	T2,KDLLST##	;GET ADDR OF LAST WORD OF THE LAST
	CAIE	T1,(T2)		;IF ANY KDL PAGES ARE DEFINED, THEN
	PUSHJ	P,CCBRNG	;  MAKE SURE THAT THEY ARE UNCACHED.
>; END IFN FTKS10
REPEAT 0,<
	SKIPL	DEBUGF##	;IF DEBUGGING WITH EDDT
	JRST	CLRCC7		;NO-DONT BOTHER
	MOVEI	T1,DDT##	;CLEAR THE CACHE BITS FOR EDDT
	MOVEI	T2,DDTEND##	;TO DDTEND, SYMBOL TABLE IS NEVER WRITTEN
	PUSHJ	P,CCBRNG
;THE ABOVE CODE, IF ALLOWED TO ASSEMBLE (PUT ";" IN FRONT OF THE REPEAT
;AND THE CLOSING ANGLE BRACKET ABOVE) WILL KEEP DDT OUT OF THE CACHE. THIS IS HANDY IF YOU
;ARE DEBUGGING MONITOR PORTIONS WHICH HANDLE CACHE!!!
CLRCC7:	MOVEI	T1,APRPAR##	;KEEP THE APR PARITY RECOVERY CODE
	MOVEI	T2,APPCP2##	;OUT OF THE CACHE UNTIL
				;THE CACHE HAS BEEN SWEPT BACK TO CORE
				;THIS WILL CLOSE DOWN (BUT NOT SHUT) THE WINDOW
				;OF RECURSIVE FAILURES
	PUSHJ	P,CCBRNG	;AND SHOULD IMPROVE RECOVERY CHANCES
>;END REPEAT 0
	MOVE	T1,LOWLIM##	;NOW CLEAR CACHE BITS FROM
	ADDI	T1,1		; LOWLIM+1 (WHERE SYSSIZ WINDS UP)
	MOVEI	T2,CSBORG##-1	;  TO END OF LOW SEG FOR LOCK/REAL TIME
	CAMG	T1,T2
	PUSHJ	P,CCBRNG
IFN FTXMON,<XJRST [MCSEC0+.+1]>	;RETURN TO SECTION 0
	SUBTTL	ALLOCATE AND INITIALIZE SCA

SCAINI:
IFN FTSCA,<
	SKIPN	[SCASIZ##]	;ANY SCA FREE POOL?
	JRST	NOSCA		;NO, NO SECTION MAP OR BUFFERS NEEDED
IFN FTXMON,<
	MOVEI	T1,(MS.SCA)	;SECTION NUMBER FOR SCA STUFF
	MOVEI	T2,SCASIZ##	;SIZE OF THE POOL
	PUSHJ	P,GFWNZN##	;ALLOCATE THE SPACE
	  HALT	.		;*** FOR NOW
	MOVEM	T1,SCALOC##	;SAVE ADDRESS OF FREE POOL
>; END IFN FTXMON
	PUSHJ	P,BHDINI##	;INITIALIZE BUFFER HEADERS AND DESCRIPTORS
	MOVE	T1,BHDADR##	;ADDRESS OF BUFFER HEADER DESCRIPTOR AREA
	LSH	T1,W2PLSH	;GET STARTING PAGE NUMBER
	MOVE	T2,BHDPGS##	;GET NUMBER OF PAGES
	PUSHJ	P,SETCTB	;SET THE "PHYSICALLY CONTIGUOUS" BIT IN PAGTAB
	MOVE	T1,BSDADR##	;ADDRESS OF BUFFER SEGMENT DESCRIPTOR AREA
	LSH	T1,W2PLSH	;GET STARTING PAGE NUMBER
	MOVE	T2,BSDPGS##	;GET NUMBER OF PAGES
	PUSHJ	P,SETCTB	;SET THE "PHYSICALLY CONTIGUOUS" BIT IN PAGTAB
	PUSHJ	P,SC.INI##	;INITIALIZE THE SCA PROTOCOL MODULE
NOSCA:
>; END IFN FTSCA

IFN FTENET,<
ETHSTR:
IFN FTKL10,<PUSHJ P,KNISYS##>	;INIT KLNI BIT MAPPED CORE
	PUSHJ	P,ETHINI##	;INITIALIZE ETHERNET DRIVER
> ;END IFN FTENET
	SUBTTL	ASK REASON FOR RELOAD

;ASK OPERATOR REASON FOR RELOAD
;ANSWER WILL BE PUT IN LOG FILE DAEMON
;ALONG WITH ARBITRARY OPERATOR COMMENT, IF ANY.
;ALLOW UNIQUE ABBREVIATION

WHYLOP:	SETZM	WHYTXT##	;CLEAR OUT AREA FOR OPERATOR COMMENT
	MOVE	T1,[XWD WHYTXT##,WHYTXT##+1]
	BLT	T1,WHYTXT##+WHYSIZ##-1
	SKIPL	DEBUGF##	;DEBUGGING STAND-ALONE?
	JRST	WHYLP1		;NO,
	MOVSI	T1,'SA '	;STAND ALONE CODE
	MOVEM	T1,WHYCOD##	;FOR DAEMON
	JRST	WHYLP7		;GO FINISH UP

WHYLP1:	MOVE	T1,CRSWHY	;GET STOPCD CHECKSUM FROM PREVIOUS LOAD
	JUMPE	T1,WHYLP2	;JUMP IF NONE
	PUSHJ	P,CHKDCS	;CHECK DATE/TIME CHECKSUM
	  JRST	WHYLP2		; IF PINK CRASH
	MOVEM	T1,WHYCOD##	;AND STORE AS REASON FOR RELOAD
	JRST	WHYLP7		;SKIP QUESTION

WHYLP2:	MOVE	T1,DEFSP	;GET VIRGIN POINTER
	MOVEM	T1,DEFPTR	;RESET IT
	MOVEI	T1,[ASCIZ /OTHER	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;STORE IN DEFAULT BUFFER
	MOVE	T1,DEFSP	;INITIAL STRING POINTER AGAIN
	MOVEM	T1,DEFPTR	;RESET FOR TIMEOUT
	MOVEI	T1,[ASCIZ /Why reload/]
	SETZ	T2,		;NO DEFAULT
	PUSHJ	P,PRSSIX	;PROMPT AND FETCH ANSWER
	JUMPE	T1,[PUSHJ P,WHELP ;GIVE SHORT HELP
		    JRST  WHYLOP] ;AND TRY AGAIN
	MOVE	T2,T1		;COPY TO A BETTER AC
	MOVE	T1,[-1,,['HELP  ']] ;SHORT TABLE
	PUSHJ	P,FNDNAM##	;DID THE OPERATOR ASK FOR HELP?
	  JRST	WHYLP3		;NO, MAYBE A REAL ANSWER
	PUSH	P,OPTPTR	;SAVE COMMAND POINTER
	PUSH	P,OPTHLP	;AND COMMAND HELP TEXT
	PUSH	P,SWTPTR	;NO SWITCHES
	MOVE	T1,[-WHYLEN,,WHYTAB] ;WHY RELOAD COMMAND POINTER
	MOVEM	T1,OPTPTR
	MOVEI	T1,WHYHLP	;WHY RELOAD HELP TEXT
	MOVEM	T1,OPTHLP
	SETZM	SWTPTR		;NO SWITCHES
	PUSHJ	P,.HELP		;PROCESS AS A HELP COMMAND
	  JFCL			;FOOL
	POP	P,SWTPTR	;RESTORE
	POP	P,OPTHLP	;...
	POP	P,OPTPTR	;ONE MORE
	JRST	WHYLOP		;TRY AGAIN

WHYLP3:	MOVE	T1,[-WHYLEN,,WHYTAB] ;POINT TO TABLE
	PUSHJ	P,FNDNAM##	;LOOKUP ABBREV.
	  JRST	[PUSHJ P,WHELP	;GIVE SHORT HELP
		 JRST  WHYLOP]	;AND TRY AGAIN
	MOVE	T1,WHYTAB(T1)	; GET UNABBREVIATED SIXBIT CODE
	MOVEM	T1,WHYCOD##	;AND STORE IN GETTAB FOR DAEMON
	MOVE	P1,SAWCMT	;GET THE COMMENT FLAG
	JUMPN	P1,WHYLP4	;GO IF MORE THAN JUST THE "WHY RELOAD" REASON
	CAME	T1,['OTHER ']	;IF END OF LINE AND RESPONSE WAS OTHER,
	JRST	WHYLP7		; TELL HIM THAT OTHER REQUIRES A COMMENT
	MOVEI	T1,[ASCIZ /% OTHER requires a comment/]
	PUSHJ	P,CONOUT	;WARN OPERATOR
	JRST	WHYLOP		;GO BACK AND ASK WHY RELOAD AGAIN
;HERE TO GET OPERATOR COMMENT AND STORE IN CRASH ACS
WHYLP4:	MOVEI	P2,<WHYSIZ##*5>-1  ;NUMBER OF ASCIZ CHARACTERS
	MOVE	P1,[POINT 7,WHYTXT##] ;BYTE POINTER FOR WHERE TO STORE
WHYLP5:	PUSHJ	P,COMTYI##	;GET NEXT CHARACTER (EVEN IF ;)
	JUMPE	T3,WHYLP6	;END OF STRING? (GETLIN STORES NULL)
	CAIL	T3,12		;NO, END OF LINE CHAR?
	CAILE	T3,15		;"
	SKIPA			;NO
	JRST	WHYLP6		;YES, DO NOT STORE, JUST GO STORE NULL
	SOJLE	P2,WHYLP6	;QUIT IF NO MORE ROOM LEFT IN BLOCK
	IDPB	T3,P1		;STILL ROOM, STORE ASCIZ CHARACTER
	JRST	WHYLP5		;GO GET MORE

;HERE WHEN FINISHED COPYING OPERATOR COMMENT TO CRASH ACS
WHYLP6:	MOVEI	T3,0		;NULL
	IDPB	T3,P1		;STORE ON END SO ASCIZ
WHYLP7:	PUSHJ	P,CHGDAT	;GET DATE/TIME
	  JFCL			;ALWAYS SKIPS
	JRST	STACON		;GO CRANK UP AUTCON
WHELP:	PUSH	P,OPTPTR	;SAVE COMMAND POINTER
	MOVE	T1,[-WHYLEN,,WHYTAB] ;AOBJN POINTER TO OPTIONS
	MOVEM	T1,OPTPTR	;SAVE TEMPORARILY
	PUSHJ	P,SHELP		;GIVE SHORT HELP
	POP	P,OPTPTR	;RESTORE COMMAND POINTER
	POPJ	P,		;RETURN
;LIST OF POSSIBLE WHY RELOAD ANSWERS (CAN BE ABBREVIATED)
; ORDER IS IMPORTANT. OPERATOR SHOULD ANSWER THE EARLIEST ONE
; IN TABLE WHICH APPLIES (WHEN MORE THAN ONE DOES)

DEFINE	OPTINS,<

;;PREVIOUS SYSTEM PROBLEM:
X (OPR,<Operator error>)
X (PARITY,<Memory parity errors>)
X (POWER,<Power failure>)
X (STATIC,<Static electricity>)
X (HARDWA,<Hardware failure>)
X (NXM,<Non-existant memory errors>)
X (HALT,<Monitor halted>)
X (LOOP,<Monitor looping>)
X (HUNG,<Monitor hung>)

;;PREVIOUS NON-TIMESHARED USE OF SYSTEM:
X (PM,<Preventive maintenance>)
X (CM,<Corrective maintenance>)
X (SA,<Stand alone>)

;;DIFFERENT MONITORS
X (NEW,<Loading new monitor>)
X (SCHED,<Scheduled monitor change>)

;;OPERATOR DOESN'T KNOW OR WON'T TELL US
X (OTHER,<None of the above>)

> ;END DEFINE OPTINS

DEFINE	X	(NAME,TEXT),<EXP <SIXBIT /NAME/>>
WHYTAB:	OPTINS
WHYLEN==.-WHYTAB		;LENGTH

DEFINE	X	(NAME,TEXT),<IFIW [ASCIZ /TEXT/]>
WHYHLP:	OPTINS
	SUBTTL	CONFIGURE DEVICES

STACON:	PUSHJ	P,AUTCPU##	;CALL AUTCON ON THE BOOT CPU
IFN FTMP,<
	SKIPN	[M.CPU##-1]	;MORE THAN ONE CPU IN SYSTEM?
	JRST	STACN3		;NOPE
	MOVEI	P1,.C0CDB##	;START WITH CPU0
	SETZ	P2,		;CLEAR MASK OF CPUS

STACN1:	MOVE	T1,.CPCPN##-.CPCDB##(P1) ;GET CPU NUMBER
	CAME	T1,.CPCPN##	;IS IT ME?
	XCTCPU	(CPN,AUTCPU##,XC.ASY) ;NO--FIRE UP AUTCON ON THIS CPU
	HLRZ	P1,.CPCDB##-.CPCDB##(P1) ;NEXT CDB
	JUMPN	P1,STACN1	;LOOP IF ANOTHER CPU TO CHECK
	MOVEI	T2,-1		;TIME TO WASTE
	SOJG	T2,.		;GIVE THE OTHER CPUS A CHANCE TO START
	MOVE	T2,CPUTIM	;WAIT AS LONG AS XCTCPU WOULD

STACN2:	SETZ	T3,		;CLEAR A FLAG
	HRROI	T1,[SKIPL .CPATO##-.CPCDB##(P1) ;CPU STILL CONFIGURING?
		    SETO  T3,	;YES
		    POPJ  P,]
	PUSHJ	P,CPUAPP##	;MAKE SURE ALL CPU'S ARE THRU AUTCON
	SKIPE	T3		; SINCE BOOT'S MAP MIGHT BE CHANGED
	SOJGE	T2,STACN2	;TIME OUT IN CASE SOMEONE'S NOT RUNNING
	SKIPGE	T2		;DID IT TIME OUT?
	STOPCD	.,DEBUG,AUTTTL,	;++AUTCON TOOK TOO LONG

STACN3:
>; END IFN FTMP
	SUBTTL	SET UP AND LINK DDBS

GETOPT:	PUSHJ	P,SLCLDS	;SET UP LOW CORE LOCATIONS
	PUSHJ	P,APRCHK	;TO TIME ACCOUNTING
IFN FTCIDSK,<
	MOVE	T1,SYSUPT##	;STORE TIME STAMP
	MOVEM	T1,BNDBEG##	; FOR BINDING LOGIC
>; END IFN FTCIDSK
	CONO	PI,PI.CPI!PI.TNP!PI.ON!II.ACO  ;TURN ON PI CHANNELS
	PUSHJ	P,AUTSYS##	;CREATE SYSINI DDB LINKAGES
	PUSHJ	P,XTCLNK##	;CREATE AND LINKUP DA28 KDBS AND UDBS
	PUSHJ	P,FILMEM##	;SETUP FILSER CORE BLOCKS
	PUSHJ	P,SETFPT	;SET UP FREPTR AND FREE CORE POOL
IFN FTCIDSK,<PUSHJ P,ONCBND##>	;BIND CI DISKS
;	JRST	STRTUP		;GO TO STARTUP OPTION
	SUBTTL	ASK FOR START-UP OPTION

;TYPING ESCAPE DURING ONCE WILL BRING YOU BACK HERE TO TRY AGAIN.

STRTUP::MOVE	P,.CPNPD##	;RESET STACK INCASE OF RESTART
	PUSHJ	P,KONCE##	;KILL OFF ONCE-ONLY DATA STRUCTURES
	PUSHJ	P,RDDISK##	;READ THE DISKS
	  JFCL			;IGNORE ERRORS
	SETZM	GOFLAG		;NO ONE'S TYPED "GO" YET
	SKIPL	DEBUGF##	;DEBUGGING?
	JRST	STRTU1		;NO--NORMAL STARTUP
	SKIPL	ALTMFL		;BUT WAS ALTMODE TYPED?
	JRST	STRTU6		;SKIP THE VERBIAGE

STRTU1:	SETZM	ALTMFL		;CLEAR FLAG THAT SAYS ALTMODE WAS TYPED
	SETZM	ONCTCH		;ALLOW NO 'TYPEAHEAD' THROUGH PRSCON
	SKIPE	GOFLAG		;READY TO START TIMESHARING?
	JRST	STRTU7		;YES
	SETZM	IGNORE		;NO--CLEAR /NOERROR FLAG
	MOVE	T1,DEFSP	;GET VIRGIN POINTER
	MOVEM	T1,DEFPTR	;RESET IT
	MOVEI	T1,[ASCIZ /GO	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;STORE IN DEFAULT BUFFER
	MOVE	T1,DEFSP	;INITIAL STRING POINTER AGAIN
	MOVEM	T1,DEFPTR	;RESET FOR TIMEOUT
	MOVEI	T1,[ASCIZ /Startup option/]
	SETZ	T2,		;NO DEFAULT
	PUSHJ	P,PRSSIX	;PROMPT AND FETCH ANSWER
	  JUMPE	T1,[PUSHJ P,SHELP ;GIVE SHORT HELP
		    JRST  STRTU1] ;AND TRY AGAIN
	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	MOVE	T2,T1		;COPY ANSWER FOR FNDNAM

;PROCESS SWITCHES
STRTU2:	MOVE	T3,ONCTCH	;RESTORE DELIMITER
	CAIE	T3,"/"		;SWITCH COMING?
	JRST	STRTU3		;NO, CHECK OPTION
	PUSH	P,T2		;SAVE OPTION
	PUSHJ	P,CTEXT##	;PICK UP SWITCH NAME
	MOVE	T1,SWTPTR	;GET POINTER TO SWITCH NAMES
	PUSHJ	P,FNDNAM##	;LOOKUP NAME
	  JRST	[PUSHJ	P,SHELP	;GIVE SHORT HELP
		 JRST	STRTU1]	;AND TRY AGAIN
	ADD	T1,SWTDSP	;INDEX INTO DISPATCH TABLE
	PUSHJ	P,@(T1)		;DO SOMETHING
	  JFCL			;IGNORE ERRORS
	POP	P,T2		;RESTORE OPTION NAME
	JRST	STRTU2		;SEE IF ANOTHER SWITCH COMING

;PROCESS COMMANDS
STRTU3:	MOVE	T1,[-1,,['HELP  ']] ;SPECIAL HACK
	PUSHJ	P,FNDNAM##	;WAS "HELP" TYPED?
	  JRST	STRTU4		;NO
	MOVEI	T1,[IFIW .HELP]	;FAKE UP A HELP COMMAND
	JRST	STRTU5		;AND GO PROCESS IT
STRTU4:	MOVE	T1,OPTPTR	;GET POINTER TO COMMAND NAMES
	PUSHJ	P,FNDNAM##	;LOOKUP NAME
	  JRST	[PUSHJ	P,SHELP	;GIVE SHORT HELP
		 JRST	STRTU1]	;AND TRY AGAIN
	MOVE	T2,OPTPTR	;GET COMMAND TABLE AGAIN
	ADDI	T2,(T1)		;INDEX TO SPECIFIED COMMAND
	MOVE	T2,(T2)		;GET FULL COMMAND NAME
	MOVEM	T2,STOPTN##	;SAVE STARTUP OPTION FOR GETTAB
	ADD	T1,OPTDSP	;INDEX INTO DISPATCH TABLE

;COMMAND DISPATCH
STRTU5:	HRLOI	T2,777		;A BIG NUMBER
	MOVEM	T2,OPRCNT	;SET FUTURE PARSER TIMEOUTS TO INFINITE
	SETZM	DEFALW		;INDICATE WE SAW SOME INPUT
	PUSHJ	P,@(T1)		;DO SOMETHING
	  JFCL			;IGNORE ERRORS
	JRST	STRTU1		;LOOP BACK FOR MORE COMMANDS

;HERE TO START SYSTEM WHEN DEBUGGING
STRTU6:	MOVE	T1,['NOINIT']	;SPECIAL HACK SO SCNSER
	MOVEM	T1,STOPTN##	; DOESN'T DRIVE US CRAZY
	PUSHJ	P,.NOINI	;MAKE IT LOOK LIKE "NOINITIA"
	  JFCL			;IGNORE ERRORS

;HERE WHEN DONE SCANNING COMMANDS AND SWITCHES
STRTU7:	HRRZ	T1,CRSSTS	;STATES BEFORE THE RELOAD
	TRO	T1,ST.NOP	;ASSUME NO OPR IN ATTENDANCE
	SKIPGE	DEFALW		;DID THE OPR ANSWER?
	HRRM	T1,STATES##	;NO, STORE STATES AS PREVIOUSLY SET BY OPR
	SETZM	CRSWHY		;SO WILL ASK "WHY RELOAD" NEXT TIME
	SETZM	GOFLAG		;CLEAR "GO" TO AVOID LOOPING ON ERRORS
	PUSHJ	P,VFCORE##	;VERIFY IN-CORE DISK DATA BASE
	  JRST	[SKIPN	IGNORE	;UNLESS /NOERROR,
		 JRST	STRTU1	;LET OPERATOR CORRECT ERRORS
		 JRST	.+1]	;WRONG--CONTINUE IN BLIND FAITH
	PUSHJ	P,GOHOME##	;REWRITE HOME BLOCKS IF NECESSARY
	PUSHJ	P,FILMAN##	;DO ONCE-ONLY MANDATORY FILE SYSTEM SETUP
	SKIPN	.UONCE##	;USER-MODE?
	SKIPN	REFLAG##	;NO--AUTOMATIC "LOGIN" WANTED?
	JRST	STRTU8		;THEN NO LOGIN OPTION
	MOVE	T1,FFAPPN##	;[OPR]
	MOVEM	T1,REFLAG##	;SET AS FREE LOGIN PPN
	MOVEI	T1,[ASCIZ /To automatically log in under /]
	PUSHJ	P,ICONM		;PRINT TEXT
	MOVE	T2,FFAPPN##	;GET [OPR]
	PUSHJ	P,PRTPPN##	;PRINT PPN
	MOVEI	T1,[ASCIZ / type "LOGIN"/]
	PUSHJ	P,CONMES##	;PRINT TEXT
	PUSHJ	P,CRLFOP	;APPEND A CRLF
STRTU8:	PJRST	PVQCK		;NOW START TIMESHARING
;SWITCH AND OPTION ACTION MACROS

;START-UP OPTIONS

DEFINE	OPTINS,<

X (CHANGE,.CHANG,<Change system parameters>)
X (DEFINE,.DEFIN,<Define structures and system lists>)
X (DESTROY,.DESTR##,<Dissolve all structures in the system>)
X (DISSOLVE,.DISSO##,<Dissolve a single structure>)
X (GO,.GO,<Start timesharing>)
X (NOINITIA,.NOINI,<Start timesharing without system initialization>)
X (REFRESH,.REFRE##,<Refresh selected structures>)
X (SHOW,.SHOW,<Display system parameters>)

>; END DEFINE OPTINS

;SWITCHES FOR START-UP OPTIONS

DEFINE	SWTCHS,<

X (NOASL,NOASL,<Don't use preserved active swapping list>)
X (NOCOPY,NOCOPY,<Don't start CRSCPY>)
IFN FTKL10,<
X (NOPRIMARY,NOPRIM,<Start timesharing in secondary protocol>)
>;; END IFN FTKL10
X (NOSDL,NOSDL,<Don't use preserved system dump list>)
X (NOSSL,NOSSL,<Don't use preserved system search list>)
X (NOVALIDATE,NOVALI,<Don't require account validation>)
X (STANDALONE,STAND,<Start timesharing with SCHED 10 set>)

>; END DEFINE SWTCHS
;STARTUP OPTION COMMAND NAMES
DEFINE	X	(NAME,ADDR,HELP),<EXP	<SIXBIT/NAME/>>
OPTTAB:	OPTINS
OPTLEN==.-OPTTAB		;LENGTH OF START-UP OPTIONS TABLE

;STARTUP OPTION COMMAND DISPATCH
DEFINE	X	(NAME,ADDR,HELP),<IFIW	ADDR>
OPTADR:	OPTINS

;STARTUP OPTION COMMAND HELP TEXT
DEFINE	X	(NAME,ADDR,HELP),<IFIW	[ASCIZ \'HELP\]>
OPTTXT:	OPTINS

;LOCATIONS POKED BY USRONC WITH USER-MODE TABLE ADDRESSES
OPTPTR::-OPTLEN,,OPTTAB		;COMMAND TABLE
OPTDSP::IFIW	OPTADR		;COMMAND DISPATCH TABLE
OPTHLP::IFIW	OPTTXT		;COMMAND HELP TEXT
;STARTUP OPTION SWITCH NAMES
DEFINE	X	(NAME,ADDR,HELP),<EXP	<SIXBIT /NAME/>>
SWTTAB:	SWTCHS
SWTLEN==.-SWTTAB		;LENGTH OF SWITCH TABLE

;STARTUP OPTION SWITCH DISPATCH
DEFINE	X	(NAME,ADDR,HELP),<IFIW	ADDR>
SWTADR:	SWTCHS

;STARTUP OPTION SWITCH HELP TEXT
DEFINE	X	(NAME,ADDR,HELP),<IFIW	[ASCIZ \'HELP\]>
SWTTXT:	SWTCHS


;LOCATIONS POKED BY USRONC WITH USER-MODE TABLE ADDRESSES
SWTPTR::-SWTLEN,,SWTTAB		;SWITCH TABLE
SWTDSP::IFIW	SWTADR		;SWITCH DISPATCH TABLE
SWTHLP::IFIW	SWTTXT		;SWITCH HELP TEXT
SUBTTL	STARTUP OPTION COMMANDS -- .CHANG - CHANGE

.CHANG::SETOM	CHGFLG		;INDICATE CHANGE, NOT DEFINE
	MOVEI	T1,[ASCIZ /Change/] ;PROMPT
	SETZ	T2,		;NO DEFAULT KEYWORD
	MOVE	T3,CHGPTR	;TABLE OF LEGAL RESPONSES
	PUSHJ	P,PRSKEY	;FETCH A KEYWORD
	  JRST	CPOPJ1##	;GUESS HE CHANGED HIS MIND
	ADD	T1,CHGDSP	;INDEX INTO THE CHANGE DISPATCH TABLE
	JRST	@(T1)		;GO DEFINE SOMETHING


DEFINE	CHGOPT,<

X	(ASL,CHGASL##)
X	(DATE,CHGDAT)
X	(NETWOR,CHGNET)
X	(SDL,CHGSDL##)
X	(SETS,CHGSET##)
X	(SSL,CHGSSL##)
X	(STRUCT,CHGSTR##)
X	(UNIT,CHGUNI##)

> ;END DEFINE CHGOPT

DEFINE	X	(NAME,ADDR),<EXP <SIXBIT/NAME/>>
CHGTAB:	CHGOPT
CHGLEN==.-CHGTAB

DEFINE	X	(NAME,ADDR),<IFIW ADDR>
CHGADR:	CHGOPT

;USRONC REWRITES THESE LOCATIONS
CHGPTR::-CHGLEN,,CHGTAB
CHGDSP::IFIW CHGADR
;CHANGE DATE
CHGDAT:	SETZM	ONCTCH		;DEFEAT PRSCON
	SETZM	FETFLG		;ASSUME NO FE TIME
	SKIPN	.UONCE##	;USER MODE CAN'T ASK THE FRONT ENDS
	PUSHJ	P,GFETIM	;SEE IF FRONT END KNOWS TIME
	  JRST	DATLP1		;IT DOES NOT, TRY FOR LAST CRASH TIME
	JRST	DATLP2		;IT DOES, USE IT FOR A DEFAULT

DATHLP:	PUSHJ	P,RSTDEF	;SOMETHING WENT WRONG, GIVE OPR TIME TO PONDER
	SETZM	FETFLG		;FORGET WHATEVER THE FE MAY HAVE TOLD US
	SKIPA	T1,[[ASCIZ /Please type today's date as MON-DD(-YY)
/]]
DATLP1:	MOVEI	T1,[ASCIZ /Date: /]
	SETOM	LOCSEC##	;NO TIME KNOWN YET
	SETOM	CRSDAY		;FAR FAR DISTANT PAST
	PUSHJ	P,CHKDCS	;CRASH CHECKSUM REASONABLE?
	  JRST	ASKDAT		;NO, SO MUST ASK FOR DATE AND TIME
	MOVE	T2,T4		;COPY DATE
	ANDI	T2,17		;MASK OUT MONTH
	MOVEM	T2,LOCMON##	;STORE
	MOVE	T1,T4		;COPY DATE AGAIN
	LSH	T1,-4		;SHIFT OFF MONTH
	MOVE	T2,T1		;COPY DATE
	ANDI	T2,37		;MASK OUT DAY
	MOVEM	T2,LOCDAY##	;STORE IN COMMON
	LSH	T1,-5		;SHIFT OFF DAY
	ADDI	T1,^D1970	;ADD IN BASE
	MOVEM	T1,LOCYER##	;STORE
	HRRZ	T1,CRSDTM	;GET TIME
	IDIVI	T1,^D60*^D60	;GET HOURS
	IDIVI	T2,^D60		;GET MIN
	MOVEM	T1,LOCHOR##	;STORE HOURS
	MOVEM	T2,LOCMIN##	;STORE MIN
	MOVEM	T3,LOCSEC##	;STORE SECONDS
	PUSHJ	P,CHKMNT##	;SEE IF PASSED THROUGH MIDNIGHT WHILE RELOADING
	CAIA			;SKIP
DATLP2:	SETOM	FETFLG		;GOT TIME FROM FE
	SKIPGE	DEFALW		;SEE IF ALREADY DEFAULTING
	MOVMS	FETFLG		;YES--REMEMBER THAT
	PUSHJ	P,THSDA##	;RECOMPUTE THSDAT
	PUSHJ	P,SUDATE##	;COMPUTE DATE TOO (FOR DOW PRINTING)
DATLP3:	MOVE	T1,THSDAT##	;GET THSDAT
	MOVEM	T1,CRSDAY	;SAVE FOR LATER
	MOVE	T1,DEFSP	;GET DEFAULT STRING POINTER
	MOVEM	T1,DEFPTR	;STORE AS POINTER
	MOVE	T1,LOCDAY##	;GET THE DAY
	PUSHJ	P,DECDEF	;STORE AS PART OF DEFAULT
	MOVEI	T1,"-"		;ADD A DASH
	IDPB	T1,DEFPTR	; ..
	MOVE	T1,LOCMON##	;GET MONTH
	MOVEI	T1,MONTHS-1(T1)	;POINT AT ASCII MNEMONIC PLUS "-" AT END
	PUSHJ	P,DEFTXT	;STUFF IT
	MOVE	T1,LOCYER##	;GET THE YEAR
	PUSHJ	P,DECDEF	;ADD THAT ON
	SKIPN	FETFLG		;GOT TIME FROM FE?
	JRST	DATLP4		;NO
	SETOM	CRSDAY		;YES, FORGET CRASH TIME
	SKIPA	T1,[[ASCIZ /	;From FE clock/]]
DATLP4:	MOVEI	T1,[ASCIZ /	;From last crash/]
	PUSHJ	P,DEFTXT	;ADD TO DEFAULT
	MOVEI	T1,[ASCIZ /Date: /]
	MOVEI	T2,DEFBUF
	SKIPN	FETFLG		;TIME FROM FE?
	SKIPA	T3,OPRCNT	;NO, USE OPRCNT
	MOVEI	T3,^D5		;YES, REDUCE WAIT TO 5 SECS
	PUSHJ	P,ASKDEF	;ASK QUESTION
	  JRST	HAVDAT
	JRST	ASKDT1		;GO PARSE THE ANSWER
;HERE WHEN WE MUST ASK THE OPERATOR THE DATE (PROMPT STRING IN T1)

ASKDAT:	PUSHJ	P,ICONM		;OUTPUT THE QUESTION
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	PUSHJ	P,GETLIN	;READ A LINE
	  JRST	DATHLP		;GIVE THEM SOME HELP
ASKDT1:	MOVEI	T1,LOCYER##	;POINT AT YEAR/MONTH/DAY TRIPLET
	PUSHJ	P,GTDATE##	;GET DATE
	  JRST	DATHLP		;ERROR
	MOVE	T2,LOCYER##	;GET THE YEAR THE OPERATOR CLAIMED
	SUBI	T2,^D1900	;SUBTRACT BASE
	CAMGE	T2,ONCYER	;WAY OUT OF LINE?
	JRST	DATHLP		;YES, GIVE THEM SOME HELP
	MOVE	T1,LOCMON##	;NOW CHECK DAY ARG
	SOS	T1		;INDEX INTO MONTAB
	LDB	T2,PMONTB##	;GET NUMBER OF DAYS (MINUS 1) THAT MONTH
	AOS	T2		;MAKE DAYS IN THAT MONTH
	SOJN	T1,ASKDT2	;JUMP IF NOT FEB
	MOVE	T1,LOCYER##	;LEAP YEAR?
	TRNN	T1,3
	AOS	T2		;YES - 29 DAYS
ASKDT2:	CAML	T2,LOCDAY##	;CHECK DAY ARG
	JRST	HAVDAT		;OK
	MOVEI	T1,[ASCIZ/?Illegal day of month
/]
	PUSHJ	P,ICONM		;START MESSAGE
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	JRST	DATHLP		;GIVE THEM SOME HELP
HAVDAT:	PUSHJ	P,THSDA##	;COMPUTE & STORE THSDAT
	PUSHJ	P,SUDATE##	;COMPUTE DATE TOO (FOR DOW PRINTING)
	MOVE	T1,THSDAT##	;GET THSDAT
	CAML	T1,CRSDAY	;SPECIFIED DATE AFTER LAST CRASH?
	JRST	VALID		;YES, GO VALIDATE THE DATE
	MOVEI	T1,[ASCIZ /
%Specified date is prior to last crash.
Last crash date:  /]
	PUSHJ	P,ICONM		;START MESSAGE
	MOVEI	T1,DEFBUF	;POINT AT THEIR RESPONSE
	JRST	VALID2		;PRINT SUSPECT DATE AND ASK IF CORRECT

VALID:	MOVE	T1,ONCMON	;FORM 12 BIT DATE FOR COMPARISON
	IMULI	T1,^D31
	MOVEM	T1,CHKDAT
	MOVE	T1,ONCDAY
	SUBI	T1,1+^D31
	ADDM	T1,CHKDAT
	MOVE	T1,ONCYER
	SUBI	T1,^D64		;ADJUST TO T=0
	IMULI	T1,^D12*^D31
	ADD	T1,CHKDAT
	CAMLE	T1,THSDAT##	;SPECIFIED DATE PRIOR TO SYSTEM CREATION DATE?
	JRST	VALID1		;YES
	SKIPE	DTCKFL		;DATE OK, WANT TO VERIFY DATE/TIME ENTERED?
	JRST	VALID3		;ASK OPR TO CONFIRM WHAT HE TYPED
	JRST	TIMLOP		;GO GET TIME

VALID1:	MOVEI	T1,[ASCIZ /
%Specified date is prior to monitor creation date.
Creation date:  /]
	PUSHJ	P,ICONM		;QUESTION EARLY DATE
	MOVEI	T1,SYSDAT##	;POINT AT SYSTEM CREATION DATE
VALID2:	PUSHJ	P,CONMES##	;OUTPUT IT
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
VALID3:	MOVEI	T1,[ASCIZ /
Specified date:   /]
	PUSHJ	P,ICONM		;START MESSAGE
	PUSHJ	P,PRDOFW##	;PRINT DAY OF THE WEEK
	PUSHJ	P,PRSPC##	;SPACE OVER
	PUSHJ	P,PRDAYD##	;PRINT DATE AND TIME
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	SKIPE	FETFLG		;DID DATE/TIME COME FROM FE?
	PUSHJ	P,RSTDEF	;YES, GIVE OPR TIME TO DISLIKE
	MOVEI	T1,[ASCIZ /Is this correct/]
	MOVSI	T2,'YES'	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ	;GET YES/NO RESPONSE
	JUMPE	T1,DATHLP	;HE SAID "NO"
	JRST	TIMLOP		;HE LIKES IT ANYWAY
	SUBTTL	ASK FOR TIME OF DAY

TIMHLP:	SETZM	FETFLG		;FORGET ANY TIME FROM THE FE
	PUSHJ	P,RSTDEF	;GIVE OPR TIME TO PONDER
	SKIPA	T1,[[ASCIZ /Please type time as HHMMSS or HH:MM:SS
/]]
TIMLOP:	MOVEI	T1,[ASCIZ /Time: /]
	SKIPGE	LOCSEC##	;DO WE KNOW TIME
	JRST	ASKTIM		;NO--GO ASK FOR IT
	MOVE	T1,DEFSP	;SET UP BYTE POINTER TO DEFBUF
	MOVEM	T1,DEFPTR
	MOVE	T1,LOCHOR##	;SETUP DEFAULT
	PUSHJ	P,DECDEF	; ..
	MOVEI	T1,":"
	IDPB	T1,DEFPTR
	MOVE	T1,LOCMIN##	; ..
	PUSHJ	P,DECDEF	; ..
	MOVEI	T1,":"
	IDPB	T1,DEFPTR
	MOVE	T1,LOCSEC##	; ..
	PUSHJ	P,DECDEF	; ..
	SKIPE	FETFLG		;GOT TIME FROM FE?
	SKIPA	T1,[[ASCIZ /		;From FE clock/]]
	MOVEI	T1,[ASCIZ /		;From last crash or previous answer/]
	PUSHJ	P,DEFTXT	;ADD TO DEFAULT
	MOVEI	T1,[ASCIZ /Time: /]
	MOVEI	T2,DEFBUF
	SKIPN	FETFLG		;TIME FROM FE?
	SKIPA	T3,OPRCNT	;NO, USE OPRCNT
	MOVEI	T3,^D5		;YES, REDUCE WAIT TO 5 SECS
	PUSHJ 	P,ASKDEF	;GO ASK ABOUT TIME
	  JRST	HAVTIM		;JUST A CR
	JRST	ASKTM1		;GO PARSE TIME

ASKTIM:	PUSHJ	P,ICONM		;OUTPUT THE QUESTION
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	PUSHJ	P,GETLIN	;READ A LINE
	  JRST	TIMHLP		;JUST A CR
ASKTM1:	PUSHJ	P,RDTIM##	;GET TIME OF DAY
	  JRST	[PUSHJ	P,ERRCRL## ;ISSUE CRLF AND ERROR MESSAGE
		 PUSHJ	P,OPOUT	;PUSH OUTPUT OUT
		 JRST	TIMHLP]	;LOOP BACK AND TRY AGAIN
	IDIVI	T1,^D60*^D60	;T1:= HOURS
	IDIVI	T2,^D60		;T2:= MINUTES, T3:= SECONDS
	MOVEM	T1,LOCHOR##	;SAVE HOURS
	MOVEM	T2,LOCMIN##	;SAVE MINUTES
	MOVEM	T3,LOCSEC##	;SAVE SECONDS
;	PJRST	HAVTIM		;GO COMPARE AGAINST LAST CRASH TIME
HAVTIM:	MOVE	T1,LOCHOR##	;GET HOURS
	MOVE	T2,LOCMIN##	;GET MINUTES
	IMULI	T1,^D60		;CONVERT HOURS TO MINUTES
	ADD	T1,T2		;MINUTES SINCE MIDNIGHT
	IMUL	T1,TICMIN##	;JIFFIES SINCE MIDNIGHT
	MOVEM	T1,TIME##	;TIME=JIFFIES SINCE MIDNIGHT
	MOVE	T1,LOCSEC##	;SECONDS INTO THIS MINUTE
	IMUL	T1,TICSEC##	;JIFFIES INTO THIS MINUTE
	ADDB	T1,TIME##	;TIME=JIFFIES SINCE MIDNIGHT
	HRRZ	T2,CRSDTM	;GET TIME OF DAY IN SECONDS AT LAST CRASH
	SUBI	T2,RLDTIM##	;SUBTRACT TIME REQUIRED FOR AUTO-RELOAD
	IMUL	T2,TICSEC##	;CONVERT SECONDS TO TICKS
	MOVE	T3,THSDAT##	;GET SPECIFIED DATE
	CAMGE	T1,T2		;SPECIFIED TIME PRIOR TO CRASH TIME?
	CAME	T3,CRSDAY	;YES, IF DAY AND CRASH DAY MATCH, COMPLAIN
	SKIPA			;TIME IS LEGAL, SEE IF OPR VERIFICATION REQ'D
	JRST	HAVTM1		;INVALID TIME, COMPLAIN
	SKIPE	DTCKFL		;OPR NEED TO VERIFY TIME?
	JRST	HAVTM3		;YES, CHECK IT OUT
	JRST	HAVTM5		;NO, GOOD TIME, MOVE ONWARD

HAVTM1:	SKIPE	DTCKFL		;OPR NEED TO VERIFY TIME?
	JRST	HAVTM2		;YES, DO THIS DIFFERENTLY
	MOVEI	T1,[ASCIZ /
%Specified time is prior to last crash.
Specified time:  /]
	PUSHJ	P,ICONM		;START MESSAGE
	PUSHJ	P,PRDTIM##	;PRINT TIME OF DAY BASED ON LOCHOR/MIN/SEC
	MOVEI	T1,[ASCIZ /Last crash time:  /]
	PUSHJ	P,CONMES##
	HRRZ	T1,CRSDTM	;GET TIME OF LAST CRASH (SECS PAST MIDNIGHT)
	SUBI	T1,RLDTIM##	;SUBTRACT TIME FOR RELOAD
	IMUL	T1,TICSEC##	;CONVERT TO TICKS
	PUSHJ	P,PRTIME##	;PRINT TIME OF DAY
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	JRST	HAVTM4		;SEE IF THEY LIKE IT
HAVTM2:	MOVEI	T1,[ASCIZ /
%Specified time is prior to last crash time.
Crash time:  /]
	PUSHJ	P,ICONM		;START MESSAGE
	HRRZ	T1,CRSDTM	;GET TIME OF LAST CRASH (SECS PAST MIDNIGHT)
	SUBI	T1,RLDTIM##	;SUBTRACT TIME FOR RELOAD
	IMUL	T1,TICSEC##	;CONVERT TO TICKS
	PUSHJ	P,PRTIMS##	;PRINT TIME
	PUSHJ	P,CRLF		;AND CRLF
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
HAVTM3:	MOVEI	T1,[ASCIZ/
Specified time:  /]
	PUSHJ	P,ICONM		;START MESSAGE
	MOVE	T1,TIME##	;GET TIME
	PUSHJ	P,PRTIMS##	;PRINT IT
	MOVEI	T1,[ASCIZ/ (/]	;GET TEXT
	PUSHJ	P,CONMES##	;TYPE
	MOVE	T1,TIME##	;GET TIME AGAIN
	PUSHJ	P,PRAMPM##	;TYPE AS AM/PM
	MOVEI	T1,[ASCIZ/)/]	;
	PUSHJ	P,CONMES##	;
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
HAVTM4:	SKIPE	FETFLG		;DID DATE/TIME COME FROM FE?
	PUSHJ	P,RSTDEF	;YES, GIVE OPR TIME TO DISLIKE
	MOVEI	T1,[ASCIZ /Is this correct/]
	MOVSI	T2,'YES'	;DEFAULT ANSWER
	PUSHJ	P,PRSYNQ	;GET YES/NO RESPONSE
	JUMPE	T1,DATLP3	;HE SAID "NO"

HAVTM5:	SKIPGE	FETFLG		;DID DATE/TIME COME FROM FE?
	PUSHJ	P,RSTDEF	;YES, GIVE OPR TIME TO REPLY AGAIN
	PUSHJ	P,TACINI	;MAKE SURE OF VALID DATE-TIME EVERYWHERE
	JRST	CPOPJ1##	;FINALLY DONE
;TABLE OF ASCIZ MONTH NAMES USED IN DEFAULTING DATE STRING

DEFINE	MONTH.(NAME),<
	IRP	NAME,<ASCIZ /'NAME'-/>
>; END DEFINE MONTH.

MONTHS:	MONTH.	(<Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec>)

ONCMON:	M.MON##			;MONTH MONITOR WAS GEN'D
ONCDAY:	M.DAY##			;DAY MONITOR WAS GEN'D
ONCYER:	M.YEAR##		;YEAR MONITOR WAS GEN'D
DTCKFL:	M.DTCK##		;FLAG IF -1 OPR MUST VERIFY DATE/TIME
;CHANGE NETWORKS
CHGNET:	SETZM	ONCTCH		;DEFEAT PRSCON
	SKIPN	[M.NET##]	;HAVE ANY NETWORKS?
	JRST	CPOPJ1##	;NO
	MOVEI	T1,[ASCIZ /System-wide node name/]
	SKIPN	T2,ANFNAM##	;ANF-10 NAME OVERWRITES OTHERS
	MOVE	T2,DCNNAM##	;TRY DECNET
	PUSHJ	P,PRSSIX	;PROMPT AND PARSE RESULTS
	MOVEM	T1,STANAM##	;UPDATE

;ANF-10
CHGNE1:	SKIPN	[M.ANF##]	;NECESSARY SOFTWARE LOADED?
	JRST	CHGNE2		;NO
	MOVEI	T1,[ASCIZ /ANF-10 node name/]
	MOVE	T2,ANFNAM##	;DEFAULT
	PUSHJ	P,PRSSIX	;PROMPT AND PARSE RESULTS
	MOVEM	T1,ANFNAM##	;UPDATE
	MOVEI	T1,[ASCIZ /ANF-10 node number/]
	MOVE	T2,ANFNUM##	;DEFAULT
	MOVEI	T3,1		;LOW RANGE
	MOVEI	T4,77		;HIGH RANGE
	PUSHJ	P,PRSOCT	;PROMPT AND PARSE RESULTS
	MOVEM	T1,ANFNUM##	;UPDATE
	PUSHJ	P,NETINI##	;ADJUST NDB, DDBS, ETC.

CHGNE2:	SKIPN	[M.DECN##]	;NECESSARY SOFTWARE LOADED?
	JRST	CHGNE3		;NO
	MOVEI	T1,[ASCIZ /DECnet node name/]
	MOVE	T2,DCNNAM##	;DEFAULT
	PUSHJ	P,PRSSIX	;PROMPT AND PARSE RESULTS
	MOVEM	T1,DCNNAM##	;UPDATE
	MOVEI	T1,[ASCIZ /DECnet area number/]
	MOVE	T2,DCNHOM##	;DEFAULT
	MOVEI	T3,1		;LOW RANGE
	MOVEI	T4,^D63		;HIGH RANGE
	PUSHJ	P,PRSDEC	;PROMPT AND PARSE RESULTS
	MOVEM	T1,DCNHOM##	;UPDATE
	MOVEI	T1,[ASCIZ /DECnet node number/]
	MOVE	T2,DCNNUM##	;DEFAULT
	MOVEI	T3,1		;LOW RANGE
	MOVEI	T4,^D1023	;HIGH RANGE
	PUSHJ	P,PRSDEC	;PROMPT AND PARSE RESULTS
	MOVEM	T1,DCNNUM##	;UPDATE

CHGNE3:	SKIPN	[M.LAT##]	;NECESSARY SOFTWARE LOADED?
	JRST	CHGNE4		;NO
	MOVEI	T1,[ASCIZ /LAT service name/]
	MOVE	T2,LATNAM##	;DEFAULT
	PUSHJ	P,PRSSIX	;PROMPT AND PARSE RESULTS
	MOVEM	T1,LATNAM##	;UPDATE

CHGNE4:	JRST	CPOPJ1##	;RETURN
SUBTTL	STARTUP OPTION COMMANDS -- .DEFIN - DEFINE

.DEFIN::SETZM	CHGFLG		;INDICATE DEFINE, NOT CHANGE
	MOVEI	T1,[ASCIZ /Define/] ;PROMPT
	SETZ	T2,		;NO DEFAULT KEYWORD
	MOVE	T3,[-DEFLEN,,DEFTAB] ;TABLE OF LEGAL RESPONSES
	PUSHJ	P,PRSKEY	;FETCH A KEYWORD
	  JRST	CPOPJ1##	;HE HAD SECOND THOUGHTS
	JRST	@DEFDSP(T1)	;GO DEFINE SOMETHING


DEFINE	DEFOPT,<

X	(ASL,DEFASL##)
X	(SDL,DEFSDL##)
X	(SSL,DEFSSL##)
X	(STRUCT,DEFSTR##)

> ;END DEFINE DEFOPT

DEFINE	X	(NAME,ADDR),<EXP <SIXBIT/NAME/>>
DEFTAB:	DEFOPT
DEFLEN==.-DEFTAB

DEFINE	X	(NAME,ADDR),<IFIW ADDR>
DEFDSP:	DEFOPT
SUBTTL	STARTUP OPTION COMMANDS -- .GO - GO

.GO::	SETOM	GOFLAG		;SAY WE'RE DONE ASKING QUESTIONS
	JRST	CPOPJ1##	;AND RETURN
SUBTTL	STARTUP OPTION COMMANDS -- .HELP - HELP


.HELP:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSHJ	P,OTSET		;SETUP OUTPUT BYTE POINTER, ETC.
	PUSHJ	P,CRLFOP	;START WITH A CRLF
	PUSHJ	P,CRLFOP	;ONE MORE FOR CLARITY
	MOVEI	T1,[ASCIZ /Options are:/]
	PUSHJ	P,CONOUT	;PRINT TEXT
	HLLZ	P1,OPTPTR	;AOBJN POINTER TO TABLES

HELP1:	PUSHJ	P,OTSET		;RESET OUTPUT BYTE POINTER, ETC.
	HRRZ	T2,P1		;GET TABLE INDEX
	ADD	T2,OPTPTR	;OFFSET INTO NAME TABLE
	MOVE	T2,(T2)		;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /	- /]
	PUSHJ	P,CONMES##	;PRINT SEPARATOR
	HRRZ	T1,P1		;GET TABLE OFFSET
	ADD	T1,OPTHLP	;OFFSET INTO HELP TEXT TABLE
	MOVE	T1,(T1)		;FETCH STRING ADDRESS
	PUSHJ	P,CONMES##	;PRINT IT
	PUSHJ	P,CRLFOP	;APPEND A CRLF
	AOBJN	P1,HELP1	;LOOP FOR ALL OPTIONS
	SKIPN	SWTPTR		;HAVE ANY SWITCHES?
	JRST	HELP3		;NO
	PUSHJ	P,OTSET		;RESET OUTPUT BYTE POINTER, ETC.
	PUSHJ	P,CRLFOP	;START WITH A CRLF
	PUSHJ	P,CRLFOP	;ONE MORE FOR CLARITY
	MOVEI	T1,[ASCIZ /Switches are:/]
	PUSHJ	P,CONOUT	;PRINT TEXT
	HLLZ	P1,SWTPTR	;AOBJN POINTER TO TABLES

HELP2:	PUSHJ	P,OTSET		;RESET OUTPUT BYTE POINTER, ETC.
	HRRZ	T2,P1		;GET TABLE INDEX
	ADD	T2,SWTPTR	;OFFSET INTO NAME TABLE
	MOVE	T2,(T2)		;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T1,[ASCIZ /	- /]
	PUSHJ	P,CONMES##	;PRINT SEPARATOR
	HRRZ	T1,P1		;GET TABLE OFFSET
	ADD	T1,SWTHLP	;OFFSET INTO HELP TEXT TABLE
	MOVE	T1,(T1)		;FETCH STRING ADDRESS
	PUSHJ	P,CONMES##	;PRINT IT
	PUSHJ	P,CRLFOP	;APPEND A CRLF
	AOBJN	P1,HELP2	;LOOP FOR ALL OPTIONS

HELP3:	PUSHJ	P,OTSET		;RESET OUTPUT BYTE POINTER, ETC.
	PJRST	CRLFOP		;END WITH AN EXTRA CRLF
SUBTTL	STARTUP OPTION COMMANDS -- SHELP - SHORT HELP


SHELP:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVE	P1,OPTPTR	;AOBJN POINTER TO OPTION NAMES
	MOVEI	P2,6		;SIX OPTIONS PER LINE
	PUSHJ	P,CRLFOP	;START WITH A CRLF
	PUSHJ	P,CRLFOP	;ONE MORE FOR CLARITY
	MOVEI	T1,[ASCIZ /Options are:/]
	PUSHJ	P,ICONM		;PRINT TEXT

SHELP1:	MOVEI	T1,[ASCIZ /	/] ;TAB OVER
	PUSHJ	P,CONMES##	;START LINE
	MOVE	T2,(P1)		;GET OPTION NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	SOJG	P2,SHELP2	;ROOM FOR MORE ON THE LINE?
	PUSHJ	P,CRLFOP	;START ANOTHER LINE
	MOVEI	T1,[ASCIZ /	/] ;TAB
	PUSHJ	P,ICONM		; OVER
	MOVEI	P2,6		;RESET COUNT

SHELP2:	AOBJN	P1,SHELP1	;LOOP FOR ANOTHER COMMAND
	PUSHJ	P,CRLFOP	;END WITH A CRLF
	MOVEI	T1,[ASCIZ /Type "HELP" for additional information/]
	PJRST	CONOUT		;PRINT TEXT AND RETURN
SUBTTL	STARTUP OPTION COMMANDS -- .NOINI - NOINITIA


.NOINI:	PUSHJ	P,NOCOPY	;PREVENT CRSCPY FROM RUNNING
	SETOM	GOFLAG		;READY TO START THE MONITOR
	JRST	CPOPJ1##	;RETURN
SUBTTL	STARTUP OPTION COMMANDS -- .SHOW -  SHOW


.SHOW::	MOVEI	T1,[ASCIZ /Show/]
	SETZ	T2,		;NO DEFAULT
	MOVE	T3,SHWPTR	;TABLE OF OPTIONS
	PUSHJ	P,PRSKEY	;GET AN ANSWER
	  JRST	CPOPJ1##	;BACK OUT OF SHOW
	ADD	T1,SHWDSP	;INDEX INTO THE DISPATCH TABLE
	PUSHJ	P,@(T1)		;DO SOMETHING
	  JFCL			;FOOL
	JRST	CPOPJ1##	;RETURN

DEFINE	SHWOPT,<

X	(ASL,SHWASL##)
X	(DATE,SHWDAT)
X	(NETWOR,SHWNET)
X	(SDL,SHWSDL##)
X	(SETS,SHWSET##)
X	(SSL,SHWSSL##)
X	(STRUCT,SHWSTR##)
X	(UNIT,SHWUNI##)

> ;END DEFINE SHWOPT

DEFINE	X	(NAME,ADDR),<EXP <SIXBIT/NAME/>>
SHWTAB:	SHWOPT
SHWLEN==.-SHWTAB

DEFINE	X	(NAME,ADDR),<IFIW ADDR>
SHWADR:	SHWOPT

;USRONC WRITES THESE LOCATIONS
SHWPTR::-SHWLEN,,SHWTAB
SHWDSP::IFIW SHWADR
;SHOW DATE
SHWDAT:	PUSHJ	P,OTSET		;SET UP OUTPUT BUFFER
	PUSHJ	P,DAYTIM##	;PRINT DAY, DATE, & TIME
	PUSHJ	P,CRLFOP	;APPEND A CRLF
	JRST	CPOPJ1##	;AND RETURN
;SHOW NETWORKS
SHWNET::MOVEI	T1,[ASCIZ /
Networks:
	System-wide node name: /]
	PUSHJ	P,ICONM		;PRINT TEXT
	MOVE	T2,STANAM##	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP	;END LINE

SHWNE1:	SKIPN	[M.ANF##]	;NECESSARY SOFTWARE LOADED?
	JRST	SHWNE2		;NO
	MOVEI	T1,[ASCIZ /	ANF-10 node /]
	PUSHJ	P,ICONM		;PRINT TEXT
	MOVE	T2,ANFNAM##	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T3,"("		;START OF DELIMITER
	PUSHJ	P,COMTYO##	;PRINT IT
	MOVE	T1,ANFNUM##	;GET NUMBER
	PUSHJ	P,PRTDI8##	;PRINT IT
	MOVEI	T3,")"		;END OF DELIMITER
	PUSHJ	P,COMTYO##	;PRINT IT
	PUSHJ	P,CRLFOP	;END LINE

SHWNE2:	SKIPN	[M.DECN##]	;NECESSARY SOFTWARE LOADED?
	JRST	SHWNE3		;NO
	MOVEI	T1,[ASCIZ /	DECnet node /]
	PUSHJ	P,ICONM		;PRINT TEXT
	MOVE	T2,DCNNAM##	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T3,"("		;START OF DELIMITER
	PUSHJ	P,COMTYO##	;PRINT IT
	MOVE	T1,DCNHOM##	;GET AREA
	PUSHJ	P,PRTDIG##	;PRINT IT
	PUSHJ	P,PRPER##	;SEPARATOR
	MOVE	T1,DCNNUM##	;GET NUMBER
	PUSHJ	P,PRTDIG##	;PRINT IT
	MOVEI	T3,")"		;END OF DELIMITER
	PUSHJ	P,COMTYO##	;PRINT IT
	PUSHJ	P,CRLFOP	;END LINE

SHWNE3:	SKIPN	[M.LAT##]	;NECESSARY SOFTWARE LOADED?
	JRST	SHWNE4		;NO
	MOVEI	T1,[ASCIZ /	LAT service: /]
	PUSHJ	P,ICONM		;PRINT TEXT
	MOVE	T2,LATNAM##	;GET NAME
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSHJ	P,CRLFOP	;END LINE

SHWNE4:	JRST	CPOPJ1##	;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /NOASL


NOASL:	SETZM	PREASL		;INVLAIDATE CORE COPY OF ASL
	POPJ	P,		;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /NOCOPY


NOCOPY:	MOVSI	T1,(DF.DCC)	;DISABLE INVOCATION OF
	IORM	T1,DEBUGF##	; CRSCPY AT STARTUP
	POPJ	P,		;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /NOPRIMARY


IFN FTKL10,<
NOPRIM:	MOVSI	T1,(ST%NPP)	;GET BIT
	IORM	T1,CNFST2##	;DISABLE PRIMARY PROTOCOL STARTUP
	POPJ	P,		;RETURN
> ;END IFN FTKL10
SUBTTL	STARTUP OPTION SWITCHES -- /NOSDL


NOSDL:	SETZM	PRESDL		;INVALIDATE CORE COPY OF SDL
	POPJ	P,		;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /NOSSL


NOSSL:	SETZM	PRESSL		;INVALIDATE CORE COPY OF SSL
	POPJ	P,		;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /NOVALIDATE


NOVALI:	MOVSI	T1,(ST%ACV)	;ACCOUNT VALIDATION BIT
	ANDCAM	T1,CNFST2##	;TELL [SYSTEM]ACCOUNTING TO BE FORGIVING
	POPJ	P,		;RETURN
SUBTTL	STARTUP OPTION SWITCHES -- /STANDALONE


STAND:	MOVEI	T1,ST.NRT	;NO REMOTE TERMINALS
	IORM	T1,STATES##	;SET SCHED 10
	POPJ	P,		;RETURN
PRSSET::MOVE	T1,[TXTBUF,,TXTBUF+1] ;SET UP BLT
	SETZM	TXTBUF		;CLEAR FIRST WORD
	BLT	T1,TXTBUF+TXTLEN-1 ;CLEAR BUFFER
	MOVE	T1,[POINT 7,TXTBUF] ;BYTE POINTER TO STORAGE
	MOVEM	T1,TXTPTR	;SAVE
	MOVEI	T1,<TXTLEN*5>-1	;BYTE COUNT
	MOVEM	T1,TXTCNT	;SAVE
	SETZM	ONCTCH		;NO LONGER HAVE A VALID SEPARATOR
	MOVEI	T1,PRSTYO	;NEW CHARACTER TYPER
	EXCH	T1,.CPTOA##	;SWAP
	POPJ	P,		;RETURN


PRSTYO:	SOSLE	TXTCNT		;COUNT DOWN
	IDPB	T3,TXTPTR	;STORE CHARACTER
	POPJ	P,		;RETURN
PRSCON::LDB	T3,ONCTIP	;GET LAST SEPARATOR SEEN
	CAMN	T3,ONCTCH	;IF IT'S THE SAME AS WHAT'S STORED,
	CAIE	T3," "		;AND IT'S A SPACE,
	JRST	CPOPJ1##	;(WRONG--GIVE MUST-PROMPT RETURN)
	PUSH	P,ONCTCH	;YES--SAVE CHARACTER
	PUSH	P,ONCTIP	;AND TYPEIN POINTER
	PUSHJ	P,SKIPS1##	;SEE IF MORE ON THIS LINE
	  AOS	-2(P)		;NO--STILL NEED TO PROMPT
	POP	P,ONCTIP	;RESTORE TYPEIN POINTER
	POP	P,ONCTCH	;AND THE CHARACTER
	POPJ	P,		;RETURN NON-SKIP TO AVOID THE PROMPT
PRSKEY:	PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,T1		;SAVE PROMPT STRING
	PUSH	P,T2		;SAVE DEFAULT ANSWER
	PUSH	P,T3		;SAVE TABLE ADDRESS
	PUSHJ	P,PRSCON	;SEE IF WE CAN CONTINUE
	  JRST	PRSKE0		;YES--DO SO

PRSKE1:	MOVE	T1,-2(P)	;GET PROMPT
	PUSHJ	P,ICONM		;START THE LINE
	SKIPN	P1,(P)		;ANY KEYWORDS?
	JRST	PRSKE2		;NO
	MOVNI	P2,1		;INIT A FLAG
	MOVEI	T1,[ASCIZ / (/]	;START OF LIST
	PUSHJ	P,CONMES##	;START OF RANGE
	PUSHJ	P,OPTKEY	;PUT OUT A LIST OF OPTIONS
	MOVEI	T1,[ASCIZ /)/]	;END OF LIST
	PUSHJ	P,CONMES##	;PRINT TERMINATOR

PRSKE2:	SKIPN	-1(P)		;HAVE A DEFAULT?
	JRST	PRSKE3		;NOPE
	MOVEI	T1,[ASCIZ / [/]	;START OF DEFAULT
	PUSHJ	P,CONMES##	;PRINT TEXT
	MOVE	T2,-1(P)	;GET KEYWORD
	PUSHJ	P,PRNAME##	;PRINT IT
	PUSH	P,.CPTOA##	;SAVE TYPEOUT ADDRESS
	MOVEI	T1,DEFTYO	;TYPEOUT ROUTINE TO SETUP DEFAULT TEXT
	MOVEM	T1,.CPTOA##	;SET IT UP
	MOVE	T1,DEFSP	;INITIAL STRING POINTER
	MOVEM	T1,DEFPTR	;STORE AT BEGINNING OF DEFAULT BUFFER
	MOVE	T2,-2(P)	;GET DEFAULT AGAIN
	PUSHJ	P,PRNAME##	;STUFF INTO THE BUFFER
	MOVEI	T1,[ASCIZ /	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;ADD SOME MORE TO THE DEFAULT BUFFER
	MOVE	T1,DEFSP	;INITIAL POINTER
	MOVEM	T1,DEFPTR	;RESET FOR PARSING
	POP	P,.CPTOA##	;RESTORE TYPEOUT ADDRESS
	MOVEI	T1,[ASCIZ /]/]	;END OF DEFAULT
	PUSHJ	P,CONMES##	;PRINT IT

PRSKE3:	MOVEI	T1,[ASCIZ /: /]
	PUSHJ	P,CONMES##	;PRINT COLON
	PUSHJ	P,OPOUT		;FORCE OUTPUT
	PUSHJ	P,GETLIN	;GET OPERATOR'S RESPONSE
	  JRST	PRSKE4		;GO USE DEFAULT
PRSKE0:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	PUSHJ	P,SIXIN		;GET ANSWER
	  JRST	PRSKE7		;BAD RESPONSE
	  JRST	PRSKE7		;BAD RESPONSE
	MOVE	T2,T1		;COPY KEYWORD
	JRST	PRSKE5		;DON'T NEED DEFAULT
PRSKE4:	SKIPN	T2,-1(P)	;PICK UP DEFAULT
	  JRST	PRSKE6		;THERE IS NO DEFAULT, HE WANTS OUT
PRSKE5:	MOVE	T1,(P)		;AND GET AOBJN POINTER TO TABLE
	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	PUSHJ	P,FNDNAM##	;NOW LOOKUP NAME IN TABLE
	  JRST	PRSKE7		;NO MATCH
	AOS	-3(P)		;SKIP RETURN
PRSKE6:	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE T2
	POP	P,(P)		;PHASE STACK
	POPJ	P,		;RETURN WITH RESULT IN T1

PRSKE7:	MOVEI	T1,[ASCIZ /% Bad response, try again/]
	PUSHJ	P,CONOUT	;PRINT MESSAGE
	JRST	PRSKE1		;LOOP BACK


;PUT OUT A LIST OF KEYWORD OPTIONS
OPTKEY:	MOVNI	P2,1		;INIT A FLAG
OPTKE1:	MOVEI	T1,[ASCIZ /,/]	;SEPARATOR
	AOSE	P2		;FIRST KEYWORD?
	PUSHJ	P,CONMES##	;NO--PRINT SEPARATOR
	MOVE	T2,(P1)		;GET A KEYWORD
	PUSHJ	P,PRNAME##	;PRINT IT
	AOBJN	P1,OPTKE1	;LOOP FOR ALL KEYWORDS
	POPJ	P,		;RETURN
;LIST OF NAMES
PRSLST::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,T1		;SAVE PROMPT STRING
	PUSH	P,T2		;SAVE VALIDATION ROUTINE
	PUSH	P,T3		;SAVE TABLE ADDRESS
	SETZM	(T3)		;CLEAR A WORD
	AOBJN	T3,.-1		;DO THE WHOLE TABLE

PRSLS1:	MOVE	T1,-2(P)	;GET PROMPT
	PUSHJ	P,CONOUT	;PRINT IT
	MOVE	P1,(P)		;GET AOBJN POINTER TO TABLE

PRSLS2:	PUSHJ	P,GETLIN	;GET OPERATOR'S RESPONSE
	  JRST	PRSLS4		;NO MORE TYPEIN
	JUMPGE	P1,PRSLS3	;ERROR IF TABLE IS FULL
	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	PUSHJ	P,SIXIN		;GET ANSWER
	  JRST	PRSLS5		;BAD RESPONSE
	  JRST	PRSLS5		;BAD RESPONSE
	MOVE	P2,T1		;COPY NAME TO A SAFE PLACE
	PUSHJ	P,@-1(P)	;CALL VALIDATION ROUTINE
	  JRST	PRSLS2		;DIDN'T PASS TEST
	TDZA	T1,T1		;CONTINUE RETURN
	MOVEI	T1,1		;LAST RETURN
	MOVEM	P2,(P1)		;SAVE RESULTS IN TABLE
	AOBJN	P1,.+1		;ADVANCE POINTER
	JUMPN	T1,PRSLS4	;SKIP ON IF DONE
	JRST	PRSLS2		;NO, GET ANOTHER REPLY

PRSLS3:	MOVEI	T1,[ASCIZ /% Table is full/]
	PUSHJ	P,CONOUT	;PRINT THE MESSAGE

PRSLS4:	HRRZ	T1,(P)		;GET STARTING ADDRESS OF TABLE
	HRRZ	T2,P1		;AND WHERE IT IS NOW
	SUBI	T1,(T2)		;COMPUTE DIFFERENCE
	HRLZS	T1		;PUT -LENGTH IN LH
	HRR	T1,(P)		;RETURN AOBJN POINTER TO READ RESULTS
	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE T2
	POP	P,(P)		;PHASE STACK
	POPJ	P,		;RETURN

PRSLS5:	MOVEI	T1,[ASCIZ /% Bad response, try again/]
	PUSHJ	P,CONOUT	;PRINT THE MESSAGE
	JRST	PRSLS2		;LOOP BACK
;RANDOM TEXT
PRSTXT::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,T1		;SAVE PROMPT STRING
	PUSH	P,T2		;SAVE DEFAULT ANSWER

PRSTX1:	MOVE	T1,-1(P)	;GET PROMPT
	PUSHJ	P,ICONM		;START THE LINE
	SKIPN	(P)		;HAVE A DEFAULT
	JRST	PRSTX2		;NO
	MOVEI	T1,[ASCIZ / [/]
	PUSHJ	P,CONMES##	;PRINT BRACKET
	MOVE	T1,(P)		;GET DEFAULT
	MOVE	T1,DEFSP	;INITIAL STRING POINTER
	MOVEM	T1,DEFPTR	;SET IT UP
	MOVE	T1,(P)		;GET THE DEFAULT AGAIN
	PUSHJ	P,DEFTXT	;STUFF IT INTO THE DEFAULT BUFFER
	MOVEI	T1,[ASCIZ /	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;APPEND NOTICE THAT WE ARE DEFAULTING
	MOVE	T1,DEFSP	;INITIAL STRING POINTER AGAIN
	MOVEM	T1,DEFPTR	;RESET FOR PARSING
	PUSHJ	P,CONMES##	;PRINT IT
	MOVEI	T1,[ASCIZ /]/]
	PUSHJ	P,CONMES##	;PRINT BRACKET

PRSTX2:	MOVEI	T1,[ASCIZ /: /]
	PUSHJ	P,CONMES##	;PRINT COLON
	PUSHJ	P,OPOUT		;FORCE OUTPUT
	PUSHJ	P,GETLIN	;GET OPERATOR'S RESPONSE
	  JRST	PRSTX3		;NOTHING TYPED SO DO DEFAULTING
	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	JRST	PRSTX6		;FINISH UP

PRSTX3:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	SKIPN	T1,(P)		;POINT TO DEFAULT
	JRST	PRSTX5		;NO DEFAULT
	MOVEI	T2,ONCTSZ	;MAXIMUM BYTE COUNT

PRSTX4:	HRLI	T1,(POINT 7,)	;MAKE A BYTE POINTER
	ILDB	T3,(T1)		;GET A CHARACTER
	IDPB	T3,LINEP	;PUT A CHARACTER
	SOSLE	T2		;COUNT CHARACTERS
	JUMPN	T3,PRSTX4	;LOOP FOR ENTIRE STRING

PRSTX5:	MOVE	T1,[POINT 7,LINBUF] ;RESET POINTER
	MOVEM	T1,LINEP	;SO CALLER CAN GRAB CHARACTERS

PRSTX6:	POP	P,T2		;RESTORE T2
	POP	P,(P)		;PHASE STACK
	MOVEI	T1,LINBUF	;POINT TO BUFFER
	POPJ	P,		;RETURN WITH RESULT IN T1

;PPN
PRSPPN::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,T1		;SAVE PROMPT STRING
	PUSH	P,T2		;SAVE DEFAULT ANSWER
	PUSH	P,T3		;SAVE POSSIBLE KEYWORD TABLE ADDRESS
	PUSHJ	P,PRSCON	;SEE IF 'TYPEAHEAD' PRESENT
	  JRST	PRSPP0		;YES--JUST USE IT

PRSPP1:	MOVE	T1,-2(P)	;GET PROMPT
	PUSHJ	P,ICONM		;START THE LINE
	MOVEI	T1,[ASCIZ / (/]	;START OF OPTIONS LIST
	PUSHJ	P,CONMES##	;PRINT TEXT
	SETO	P2,		;IN CASE NO KEYWORD LIST
	SKIPE	P1,(P)		;HAVE A KEYWORD LIST?
	PUSHJ	P,OPTKEY	;YES--PUT OUT A LIST OF OPTIONS
	MOVEI	T1,[ASCIZ /,/]	;SEPARATOR
	AOSE	P2		;FIRST KEYWORD?
	PUSHJ	P,CONMES##	;NO--PRINT SEPARATOR
	MOVEI	T1,[ASCIZ /[p,pn])/]
	PUSHJ	P,CONMES##	;LAST ALTERNATIVE
	SKIPN	-1(P)		;HAVE SOME KIND OF DEFAULT?
	JRST	PRSPP2		;NO
	MOVEI	T1,[ASCIZ / [/]
	PUSHJ	P,CONMES##	;PRINT BRACKET
	MOVE	T1,-1(P)	;GET DEFAULT
	MOVE	T2,T1		;MAKE A COPY
	TLC	T2,-1		;WANT TO TEST FOR -1
	TLCE	T2,-1		;WAS IT (AND NOW AGAIN)?
	SKIPL	T2		;NO--OTHER NEGATIVE IS SIXBIT
	SKIPA	T3,[PRTPPN##]	;YES--TYPE AS A PPN
	MOVEI	T3,PRNAME##	;HERE FOR SIXBIT TYPEOUT FROM WRONG REGISTER
	PUSH	P,T3		;SAVE FORMAT ROUTINE FOR RE-USE
	PUSHJ	P,(T3)		;PRINT SOMETHING
	MOVEI	T3,DEFTYO	;TYPEOUT ROUTINE TO USE FOR DEFAULT TEXT
	EXCH	T3,.CPTOA##	;SET IT UP AND GET OLD
	EXCH	T3,(P)		;SAVE AND RESTORE FORMAT ROUTINE
	MOVE	T1,DEFSP	;INITIAL STRING POINTER
	MOVEM	T1,DEFPTR	;START STUFFING INTO BEGINNING OF DEFAULT BUFFER
	MOVE	T1,-2(P)	;GET DEFAULT VALUE BACK
	PUSHJ	P,(T3)		;STORE IT IN THE BUFFER
	MOVEI	T1,[ASCIZ /	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;APPEND THE USUAL NOTICE ABOUT DEFAULTING
	MOVE	T1,DEFSP	;INITIAL POINTER AGAIN
	MOVEM	T1,DEFPTR	;RESET FOR PARSING
	POP	P,.CPTOA##	;RESTORE TYPEOUT ADDRESS
	MOVEI	T1,[ASCIZ /]/]
	PUSHJ	P,CONMES##	;PRINT BRACKET

PRSPP2:	MOVEI	T1,[ASCIZ /: /]
	PUSHJ	P,CONMES##	;PRINT COLON
	PUSHJ	P,OPOUT		;FORCE OUTPUT
	PUSHJ	P,GETLIN	;GET OPERATOR'S RESPONSE
	  JRST	PRSPP5		;GO DEFAULT THE ANSWER
PRSPP0:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	PUSHJ	P,SIXIN		;FIRST TRY FOR A KEYWORD
	  JRST	PRSPP5		;GO DEFAULT THE ANSWER
	  SKIPA			;TRY FOR A PPN INSTEAD
	JRST	PRSPP4		;GO CHECKOUT THE KEYWORD
	PUSHJ	P,GTPPN		;TRY TO READ A PPN
PRSPP3:	  SKIPA	T1,[[ASCIZ /% Bad response, try again/]]
	JRST	PRSPP6		;GO FINISH UP
	PUSHJ	P,CONOUT	;PRINT THE MESSAGE
	JRST	PRSPP1		;TRY AGAIN

PRSPP4:	MOVE	T1,(P)		;AND GET AOBJN POINTER TO TABLE
	PUSHJ	P,FNDNAM##	;NOW LOOKUP NAME IN TABLE
	  JRST	PRSPP3		;NO MATCH
	JRST	PRSPP6		;GO FINISH UP

PRSPP5:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	MOVE	T2,-1(P)	;GET DEFAULT ANSWER
	HLRZ	T1,T2		;ISOLATE LH OF ANSWER
	CAIE	T1,-1		;IF NOT [*,...]
	JUMPL	T2,PRSPP4	;THEN IT HAD BETTER BE SIXBIT IN THE KEYS LIST
	MOVE	T1,T2		;PPN--PUT IN RIGHT REGISTER
PRSPP6:	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE T2
	POP	P,(P)		;PHASE STACK
	POPJ	P,		;RETURN WITH RESULT IN T1
GTPPN:	CAIE	T3,"["		;BEGINNING OF PPN
	POPJ	P,		;NOT THERE
	PUSHJ	P,GETOCT	;GET THE FIRST OCTAL NUMBER
	JUMPE	T2,CPOPJ##	;NULL PROJECT NUMBER IS BAD
	TLNN	T2,777777	;TOO BIG?
	CAIE	T3,","		;OR A BAD P,PN SEPARATER
	POPJ	P,		;YEP
	PUSH	P,T2		;SAVE IT
	PUSHJ	P,GETOCT	;GET THE PROGRAMMER NUMBER
	POP	P,T1		;GET PROJECT NUMBER BACK
	JUMPE	T2,CPOPJ##	;NULL PROGRAMMER NUMBER IS BAD
	CAIE	T3,"]"		;CHECK FOR LEGAL TERMINATER
	CAIN	T3,0		;CRLF IS OK TOO
	TLNE	T2,777777	;TOO BIG?
	POPJ	P,		;YEP
	HRL	T1,T2		;GET PROGRAMMER NUMBER
	MOVSS	T1		;SET IT UP AS [PROJ,PROG]
	AOS	(P)		;GIVE A SKIP
	POPJ	P,		;AND RETURN

GETOCT:	MOVEI	T2,777777	;ASSUME WILD
	PUSHJ	P,COMTYS##	;GET NEXT CHARACTER
	CAIE	T3,"*"		;WILD?
	TDZA	T2,T2		;NO - CLEAR RESULT
GETOC1:	PUSHJ	P,COMTYS##	;GET NEXT CHARACTER
	CAIL	T3,"0"		;IN RANGE?
	CAILE	T3,"7"
	POPJ	P,
	LSH	T2,3		;CLEAR NULL DIGIT
	SUBI	T3,"0"		;CONVERT TO BINARY
	ADDI	T2,(T3)		;ADD TO TOTAL
	JRST	GETOC1		;LOOP UNTIL DONE
;OCTAL
PRSOCT::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVEI	P1,PRTDI8##	;TYPEOUT ROUTINE
	MOVEI	P2,OCTIN##	;TYPEIN ROUTINE
	PJRST	PRSANS		;ENTER COMMON CODE

;DECIMAL
PRSDEC::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVEI	P1,RADX10##	;TYPEOUT ROUTINE
	MOVEI	P2,DECIN##	;TYPEIN ROUTINE
	PJRST	PRSANS		;ENTER COMMON CODE


;SIXBIT
PRSSIX::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	MOVEI	P1,SIXOUT	;TYPEOUT ROUTINE
	MOVEI	P2,SIXIN	;TYPEIN ROUTINE
	SETZB	T3,T4		;NO RANGE
	PJRST	PRSANS		;ENTER COMMON CODE


;YES/NO
PRSYN0:	POP	P,T1		;RESTORE POINTER TO QUESTION
PRSYNQ::PUSH	P,T1		;SAVE POINTER TO QUESTION
	SETZM	ONCTCH		;DEFEAT PRSCON
	MOVE	T3,[-2,,[SIXBIT /NO    YES   /]] ;AOBJN POINTER TO TABLE
	PUSHJ	P,PRSKEY	;PARSE KEYWORD
	  JRST	PRSYN0		;HMMMMM, LET'S TRY AGAIN
	POP	P,(P)		;REPHASE STACK
	POPJ	P,		;RETURN

SIXIN:	PUSHJ	P,CTEXT##	;READ SIXBIT QUANTITY
	SKIPE	T1,T2		;GET RESULT
	AOS	(P)		;NO RESPONSE
	AOS	(P)		;NOT SIXBIT
	POPJ	P,		;RETURN

SIXOUT:	MOVE	T2,T1		;GET QUANTITY
	PJRST	PRNAME##	;PRINT AND RETURN
PRSANS:	PUSH	P,T1		;SAVE PROMPT STRING
	PUSH	P,T2		;SAVE DEFAULT ANSWER
	PUSH	P,T3		;SAVE LOW RANGE
	PUSH	P,T4		;SAVE HIGH RANGE
	PUSHJ	P,PRSCON	;SEE IF MORE ON SAME LINE
	  JRST	PRSAN0		;YES--JUST GO USE THE TEXT

PRSAN1:	MOVE	T1,-3(P)	;GET PROMPT
	PUSHJ	P,ICONM		;START THE LINE
	SKIPN	(P)		;ANY RANGE RESTRICTIONS?
	JRST	PRSAN2		;NO
	MOVEI	T1,[ASCIZ / (/]
	PUSHJ	P,CONMES##	;START OF RANGE
	MOVE	T1,-1(P)	;GET LOW NUMBER
	PUSHJ	P,(P1)		;PRINT IT
	MOVEI	T1,[ASCIZ / - /]
	PUSHJ	P,CONMES##	;PRINT SEPARATOR
	MOVE	T1,(P)		;GET HIGH NUMBER
	PUSHJ	P,(P1)		;PRINT IT
	MOVEI	T1,[ASCIZ /)/]
	PUSHJ	P,CONMES##	;END OF NUMBER

PRSAN2:	MOVE	T1,-2(P)	;GET DEFAULT
	CAIN	P2,SIXIN	;SIXBIT?
	JUMPE	T1,PRSAN3	;THEN NOT DEFAULTING
	MOVEI	T1,[ASCIZ / [/]
	PUSHJ	P,CONMES##	;PRINT BRACKET
	MOVE	T1,-2(P)	;GET DEFAULT ANSWER
	PUSHJ	P,(P1)		;PRINT IT
	PUSH	P,.CPTOA##	;SAVE OUTPUT ADDRESS
	MOVEI	T1,DEFTYO	;TYPEOUT ROUTINE TO STORE DEFAULT TEXT
	MOVEM	T1,.CPTOA##	;SET IT UP
	MOVE	T1,DEFSP	;INITIAL STRING POINTER
	MOVEM	T1,DEFPTR	;SETUP FOR DEFAULTING
	MOVE	T1,-3(P)	;GET DEFAULT ANSWER AGAIN
	PUSHJ	P,(P1)		;STUFF IT INTO THE DEFAULT BUFFER
	MOVEI	T1,[ASCIZ /	;Operator did not answer/]
	PUSHJ	P,DEFTXT	;APPEND SOME ADDITIONAL TEXT
	MOVE	T1,DEFSP	;INITIAL STRING POINTER AGAIN
	MOVEM	T1,DEFPTR	;RESET FOR PARSING
	POP	P,.CPTOA##	;RESTORE TYPEOUT ADDRESS
	MOVEI	T1,[ASCIZ /]/]
	PUSHJ	P,CONMES##	;PRINT BRACKET

PRSAN3:	MOVEI	T1,[ASCIZ /: /]
	PUSHJ	P,CONMES##	;PRINT COLON
	PUSHJ	P,OPOUT		;FORCE OUTPUT
	PUSHJ	P,GETLIN	;GET OPERATOR'S RESPONSE
	  JRST	[MOVE  T1,-2(P)	;PICK UP DEFAULT
		 JRST  PRSAN4]	;AND CONTINUE
PRSAN0:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	PUSHJ	P,(P2)		;GET ANSWER
	  JRST	PRSAN5		;BAD RESPONSE
	  JRST	PRSAN5		;BAD RESPONSE
	MOVE	T1,T2		;POSITION RETURN VALUE PROPERLY

PRSAN4:	PUSHJ	P,ALTM		;BACK TO STARTUP OPTION IF ALTMODE TYPED
	SKIPN	-1(P)		;RANGE
	SKIPE	(P)		; CHECKING?
	TRNA			;YES--DO THE TESTS
	JRST	PRSAN6		;SKIP TESTS
	CAML	T1,-1(P)	;RANGE
	CAMLE	T1,(P)		; CHECK
	SKIPA			;NO GOOD
	JRST	PRSAN6		;FINISH UP

PRSAN5:	MOVEI	T1,[ASCIZ /% Bad response, try again/]
	PUSHJ	P,CONOUT	;PRINT THE MESSAGE
	JRST	PRSAN1		;LOOP BACK

PRSAN6:	POP	P,T4		;RESTORE T4
	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE T2
	POP	P,(P)		;PHASE STACK
	POPJ	P,		;RETURN WITH RESULT IN T1
	SUBTTL	EXIT FROM STARTUP OPTION

;HERE ON EXIT FROM STARTUP OPTION
PVQCK::	SKIPE	.UONCE##	;IF THIS IS USER-MODE, THEN "GO" IS QUIT
	CALLI	12		;EXIT
	SETZM	.CPJOB##	;CLEAR CURRENT JOB
IFE FTMP,<SETOM	.CPOK##>	;MAKE THE ONE AND ONLY LOOK ALIVE
	SUBTTL	SWPSER/QUESER INITIALIZATION

	SETZ	J,		;CLEAR J TO SET UP A PDB FOR THE NULL JOB
	PUSHJ	P,CREPDB##	;ALLOCATE A PDB
	  STOPCD .,STOP,CCPNUL,	;++CAN'T CREATE PDB FOR NULL JOB

	PUSHJ	P,SWPINI	;INIT SWAPPING SPACE ALLOCATION
	PUSHJ	P,ENQINI##	;INITIALIZE ENQ/DEQ

IFN FTKL10,<
	MOVE	T1,SYSSIZ##	;HIGHEST ADDRESS IN THE LOW SEGMENT
	LSH	T1,W2PLSH	;HIGHEST PAGE
	MOVE	T2,.CPKPM##	;KEEP ME BIT OR 0
	MOVE	T3,.CPMAP##	;ADDRESS OF THIS CPU'S MAP
	IORM	T2,(T3)		;TURN ON "KEEP ME" IF THIS CPU HAS AN MCA25
	AOS	T3		;NEXT PAGE
	SOJG	T1,.-2		;FOR ALL LOW SEGMENT PAGES
>; END IFN FTKL10
	PUSHJ	P,SCDINI##	;INITIALIZE SCHEDULER
	SUBTTL	INITIALIZE ALL I/O DEVICES

IFN FTKL10,<PIBITS==PI.CPI!PI.TFP!PI.OFF!LI.ACO!LI.CPP>	;KL10 PI BITS
IFN FTKS10,<PIBITS==PI.CPI!PI.TFP!PI.OFF!SI.ACO!SI.CPP>	;KS10 PI BITS

IOGO:	CONO	PI,PIBITS	;CLEAR PI SYSTEM (AND MEM PARITY)
IFN FTKL10,<
	CONO	APR,LP.CSF!LP.PAR ;CLEAR PARITY ERROR
>; END IFN FTKL10
IFN FTKS10,<
	WRAPR	SP.DSF!SP.CSF!SP.HMP!SP.SMP!SP.NXM ;CLEAR PARITY/NXM ERROR
>; END IFN FTKS10
	CONO	APR,APRNUL##	;SET UP THE APR (DON'T DO I/O RESET)
	HRRZS	.CPMPC##	;CLEAR SERIOUS PARITY ERROR FLAG WHICH
				; CAUSES HALT AFTER CTY PRINTING
;CALL DEVICE-SPECIFIC INITIALIZATION ROUTINE FOR EACH DEVICE

IOGO1:	HLRZ	P3,DEVLST##	;ADDR OF FIRST DDB
	SETZB	S,SAVITM
IOGO3:	MOVE	F,P3		;SET UP F FOR INITIALIZATION CODE
				; (NOT ALWAYS USED)
	MOVE	P3,DEVSER(P3)
IFN FTMP,<
	LDB	T1,DEYCPF##	;CPU OWNING THE DEVICE
	CAIE	T1,CPFBOO##	;GENERIC BOOT CPU?
	CAIN	T1,CPFBIT##	;FOR DUAL PORTED BEASTY?
	JRST	IOGO4		;YES, THAT'S US
	CAME	T1,.CPCPN##	;THIS CPU?
	JRST	IOGO5		;NO
IOGO4:
>; END IFN FTMP
	HRRZ	T1,P3
	CAIE	T1,@SAVITM	;SAME DEVICE
	PUSHJ	P,DINI(P3)	;NO. INITIALIZE IT.
	  HRRZM	P3,SAVITM	;SKIPS IF CODE TO BE CALLED FOR EACH DEVICE

IOGO5:	HLRZS	P3
	JUMPN	P3,IOGO3	;GO IF MORE DEVICES
	SETZM	DINITF##	;NO LONGER INITIALIZING
IFN FTRTTRP,<PUSHJ P,RTINI##>	;INITIALIZE PI CHANNELS AND RT DEVICES
IFN FTLOCK,<PUSHJ P,LOKINI##>	;INITIALIZATION FOR LOCK UUO
	PUSHJ	P,TIMINI	;START TICKS COMING (TIMINT STUFF)
IFN FTEMRT,<
	PUSHJ	P,ACCMON##	;START UP ACCOUNTING METERS
	PUSHJ	P,CLREMB##	;CLEAR OUT E AND MBOX ACCOUNTING METERS
>;END IFN FTEMRT
IFN FTKL10,<PUSHJ P,ABKCHK##>	;CHECK & POSSIBLY SET EXEC MODE ADDRESS BREAK
	SUBTTL	INITIALIZE TABLE OF AVAILABLE EXEC VIRTUAL MEMORY

	MOVE	T1,EVMPTR##	;AOBJN POINTER TO EVBTAB
	SETZM	(T1)		;INITIALIZE TO ALL BITS OFF
	AOBJN	T1,.-1		;SET EVERY WORD IN THE TABLE
	MOVE	T1,[-1_-<^D<512-36*<512/36>>>]
	MOVEM	T1,EVBTAB##+^D<512/36>
	MOVE	T3,SYSSIZ##	;FROM 0 THROUGH SYSSIZ
	LSH	T3,W2PLSH	;NUMBER OF PAGES
	MOVSI	T4,^D36		;STARTING AT PAGE 0
	HRRI	T4,EVBTAB##+0	;WHERE IN THE TABLE
	MOVEM	T3,.C0EVU##	;ACCUMULATE PAGES USED
	PUSHJ	P,CSETOS##	;MARK THE BITS (NOT AVAILABLE FOR EVM)
	MOVEI	T3,HLCSAD##/PAGSIZ ;FIRST PAGE OF NON-CODE SPACE
	IDIVI	T3,^D36		;WORD NUMBER AND BIT POSITION
	SUBI	T4,^D36
	MOVNS	T4		;BIT POSITION
	MOVSS	T4		;TO THE LEFT HALF
	HRRI	T4,EVBTAB##(T3)	;STARTING WORD WITHIN TABLE
	MOVEI	T3,<<1,,0>-HLCSAD##>/PAGSIZ ;NUMBER OF PAGES
	ADDM	T3,.C0EVU##	;ACCUMULATE PAGES USED
	PUSHJ	P,CSETOS##	;MARK OFF BITS REPRESENTING FS AND PP SLOTS
IFN FTXMON,<
	MOVEI	T3,CSBORG##/PAGSIZ ;ORIGIN OF COMMON SUBROUTINES
	IDIVI	T3,^D36		;WORD NUMBER AND BIT POSITION
	SUBI	T4,^D36
	MOVNS	T4		;MAKE AN AOBJN POINTER
	MOVSS	T4
	HRRI	T4,EVBTAB##(T3)
	MOVE	T3,CSBLEN##	;GET LENGTH OF COMMON SUBRTNS PSECT
	TRZE	T3,PG.BDY	;ROUND UP
	ADDI	T3,PAGSIZ
	LSH	T3,W2PLSH	;NUMBER OF BITS TO SET
	ADDM	T3,.C0EVU##	;ACCUMULATE PAGES USED
	PUSHJ	P,CSETOS##	;MONITOR PAGES ARE NOT AVAILABLE AS EVM
>; END IFN FTXMON
	MOVEI	T3,MONORG##/PAGSIZ ;ORIGIN OF HIGH SEGMENT
	IDIVI	T3,^D36		;WORD NUMBER AND BIT POSITION
	SUBI	T4,^D36
	MOVNS	T4		;MAKE AN AOBJN POINTER
	MOVSS	T4
	HRRI	T4,EVBTAB##(T3)
	MOVE	T3,MONVFF##	;FIRST FREE VIRTUAL LOCATION ABOVE THE MONITOR
	SUBI	T3,MONORG##	;MINUS START OF THE MONITOR
	LSH	T3,W2PLSH	;NUMBER OF BITS TO SET
	ADDM	T3,.C0EVU##	;ACCUMULATE PAGES USED
	PUSHJ	P,CSETOS##	;MONITOR PAGES ARE NOT AVAILABLE AS EVM
	MOVE	P1,EVMPTR##	;AOBJN POINTER TO EVM TABLE
	MOVEI	P2,0
	MOVEI	P3,-1
	PUSHJ	P,GETZ##	;FIND THE LARGEST CONTIGUOUS PIECE OF EVM
	  MOVEM	P2,EVBMAX##	;STORE THAT AS THE LARGEST IOWD SIZE
	MOVEI	T1,^D512	;MAXIMUM SIZE OF EVM
	SUB	T1,.C0EVU##	;MINUS AMOUNT USED BY MONITOR
	MOVEM	T1,.C0EVM##	;NUMBER OF PAGES AVAILABLE FOR LOCKING IN EVM
	SETZM	.C0EVU##	;NUMBER OF PAGES IN USE FOR LOCKING IN EVM
	SUBTTL	MISCELLANEOUS INITIALIZATION


IFN FTKL10,<
	PUSHJ	P,GIVPMR##	;INITIALIZE PERFORMANCE METER
	SETOM	.CPPTF##	;INITIALIZE FLAG WHICH ALLOWS IO PAGE TABLE
>; END IFN FTKL10
	PUSHJ	P,WRTLOK	;WRITE LOCK CODE SEGMENTS
IFE FTXMON,<
	JRSTF	@[EXP IC.UOU+.+1] ;LIGHT USER IOT IN THE PC
>; END IFE FTXMON
IFN FTXMON,<
	XJRSTF	[IC.UOU
		 0,,.+1]	;SAME BUT ENTER SECTION 0
>; END IFN FTXMON
	MOVEI	T1,0		;USER APR ENABLE BITS
	PUSHJ	P,SETCNA##	;SETUP APR ENABLE BITS AND CONSO MASK

	EXECAC			;MAKE SURE AC BLOCKS ARE OK
IFN FTKL10,<
	PUSHJ	P,SETCSH##	;SET CACHE STRATEGY AS ESTABLISHED BY KLI
	CONO	APR,LP.CSF+LP.CSD ;CLEAR CACHE SWEEP DONE
	SWPUA			;SWEEP CACHE, UNLOAD ALL
	CONSO	APR,LP.CSD	;WAIT UNTIL COMPLETED
	JRST	.-1
	CONO	APR,LP.CSF+LP.CSD ;CLEAR CACHE SWEEP DONE
	CONO	PAG,@.CPEBR##	;ENABLE CACHE IF DESIRED
>; END IFN FTKL10
IFN FTKS10,<
	WREBR	@.CPEBR##
	PUSHJ	P,ENAKAL##	;ENABLE KEEP-ALIVE COUNTING
>; END IFN FTKS10
	SETZM	.USPFW		;CLEAR NULL JOB'S PAGE FAIL WORD
	SUBTTL	NETWORK INITIALIZATION

IFN FTKS10,<PUSHJ  P,KDPONC##>	;GO INIT THE KMC/DUP LINES

IFN FTNET,<
ANFSTR:	PUSHJ	P,NETINI##	;INITIALIZE ANF-10
>; END IFN FTNET

FEKSTR:
IFN FTENET,<PUSHJ P,D8EINI##>	;INITIALIZE ANF/ETHERNET FEK SERVICE
	MOVEI	J,FEKFST##	;GET THE ADDR OF FIRST FEK (0 IF NONE)
	JRST	FEKST2		;ENTER FEK "ONCE ONLY" LOOP

FEKST1:	MOVEI	T1,FF.ONC	;GET THE "ONCE ONLY" FUNCTION CODE
	XCT	FEKDSP(J)	;CALL THE "DISPATCH ROUTINE"
	HRRZ	J,FEKBLK(J)	;STEP TO THE NEXT FEK
FEKST2:	JUMPN	J,FEKST1	;IF NO MORE FEKS, GO CONTINUE SYSINI

IFN FTDECNET,<
D36STR:	PUSHJ	P,D36INI##	;INITIALIZE DECNET
>; END IFN FTDECNET

IFN FTENET,<
LATSTR:	PUSHJ	P,LATINI##	;INITIALIZE LAT TERMINAL SERVICE
IFN FTKL10,<
LLMSTR:	PUSHJ	P,LLMINI##	;INITIALIZE LLMOP
>; END IFN FTKL10
>; END IFN FTENET
IFN FTKS10,<PUSHJ  P,DMRONC##>	;INITIALIZE THE DMR11 LINES
	SUBTTL	FINAL CPU AND DEVICE INITIALIZATION

	CONO	APR,APRNUL##	;CLEAR ALL APR ERRORS (DO NOT DO RESET)
	CONO	PI,PI.CPI!PI.TNP!PI.ON!II.ACO!IFN FTKL10,<PI.EPE>  ;TURN ON ALL PI CHANNELS (ENABLE MEM PARITY)

IFN FTKL10,<PUSHJ  P,STAPPC##>	;INITIALIZE PRIMARY PROTOCOL
IFN FTMP,<PUSHJ  P,BECOM1##>	;ESTABLISH "CTY" ON BOOT PROCESSOR
	PUSHJ	P,SYSRLD	;MAKE SYSTEM RELOAD ENTRY IN ERROR.SYS
	PUSHJ	P,SYSAVL	;MAKE SYSTEM RELOAD ENTRY IN AVAIL.SYS

	PUSHJ	P,CTXINI##	;COMPUTE SYSTEM CONTEXT QUOTAS BASED ON
				; THE NUMBER OF JOBS AND THE AMOUNT OF
				; SWAPPING SPACE AVAILABLE
	PUSHJ	P,FRCCPY##	;COPY ANY CRASHES
	MOVEI	T1,DF.BPT	;GET MASK OF ALL CPU BREAKPOINT ENABLE BITS
	MOVEI	T2,JS.BPT	;GET THE "SET EDDT BREAKPOINT" ON BIT
	TDNE	T1,DEBUGF##	;ANY CPUS SET TO BREAKPOINT?
	IORM	T2,JBTSTS##+0	;YES--ALLOW ^D TO DO IT'S THING
	PUSHJ	P,CSHINI##	;INIT MONITOR DISK CACHE
	MOVSI	T1,(CAI)	;SETUP NO-OP IN CASE NO EDDT
NODDT:	HLLM	T1,SYSDDT##	;TURN 401 INTO A CAI UNLESS EDDT STILL AROUND
	MOVE	T1,[<PM.DCD>B2+PM.WRT+PM.PUB+<DOORBL##/PAGSIZ>] ;STORE MAPPING
	MOVEM	T1,NLUPMP##(T1)	; FOR DOORBELL
IFN FTMP,<
	MOVE	T2,.CPUPT##	;GET BOOT CPU UPTIME
	MOVN	T3,TICSEC##	;.CPOK INITIALIZER
	HRROI	T1,[SKIPE .CPRUN##-.CPCDB##(P1) ;THIS CPU ALIVE?
		    POPJ  P,
		    MOVEM T2,.CPUPT##-.CPCDB##(P1) ;FIX CPU UPTIME
		    MOVEM T3,.CPOK##-.CPCDB##(P1) ;FIX OK WORD
		    POPJ  P,]
	PUSHJ	P,CPUAPP##	;FIX UPTIMES
> ;END IFN FTMP
	PUSHJ	P,CRSINI##	;START TRYING TO READ THE CRASH FILE
	MOVE	17,[SYSINH,,2]	;BLT REMAINDER OF INITIALIZATION CODE INTO ACS
	BLT	17,7
	MOVE	0,[NUPPPM##,,NUPPPM##+1] ;SET UP BLT WORD IN AC 0
	JRST	2		;FINISH UP

SYSINH:	SETZM	NUPPPM##	;(2) ZERO PER-PROCESS MAPPING IN NULL JOB'S MAP
	BLT	0,NLUPMP##+.UMUPM-1 ;(3)
	CLRPGT			;(4) FLUSH OLD MAPPING
	MOVEI	0,1		;(5) GET A FLAG
	MOVEM	0,ONCCOM##	;(6) START TIMESHARING
	SJSP	U,NULJB1##	;(7) START THE NULL JOB (U NON-ZERO)
	SUBTTL	ERROR.SYS/SYSTEM RELOAD


SYSRLD:	HLLZ	T1,NXMPTR##	;GET NXMTAB POINTER
	HRR	T1,@SRLTBL+.EXHDR+13 ;AND OFFSET TO WHY RELOAD COMMENTS
	ADDI	T1,WHYSIZ##	;ADVANCE TO START OF NXMTAB STORAGE
	MOVEM	T1,SRLNXM	;SAVE
	HLLZ	T1,SRLTBL+.EXFLG ;GET -VE LENGTH OF XFER TABLE
	ADD	T1,[-WHYSIZ##,,0] ;PLUS -VE LENGTH OF WHY RELOAD COMMENT
	ADD	T1,NXMPTR##	;PLUS -VE LENGTH OF NXMTAB
	HLRES	T1		;GET FULL WORD COUNT
	MOVMS	T1		;MAKE POSITIVE
	PUSHJ	P,ALCSEB##	;ALLOCATE A SYSTEM ERROR BLOCK
	  POPJ	P,		;NO CORE
	HRRZ	T2,@SRLTBL+.EXHDR+13 ;GET OFFSET TO COMMENT STORAGE
	ADDI	T2,1(T1)	;RELOCATE
	MOVSI	T3,WHYTXT##	;POINT TO WHY RELOAD COMMENTS
	HRRI	T3,(T2)		;MAKE A BLT POINTER
	BLT	T3,WHYSIZ##-1(T2) ;COPY COMMENTS
	HRRZ	T2,@SRLTBL+.EXHDR+15 ;GET OFFSET TO NXMTAB STORAGE
	ADDI	T2,1(T1)	;RELOCATE
	HLRE	T3,NXMPTR##	;GET -VE LENGTH
	MOVMS	T3		;MAKE POSITIVE
	ADDI	T3,(T2)		;COMPUTE END OF BLOCK
	HRLZ	T4,NXMPTR##	;POINT TO NXMTAB
	HRRI	T4,(T2)		;MAKE A BLT POINTER
	BLT	T4,-1(T3)	;COPY NXMTAB
	XMOVEI	T2,SRLTBL	;POINT TO TRANSFER TABLE
	PUSHJ	P,XFRSEB##	;FILL REMAINDER
	  JFCL			;SHOULDN'T FAIL
	MOVEM	T1,CRSRLD##	;WAIT FOR CRSINI BEFORE QUEUEING THE BLOCK
	POPJ	P,		;RETURN

SRLTBL:	SEBTBL	(.ERWHY,SRLEND,)
	MOVE	CONFIG##+0	;(R00) SYSTEM NAME
	MOVE	CONFIG##+1	;(R01)
	MOVE	CONFIG##+2	;(R02)
	MOVE	CONFIG##+3	;(R03)
	MOVE	CONFIG##+4	;(R04)
	MOVE	SYSDAT##+0	;(R05) SYSTEM BUILD DATE
	MOVE	SYSDAT##+1	;(R06)
	MOVE	STATES##	;(R07) MONITOR STATES WORD
	MOVE	CNFDVN##	;(R10) MONITOR VERSION
	MOVE	SERIAL##	;(R11) POLICY CPU SERIAL NUMBER
	MOVE	WHYCOD##	;(R12) "WHY RELOAD" CODE
	MOVE	[-WHYSIZ##,,23]	;(R13) "WHY RELOAD" COMMENTS POINTER
	MOVE	[707070,,1]	;(R14) SYSERR CODE,,PAGING HARDWARE
	MOVE	SRLNXM		;(R15) NXMTAB POINTER
SRLEND:				;END OF TABLE
	SUBTTL	AVAIL.SYS/SYSTEM RELOAD


SYSAVL:	MOVE	T1,SYSUPT##	;GET CURRENT UPTIME
	PUSHJ	P,SEBTIM##	;CONVERT TO A UDT
	SUB	T1,DATE##	;GET -VE TIME OF RELOAD
	MOVNM	T1,LODTIM	;SAVE FOR AVAIL
	PUSH	P,LOCYER##	;SAVE YEAR
	PUSH	P,LOCMON##	;SAVE MONTH
	PUSH	P,LOCDAY##	;SAVE DAY
	PUSH	P,LOCHOR##	;SAVE HOUR
	PUSH	P,LOCMIN##	;SAVE MINUTE
	PUSH	P,LOCSEC##	;SAVE SECOND
	PUSH	P,DATE##	;SAVE CURRENT DATE/TIME
	PUSH	P,DATREM##	;AND REMAINDER
	LDB	T1,[POINT 12,CRSSAV,26] ;GET CRASH YEAR
	MOVEM	T1,LOCYER##	;STORE YEAR
	LDB	T1,[POINT 5,CRSSAV,31] ;GET CRASH MONTH
	MOVEM	T1,LOCMON##	;STORE MONTH
	LDB	T1,[POINT 4,CRSSAV,35] ;GET CRASH DAY
	MOVEM	T1,LOCDAY##	;STORE DAY
	SUBI	T1,^D1970	;SUBTRACT BASE
	HRRZ	T1,CRSDTM	;GET TIME
	IDIVI	T1,^D60*^D60	;GET HOURS
	IDIVI	T2,^D60		;GET MIN
	MOVEM	T1,LOCHOR##	;STORE HOURS
	MOVEM	T2,LOCMIN##	;STORE MIN
	MOVEM	T3,LOCSEC##	;STORE SECONDS
	PUSHJ	P,SUDATE##	;GENERATE UDT
	MOVE	T1,DATE##	;GET CRASH DATE/TIME
	MOVEM	T1,CRSSAV	;SAVE IT AWAY
	POP	P,DATREM##	;RESTORE DATE/TIME REMAINDER
	POP	P,DATE##	;RESTORE CURRENT UDT
	POP	P,LOCSEC##	;RESTORE SECOND
	POP	P,LOCMIN##	;RESTORE MINUTE
	POP	P,LOCHOR##	;RESTORE HOUR
	POP	P,LOCDAY##	;RESTORE DAY
	POP	P,LOCMON##	;RESTORE MONTH
	POP	P,LOCYER##	;RESTORE YEAR

	SETZ	T1,		;CAUSE SEB ALLOCATION TO HAPPEN
	XMOVEI	T2,AVLTBL	;POINT TO TRANSFER TABLE
	PUSHJ	P,XFRSEB##	;FILL UP RECORD
	  SETZ	T1,		;NO CORE
	MOVEM	T1,CRSAVL##	;WAIT FOR CRSINI TO QUEUE UP THE BLOCK
	POPJ	P,		;RETURN


;TRANSFER TABLE FOR AVAIL.SYS
AVLTBL:	SEBTBL	(.ERMRV,AVLEND,)
	MOVE	[-5,,7]		;(R00) OFFSET TO ASCIZ SYSTEM NAME
	MOVE	CNFDVN##	;(R01) MONITOR VERSION
	MOVE	SYSUPT##	;(R02) UPTIME
	MOVE	CRSSAV		;(R03) MONITOR CRASH TIME (+/- 6 MINUTES)
	MOVE	LODTIM		;(R04) MONITOR RELOAD TIME
	MOVE	WHYCOD##	;(R05) "WHY RELOAD" CODE
	SETZ			;(R06) SUM INCR DATE/TIME CHANGES SINCE RELOAD
	MOVE	CONFIG##+0	;(R07) SYSTEM NAME
	MOVE	CONFIG##+1	;(R10)
	MOVE	CONFIG##+2	;(R11)
	MOVE	CONFIG##+3	;(R12)
	MOVE	CONFIG##+4	;(R13)
AVLEND:				;END OF TABLE
	SUBTTL	MULTI-CPU I/O PROCESSING


IFN FTMP,<

; UDBS
CPUUNI::DMOVEM	T1,CPUACS+T1	;SAVE TEMPS
	DMOVEM	T3,CPUACS+T3	;...
	MOVE	T1,UDBCAM(U)	;GET TARGET CPU NUMBER
	PUSHJ	P,CAMCPU##	;DETERMINE CPU NUMBER TO USE
	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
	TLNN	T3,(XC.LNG)	;LONG WAIT?
	LSH	T1,-2		;NO, WAIT ONE FOURTH OF THE USUAL TIME
	MOVE	P1,T2		;CPU INDEX
	IMULI	P1,.CPLEN##	;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
	TLNN	T2,(XC.LNG)	;LONG WAIT?
	LSH	T1,-2		;NO, 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	GET DATE/TIME FROM ANY FE WILLING TO TALK

;ROUTINE TO ASK FRONT ENDS FOR DATE/TIME.  RETURNS CPOPJ IF NONE
;KNOW THE DATE/TIME, CPOPJ1 IF ONE DOES.

GFETIM:	PUSHJ	P,SAVE1##	;SAVE AN AC
	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	CPOPJ1##	;LOCxxx NOW MATCH FE
	AOBJN	P1,GFETM1	;TRY NEXT POSSIBLE CPU
	POPJ	P,		;NONE WERE HELPFUL, RETURN FAILURE
	SUBTTL	SET UP NXMTAB

SUNXMT:	PUSH	P,P1		;SAVE WORKING ACS
	PUSH	P,P2
	SETZB	T4,NXMTAB##	;ZERO HIGHEST EXISTANT ADDRESS SEEN, AND NXMTAB
	MOVE	T1,[NXMTAB##,,NXMTAB##+1]
	MOVEI	T2,NXMTAB##	; ..
	BLT	T1,NXMTBL##-1(T2)
	MOVEI	P1,CORBLK##	;NUMBER OF PAGES OF CORE POSSIBLE
	MOVE	T2,[POINT 1,NXMTAB##]
	MOVEI	T3,1		;TO MARK A PAGE AS NON-EXISTANT
	SETZ	U,		;START LOOKING FOR NXM AT ADDRESS 0
SUNXM1:	CONO	APR,AP.NXE##	;CLEAR NXM FLAG
	IBP	T2		;NEXT BYTE IN NXMTAB
	MOVEI	P2,MEMITL##	;NUMBER OF WAYS THE MEMORY CAN BE INTERLEAVED
SUNXM2:	PUSH	P,U		;SAVE THE CURRENT ADDRESS
	ADDI	U,-1(P2)	;CHECK PAGE PLUS INTERLEAVE OFFSET
	PUSHJ	P,REFMEM##	;REFERENCE TIS ADDRESS
	POP	P,U		;RESTORE THE CURRENT ADDRESS
	SOJG	P2,SUNXM2	;LOOK AT NEXT ADDRESS WITHIN THIS PAGE
	CONSO	APR,AP.NXM##	;NON-EXISTANT MEMORY SEEN?
	JRST	SUNXM3		;NO
	DPB	T3,T2		;YES, MARK THE PAGE AS NON-EXISTANT
	JUMPN	T4,SUNXM4	;JUMP IF THE LAST PAGE LOOKED AT WAS NXM
	SKIPA	T4,U		;NOT SO, SO REMEMBER THE ADDRESS OF HIGHEST
				; EXISTANT PAGE SEEN SO FAR
SUNXM3:	MOVEI	T4,0		;MEMORY EXISTS, HAVEN'T SEEN THE HIGHEST EXISTANT PAGE YET
SUNXM4:	ADDI	U,PAGSIZ	;GO ON TO THE NEXT PAGE OF MEMORY
	SOJG	P1,SUNXM1	; PROVIDED ALL POSSIBLE MEMORY HASN'T BEEN CHECKED
SUNXM5:	IDPB	T3,T2		;ONES TO THE END OF THIS WORD IN NXMTAB
	TLNE	T2,770000	; ..
	JRST	SUNXM5		; ..
	SKIPN	T4		;SKIP IF THE HIGHEST POSSIBLE PAGE OF MEMORY DIDNT EXIST
	MOVE	T4,U		;IT DID, SO U CONTAINS THE ADDRESS OF THE HIGHEST PAGE
	POP	P,P2		;RESTORE ACS
	POP	P,P1
	POPJ	P,
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- FIXUP ASL/SSL/SDL FOR DEBUGGING

BOOTDB::SKIPN	T3,DDTDSK	;WANT TO HACK THE ASL, ETC.?
	POPJ	P,		;NO
	SE1ENT			;ENTER SECTION ONE
	CAMN	T3,[EXP -1]	;USE BOOTSTRAP DEVICE?
	MOVE	T3,DEVICE	;YES
	MOVE	T1,STRAOB##	;AOBJN POINTER
	CAME	T3,@TABSTR##(T1) ;MATCH SPECIFIED STRUCTURE NAME?
	AOBJN	T1,.-1		;KEEP SEARCHING
	JUMPGE	T1,CPOPJ##	;GIVE UP IF JUNK SPECIFIED
	MOVE	T4,TABSTR##(T1)	;GET STR ADDR
	HLRZ	T4,STRUNI##(T4)	;GET UDB
	MOVE	T4,UNILOG##(T4)	;AND FINALLY THE LOGICAL UNITID
	MOVEI	T1,.BTSSL	;SSL
	PUSHJ	P,ZLIST		;FETCH, STORE & ZERO REMAINDER OF LIST
	MOVEI	T1,.BTSDL	;SDL
	PUSHJ	P,ZLIST		;FETCH, STORE & ZERO REMAINDER OF LIST
	MOVE	T3,T4		;COPY LOGICAL UNITID
	MOVEI	T1,.BTASL	;ASL
	PUSHJ	P,ZLIST		;FETCH, STORE & ZERO REMAINDER OF LIST
	POPJ	P,		;RETURN

ZLIST:	PUSHJ	P,BTDATA##	;FETCH ADDRESS IN BOOTSTRAP VECTOR
	  JRST	TPOPJ##		;NOT THERE--POP OFF CALLER AND RETURN
	MOVEM	T3,(T2)		;STORE IN LIST
	AOBJP	T1,CPOPJ##	;ACCOUNT FOR THE FIRST WORD
	AOS	T2		;...
	SETZM	(T2)		;ZERO NEXT
	AOBJN	T1,.-2		;CLEAN OUT THE TABLE
	POPJ	P,		;RETURN
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- COPY NXMTAB

BOOTNX:	SETOM	NXMTAB##	;INITIALIZE NXMTAB TO -1'S
	MOVE	T1,[NXMTAB##,,NXMTAB##+1]
	BLT	T1,NXMTAB##+NXMTBL##-1
	SKIPN	U,BOOTPA	;PHYSICAL ADDRESS OF BOOT ORIGIN
	JSP	T4,BOOTN4	;GIVE UP
	ADDI	U,.BTNAM	;OFFSET TO IDENTIFIER
	PUSHJ	P,REFMEM##	;FETCH
	CAME	T1,['BOOT  ']	;SANITY CHECK
	JSP	T4,BOOTN4	;DON'T KNOW HOW WE WERE BOOTED
	MOVE	U,BOOTPA	;BASE ADDRESS
	ADDI	U,.BTSIZ	;OFFSET TO SIZE WORD
	PUSHJ	P,REFMEM##	;FETCH
	SKIPL	T1		;MUST BE NEGATIVE
	JSP	T4,BOOTN4	;ELSE FATAL ERROR
	MOVE	U,BOOTPA	;BASE ADDRESS
	ADDI	U,.BTNXM	;OFFSET TO BOOT'S COPY OF NXMTAB
	PUSHJ	P,REFMEM##	;FETCH POINTER
	HLRE	T2,T1		;GET -LENGTH
	MOVNS	T2		;MAKE POSITIVE
	CAILE	T2,NXMTBL##	;BIGGER THAN THE ONE IN COMMON?
	MOVEI	T2,NXMTBL##	;YES, USE OUR LENGTH
	MOVNS	T2		;NEGATE
	HRLZS	T2		;MAKE AN AOBJN POINTER
	HRRZ	T3,T1		;COPY OFFSET
	ADD	T3,BOOTPA	;COMPUTE PHYSICAL START ADDRESS

;LOAD UP OUR COPY OF NXMTAB ONE WORD AT A TIME
BOOTN1:	HRRZ	U,T2		;GET OFFSET INTO BOOT'S NXMTAB
	ADD	U,T3		;RELOCATE
	PUSHJ	P,REFMEM##	;FETCH WORD
	MOVEM	T1,NXMTAB##(T2)	;STORE IT
	AOBJN	T2,BOOTN1	;LOOP FOR ALL WORDS
	MOVEI	T1,NXMTBL##-1	;OFFSET OF LAST WORD IN NXMTAB

;SEARCH NXMTAB BACKWARDS LOOKING FOR THE HIGHEST EXISTANT PAGE
BOOTN2:	MOVE	T2,NXMTAB##(T1)	;GET A WORD FROM NXMTAB
	CAMN	T2,[EXP -1]	;36 NON-EXISTANT PAGES
	SOJG	T1,BOOTN2	;KEEP SEARCHING
	SKIPG	T1		;4096K SYSTEM?
	DMOVE	T1,[EXP NXMTBL##-1,0] ;YES
	MOVEI	T4,^D36		;36 PAGES MAPPED PER WORD
BOOTN3:	LSHC	T2,-1		;GET A BIT IN T3
	SKIPGE	T3		;FOUND HIGHEST PAGE YET?
	SOJA	T4,BOOTN3	;NO--LOOK TO THE NEXT ONE
	IMULI	T1,^D36		;36 PAGES MAPPED PER WORD
	ADDI	T1,(T4)		;PLUS OVERFLOW
	LSH	T1,P2WLSH	;CONVERT HIGHEST PAGE TO HIGHEST ADDRESS
	MOVEM	T1,SYSORG##	;SAVE HIGHEST ADDR AS WHERE TO START ALLOCATING
	POPJ	P,		;RETURN

BOOTN4:	STOPCD	.,HALT,BNU,	;++BOOTSTRAP NXMTAB UNAVAILABLE
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- ACCOUNT FOR CORE USAGE

;SUBROUTINE TO FIXUP SYSORG TO ACCOUNT FOR THE PRESENCE OF THE YET
;TO BE MAPPED BOOTSTRAP.  THIS MUST BE DONE IMMEDIATELY AFTER SETTING
;UP NXMTAB AND BEFORE ANY SECTION MAPS ARE ALLOCATED.  OTHERWISE,
;PORTIONS OF THE BOOTSTRAP MAY BE TAKEN FOR A SECTION MAP.

BOOTSZ:	SKIPN	P1,BOOTPA	;PHYSICAL ADDRESS OF BOOT ORIGIN
	JRST	BOOTZA		;NOT THERE--GO ZERO ADDRESSES
	MOVE	U,P1		;COPY IT
	HRRI	U,.BTNAM(P1)	;POINT TO IDENTIFIER
	PUSHJ	P,REFMEM##	;FETCH
	CAME	T1,['BOOT  ']	;SANITY CHECK
	JRST	BOOTZA		;DON'T KNOW HOW WE WERE BOOTED
	HRRI	U,.BTSIZ(P1)	;OFFSET TO SIZE WORD
	PUSHJ	P,REFMEM##	;FETCH
	JUMPGE	T1,BOOTZA	;MUST BE NEGATIVE
	HLRE	T2,T1		;GET -PAGE COUNT
	MOVNS	T2		;MAKE POSITIVE
	HRRZ	T3,T1		;ISOLATE LENGTH IN WORDS
	ADDI	T3,PAGSIZ	;ROUND UP A PAGE
	LSH	T3,W2PLSH	;CONVERT TO A PAGE NUMBER
	CAME	T3,T2		;MUST MATCH
	JRST	BOOTZA		;NOT GOOD
	HLRES	T1		;GET -LENGTH IN PAGES
	LSH	T1,P2WLSH	;CONVERT TO -WORD COUNT
	MOVEM	P1,SYSORG##	;START ALLOCATING AT BOTTOM OF BOOTSTRAP
	SUB	P1,T1		;DETERMINE END OF BOOTSTRAP
	MOVEM	P1,BTSPFF	;SAVE FOR KLUDGERY AT BOOTMP
	POPJ	P,		;RETURN

BOOTZA:	SETZM	BOOTPA		;CLEAR PHYSICAL ADDRESS
	SETZM	BOOTVA##	;CLEAR VIRTUAL ADDRESS
	POPJ	P,		;RETURN

BTSPFF:	0			;FIRST PHYSICAL ADDRESS FOLLOWING BOOTSTRAP
				; USED TO FAKE OUT ONCMAP TO ALLOCATE THE
				; PHYSICAL PAGES CONTAINING THE BOOTSTRAP
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- MAP BOOTSTRAP

BOOTMP:	SKIPN	P1,BOOTPA	;PHYSICAL ADDRESS OF BOOT ORIGIN
	POPJ	P,		;NOT THERE
	MOVE	U,P1		;COPY ADDRESS
	HRRI	U,.BTSIZ(P1)	;OFFSET TO SIZE WORD
	PUSHJ	P,REFMEM##	;FETCH
	HLLZ	P2,T1		;PRESERVE -LENGTH IN PAGES
IFN FTXMON,<
	MOVSI	T1,(MS.RLC)	;SECTION NUMBER FOR RELOCATABLE CODE
	PUSHJ	P,ALCSMP	;ALLOCATE A MAP IF NECESSARY
>; END IFN FTXMON
	MOVE	T1,.CPEPT##	;POINT TO THIS CPU'S MAP
	ADDI	T1,SECTAB+(MS.RLC) ;OFFSET INTO THE SECTION MAP TABLE
	MOVE	T2,(T1)		;GET MAP POINTER
	MOVE	T1,.CPMAP##	;GET ADDRESS OF SECTION ZERO MAP
	MOVEM	T2,.EUPMP/PAGSIZ(T1) ;MAKE THE MAP ADDRESSABLE
IFE FTXMON,<
	HRRZ	T2,MONVFF##	;GET FIRST FREE ABOVE HIGH SEGMENT
	LSH	T2,W2PLSH	;CONVERT TO A PAGE NUMBER
	HRRI	T1,.EUPMP(T2)	;START HERE
	ADDI	T2,-PAGSIZ	;GET -REMANING PAGE COUNT IN T2
	HRL	T1,T2		;MAKE AN AOBJN POINTER
>; END IFE FTXMON
IFN FTXMON,<
	MOVSI	T1,-PAGSIZ	;PAGES PER SECTION
	HRRI	T1,.EUPMP	;START OF SECTION MAP
>; END IFN FTXMON
	HRR	P2,T1		;PRESERVE SECTION MAP ADDRESS
BOOTM1:	HLL	T2,P2		;GET -PAGE COUNT
BOOTM2:	SKIPE	(T1)		;PAGE IN USE?
	JRST	BOOTM1		;YES--TRY ANOTHER
	AOBJP	T1,BOOTZA	;GIVE UP IF SECTION IS FULL
	AOBJN	T2,BOOTM2	;LOOP FOR THE REQUIRED NUMBER OF PAGES
	ANDI	T1,PG.BDY	;KEEP ONLY ENDING PAGE NUMBER
	HLRE	T2,P2		;GET -LENGTH IN PAGES
	ADDI	T2,(T1)		;COMPUTE STARTING VIRTUAL PAGE NUMBER
	LSH	T2,P2WLSH	;CONVERT TO AN ADDRESS
	HRLI	T2,(MS.RLC)	;INCLUDE SECTION NUMBER FOR RELOCATABLE CODE
	MOVEM	T2,BOOTVA##	;SAVE ADDRESS
	HLRE	T1,P2		;-PAGES NEEDED
	MOVNS	T1		;MAKE POSITIVE
	LSH	T1,P2WLSH	;CONVERT TO A WORD COUNT
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.SWB) ;DIRECT POINTER + WRITABLE
	PUSH	P,SYSORG##	;SAVE SYSORG
	PUSH	P,MONVFF##	;WILL BE CHANGED BY ONCMAP
	MOVE	T3,BTSPFF	;FIRST PHYSICAL ADDRESS FOLLOWING BOOTSTRAP
	MOVEM	T3,SYSORG##	;RESET SYSORG SO WE MARK THOSE PAGES AS TAKEN
	PUSHJ	P,ONCMAP	;MAP THE PAGES
	POP	P,MONVFF##	;RESTORE FIRST FREE
	POP	P,SYSORG##	;RESTORE SYSORG
	MOVE	T1,P1		;GET STARTING PHYSICAL ADDRESS
	LSH	T1,W2PLSH	;CONVERT TO A PAGE NUMBER
	HRLI	T1,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.SWB) ;DIRECT POINTER + WRITABLE

BOOTM3:	MOVEM	T1,(P2)		;STORE IN SECTION MAP
	AOS	T1		;ADVANCE TO NEXT PAGE
	AOBJN	P2,BOOTM3	;LOOP
	CLRPT	.EUPMP		;MAKE NEW MAPPING VISIBLE
IFE FTXMON,<
	MOVE	T1,BOOTVA##	;VIRTUAL ADDRESS OF BOOT
	HLRE	T1,.BTSIZ(T1)	;- LENGTH IN PAGES OF BOOT
	MOVMS	T1		;LENGTH IN PAGES
	LSH	T1,P2WLSH	;LENGTH IN WORDS
	ADDM	T1,MONVFF##	;UPDATE TO REFLECT PAGES ALLOCATED FOR BOOT
>; END IFE FTXMON
	POPJ	P,		;DONE
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- COPY MONITOR FILESPEC

BOOTFX:	SKIPN	W,BOOTPA	;PHYSICAL ADDRESS OF BOOT ORIGIN
	POPJ	P,		;NOT THERE
	MOVE	U,W		;COPY IT
	HRRI	U,.BTSIZ(W)	;POINT TO SIZE WORD
	PUSHJ	P,REFMEM##	;FETCH
	HRRI	U,.BTDEV(W)	;POINT TO START OF FILESPEC
	MOVSI	T2,-BOOTLN	;-LENGTH OF TRANSLATION TABLE
BOOTF1:	HLRZ	U,BOOTBL(T2)	;GET AN OFFSET
	ADD	U,W		;INDEX INTO BOOT VECTOR
	PUSHJ	P,REFMEM##	;FETCH WORD
	HRRZ	T3,BOOTBL(T2)	;GET STORAGE LOCATION
	MOVEM	T1,@T3		;SAVE WORD
	AOBJN	T2,BOOTF1	;LOOP
	MOVE	T1,DEVICE	;WORD FOR STRUCTURE
	SETO	T2,		;VALUE TO COMPARE
	CAMN	T2,DDTDSK	;IF WANT TO USE BOOT STRUCTURE,
	MOVEM	T1,DDTDSK	;UPDATE THE NAME
	HRRI	U,.BTCRS(W)	;POINT TO START OF CRASH SPEC
	MOVSI	T2,-<7+3>	;AOBJN INDEX FOR STORING THE SPEC
BOOTF2:	PUSHJ	P,REFMEM##	;FETCH A WORD
	MOVEM	T1,CRSFIL##(T2)	;SAVE FOR DAEMON STARTUP
	AOJ	U,		;ADVANCE POINTER INTO BOOT
	AOBJN	T2,BOOTF2	;LOOP OVER ENTIRE SAVED FILESPEC
	POPJ	P,		;DONE


BOOTBL:	.BTDEV,,DEVICE		;DEVICE
	.BTFIL,,FNAME		;FILE NAME
	.BTEXT,,FEXT		;EXTENSION
	.BTPTH+0,,PPN		;PPN
	.BTPTH+1,,SFDLST+0	;SFD #1
	.BTPTH+2,,SFDLST+1	;SFD #2
	.BTPTH+3,,SFDLST+2	;SFD #3
	.BTPTH+4,,SFDLST+3	;SFD #4
	.BTPTH+5,,SFDLST+4	;SFD #5
BOOTLN==.-BOOTBL		;LENGTH OF TABLE
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- BUILD BOOTXT

BSTRNG:	SKIPN	W,BOOTPA	;PHYSICAL ADDRESS OF BOOT ORIGIN
	POPJ	P,		;NOT THERE
	MOVEI	T1,BOOTYO	;ROUTINE TO BUILD UP STRING
	MOVEM	T1,.CPTOA##	; SAVE AS TTY OUTPUT ROUTINE
	MOVE	T1,[POINT 7,BOOTXT##]	;BYTE POINTER
	MOVEM	T1,BOOTBP	;STORE THE POINTER
	MOVEI	T1,[ASCIZ ./D .];FIRST DO A DUMP
	PUSHJ	P,CONMES##	; ..
	SKIPN	T2,DEVICE	;A DEVICE SPECIFIED?
	POPJ	P,		;NO, LEAVE DEFAULT ALONE
	MOVEM	T2,STRMON##
	PUSHJ	P,PRNAME##	;YES--PUT IN COMMAND STRING
	MOVEI	T1,[ASCIZ /:/]	;DELIMIT WITH A COLON
	PUSHJ	P,CONMES##	; ..
	SKIPN	T2,FNAME	;FILE NAME?
	JRST	BSTRN2		;NO
	MOVEM	T2,FILMON##
	PUSHJ	P,PRNAME##	;PUT IN NAME
	HLLZ	T2,FEXT		;PICK UP EXTENSION
	JUMPE	T2,BSTRN2	;NONE--LOOK FOR PPN
	MOVEM	T2,EXTMON##
	LSH	T2,-6		;PUT IN A DOT
	TLO	T2,('.'B5)	; ..
	PUSHJ	P,PRNAME##	;TOSS IN EXT
BSTRN2:	SKIPN	T2,PPN		;A PPN?
	JRST	BSTRN5		;NO
	MOVEM	T2,PPNMON##
	PUSHJ	P,PRLBK##	;FIRST A BRACKET
	HLRZ	T1,PPN		;GET PROJECT
	PUSHJ	P,PRTDI8##	;PRINT IN OCTAL
	PUSHJ	P,PRCOM##	;ADD A COMMA
	HRRZ	T1,PPN		;GET PROG NUMBER
	PUSHJ	P,PRTDI8##	;PRINT PROG
	PUSH	P,P1		;SAVE P1
	MOVSI	P1,-5		;SETUP AOBJN POINTER TO SFDLST
BSTRN3:	SKIPN	T2,SFDLST(P1)	;NEXT SFD SPECIFIED?
	JRST	BSTRN4		;NO
	PUSHJ	P,PRCOM##	;PRINT COMMA
	PUSHJ	P,PRNAME##	;PRINT SFD NAME
	AOBJN	P1,BSTRN3	;LOOP FOR ALL
BSTRN4:	POP	P,P1		;RESTORE P1
	PUSHJ	P,PRRBK##	;ADD IN RIGHT SQUARE BRACKET
	MOVE	T1,[SFDLST,,SFDMON##] ;COPY SFD LIST TO
	BLT	T1,SFDMON##+4	;WHERE MONITOR WANTS IT
BSTRN5:	MOVEI	T3,15
	IDPB	T3,BOOTBP
	MOVEI	T3,0
	IDPB	T3,BOOTBP
	POPJ	P,
BOOTYO:	IDPB	T3,BOOTBP	;STORE BYTE IN STRING
	POPJ	P,		;RETURN

BOOTBP:	POINT	7,BOOTXT##	;RELOAD STRING POINTER
	SUBTTL	MOVE PSECT INTO FINAL POSITION

;ROUTINE TO MOVE A MONITOR PSECT INTO THE FINAL POSITION.  PSECTS ARE
;MOVED TO THE END OF PHYSICAL MEMORY (A TRADITION).
;CALL WITH:
;	T1/ STARTING VIRTUAL ADDRESS (ASSUMED TO BE ON A PAGE BOUNDARY)
;	T2/ ENDING VIRTUAL ADDRESS (LAST ADDRESS USED)
;	PUSHJ	P,MOVPSE
;CALLS ONCMAP/NZSCGC AS APPROPRIATE TO SET UP MAPPING.  THIS ROUTINE
;ASSUMES BOOT HAS LOADED THE MONITOR "IN PLACE", I.E., THERE IS A 1:1
;CORRESPONDANCE BETWEEN VIRTUAL ADDRESSES IN THE .EXE FILE AND THE
;PHYSICAL ADDRESSES CONTAINING THE PSECT TO BE MOVED.

MOVPSE:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	DMOVE	P1,T1		;COPY ARGUMENTS
	ADDI	P2,1		;FIRST ADDRESS FOLLOWING PSECT
	TRZE	P2,PG.BDY	;ROUND UP TO NEXT PAGE BOUNDARY
	ADDI	P2,PAGSIZ
	MOVE	P3,P2		;GET A COPY
	SUB	P3,P1		;COMPUTE NUMBER OF WORDS IN AREA
IFN FTXMON,<
	TLNN	T1,-1		;IF ADDRESS IS IN SECTION 0/1,
	JRST	MOVPS1		; USE ONCMAP TO ALLOCATE SPACE
	SE1ENT			;ENTER SECTION 1
	PUSHJ	P,NZSCGC	;ALLOCATE NON-ZERO SECTION CODE SPACE
	JRST	MOVPS2		;CONTINUE
>; END IFN FTXMON
MOVPS1:	PUSH	P,MONVFF##	;SAVE HONORABLE VARIABLE
	MOVEM	T1,MONVFF##	;WHERE TO ALLOCATE FROM
	MOVE	T1,P3		;COPY NUMBER OF WORDS TO MOVE
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB+PM.CSH) ;PAGE MAP BITS
	PUSHJ	P,ONCMAP	;FILL IN MAP SLOTS
	POP	P,MONVFF##	;RESTORE HONORABLE VARIABLE
MOVPS2:	MOVE	P1,.CPMAP##	;GET ADDRESS OF SECTION 0/1 MAP
	MOVE	T3,P2		;FIRST PAGE (ADDRESS) BEYOND AREA TO MOVE
	LSH	P2,W2PLSH	;;CONVERT ADDRESS TO PAGE NUMBER
	HRLI	P2,(<PM.DCD>B2)	;MAKE THAT PAGE ADDRESSABLE
	MOVEM	P2,.ECKSM/PAGSIZ(P1)
	LSH	P3,W2PLSH	;GET NUMBER OF PAGES TO MOVE
MOVPS3:	SOS	.ECKSM/PAGSIZ(P1) ;MAP THE PREVIOUS PAGE
	CLRPT	.ECKSM		;FLUSH THE MAPPING FOR THE TEMP SLOT
IFE FTXMON,<
	SUBI	T3,PAGSIZ	;BACK OFF TO START OF PAGE
	MOVE	T1,T3		;GET A COPY
	HRLI	T1,.ECKSM	;VIRTUAL SOURCE ADDRESS
	BLT	T1,PG.BDY(T3)	;COPY THE PAGE
>; END IFE FTXMON
IFN FTXMON,<
	MOVEI	T1,PAGSIZ	;NUMBER OF WORDS TO MOVE
	XMOVEI	T2,.ECKSM	;VIRTUAL SOURCE ADDRESS
	SUBI	T3,PAGSIZ	;DESTINATION ADDRESS
	PUSH	P,T3		;SAVE ACROSS BLT
	EXTEND	T1,[XBLT]	;COPY THE PAGE
	POP	P,T3		;RESTORE DESTINATION ADDRESS
>; END IFN FTXMON
	SOJG	P3,MOVPS3	;LOOP FOR ALL PAGES
	POPJ	P,		;RETURN
	SUBTTL	ONCE-ONLY HIDDEN SYMBOL TABLE SETUP

SYTBFX:
IFN FTXMON,<
	SKIPLE	P1,.JBSYM##	;HAVE SYMBOL TABLE?
	PUSHJ	P,DDTCHK	;AND RUNNING WITH EDDT?
	  POPJ	P,		;DON'T MOVE SYMBOLS
	SE1ENT			;ENTER SECTION 1
	MOVSI	T1,(MS.SYM)	;GET SECTION NUMBER FOR SYMBOLS
	PUSHJ	P,ALCSMP	;ALLOCATE A SECTION MAP
	MOVE	T1,.SYSTB+.SYTYP(P1) ;GET FLAGS,,LENGTH OF DEFINED SYMBOL TABLE
	AND	T1,[SY.LEN]	;KEEP JUST THE LENGTH
	ADD	T1,.SYSTB+.SYADR(P1) ;COMPUTE LAST ADDRESS IN DEFINED S.T.
	MOVE	T2,.SYSTB+.SYSTL+.SYTYP(P1) ;GET FLAGS,,LENGTH OF UNDEFINED S.T.
	AND	T2,[SY.LEN]	;KEEP JUST THE LENGTH
	ADD	T2,.SYSTB+.SYSTL+.SYADR(P1) ;COMPUTE LAST ADDRESS IN UNDEF S.T.
	CAMG	T1,T2		;USE THE GREATER OF THE TWO TABLES
	MOVE	T1,T2		; TO COMPUTE NUMBER OF PAGES IN S.T.
	SUB	T1,.JBSYM##	;SUBTRACT BASE OF TABLE
	MOVE	P1,T1		;SAVE LENGTH IN WORDS
	ADDI	P1,PG.BDY	;ROUND TO A PAGE BOUNDARY
	LSH	P1,W2PLSH	;REMEMBER NUMBER OF PAGES IN S.T.
	SSX	T1,MS.SYM	;SECTION NUMBER FOR SYMBOLS
	MOVE	T2,.JBSYM##	;ADDRESS OF SYMBOL TABLE
	SSX	T2,MS.SYM	;PLUG IN THE CORRECT SECTION NUMBER
	EXCH	T1,T2		;SWAP ARGUMENTS FOR NZSCGT
	PUSHJ	P,NZSCGT	;ALLOCATE SPACE FOR THE SYMBOL TABLE
;MOVE S.T. PAGE BY PAGE
	MOVE	T2,.JBSYM##	;START OF SYMBOL TABLE
	MOVE	T1,P1		;COPY NUMBER OF PAGES IN SYMBOL TABLE
	LSH	T1,P2WLSH	;CONVERT TO AN ADDRESS
	ADD	T2,T1		;FIRST ADDRESS PAST SYMBOL TABLE
SYTBF1:	MOVEI	T1,PAGSIZ	;NUMBER OF WORDS TO MOVE
	SUBI	T2,PAGSIZ	;START AT BEGINNING OF PAGE
	PUSH	P,T2		;SAVE SOURCE ADDRESS
	MOVE	T3,T2		;SET UP DESTINATION ADDRESS
	SSX	T3,MS.SYM	;PLUG IN THE SECTION NUMBER
	EXTEND	T1,[XBLT]	;MOVE ONE PAGE
	POP	P,T2		;RESTORE SOURCE ADDRESS
	SOJG	P1,SYTBF1	;LOOP FOR ALL PAGES OF SYMBOL SPACE
	MOVSI	T1,(MS.SYM)	;GET SECTION NUMBER
	MOVE	T2,.JBSYM##	;GET CURRENT ADDRESS OF SYMBOL TABLE
	SSX	T2,MS.SYM	;INSERT SECTION NUMBER
	HLLM	T1,.SYSTB+.SYADR(T2) ;FIXUP ADDRESS OF DEFINED SYMBOL TABLE
	HLLM	T1,.SYSTB+.SYSTL+.SYADR(T2) ;DITTO FOR UNDEFINED SYMBOL TABLE
	HLLM	T1,.JBSYM##	;RESET POINTER IN .JBSYM
	POPJ	P,		;RETURN
>; END IFN FTXMON
;HERE FOR NON-EXTENDED SYMBOL TABLE (KS)

IFE FTXMON,<
	SKIPGE	P1,.JBSYM##	;HAVE SYMBOL TABLE?
	PUSHJ	P,DDTCHK	;AND RUNNING WITH EDDT?
	  POPJ	P,		;DON'T MOVE SYMBOLS
	HLRE	T1,.JBSYM##	;GET LENGTH OF SYMBOL TABLE
	MOVMS	T1		;GET REAL LENGTH
	HRRZ	T2,.JBSYM##	;ADDRESS OF SYMBOL TABLE
	ADDI	T1,(T2)		;FIRST ADDRESS OUTSIDE OF THE SYMBOL TABLE
	SKIPN	T2,.JBUSY##	;IN CASE ANY UNDEF'S STILL LYING AROUND
	HRRZ	T2,.JBSYM##	;NONE, GET SYMBOL TABLE AGAIN
	ANDI	T2,-1-PG.BDY	;MOVING WHOLE PAGES, ADJUST
	SUBI	T1,(T2)		;NOW KNOW NUMBER OF WORDS TO MOVE
	ADDI	T1,PG.BDY	;BUT STILL HAVE TO ROUND IT UP
	LSH	T1,W2PLSH	;NOW HAVE THE NUMBER OF PAGES
	CAILE	T1,SYMSIZ##	;ENOUGH SPACE (SYMBK1 IN COMMON.MAC)
	MOVEI	T1,SYMSIZ##	;NO, REDUCE TO MAXIMUM
	LSH	T2,W2PLSH	;STARTING PAGE NUMBER
	PUSHJ	P,MOVSTB	;MOVE THE SYMBOL TABLE
	MOVE	T2,.JBSYM##	;GET .JBSYM
	MOVE	T3,.JBUSY##	;GET .JBUSY
	TRZ	T2,-1-PG.BDY	;KEEP JUST IN-PAGE PORTION
	TRO	T2,MONORG##	;RELOCATED .JBSYM
	TRZ	T3,-1-PG.BDY	;KEEP JUST IN-PAGE PORTION
	TRO	T3,MONORG##	;RELOCATED .JBUSY
	MOVEI	T1,[		;SUBROUTINE TO CALL
		MOVEM T2,.CPEDV##-.CPCDB##+.EDSYM(P1) ;STORE RELOCATED .JBSYM
		MOVEM T3,.CPEDV##-.CPCDB##+.EDUSY(P1) ;STORE RELOCATED .JBUSY
		MOVE T4,.CPSYB##+1 ;COUNT OF MAP WORDS TO REPLACE
		MOVEM T4,.CPSYB##-.CPCDB##+1(P1) ;STORE
		POPJ P,]
	PUSHJ	P,CPUAPP##	;FILL IN ALL CPU'S EDV'S
	PUSHJ	P,SETEDV##	;SETUP REMAINDER OF THE EDV
	SETZM	.JBSYM##	;FORGET ABOUT THESE NOW (OR IF AN ERROR)
	SETZM	.JBUSY##	;...
	POPJ	P,		;RETURN
>; END IFE FTXMON
;ROUTINE TO MOVE THE SYMBOL TABLE TO A HIDDEN PLACE.
;CALL:
;	T1/ NUMBER OF PAGES TO MOVE
;	T2/ FIRST PAGE TO MOVE
;	PUSHJ	P,MOVSTB
;RETURN:
;	CPOPJ ALWAYS

IFE FTXMON,<
MOVSTB:	MOVEM	T1,.CPSYB##+1	;NUMBER OF PAGES IN HIDDEN SYMBOL TABLE
	PUSH	P,P1		;SAVE THE AC'S
	PUSH	P,P2		;...
	MOVN	P1,T1		;GET -VE NUMBER OF PAGES TO MOVE
	HRLZS	P1		;BUILD AN AOBJN WORD
	HRRI	P1,-1(T1)	;BACKWARDS INDEX FOR SYMBK1
	MOVE	P2,T2		;FIRST PAGE NUMBER
	ADDI	P2,-1(T1)	; PLUS COUNT-1 GIVES LAST PAGE NUMBER
	PUSH	P,MONVFF##	;GOING TO FAKE OUT ONCMAP, SAVE REAL ORIGIN
MOVST1:	MOVE	T1,P2		;PAGE OF SYMBOLS
	MOVE	T2,.CPMAP##	;MAP ADDRESS
	HRLI	T1,(<PM.DCD>B2)	;ALLOW ACCESS
	MOVEM	T1,.ECKSM/PAGSIZ(T2) ;MAKE ADDRESSABLE

	MOVEI	T1,.EUPMP	;WHERE WE WANT IT TO BE MAPPED
	MOVEM	T1,MONVFF##	;SO WE DON'T CHEW UP LOTS OF VIRTUAL SPACE
	MOVEI	T1,PAGSIZ	;ONLY ALLOCATE ONE PAGE AT A TIME
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB)
	SKIPN	[M.CPU##-1]
	TDO	T2,[PM.CSH]
	PUSHJ	P,ONCMAR	;ALLOCATE A PAGE FROM SOMEWHERE
	HRLI	T1,.ECKSM	;OLD SYMBOL TABLE LOCATION (RE-MAPPED)
	HRRI	T1,.EUPMP	;NEW, SAFER, LOCATION
	BLT	T1,.EUPMP+PG.BDY ;MOVE PART OF THE SYMBOL TABLE
	MOVE	T1,.CPMAP##	;GET MAP ADDRESS
	MOVE	T1,.EUPMP/PAGSIZ(T1) ;GET MAP CONTENTS
	MOVEM	T1,SYMBK1##(P1)	;STORE SO DDT CAN RE-MAP IT IN
	ANDI	T1,17777	;ISOLATE PAGE NUMBER
	IDIVI	T1,^D36		;COMPUTE POSITION IN NXMTAB
;	MOVE	T2,BITTBL##(T2)	;GET BIT FOR PAGE
	MOVN	T3,T2		;BITTBL NOT SET UP YET
	MOVSI	T2,(1B0)	; SO WE MUST DO IT BY HAND
	LSH	T2,(T3)		;GET THE BIT
	IORM	T2,NXMTAB##(T1)	;MARK THE PAGE SO IT DOESN'T GET RE-USED
	SUBI	P1,2		;EFFECT A "BACKWARDS" AOBJN
	SUBI	P2,1		;NEXT PAGE OF THE SYMBOL TABLE
	AOBJN	P1,MOVST1	;MOVE THE WHOLE THING
	POP	P,MONVFF##	;BACK TO NORMAL ALLOCATION NOW
	POP	P,P2		;RESTORE AC'S
	POP	P,P1		;...
	POPJ	P,		;RETURN
>; END IFE FTXMON
	SUBTTL	COMPUTE MONITOR SYMBOL TABLE CHECKSUM, FIXUP PATSIZ

PATFIX:	SETZM	MSTCKS##	;INITIALIZE MONITOR SYMBOL TABLE CHECKSUM
	SKIPGE	P1,.JBSYM##	;GET POINTER TO SYMBOL TABLE
	JRST	PATFI1		;A NON-EXTENDED SYMBOL TABLE
	JUMPE	P1,CPOPJ##	;RETURN IF NO SYMBOLS
IFN FTXMON,<
	SE1ENT			;ENTER SECTION 1
	MOVE	T1,.SYCNT(P1)	;GET LENGTH OF VECTOR
	CAIGE	T1,.SYSTB+<.SYSTL*2> ;IS BLOCK LONG ENOUGH?
	STOPCD	CPOPJ,DEBUG,SYVCTS, ;++SYMBOL VECTOR TOO SHORT
	MOVE	P2,.SYSTB+.SYTYP(P1) ;GET FLAGS,,LENGTH OF DEFINED SYMBOL TABLE
	AND	P2,[SY.LEN]	;KEEP JUST THE LENGTH
	MOVE	P1,.SYSTB+.SYADR(P1) ;GET ADDRESS OF DEFINED SYMBOL TABLE
	JRST	PATFI2		;PROCEED
>; END IFN FTXMON

PATFI1:	HLRE	P2,P1		;GET -VE LENGTH OF SYMBOL TABLE
	MOVMS	P2		;MAKE IT POSITIVE
	HRRZS	P1		;ISOLATE SYMBOL TABLE ADDRESS
PATFI2:	SKIPA	T1,[RADIX50 4,PAT] ;FIND "PAT" GLOBAL, SKIP AOS OF P1
PATLOP:	AOS	P1		;ADVANCE POINTER INTO SYMBOL TABLE
	MOVE	T3,(P1)		;FETCH A WORD
	EXCH	T3,MSTCKS##	;SWAP WITH PREVIOUS CHECKSUM
	ROT	T3,1		;MUNGE IT AROUND
	ADD	T3,MSTCKS##	;ADD IN PREVIOUS CHECKSUM
	EXCH	T3,MSTCKS##	;PUT IT BACK
	TRNN	P2,1		;IS THIS THE SYMBOL VALUE WORD?
	SOJA	P2,PATLOP	;NO, GO DO IT
	CAME	T1,-1(P1)	;WAS PREVIOUS WORD "PAT"?
	JRST	PATLO1		;NO
	HRRZ	T3,(P1)		;GET VALUE OF "PAT" SYMBOL
	HRRZ	T4,PATSIZ	;CHECK WITH PATCHED INDICATION
	CAMLE	T3,T4		;USE MAX
	HRRM	T3,PATSIZ
PATLO1:	SOJG	P2,PATLOP	;GET NEXT SYMBOL,VALUE PAIR
	POPJ	P,		;DONE
	SUBTTL	SET UP SYSSIZ, CHECK FOR BREAKPOINTS AND NO EDDT

PATSIZ::MOVEI	T1,PAT##	;NO LONGER NEEDED, BUT HABITS ARE HARD TO BREAK
	PUSHJ	P,DDTCHK	;RUNNING WITH EDDT?
	  JFCL			;DON'T REALLY CARE
	MOVEM	T1,SYSSIZ##	;UPDATE FIRST FREE WITH ADDRESS RETURNED IN T1
	MOVSI	T2,(CAI)
	CAIL	T1,DDTEND##	;SEE IF EDDT INTACT
	TDZA	T3,T3		;YES--CLEAR MASK (PRESERVE DEBUGF BITS)
	SKIPA	T3,[DF.BPT]	;GET MASK OF ALL CPUS
	HLLM	T2,NODDT	;LEAVE 401 ALONE
	ANDCAM	T3,DEBUGF##	;CLEAR CPU MASK IF NO EDDT
	PUSHJ	P,CPUDDT##	;MAKE SURE CPUS CAN ENTER EDDT
	MOVEI	T1,CSBORG##	;START OF COMMON CODE AREA
	CAIL	T1,MONORG##	;DOES IT LIVE ABOVE THE HIGH SEGMENT?
	MOVEI	T1,MONORG##	;YES--THIS IS FIRST CORE AREA ABOVE LOW SEGMENT
	SUBI	T1,<M.EVM##*PAGSIZ>+1 ;BACK OFF BY AMOUNT OF RESERVED EVM AND
				; ALSO MAKE THIS THE HIGHEST ADDRESS
	MOVEM	T1,LOWLIM##	;SAVE FOR CURIOUS EYES
	CAMG	T1,SYSSIZ##	;BETTER BE ENOUGH ROOM TO EVEN ATTEMPT THIS!
	STOPCD	.,STOP,TME,	;++TOO MANY PAGES RESERVED FOR EVM
	POPJ	P,
	SUBTTL	ALLOCATE SECTION MAP

;SUBROUTINE TO ALLOCATE A MAP FOR A NON-ZERO SECTION
;CALL WITH:
;	T1 = SECTION NUMBER,,0
;RETURNS WITH A MAP ALLOCATED AND ITS ADDRESS STORED IN THIS CPUS
; EXEC SECTION MAP

IFN FTXMON,<
ALCSMP:	HLRZ	T2,T1		;GET DESIRED SECTION
	ADDI	T2,SECTAB	;OFFSET INTO SECTION MAP TABLE
	ADD	T2,.CPEPT##	;INDEX INTO THE EPT
	SKIPE	(T2)		;MAP ALREADY ALLOCATED?
	POPJ	P,		;YES--DONE
	PUSH	P,MONVFF##	;SAVE ALLOCATION VARIABLE
	PUSH	P,T1		;SAVE DESIRED SECTION NUMBER
	MOVEI	T1,.EUPMP	;ALLOCATE THIS VIRTUAL ADDRESS
	MOVEM	T1,MONVFF##
	MOVEI	T1,PAGSIZ	;LENGTH OF A SECTION MAP
	MOVSI	T2,(<PM.DCD>B2+PM.WRT+PM.CSH+PM.SWB) ;MAP BITS
	PUSHJ	P,ONCMAR	;ALLOCATED THE RESERVED PAGE
	SETZM	.EUPMP		;ZERO OUT THE PAGE
	MOVE	T1,[.EUPMP,,.EUPMP+1]
	BLT	T1,.EUPMP+PG.BDY
	POP	P,T1		;GET SECTION NUMBER BACK
	HLRZS	T1		;PUT IN THE RIGHT HALF
	MOVE	T2,.CPMAP##	;GET ADDRESS OF S0 MAP
	MOVE	T3,.EUPMP/PAGSIZ(T2) ;GET PAGE NUMBER WE ALLOCATED
	TLZ	T3,(PM.KPM)	;TURN OFF "KEEP ME" (ALWAYS SET BY ONCMAR)
	IOR	T3,.CPKPM##	;LIGHT PM.KPM IF CPU HAS AN MCA25
	MOVE	T2,.CPEPT##	;GET EPT ADDRESS
	ADDI	T2,(T1)		;PLUS SECTION NUMBER
	MOVEM	T3,SECTAB(T2)	;MAKE SECTION ADDRESSABLE
	MOVEM	T3,.CPMMA##(T1)	;MAKE SECTION MAP ADDRESSABLE IN SECTION 37
	CLRPGT			;LET HARDWARE SEE NEW PAGING
	POP	P,MONVFF##	;RESTORE FIRST FREE FOLLOWING HIGH SEGMENT
	POPJ	P,		;AND RETURN
>; END IFN FTXMON
	SUBTTL	ALLOCATE NON-ZERO SECTION MEMORY

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

IFN FTXMON,<
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) ;.EUPMP MAPS THE MAP
	CLRPT	.EUPMP		;MAKE NEW MAPPING VISIBLE
	ADD	P1,-1(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:	PUSHJ	P,GTPHPG	;GET A PHYSICAL PAGE
	TDO	T1,(P)		;SET PAGE BITS
	MOVEM	T1,.EUPMP(P1)	;STORE IT IN MAP FOR THIS SECTION
	SOSLE	-2(P)		;ALLOCATED ALL PAGES REQUESTED?
	SOJA	P1,NZSCG1	;NO, LOOP FOR MORE
	POP	P,(P)		;POP OFF JUNK
	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 SAFE TO ALLOW INTERRUPTS (KLIPA)
	POPJ	P,		;AND RETURN
>; END IFN FTXMON
	SUBTTL	SELECT PHYSICAL AND VIRTUAL ADDRESS SPACE

;SUBROUTINE TO SELECT PHYSICAL AND VIRTUAL ADDRESS FOR SPACE IN HIGH SEGMENT

;CALL:	MOVEI	T1,NUMBER-OF-WORDS-NEEDED
;	MOVEI	T2,PAGE-MAP-ACCESS-BITS-DESIRED

ONCMAR:	TDZA	T4,T4		;INDICATE NO CHECK ON EXCEEDING HLCSAD
ONCMAP:	SETO	T4,		;INDICATE SHOULD CHECK ON EXCEEDING HLCSAD
IFN FTKL10,<
	TLO	T2,(PM.KPM)	;LITE "KEEP ME"
>; END IFN FTKL10
	PUSH	P,P1		;SAVE P AC'S
	PUSH	P,P2		;...
	PUSH	P,P3		;...
	MOVE	T3,BOOTCP##	;BOOT CPU NUMBER
	IMULI	T3,.CPLEN##	;OFFSET INTO BOOT CPU'S CDB
	PUSH	P,.C0MAP##(T3)	;ADDRESS OF THE BOOT CPU'S MAP
	MOVEI	P1,PG.BDY(T1)	;ROUND UP AMOUNT OF WORDS REQUESTED
	TRZ	P1,PG.BDY	; TO FULL PAGES
	MOVE	P2,P1		;COPY NUMBER OF WORDS
	ADDB	P1,MONVFF##	;UPDATE FIRST FREE
	LSHC	P1,W2PLSH	;CONVERT P1 TO VIRTUAL PAGE NUMBER, P2 TO COUNT
	SOS	P1		;P1 = HIGHEST VIRTUAL PAGE TO BE ALLOCATED NOW
	JUMPE	T4,ONCMA1	;NO CHECK IF CALLER IS ALLOCATING BEYOND HLCSAD
	CAIL	P1,HLCSAD##/PAGSIZ ;GONE INTO THE RESERVED AREA?
	STOPCD	.,STOP,OVA,	;++ OUT OF VIRTUAL ADDRESS SPACE
ONCMA1:	MOVE	P3,T2		;COPY PAGE MAP BITS
ONCMA2:	PUSHJ	P,GTPHPG	;GET A PHYSICAL PAGE
	TDO	T1,P3		;INCLUDE PAGE MAP BITS
	ADD	P1,(P)		;OFFSET INTO BOOT CPU'S MAP
	MOVEM	T1,(P1)		;STORE PAGE MAP ENTRY
	SUB	P1,(P)		;BACK TO VIRTUAL PAGE NUMBER
	SOSLE	P2		;ANY MORE PAGES TO ALLOCATE?
	SOJA	P1,ONCMA2	;YES, LOOP FOR THEM
	CLRPGT			;LET HARDWARE SEE THE CHANGES
	POP	P,(P)		;POP OFF JUNK
	POP	P,P3		;...
	POP	P,P2		;...
	POP	P,P1		;...
	POPJ	P,
	SUBTTL	ALLOCATE PHYSICAL PAGE

;SUBROUTINE TO ALLOCATE ONE PHYSICAL PAGE.  USED BY ONCMAP AND NZSCGT.
;CALL:
;	PUSHJ	P,GTPHPG
;RETURN:
;	T1/ PHYSICAL PAGE NUMBER OBTAINED

GTPHPG:	MOVNI	T1,PAGSIZ	;AMOUNT TO BACK OFF SYSORG
	ADDB	T1,SYSORG##	;GET NEXT FREE PHYSICAL ADDRESS
	LSH	T1,W2PLSH	;CONVERT TO A PAGE NUMBER
	MOVE	T2,T1		;COPY IT HERE
	IDIVI	T2,^D36		;COMPUTE OFFSET AND BIT IN NXMTAB
	MOVNS	T3		;SELECT THE BIT
	MOVSI	T4,400000
	LSH	T4,(T3)
	TDNE	T4,NXMTAB##(T2)	;DOES THIS PAGE EXIST?
	JRST	GTPHPG		;NO, TRY NEXT LOWER ONE
	POPJ	P,		;RETURN
	SUBTTL	MARK OFF IOWD SPACE

;ROUTINE TO MARK OFF SPACE USED FOR IOWD 4-WORD BLOCKS.
;CALL:
;	T1/ NUMBER OF BLOCKS
;	T2/ STARTING ADDRESS OF BLOCK
;	PUSHJ	P,MRKIOW

IFN FTKL10,<
MRKIOW:	SUB	T2,LOWLOC##	;SUBTRACT BASE OF AREA
	JUMPL	T2,CPOPJ##	;IN CASE THE BLOCK APPEARS BEFORE THE TABLE
	PUSHJ	P,SAVE4##	;FREE UP ARGUMENT ACS FOR SETOS
	LSH	T2,-2		;CONVERT TO BIT NUMBER
	IDIVI	T2,^D36		;GET WORD AND BIT IN TABLE
	MOVE	P4,T2		;COPY OFFSET TO BIT
	ADD	P4,LOWPTR##	;ADD IN BASE OF AOBJN POINTER TO TABLE
	MOVNS	T3		;GET -VE BIT NUMBER TO START WITH
	HRLI	P4,^D36(T3)	;BIT POSITION,,ADDRESS
	MOVE	P3,T1		;GET NUMBER OF BLOCKS TO RETURN FOR SETOS
	PUSHJ	P,SETOS##	;MARK OFF THE BITS
	  POPJ	P,		;BLOCK ALREADY MARKED OFF (IE, NOT IN LTINIT)
	MOVNS	P3		;GET -VE NUMBER OF BLOCKS WE RETURNED
	ADDM	P3,NOIOWD##	;DECREMENT NUMBER OF AVAILABLE BLOCKS
	POPJ	P,		;RETURN
>; END IFN FTKL10
	SUBTTL	TYPE-IN/TYPE-OUT ROUTINES

CONOUT::PUSHJ	P,ICONM
CRLFOP::PUSHJ	P,CRLF##
	PJRST	OPOUT


ICONM::	PUSHJ	P,OTSET		;INITIALIZE LINE BUFFER
	JRST	CONMES##	;OUTPUT MESSAGE


OTSET::	PUSH	P,T1		;SAVE A TEMP
	MOVEI	T1,ONCTSZ	;SIZE OF BUFFER
	MOVEM	T1,ONCCNT	;SO CANT OVERFLOW
	MOVE	T1,LINEP	;INITIAL OUTPUT POINTER
	MOVEM	T1,ONCTOP
	MOVEI	T1,ONCTIV	;ADDRESS FOR READ ROUTINES TO USE
	MOVEM	T1,.CPTIV##	; ..
	MOVEI	T1,ONCTYO	;ADDRESS FOR TYPEOUT ROUTINES TO GO TO
	MOVEM	T1,.CPTOA##	; ..
	SETZM	ONCTCH		;CAN NO LONGER CONTINUE THE COMMAND
	JRST	TPOPJ##		;RESTORE A TEMP AND RETURN
;ASK A QUESTION WITH A DEFAULT ANSWER
;CALL WITH:
;	MOVEI	T1,[ASCIZ /QUESTION/]
;	MOVEI	T2,[ASCIZ /ANSWER/]
;	PUSHJ	P,ASKDEF
;	  RETURN HERE ON CRLF
;	ELSE RETURN HERE

ASKDEF:	PUSH	P,OPRCNT	;SAVE OLD OPRCNT
	EXCH	T3,OPRCNT	;FORCE CALLER'S
	TLNE	T3,-1		;UNLESS OLD WAS VERY LARGE - IN WHICH CASE
	MOVEM	T3,OPRCNT	;OPR TYPED SOMETHING, DON'T INTERFERE
	PUSH	P,T2		;SAVE T2
	PUSHJ	P,ICONM		;OUTPUT QUESTION
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	POP	P,T1		;RESTORE ANSWER
	MOVE	T2,DEFSP	;GET BYTE POINTER
	HLL	T1,T2		; ..
ASKDF1:	ILDB	T3,T1		;COPY STRING
	IDPB	T3,T2		; ..
	JUMPN	T3,ASKDF1	; ..
	MOVEI	T3,15		;ADD ON A CR
	IDPB	T3,T2		; ..
	PUSHJ	P,GETLND
	  CAIA			;PRESERVE SKIPNESS
	AOS	-1(P)		;...
	POP	P,OPRCNT	;RESTORE OLD TIMEOUT
	POPJ	P,
;ROUTINE TO MAKE SURE WE GIVE THE OPR TIME TO ANSWER, BECAUSE WE
;THINK WE MAY HAVE TIMED HIM OUT UNFAIRLY, AND THE NEXT QUESTION IS IMPORTANT
RSTDEF:	SKIPL	DEFALW		;HAS OPR BEEN TIMED OUT?
	POPJ	P,		;NO, NOTHING TO DO
	PUSH	P,T1		;YES, SAVE T1
	MOVEI	T1,^D60		;MAKE TIMEOUT AT LEAST A MINUTE AGAIN
	CAMLE	T1,OPRCNT	;SO OPR CAN INTERVENE
	MOVEM	T1,OPRCNT	; (NEW IS LONGER, USE IT)
	SETZM	DEFALW		;AND FORGET HE ISN'T THERE
	JRST	TPOPJ##		;RETURN


DEFSP:	POINT	7,DEFBUF
DEFLAG:	-1
DEFPTR:	POINT	7,DEFBUF
DEFBUF:	BLOCK	24		;ENOUGH FOR 99 CHAR DEFAULT
OPRCNT:	EXP	^D60		;SECONDS TILL OPR ASSUMED NOT PRESENT

DEFALW:	0			;-1 TO TAKE DEFAULT ALWAYS
;SUBROUTINE TO PUT A DECIMAL STRING INTO THE DEFAULT BUFFER
DECDEF:	MOVEI	T2,"0"		;ALWAYS FORCE 2 DIGITS
	CAIGE	T1,^D10		;WILL WE GET MORE THAN ONE ANYWAY?
	IDPB	T2,DEFPTR	;NO--ADD IN LEADING DIGIT
	PUSHJ	P,DCDFLP	;STUFF THE TEXT
	SETZ	T2,		;GET A ZERO
	MOVE	T1,DEFPTR	;AND A COPY OF THE POINTER
	IDPB	T2,T1		;ENSURE PROPER ASCIZ TERMINATION
	POPJ	P,		;RETURN TO CALLER
DCDFLP:	IDIVI	T1,12
	HRLM	T2,(P)
	SKIPE	T1
	PUSHJ	P,DCDFLP
	HLRZ	T1,(P)
	ADDI	T1,"0"
	IDPB	T1,DEFPTR
	POPJ	P,


;TYPEOUT ROUTINE TO STUFF INTO THE DEFAULT BUFFER

DEFTYO:	IDPB	T3,DEFPTR	;STUFF THE CHARACTER
	POPJ	P,		;ASSUME THE CALLER WILL MAKE IT ASCIZ


;SUBROUTINE TO PUT AN ASCIZ STRING INTO THE DEFAULT BUFFER

DEFTXT:	HRLI	T1,(POINT 7,)	;MAKE A BYTE POINTER
DEFTX1:	ILDB	T2,T1		;FETCH A CHAR
	JUMPE	T2,DEFTX2	;RETURN TO CALLER
	IDPB	T2,DEFPTR	;STORE THIS ONE
	JRST	DEFTX1		;ONWARDS
DEFTX2:	MOVE	T1,DEFPTR	;GET A COPY OF THE POINTER
	IDPB	T2,T1		;MAKE SURE IT'S ASCIZ
	POPJ	P,		;RETURN TO CALLER
	SUBTTL	ROUTINE TO WARN ABOUT OFFLINE MEMORY

MEMBAD:	PUSHJ	P,RSTDEF	;RESET DEFAULT TIMEOUT, ETC.
	MOVEI	T1,[ASCIZ /%Memory from /]
	PUSHJ	P,ICONM		;START MESSAGE
	MOVE	T1,U		;GET LOWER ADDRESS
	PUSHJ	P,PRT22A##	;PRINT AS 22-BIT OCTAL NUMBER
	MOVEI	T1,[ASCIZ / to /]
	PUSHJ	P,CONMES##	;SOME NOISE
	MOVE	T1,P3		;GET FIRST ADDRESS PAST HOLE
	SUBI	T1,1		;BACK DOWN TO END OF HOLE
	PUSHJ	P,PRT22A##	;PRINT AS 22-BIT OCTAL NUMBER
	MOVEI	T1,[ASCIZ / is offline
/]
	PUSHJ	P,CONMES##	;END MESSAGE
	PUSHJ	P,OPOUT		;PUSH OUTPUT OUT
	MOVEI	T1,[ASCIZ /Set memory/]
	MOVE	T2,['OFFLIN']	;DEFAULT
	MOVE	T3,[-3,,MEMOPT]	;TABLE OF OPTIONS
	PUSHJ	P,PRSKEY	;PROMPT AND FETCH ANSWER
	  JFCL			;SHOULDN'T HAPPEN
	SOJL	T1,CPOPJ1##	;RETURN IF "DOWN"
	SOJG	T1,CPOPJ	;"ONLINE" REQUESTED
	JRST	CPOPJ2##	;ELSE "OFFLINE" WANTED

MEMOPT:	SIXBIT	/DOWN/
	SIXBIT	/OFFLIN/
	SIXBIT	/ONLINE/
	SUBTTL	READ A LINE FROM OPERATOR CONSOLE

;ROUTINE TO READ A LINE FROM OPERATORS CONSOLE
;CALL:	PUSHJ	P,GETLIN
;	  <JUST A CR TYPED IN>
;	<NORMAL RETURN (NOT A BLANK LINE)>

GETLND:	MOVE	T1,DEFSP	;GET INITIAL STRING POINTER
	MOVEM	T1,DEFPTR	;SETUP FOR DEFAULTING
GETLIN::PUSHJ	P,SAVE1##	;SAVE P1
	SETZM	SAWCMT		;ZERO THE COMMENT FLAG
	MOVE	T1,OPRCNT	;ALLOW 60 SEC.
	IMUL	T1,TICSEC##	; ..
	SKIPGE	DEFALW		;IF THE OPR HAS BEEN TIMED OUT ALREADY,
	MOVEI	T1,1		; HURRY ALONG
	MOVEM	T1,DEFLAG	;STORE TICKS TILL TIMOUT AS A FLAG
GETLI0:	MOVE	T1,LINEP
	MOVEM	T1,ONCTIP	;INITIAL STORAGE POINTER
	MOVEI	T3," "		;PRIME COMMAND ROUTINES WITH A SPACE
	MOVEM	T3,ONCTCH	; ..
	MOVEI	P1,0		;FLAG NO ALTMODE SEEN, ZERO CHARACTER COUNT (RH
				; OF P1), CLEAR DELETE FLAG (LH OF P1)
GET1:	PUSHJ	P,XTYI		;WAIT FOR A CHARACTER
	SKIPGE	DEFLAG		;NEED A DEFAULT?
	JRST	[ILDB	T3,DEFPTR	;YES--GET BYTE
		 SKIPN	T3		;IF HIT END OF STRING,
		 MOVEI	T3,15		;MAKE IT END OF COMMAND
		 JRST	.+1]		;REJOIN
	SKIPL	DEFLAG		;NEED A DEFAULT?
	MOVE	T3,FROMFE	;GET CHAR FROM WHERE IT WAS SAVED
	ANDI	T3,177		;STRIP PARITY
	CAIE	T3,"H"-100	;BACKSPACE?
	CAIN	T3,177		;RUBOUT?
	JRST	DELETE		;YES
	TLZE	P1,1
	PUSHJ	P,BKSLSH	;TERMINAL BACKSLASH IF WE HAD BEEN DELETING
	CAIN	T3,"R"-100	;CONTROL-R?
	JRST	RETYPE		;YES
	CAIN	T3,"U"-100	;CONTROL-U?
	JRST	CNTRLU		;YES
	CAIN	T3,33		;ALTMODE/ESCAPE?
	JRST	GETLN1		;YES
	CAIE	T3,175		;OTHER ALTS?
	CAIN	T3,176		; ..
	JRST	GETLN1		;YES
GET2:	SKIPN	.UONCE##	;USER MODE?
	PUSHJ	P,XTYO		;ECHO
	CAIL	T3,140		;LOWER CASE?
	TRZ	T3,40		;YES. MAKE UPPER
	CAIE	T3,";"		;WAS IT ONE KIND OF COMMENT INDICATOR?
	CAIN	T3,"!"		;OR ANOTHER?
	SETOM	SAWCMT		;YES - LIGHT FLAG
	CAIN	T3," "		;WAS IT A SPACE?
	SETOM	SAWCMT		;THAT'S A COMMENT INDICATOR TOO
	IDPB	T3,T1		;STORE IN INPUT BUFFER
	CAIE	T3,15		;CAR RET?
	AOJA	P1,GET1		;NO. LOOP TILL BREAK
	MOVEI	T3,12		;YES. ADD LF
	SKIPN	.UONCE##	;ALREADY HAD LF IF USER MODE
	PUSHJ	P,XTYO		;OUTPUT LF
	MOVEI	T3,0		;TERMINATE INPUT STRING IN BUFFER
	IDPB	T3,T1		; ..
	SKIPE	P1		;NON-NULL LINE?
	AOS	(P)		;TAKE SKIP RETURN
	SKIPE	.UONCE##	;USER MODE?
	CLRBFI			;CLEAN UP
	MOVEM	P1,ALTMFL	;SAVE ALTMODE TYPED FLAG
	POPJ	P,		;AND RETURN
;ROUTINE TO SEE IF ALTMODE WAS TYPED IN RESPONSE TO A QUESTION
ALTM::	SKIPGE	ALTMFL		;ALTMODE TYPED?
	JRST	STRTUP		;GO BACK TO THE BEGINING
	POPJ	P,		;JUST RETURN
DELETE:	TRNN	P1,-1		;AT BEGINNING OF LINE ?
	JRST	DELET1		;YES
	TLON	P1,1		;SET DELETE FLAG
	PUSHJ	P,BKSLSH	;TYPE BACKSLASH IF JUST STARTING TO DELETE
	LDB	T3,T1		;GET PREVIOUS CHARACTER
	PUSHJ	P,XTYO		;ECHO IT AS WE DELETE IT
	ADD	T1,[XWD 070000,0] ;BACK UP BYTE POINTER
	TLNE	T1,400000	;FINISHED THIS WORD YET ?
	ADD	T1,[XWD 347777,-1] ;YES, BACK UP ADDRESS
	SOJA	P1,GET1

DELET1:	TLZE	P1,1
	PUSHJ	P,BKSLSH	;TERMINAL BACKSLASH IF DELETED ANY CHARS
DELET2:	MOVEI	T3,15
	PUSHJ	P,XTYO
	MOVEI	T3,12
	PUSHJ	P,XTYO
	HRLOI	T1,777		;DO NOT ALLOW A DEFAULT
	MOVEM	T1,DEFLAG	;STORE FLAG
	JRST	GETLI0

CNTRLU:	MOVEI	T3,"^"		;TYPE UP ARROW
	PUSHJ	P,XTYO
	MOVEI	T3,"U"		;TYPE U
	PUSHJ	P,XTYO
	JRST	DELET2		;FINISH UP

BKSLSH:	PUSH	P,T3
	MOVEI	T3,134		;TYPE BACKSLASH
	PUSHJ	P,XTYO
	POP	P,T3
	POPJ	P,

GETLN1:	MOVEI	T3,"$"		;OUTPUT DOLLAR SIGN IF ALT-MODE TYPED
	SKIPN	.UONCE##	;ALREADY ECHOED IF USER-MODE
	PUSHJ	P,XTYO
	HRROS	P1		;MECHANISM USED TO BY-PASS PART OF DIALOGUE
	MOVEI	T3,15		; WHEN ALTMODE IS TYPED (ALTMFL NEGATIVE ON
	JRST	GET2		; RETURN FROM GETLIN).

RETYPE:	MOVEI	T3,15		;CARRIAGE RETURN
	PUSHJ	P,XTYO
	MOVEI	T3,12		;LINE FEED
	PUSHJ	P,XTYO
	PUSH	P,T1		;SAVE THE BYTE POINTER
	SETZ	T3,		;GET A ZERO
	IDPB	T3,T1		;MAKE ASCIZ
	MOVE	T1,LINEP	;GET VIRGIN BYTE POINTER TO INPUT LINE
RETYP1:	ILDB	T3,T1		;GET A CHARACTER
	JUMPE	T3,RETYP2	;DONE AT NULL
	PUSHJ	P,XTYO		;TYPE IT
	JRST	RETYP1		;LOOP
RETYP2:	POP	P,T1		;RESTORE BYTE POINTER
	JRST	GET1		;GET NEXT CHARACTER
	SUBTTL	TYPE A LINE ON OPERATOR CONSOLE

;ROUTINE TO TYPE A LINE ON OPERATOR CONSOLE
;ECHO CHECK STOPS LINE AND RETURNS
;CALL:	ONCTOP SET TO END OF MESSAGE
;CALL OPOUTX FOR MESSAGE CONTINUATIONS TO BE SUPPRESSED IF
; THE PREVIOUS PART OF THE MESSAGE WAS ^O'D

OPOUTX::SKIPE	CNTRLO		;^O IN EFFECT ?
	PJRST	OTSET		;YES, JUST CLEAR BUFFER AND GO AWAY

OPOUT::	SETZM	CNTRLO		;CLEAR ^O FLAG
	SKIPE	.UONCE##	;IF USER MODE,
	SKPINL			;MAKE SURE TO DEFEAT ^O
	  JFCL			;IT MIGHT EVEN SKIP
	MOVEI	T3,0		;MAKE SURE STRING ENDS
	IDPB	T3,ONCTOP	;WITH A NULL
	MOVE	T1,LINEP	;AND RESTART AT BEGINNING
	MOVEM	T1,ONCTOP	; ..

OPOUT1:	SKIPE	.UONCE##	;USER MODE?
	JRST	OPOUT2		;YES, USER-MODE HAS THE REAL ^O, SKIP THIS CRUFT
IFN FTKL10,<
	PUSHJ	P,SPCGTI##	;CHECK FOR INPUT, SKIP WITH CHAR IN T3
	  JRST	OPOUT2		;NO INPUT
	JRST	OPOUT3		;YES
>; END IFN FTKL10
IFN FTKS10,<
	SKIPN	T3,CTYIWD	;SKIP IF CHAR IS THERE
	  JRST	OPOUT2		;NONE THERE
	SETZM	CTYIWD		;CLEAR CTYIWD
	JRST	OPOUT3		;GO DO CTRL-O
>; END IFN FTKS10
OPOUT2:	ILDB	T3,ONCTOP	;GET CHAR TO TYPE
	JUMPE	T3,OTSET	;QUIT ON NULL
	PUSHJ	P,XTYO		;TYPE CHAR
	MOVEI	T3,0		;GET A ZERO
	DPB	T3,ONCTOP	;CLEAR BUFFER AS WE GO
	JRST	OPOUT1		;LOOP

;HERE WHEN KEY STRUCK DURING TYPEOUT
OPOUT3:	SETOM	CNTRLO		;SET ^O FLAG
	MOVEI	T3,"^"
	PUSHJ	P,XTYO
	MOVEI	T3,"O"
	PUSHJ	P,XTYO
	MOVEI	T3,15
	PUSHJ	P,XTYO		;TYPE OUT CRLF
	MOVEI	T3,12
	PUSHJ	P,XTYO
	JRST	OTSET		;RESET OUTPUT BUFFER, RETURN FROM OPOUT

CNTRLO:	0			;SUPPRESS TYPE-OUT WHEN -1
	SUBTTL	LOWEST LEVEL CONSOLE OUTPUT ROUTINE

XTYO::	CAIL	T3," "		;CONTROL CHARACTER?
	JRST	XTYOCH		;NO
	CAIN	T3,15		;CARRIAGE RETURN?
	SETZM	ONCCOL		;YES, BACK AT BEGINNING OF LINE
	CAIE	T3,11		;TAB?
	JRST	XTYOCN		;NO, DON'T COUNT WIDTH OF CONTROL CHARACTERS
	PUSH	P,T3		;SAVE ORIGINAL CHARACTER
	MOVE	T3,ONCCOL	;GET COLUMN
	ADDI	T3,^D8		;GET TO NEXT TAB STOP
	TRZ	T3,7		;...
	SUB	T3,ONCCOL	;FIND NUMBER OF SPACES NEEDED
	PUSH	P,T3		;SAVE COUNT
	MOVEI	T3," "		;GET A SPACE
	PUSHJ	P,XTYOCH	;OUTPUT IT
	SOSLE	(P)		;NEED ANY MORE?
	JRST	.-2		;YES, DO ANOTHER
	ADJSP	P,-1		;TOSS THE COUNT
	POP	P,T3		;RESTORE ORIGINAL TAB
	POPJ	P,		;RETURN

XTYOCH:	AOS	ONCCOL		;INCREMENT COLUMN COUNT
XTYOCN:	SKIPE	.UONCE##	;USER MODE?
	JRST	[OUTCHR	T3	;PRINT CHARACTER
		 POPJ	P,]	;AND RETURN
	PUSHJ	P,PEVEN8##	;GET GOOD PARITY FOR CHAR
IFN FTKL10,<
	PUSHJ	P,SPCTYO##	;TYPE OUT
	PUSHJ	P,OPRFIL##	;DO FILLERS
	PUSHJ	P,APRCHK	;UPDATE TIME
	PUSHJ	P,SPCWTO##	;WAIT FOR OUTPUT DONE
	  JRST	.-2		;NOT DONE, WAIT SOME MORE
>; END IFN FTKL10
IFN FTKS10,<
	PUSHJ	P,APRCHK	;UPDATE TIME
	SKIPE	CTYOWD		;CAN WE TYPE YET?
	JRST	.-2		;NO, WAIT
	TRO	T3,CTYOVL	;SET VALID FLAG
	MOVEM	T3,CTYOWD	;PUT IT IN 8080'S WORD
	WRAPR	SP.SSF+SP.IFE	;INTERRUPT THE 8080
	PUSHJ	P,APRCHK	;UPDATE TIME
	SKIPE	CTYOWD		;CHAR TAKEN YET?
	JRST	.-2		;NO, WAIT
>; END IFN FTKS10
	ANDI	T3,177		;ONLY CHAR FOR COMPARES IN GETLIN
	POPJ	P,		;RETURN

ONCCOL:	0			;COLUMN NUMBER FOR TAB SIMULATION
	SUBTTL	LOWEST LEVEL CONSOLE INPUT ROUTINE

;WAIT TIL INPUT DONE ON BEFORE RETURNING WITH NEXT CHAR.

XTYI:	PUSH	P,T1		;SAVE AN AC
	SKIPN	.UONCE##	;USER MODE?
	JRST	XTYI1		;NO
	INCHWL	T3		;WAIT ON LINE, READ A CHARACTER
	JRST	XTYI2		;GO FINISH UP
XTYI1:	PUSHJ	P,APRCHK
	SKIPGE	DEFLAG
	JRST	XTYI3
IFN FTKL10,<
	PUSHJ	P,SPCGTI##	;SKIP IF CHAR PRESENT, WITH IT IN T3
	  JRST	XTYI1
> ;END IFN FTKL10
IFN FTKS10,<
	SKIPN	T3,CTYIWD	;SKIP IF CHAR PRESENT, WITH IT IN T3
	JRST	XTYI1
	SETZM	CTYIWD		;CLEAR FOR NEXT TIME
> ;END IFN FTKS10
XTYI2:	MOVEM	T3,FROMFE	;SAVE CHARACTER FOR USE LATER
	HRLOI	T1,777		;RESET THE TIMER
	MOVEM	T1,DEFLAG	; SO WE DON'T START UP
	MOVEM	T1,OPRCNT
	SETZM	DEFALW
	JRST	TPOPJ##		;RETURN AND RESTORE T1

XTYI3:	SETOM	DEFALW
	JRST	TPOPJ##

ONCKLT::BLOCK	1		;PLACE TO KEEP BITS FOR KL10 INTERVAL TIMER
FROMFE:	BLOCK	1		;PLACE TO KEEP CHAR AFTER XTYO GETS IT
	SUBTTL	CHECK FOR CLOCK TICK

;CHECK APR FOR CLOCK FLAG SO TIME USER TYPES IN WILL BE ACCURATE

APRCHK::
IFN FTKL10,<SKIPN .CPTIM##>	;APR CLOCK TICKED?
IFN FTKS10,<CONSO APR,SP.ITI>	;APR CLOCK TICKED?
	POPJ	P,		;NO
	PUSHJ	P,SAVT##	;SAD BUT NEEDED
IFN FTKS10,<WRAPR SP.CSF!SP.ITI>	;SET UP FOR ANOTHER CLOCK TICK

IFN FTMP,<
	MOVEI	T1,.C0CDB##	;INCREMENT .CPOK FOR ALL CPUS
APRCH1:	AOS	.CPOK##-.CPCDB##(T1)
	HLRZ	T1,.CPCDB##-.CPCDB##(T1) ;STEP TO NEXT CPU
	JUMPN	T1,APRCH1
>; END IFN FTMP
IFN FTKS10,<PUSHJ P,APRTIM##>	;COMPUTE INTERVAL SINCE LAST INTERRUPT
	SETZ	T1,		;GET A ZERO
	EXCH	T1,.CPTIM##	;GET AND CLEAR THE FLAG
	ADDM	T1,TIME##	;UPDATE THE CLOCK
	ADDM	T1,SYSUPT##	;AND SYSTEM UPTIME
	MOVNS	T1		;'CAUSE SUBM GOES THE WRONG WAY
	ADDM	T1,DEFLAG	;FOR CALLER TO SEE IF TIME FOR DEFAULT
	PUSHJ	P,INITIC##	;DO SPECIAL ONCE-A-TICK PROCESSING
IFN FTSCA,<
	PUSHJ	P,SC.TIC##	;DO ONCE/TICK SCA MEMORY ALLOCATION
	PUSHJ	P,PPDTIC##	;DITTO FOR THE KLIPA
>; END IFN FTSCA
	POPJ	P,
	SUBTTL	ONCE TTY INPUT VECTOR

;ONCTIV	ONCE TTY INPUT VECTOR.

ONCTIV::PUSHJ	P,ONCTYI	;(0 = CTIGNC) GET NEXT CHAR
	MOVE	T3,ONCTCH	;(1 = CTIGLC) GET LAST CHAR
	MOVEM	T3,ONCTCH	;(2 = CTISLC) SET LAST CHAR
	MOVE	T1,ONCTIP	;(3 = CTIGBP) GET BYTE POINTER
	MOVEM	T1,ONCTIP	;(4 = CTISBP) SET BYTE POINTER

;HERE TO READ THE NEXT CHAR FOR COMCON.

ONCTYI:	ILDB	T3,ONCTIP	;GET INPUT CHARACTER
	MOVEM	T3,ONCTCH	;STORE FOR RE-READS
	POPJ	P,		;AND RETURN TO CALLING ROUTINE


ONCTYO::SOSLE	ONCCNT		;COUNT CHARACTERS
	IDPB	T3,ONCTOP	;PUT IN BUFFER
	POPJ	P,		;AND RETURN
	SUBTTL	SWAPPER INITIALIZATION

;ROUTINE TO RE-INITIALIZE THE SWAPPING AVAILABILITY TABLE.  CALLED AT
; SYSTEM INITIALIZATION TIME.

SWPINI:	MOVEI	T1,SWPDDB##	;SWAPPER DDB
	HLRZ	T2,DSKDDB##+DEVSER ;GET DDB POINTED TO BY PROTOTYPE
	HRLM	T1,DSKDDB##+DEVSER ;LINK UP SWAPPER DDB
	HRLM	T2,SWPDDB##+DEVSER ;SPLICE SWAPPER DDB INTO CHAIN
	MOVEI	T1,ASSCON	;FLAG SWAPPER DDB AS ASSIGNED BY CONSOLE
	IORM	T1,SWPDDB##+DEVMOD ;SINCE IT APPEARS IN SYSTEM DDB LIST (BEFORE PROTOTYPE
				; ELSE USERS COULD INIT IT.
IFN FTMP,<
	MOVE	T1,DSKDDB##+DEVCPU ;INITIALIZE INTERLOCK POINTER
	HRRM	T1,SWPDDB##+DEVCPU
>; END IFN FTMP
	SETZB	T1,R		;MAKE SURE ASSIGNED TO JOB 0
	DPB	T1,PJOBN##
	HLRZ	U,SWPUNI##	;GET ADDR OF FIRST UNIT FOR SWAPPING
	JUMPE	U,CPOPJ##	;EXIT IF NOT A UNIT DATA BLOCK
	HRLM	U,NXTSUN##	;INITIALIZE NEXT SWAPPING UNIT
	SETZM	SQREQ##		;CLEAR SWAPPPING LOCS
	SETZM	VIRTAL##	;START TOTAL VIRTUAL CORE FOR SYSTEM AT 0
IFN FTXMON,<
	LDB	R,UNYSNS##	;SECTION NUMBER FOR SWAPPING SATS
	MOVSS	R		;TO THE LEFT HALF
>; END IFN FTXMON

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	SE1ENT			;MUST BE IN SECTION 1
SWPIN1:	SETZM	UNIFKS(U)	;CLEAR FREE J FOR SWAP
	SKIPL	T1,UNIPTR(U)	;SKIP IF SWAPPING SPACE ON THIS UNIT
	JRST	SWPIN2		;NONE
	HLRE	T2,T1		;T2=-LENGTH OF SWAPPING SAT
	HRLS	T1		;T1=ADDR IN BOTH HALVES
	SUBB	T1,T2		;T1=BLT PTR
	MOVSS	T1
IFE FTXMON,<
	BLT	T1,-1(T2)	;COPY INITIAL SWAPPING SAT
>; END IFE FTXMON
IFN FTXMON,<
	HLRZ	T2,T1		;STARTING ADDRESS, SECTION RELATIVE
	HRRZ	T3,T1		;WHERE TO BLT TO, SECTION RELATIVE
	ADD	T2,R		;ADD IN SECTION NUMBER
	ADD	T3,R		; DITTO
	MOVSI	T1,400000	;MAKE LOGICAL BLOCK 0 BE UNAVAILABLE
	IORM	T1,(T2)
	HLRE	T1,UNIPTR(U)	;NEGATIVE LENGTH
	MOVMS	T1		;LENGTH
	EXTEND	T1,[XBLT]	;MOVE IT
>; END IFN FTXMON
	MOVE	T1,UNIPTR(U)	;PTR TO SWAPPING SAT
IFE FTXMON,<
	MOVSI	T2,400000	;MAKE LOGICAL BLOCK 0 BE UNAVAILABLE
	IORM	T2,(T1)		; SINCE SLOT=0 MEANS PAGE NOT IN USE AT ALL
>; END IFE FTXMON
	PUSHJ	P,SATCN##	;COUNT 0 BITS=FREE K
	ADDM	T2,VIRTAL##	;COUNT TOTAL IN SYSTEM
	MOVEM	T2,UNIFKS(U)	;AND GET FOR UNIT
SWPIN2:	HLRZ	U,UNISWP(U)	;NEXT UNIT IN SWAP LIST
	JUMPN	U,SWPIN1	;LOOP FOR ALL UNITS IN SWAP LIST
	MOVE	T1,VIRTAL##	;GET #K VIRTUAL CORE IN SYSTEM
	MOVEM	T1,K4SWAP##	;AS #K FOR SWAPPING IN SYSTEM
	MOVEM	T1,VMCMAX##	;SAVE AS MAX K FOR VIRTUAL JOBS
	POPJ	P,
	SUBTTL	TIME AND ACCOUNTING INITIALIZATION

TACINI:	MOVE	T1,TIME##	;GET TIME OF DAY AS UPDATED DURING TTY LOOP
	MOVE	T2,TICSEC##	;TICS PER SECOND
	LSH	T2,-1		;DIVIDE BY 2
	ADD	T1,T2		;AND ROUND
	IDIV	T1,TICMIN##	;MINUTES IN T1, REMAINDER IN TICS
	PUSH	P,T2		;SAVE REMAINDER
	IDIVI	T1,^D60		;HOURS IN T1, MINUTES IN T2
	MOVEM	T1,LOCHOR##	;UPDATE GETTAB HOURS
	MOVEM	T2,LOCMIN##	;AND MINUTES
	POP	P,T1		;GET BACK REMAINING TICS
	IDIV	T1,TICSEC##	;AND ROUND TO SECONDS
	MOVEM	T1,LOCSEC##	;AND STORE
	SUBI	T1,^D60		;-VE SECONDS UNTIL NEXT MINUTE
	MOVNM	T1,.CPSEC##	;STORE POSITIVE NUMBER FOR ONCE-A-MINUTE CALLS
	SUB	T2,TICSEC##	;-VE TICKS UNTIL NEXT SECOND
	MOVNM	T2,.CPHTM##	;STORE POSITIVE FOR ONCE-A-SECOND CALLS
	PUSHJ	P,SUDATE##	;SET UP UNIVERSAL DATE-TIME
	PUSHJ	P,CHKMNT##	;CHECK IF WENT PAST MIDNIGHT
	MOVE	T1,TIME##	;GET UPDATED TIME OF DAY
	MOVEM	T1,.CPTML##	;INITIALIZE LAST TIME OF DAY
	PUSHJ	P,APRTIM##	;UPDATE TICKS SINCE LAST INTERRUPT
	PUSHJ	P,SETIME##	; TO INITILIZE GETIME
	PUSHJ	P,OMSTIM##	;COMPUTE TIME TO FIRST OPR MESSAGE
	POPJ	P,		;RETURN
	SUBTTL	START CLOCK

;THIS ROUTINE CALLED AT THE POINT AT WHICH WE WOULD
; LIKE CLOCK TICKS TO START HAPPENING.

TIMINI:	MOVE	T1,SYSUPT##	;GET CURRENT UPTIME
	MOVEM	T1,.CPUPT##	;KEEP CPU'S COPY IN SYNCH
IFN FTKL10,<
	MOVE	T1,.CPEPT##	;GET ADDRESS OF EPT
	MOVE	T1,.EPTII(T1)	;GET ADDRESS OF XPCW BLOCK
	MOVEI	T2,TIMINT##	;ADDRESS OF INTERRUPT ROUTINE
	MOVEM	T2,3(T1)	;SALT AWAY IN TM'N'INT BLOCK
	MOVEI	T1,^D1666	;ASSUME 60HZ
	MOVE	T2,STATES##
	TLNE	T2,(ST.CYC)	;IS OUR ASSUMPTION CORRECT?
	MOVEI	T1,^D2000	;NO, 2000 IS INTERVAL
	CONO	TIM,TO.CTD!TO.CIT!TO.SIT(T1) ;START TIMER GOING
	CONO	PI,PI.ON!PI.TNP!<1_<7-APRCHN##>> ;MAKE SURE WE GET INTERRUPTS
>;END IFN FTKL10
IFN FTKS10,<
	WRAPR	SP.SSF!SP.ITI	;TURN INTERVAL TIMER ON
	MOVEI	T1,^D17*10000	;ASSUME 60 HZ
	MOVE	T2,STATES##
	TLNE	T2,(ST.CYC)	;IS IT?
	MOVEI	T1,^D20*10000	;NO, 50HZ
	WRINT	T1		;SET UP INTERVAL REG
>;END IFN FTKS10
	POPJ	P,		;RETURN
	SUBTTL	ROUTINES TO MARK AND LINK PAGTAB

;SUBROUTINE TO MARK AND LINK PAGTAB FOR THE PHYSICAL PAGES ALLOCATED TO
;	THE MONITORS HIGH SEGMENT ( OR AT LEAST THINGS ABOVE 400000 )

;CALL:	T1 = VIRTUAL ADDRESS OF FIRST PAGE TO ACCOUNT FOR
;	T3 = LAST PAGE ACCOUNTED FOR ( RETURNED BY THIS ROUTINE )
;	T4 = NUMBER OF PAGES TO LOOK AT
;
;RETURNS T3 = SET UP FOR ANY SUBSEQUENT CALL
;ALSO WRITE PROTECTS THE HIGH SEGMENT ON THE WAY THROUGH UNLESS PM.SWB
;	IS LIT IN THE PAGE MAP ENTRY.

;THE SCREWY CONVENTIONS HAPPENED TO FALL OUT OF THE WAY KIINI USED TO WORK

SETMRB:	LSH	T1,W2PLSH
	ADD	T1,.CPMAP##
SETMRP:	HRLI	T1,(POINT 36,0)
SETMR1:	ILDB	T2,T1		;GET PHYSICAL PAGE CONTAINING THE MONITOR
	JUMPE	T2,SETMR2	;OK IF NOT ALLOCATED
	TLNN	T2,(<PM.ACD>B2^!<PM.DCD>B2) ;ANYTHING BESIDES DIRECT POINTER?
	TLNN	T2,(<PM.DCD>B2)	;YES, MAKE SURE DIRECT POINTER (RSVD SLOTS)
	JRST	SETMR2		;THIS ISN'T A PAGE NUMBER
	ANDI	T2,17777	;CLEAR THE ACCESS BITS
	TLO	T2,MONTRB	;INDICATE THIS PHYSICAL PAGE CONTAINS THE MONITOR
	MOVEM	T2,PAGTAB(T3)	; IN PAGTAB
	SSX	T2,MS.MEM
	HRRZM	T3,PT2TAB(T2)	;SET BACK LINK
	HRR	T3,T2		;SAVE LAST MONITOR PAGE SEEN
SETMR2:	SOJG	T4,SETMR1	;LOOP OVER ALL THE MONITORS PAGES
	MOVSI	T2,MONTRB	;IN CASE SOME PAGES WERE SKIPPED (T2=0)
	MOVEM	T2,PAGTAB(T3)	;INDICATE THE LAST PAGE OF THE MONITOR
	HRRZM	T3,LMPAG##	;..
	POPJ	P,


;SUBROUTINE TO MARK PAGES IN PAGTAB WITH THE "PHYSICALLY CONTIGUOUS" BIT.
;CALL:
;	T1/ STARTING PHYSICAL PAGE NUMBER
;	T2/ NUMBER OF PAGES
;	PUSHJ	P,SETCTB
;RETURN:
;	CPOPJ ALWAYS

SETCTB:	SE1ENT			;FOR PAGTAB REFERENCE
	SSX	T1,MS.MEM	;THE PAGTAB SECTION
	MOVSI	T3,CONTGB	;THE BIT WE LIKE
SETCT1:	IORM	T3,PAGTAB(T1)	;LIGHT IT FOR THIS PAGE
	SOJLE	T2,CPOPJ##	;RETURN IF NO MORE PAGES TO MARK
	AOJA	T1,SETCT1	;ELSE LOOP FOR THE NEXT PAGE
	SUBTTL	ROUTINES TO SET/CLEAR CACHE BITS

;ROUTINE TO SET OR CLEAR CACHE BITS FOR A RANGE OF EXEC ADDRESSES.
; THE RANGE IS C(T1)R THROUGH C(T2)R INCLUSIVE.
; USES ALL T ACS, AC U WITHOUT RESTORING THEM. ORIGINAL ARGUMENTS
; IN T1 AND T2 ARE LOST.
; ARGUMENTS MUST NOT BE IN PER-PROCESS SPACE
; WHEN CALLING CCTRNS, THE SECTION MAP SHOULD BE ADDRESSABLE VIA
; EXEC VIRTUAL ADDRESS .EUPMP (SEE CALL AT CLRCC1-4).

IFN FTMP,<
CCTRNG:	TDZA	T3,T3		;NOTE "ADDRESS RANGE" ENTRY
CCTRNS:	SETO	T3,		;NOTE "ENTIRE SECTION" ENTRY
	SE1ENT			;FOR PAGTAB REFERENCES
	PUSHJ	P,SAVE1##	;NEED P1
	MOVE	P1,[TLO	T2,TNCSHB] ;SET TEMPORARY
	MOVE	U,NCPRUN##	;GET NUMBER OF RUNNABLE CPUS
	CAIN	U,1		;SKIP IF MORE THAN 1 RUNNABLE CPU
	SKIPA	U,[TLO T1,(PM.CSH)]	;SET CACHE BIT
	MOVE	U,[TLZ T1,(PM.CSH)]	;CLEAR CACHE BIT
	JUMPE	T3,CCBRN1	;GO IF "ADDRESS RANGE" ENTRY
	MOVEI	T1,0		;STARTING PAGE NUMBER
	MOVEI	T2,^D511	;HIGHEST PAGE NUMBER
	MOVEI	T4,.EUPMP	;ADDRESS OF ADDRESSABLE SECTION MAP
	JRST	CCBRN2		;GO DO THE ENTIRE SECTION
>; END IFN FTMP
CSBRNG:	SKIPA	U,[TLO T1,(PM.CSH)]	;CLEAR CACHE BIT
CCBRNG:	MOVE	U,[TLZ T1,(PM.CSH)]	;CLEAR CACHE BIT
IFN FTMP,<
	SE1ENT			;FOR PAGTAB REFERENCES
	PUSHJ	P,SAVE1##
	MOVE	P1,[TLZ	T2,TNCSHB] ;CLEAR TEMPORARY BIT
>; END IFN FTMP
CCBRN1:	LSH	T1,W2PLSH	;CONVERT TO PAGES
	LSH	T2,W2PLSH
	MOVEI	T4,(T1)		;COPY STARTING PAGE NUMBER
	ADD	T4,.CPMAP##	;ADD IN ADDRESS OF S0/1 MAP
CCBRN2:	HRRZ	T3,T1		;SAVE STARTING VIRTUAL PAGE
	HRLI	T4,(POINT 36,0)	;SET UP BYTE POINTER TO SECTION MAP
CCBRN3:	ILDB	T1,T4		;GET CONTENTS OF SLOT
	JUMPE	T1,CCBRN4
	XCT	U		;SET OR CLEAR CACHE BIT ACCORDINGLY
	DPB	T1,T4		;AND PUT IT IN MAP
IFN FTMP,<
	ANDI	T1,17777	;GET PHYSICAL PAGE NUMBER
	SSX	T1,MS.MEM	;SECTION NUMBER
	EXCH	T2,PAGTAB(T1)	;GET ENTRY, SAVE T2
	TLNE	T2,MONTRB	;A MONITOR PAGE
	XCT	P1		;YES, SET/CLEAR TEMPORARY UNCACHED
	EXCH	T2,PAGTAB(T1)	;STORE NEW SETTING, RESTORE T2
>; END IFN FTMP
CCBRN4:	CAIGE	T3,(T2)		;DID WE JUST DO LAST PAGE?
	AOJA	T3,CCBRN3	;LOOP, WE HAVE MORE TO DO.
	POPJ	P,		;YES, BYE.
	SUBTTL	WRITE LOCK MONITOR CODE SEGMENTS

;ROUTINE TO TURN OFF PM.WRT IN CODE SEGMENT PAGES.
;ALL OTHER PAGES ARE LEFT WRITE-ENABLED.

WRTLOK:	SKIPA	DEBUGF##	;PATCH TO SKIPGE IF DEBUGGING WITH MONITOR
				; WRITE-ENABLED
	POPJ	P,		;LEAVE THINGS ALONE
	MOVEI	T1,WRTLKA	;GET ADDRESS OF ROUTINE
	PJRST	CPUAPP##	;APPLY OVER ALL CPUS

WRTLKA:	MOVE	T1,.CPEPT##-.CPCDB##(P1) ;GET ADDRESS OF EPT
	HRRZ	T2,SECTAB(T1)	;GET PAGE NUMBER OF SECTION 0 MAP
	PUSHJ	P,WRTLKB	;TWIDDLE THE BITS IN THE PAGE MAP
IFN FTXMON,<
	HRRZ	T2,SECTAB+<(MS.HGH)>(T1) ;GET PAGE NUMBER OF SECTION 2 MAP
	PUSHJ	P,WRTLKB	;TWIDDLE THE BITS IN THE PAGE MAP
>; END IFN FTXMON
	POPJ	P,		;RETURN

WRTLKB:	LSH	T2,P2WLSH	;CONVERT PAGE NUMBER TO AN ADDRESS
	LDB	T3,[POINT 14,SYSSIZ##,26] ;GET NUMBER OF LOW SEGMENT PAGES
	ADD	T2,T3		;SKIP LOW SEGMENT PAGES (ALWAYS WRITABLE)
	MOVNS	T3		;NEGATE THE COUNT
	ADDI	T3,HLCSAD##/PAGSIZ ;NUMBER OF ENTRIES IN THE MAP TO CONSIDER
WRTLK1:	MOVE	T4,(T2)		;GET AN ENTRY
	TLZN	T4,(PM.SWB)	;SKIP IF PAGE SHOULD BE WRITE ENABLED
	TLZ	T4,(PM.WRT)	;CLEAR WRITE ENABLE
	MOVEM	T4,(T2)		;SAVE THE PAGE ENTRY AWAY
	SOJLE	T3,CPOPJ##	;QUIT WHEN ALL ENTRIES HAVE BEEN DONE
	AOJA	T2,WRTLK1	;GET NEXT ENTRY
	SUBTTL	SET UP INTERVAL TIMER TO GIVE CLOCK TICKS

;SETUP INTERNAL TIMER ON KL10 TO MIMIC CLOCKS OF EARLIER CPUS.

ONCINT:
IFN FTKL10,<
	CONO	MTR,MO.TOF!MO.CTB ;TURN OFF TIMER, CLEAR TIME BASE
	MOVE	T1,.CPEPT##	;GET ADDRESS OF EPT
	MOVE	T1,.EPTII(T1)	;GET ADDRESS OF XPCW BLOCK
	MOVEM	T1,ONCINJ	;SAVE FOR LATER XJEN
	MOVEI	T2,ONCIN0	;GET ADDRESS OF INTERRUPT ROUTINE
	MOVEM	T2,3(T1)	;SALT AWAY IN TM'N'INT BLOCK
	CONO	MTR,MO.TON!APRCHN## ;TURN ON TIMER
	MOVEI	T2,^D1666+TO.SIT+TO.CTD	;WORD TO KEEP TIMER GOING
	MOVE	T1,STATES##	;GET STATES
	TLNE	T1,(ST.CYC)	;50 HZ?
	MOVEI	T2,^D2000+TO.SIT+TO.CTD	;50 HZ WORD TO KEEP TIMER GOING
	MOVEM	T2,ONCKLT	;CONO TIM,@ONCKLT STARTS TIMER GOING AGAIN
	CONO	TIM,TO.CIT(T2)	;CLEAR INTERNAL TIMER & START FIRST TIME
	CONO	PI,PI.ON!PI.TNP!<1_<7-APRCHN##>> ;MAKE SURE WE GET INTERRUPTS
	POPJ	P,		;RETURN
>;END IFN FTKL10
IFN FTKS10,<
	WRAPR	SP.SSF!SP.ITI	;TURN ON INTERVAL TIMER
	MOVEI	T2,^D17*10000	;60HZ
	MOVE	T1,STATES	;GET STATES
	TLNE	T1,(ST.CYC)	;50HZ?
	MOVEI	T2,^D20*10000	;YES
	WRINT	T2		;SET UP INTERVAL REGISTER
	POPJ	P,		;RETURN
>;END IFN FTKS10

IFN FTKL10,<
;ROUTINE CALLED ON A CLOCK INTERRUPT
ONCIN0:	MOVEM	P,.CPSP##	;SAVE P1
	MOVE	P,.CPAPP##	;SET UP APR STACK
	PUSHJ	P,APRTIM##	;COMPUTE INTERVAL SINCE LAST INTERRUPT
	MOVE	P,.CPSP##	;RESTORE P
	CONO	TIM,@ONCKLT	;CLEAR INTERNAL TIMER DONE AND START UP AGAIN
	XJEN	@ONCINJ		;DISMISS THE INTERRUPT

ONCINJ:	BLOCK	1		;ADDRESS OF INTERVAL TIMER XPCW BLOCK
>; END IFN FTKL10
	SUBTTL	CHECK CRASH DATE/TIME CHECKSUM

;ROUTINE TO CHECK DATE/TIME CHECKSUM
;RETURNS CRASH DATE IN T4
CHKDCS:	HLRZ	T4,CRSDTM
	HRRZ	T2,CRSDTM
	ADD	T2,T4		;ADD DATE AND TIME
	HLRZ	T3,CRSWHY
	ADD	T2,T3		;PLUS STOPCD NAME
	HRRZ	T3,CRSSTS
	ADD	T2,T3
	ADDI	T2,507601	;PLUS MAGIC CONSTANT
	HRRZ	T3,CRSCHK	;GET CHECKSUM COMPUTED BY COMMON
	CAIN	T3,(T2)		;MATCH?
	AOS	(P)
	POPJ	P,
	SUBTTL	SETUP LOWER CORE LOCATIONS

SLCLDS:
IFN FTKL10,<
	SKIPE	[M.CPU##-1]	;IF MORE THAN 1 CPU,
	SKIPA	T1,[JRST SYSTOP##] ;LET WARM RESTART=J407
	MOVE	T1,[JRST APRWRS##] ;WARM RESTART INSTRUCTION
	MOVEM	T1,WRSINS	;STORE IN WARM RESTART LOCATION
>; END IFN FTKL10
IFN FTMP,<
	MOVE	T1,[JRST APRRES##] ;POWER FAIL-AUTO-RESTART INSTR.
>; END IFN FTMP
IFE FTMP,<
	MOVE	T1,[HALT APRRES##] ;HALT IF NOTHING SAVED
>; END IFE FTMP
	MOVEM	T1,ARSLOC	;STORE IN AUTO-RESTART LOCATION

	MOVE	T1,[XPCW @.CPKAF##]
	MOVEM	T1,KAFLOC	;STORE IT IN RIGHT SPOT

	MOVE	T2,.CPMAP##	;GET ADDRESS OF SECTION 0 MAP
	PUSH	P,.EUPMP/PAGSIZ(T2) ;SAVE TEMPORARY MAP SLOT
	MOVSI	T1,(<PM.DCD>B2+PM.WRT) ;MAKE HARDWARE LOCS 0-17 ADDRESSABLE
	MOVEM	T1,.EUPMP/PAGSIZ(T2) ; VIA .EUPMP - .EUPMP+17
	CLRPT	.EUPMP		;MAKE NEW MAPPING VISIBLE
	MOVEI	17,.EUPMP	;MOVE HARDWARE AC'S INTO SHADOW AC'S TO CLEAR PARITY
	BLT	17,.EUPMP+17	;STOP WITH SHADOW AC 17
	MOVE	T1,.CPMAP##	;GET ADDRESS OF SECTION 0 MAP
	POP	P,.EUPMP/PAGSIZ(T1) ;RESTORE TEMPORARY MAP SLOT
	CLRPT	.EUPMP		;MAKE OLD MAPPING VISIBLE
	POPJ	P,		;RETURN
SUBTTL	SET UP FREE CORE AND BITMAP

SETFPT:	MOVE	T1,LOWLIM##	;GET HIGHEST ADDRESS IN LOW SEGMENT
	AOS	T1		;MAKE IT FIRST ADDRESS PAST LOW SEGMENT
	MOVE	T2,SYSSIZ##	;CURRENT END OF ALLOCATED LOW SEGMENT CORE
	MOVEM	T2,FREPTR##	;FREE CORE BITMAP GOES HERE
	SUB	T1,T2		;COMPUTE WORDS IN BETWEEN
	IDIVI	T1,^D36*4	;COMPUTE NUMBER OF BITMAP WORDS NEEDED
				;DON'T ROUND SO FREPTR WON'T DESCRIBE MORE THAN
				; THE SPACE UP TO LOWLIM
	MOVE	T3,T1		;GET A COPY
	IDIVI	T3,^D36*4	;COMPUTE NUMBER OF WORDS USED BY BITMAP
	SKIPE	T4		;IF A REMAINDER,
	AOS	T3		; ROUND UP
	SUB	T3,T1		;SUBTRACT THAT FROM SIZE OF POOL
	HRLM	T3,FREPTR##	;SET UP AOBJN POINTER TO FREE CORE BITMAP
	MOVMS	T3		;GET THE SIZE OF THE BITMAP
	ADD	T3,FREPTR##	;GET ADDRESS OF START OF FREE CORE
	HRRZM	T3,LOCORE##	;SET UP LOCORE
	MOVE	T1,LOWLIM##	;*** GET HIGHEST ADDRESS-1
	AOS	T1		;*** BUMP IT
	MOVEM	T1,SYSSIZ##	;*** FAKE OUT SYSTAT AND FRIENDS
	MOVE	T1,FREPTR##	;GET POINTER TO BITMAP
	SETZM	(T1)		;MAKE SURE IT IS ZEROED
	AOBJN	T1,.-1
	POPJ	P,		;RETURN
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- BUILD THE SYSTEM LISTS

BLDSSL::SE1ENT			;ENTER SECTION ONE
	MOVEI	T1,.BTSSL	;OFFSET
	SKIPE	PRESSL		;USING THE PRESERVED SSL?
	PUSHJ	P,BTDATA##	;BOOTSTRAP AVAILABLE?
	  POPJ	P,		;NO
	MOVEI	T3,[ASCIZ/system search list/]
	PUSHJ	P,SETENT	;SET POINTERS
BLDSS1:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	BLDSS2		;NO MORE DATA--ALL STRUCTURES VALID
	PUSHJ	P,FNSTR##	;DOES THIS STRUCTURE EXIST?
	  PUSHJ	P,BADSTR	;NO--COMPLAIN TO OPERATOR
	JRST	BLDSS1		;GO CHECK OUT THE NEXT STRUCTURE
BLDSS2:	PUSHJ	P,RSTENT	;RESET POINTERS
	SKIPN	PRECNT		;ANY ENTRIES FOUND?
	AOS	PREERR		;NO--CALL THIS AN ERROR
	SKIPN	PREERR		;ANY ERRORS?
	JRST	BLDSS3		;NO
	PUSHJ	P,BLDDSK	;TELL OPERATOR WE WILL USE DISK DATA BASE
	POPJ	P,		;GIVE UP
BLDSS3:	HLRZ	T1,SYSSTR##	;POINT TO START OF STR DB CHAIN
BLDSS4:	SETOM	STRSRC##(T1)	;EMPTY THE SSL
	HLRZ	T1,STRSYS##(T1)	;GET NEXT STR DB
	JUMPN	T1,BLDSS4	;LOOP
BLDSS5:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	CPOPJ1##	;RETURN
	PUSHJ	P,FNSTR##	;FIND THE STR DB
	  JRST	BLDSS5		;CAN'T HAPPEN
	HRRZ	T2,BLDPTR	;GET RELATIVE OFFSET IN TABLE
	MOVEM	T2,STRSRC##(P2)	;MAKE THAT THE POSITION IN THE SSL
	JRST	BLDSS5		;LOOP FOR THE NEXT STRUCTURE
BLDASL::SE1ENT			;ENTER SECTION ONE
	MOVEI	T1,.BTASL	;OFFSET
	SKIPE	PREASL		;USING THE PRESERVED ASL?
	PUSHJ	P,BTDATA##	;BOOTSTRAP AVAILABLE?
	  POPJ	P,		;NO
	MOVEI	T3,[ASCIZ/active swapping list/]
	PUSHJ	P,SETENT	;SET POINTERS
BLDAS1:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	BLDAS2		;NO MORE DATA--ALL UNITS VALID
	MOVE	T2,T1		;PUT NAME IN PROPER PLACE
	PUSHJ	P,FNDUNI	;DOES THIS UNIT EXIST?
	  JRST	[PUSHJ P,BADUNI	;NO--COMPLAIN TO OPERATOR
		 JRST  BLDAS1]	;GO CHECK OUT THE NEXT UNIT
	LDB	T1,UNYK4S##	;GET SWAPPING SPACE ALLOCATED ON UNIT
	SKIPG	T1		;HAVE ANY?
	PUSHJ	P,BLDSWP	;NO--COMPLAIN TO OPERATOR
	JRST	BLDAS1		;GO CHECK OUT THE NEXT UNIT
BLDAS2:	PUSHJ	P,RSTENT	;RESET POINTERS
	SKIPN	PRECNT		;ANY ENTRIES FOUND?
	AOS	PREERR		;NO--CALL THIS AN ERROR
	SKIPN	PREERR		;ANY ERRORS?
	JRST	BLDAS3		;NO
	PUSHJ	P,BLDDSK	;TELL OPERATOR WE WILL USE DISK DATA BASE
	POPJ	P,		;GIVE UP
BLDAS3:	HLRZ	T1,SYSUNI##	;POINT TO START OF UDB CHAIN
BLDAS4:	SETOM	UNISUN(T1)	;EMPTY THE ASL
	HLRZ	T1,UNISYS(T1)	;GET NEXT UDB
	JUMPN	T1,BLDAS4	;LOOP
BLDAS5:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	CPOPJ1##	;DONE
	MOVE	T2,T1		;PUT NAME IN PROPER PLACE
	PUSHJ	P,FNDUNI	;FIND THE UDB
	  JRST	BLDAS5		;CAN'T HAPPEN
	HRRZ	T2,BLDPTR	;GET RELATIVE OFFSET IN TABLE
	MOVEM	T2,UNISUN(U)	;MAKE THAT THE POSITION IN THE ASL
	JRST	BLDAS5		;LOOP FOR THE NEXT UNIT

FNDUNI:	HLRZ	U,SYSUNI##	;GET FIRST UNIT DATA BLOCK IN SYSTEM
FNDUN1:	CAME	T2,UNIHID(U)	;ACCEPT MATCH ON UNIT ID
	CAMN	T2,UDBNAM(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
BLDSDL::SE1ENT			;ENTER SECTION ONE
	MOVEI	T1,.BTSDL	;OFFSET
	SKIPE	PRESDL		;USING THE PRESERVED SDL?
	PUSHJ	P,BTDATA##	;BOOTSTRAP AVAILABLE?
	  POPJ	P,		;NO
	MOVEI	T3,[ASCIZ/system dump list/]
	PUSHJ	P,SETENT	;SET POINTERS
BLDSD1:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	BLDSD2		;NO MORE DATA--ALL STRUCTURES VALID
	PUSHJ	P,FNSTR##	;DOES THIS STRUCTURE EXIST?
	  PUSHJ	P,BADSTR	;NO--COMPLAIN TO OPERATOR
	JRST	BLDSD1		;GO CHECK OUT THE NEXT STRUCTURE
BLDSD2:	PUSHJ	P,RSTENT	;RESET POINTERS
	SKIPN	PRECNT		;ANY ENTRIES FOUND?
	AOS	PREERR		;NO--CALL THIS AN ERROR
	SKIPN	PREERR		;ANY ERRORS?
	JRST	BLDSD3		;NO
	PUSHJ	P,BLDDSK	;TELL OPERATOR WE WILL USE DISK DATA BASE
	POPJ	P,		;GIVE UP
BLDSD3:	HLRZ	T1,SYSSTR##	;POINT TO START OF STR DB CHAIN
BLDSD4:	SETOM	STRSDL##(T1)	;EMPTY THE SDL
	HLRZ	T1,STRSYS##(T1)	;GET NEXT STR DB
	JUMPN	T1,BLDSD4	;LOOP
BLDSD5:	PUSHJ	P,NXTENT	;GET NEXT ENTRY
	  JRST	CPOPJ1##	;DONE
	PUSHJ	P,FNSTR##	;FIND THE STR DB
	  JRST	BLDSD5		;CAN'T HAPPEN
	HRRZ	T2,BLDPTR	;GET RELATIVE OFFSET IN TABLE
	MOVEM	T2,STRSDL##(P2)	;MAKE THAT THE POSITION IN THE SDL
	JRST	BLDSD5		;LOOP FOR THE NEXT STRUCTURE
SUBTTL	ONCE-ONLY/BOOTSTRAP INTERFACE -- MISCELLANEOUS ROUTINES

;SET UP TO ACCESS BOOTSTRAP VECTOR ENTRIES
;CALL:	MOVE	T1, LENGTH OF TABLE
;	MOVE	T2, TABLE ADDRESS
;	MOVE	T3, IDENTIFYING TEXT (OR -1 IF NOT TO STORE ANY)
;	PUSHJ	P,SETENT
;	<RETURN>

SETENT:	ADJSP	T1,-1		;PREDECREMENT POINTER
	SUBI	T2,1		;PREDECREMENT ADDRESS
	MOVEM	T1,BLDPTR	;SAVE POINTER
	MOVEM	T1,SAVPTR	;MAKE A COPY
	MOVEM	T2,BLDTBL	;SAVE ADDRESS
	MOVEM	T2,SAVTBL	;MAKE A COPY
	SKIPL	T3		;STORE BUILD TEXT?
	MOVEM	T3,BLDTXT	;YES
	SETZM	PRECNT		;CLEAR COUNT OF ENTRIES FOUND
	SETZM	PREERR		;CLEAR ERROR FLAG
	POPJ	P,		;RETURN


;RESET THE VECTOR ENTRY POINTERS
;CALL:	PUSHJ	P,RSTENT
;	<RETURN>

RSTENT:	MOVE	T1,SAVPTR	;GET SAVED POINTER
	MOVEM	T1,BLDPTR	;RESET IT
	MOVE	T1,SAVTBL	;GET SAVED ADDRESS
	MOVEM	T1,BLDTBL	;RESER IT
	POPJ	P,		;RETURN


;RETRIEVE THE NEXT ENTRY
;CALL:	PUSHJ	P,NXTENT
;	  <NON-SKIP>		;RAN OUT OF DATA
;	<SKIP>			;T1 CONTAINS THE ENTRY

NXTENT:	MOVE	T1,BLDPTR	;GET AOBJN POINTER
	AOBJP	T1,CPOPJ##	;RETURN IF DONE
	MOVEM	T1,BLDPTR	;UPDATE
	AOS	BLDTBL		;ADVANCE POINTER
	SKIPN	T1,@BLDTBL	;GET NEXT ENTRY
	JRST	NXTENT		;EMPTY SLOT--TRY AGAIN
	AOS	PRECNT		;COUNT THE ENTRY
	JRST	CPOPJ1##	;RETURN
;TELL THE OPERATOR THE PRESERVED DATA CANNOT BE USED
;CALL:	PUSHJ	P,BLDDSK
;	<RETURN>

BLDDSK:	MOVEI	T1,[ASCIZ /[Rebuilding the /]
	PUSHJ	P,ICONM		;TYPE TEXT
	MOVE	T1,BLDTXT	;GET TEXT
	PUSHJ	P,CONMES##	;TYPE IT
	MOVEI	T1,[ASCIZ/ from the HOM blocks]
/]
	PUSHJ	P,CONMES##	;TYPE TEXT
	PJRST	CRLFOP		;APPEND A CRLF AND RETURN


;TELL THE OPERATOR THAT A STRUCTURE OR LOGICAL UNIT IS MISSING
;CALL:	MOVE	T1, SIXBIT NAME
;	PUSHJ	P,BADSTR/BADUNI
;	<RETURN>

BADSTR:	SKIPA	T2,[[ASCIZ/%Structure /]]
BADUNI:	MOVEI	T2,[ASCIZ/%Logical unit /]
	AOS	PREERR		;FLAG THE ERROR
	PUSH	P,T1		;SAVE STRUCTURE OR LOGICAL UNIT NAME
	MOVE	T1,T2		;POINT TO TEXT
	PUSHJ	P,ICONM		;TYPE IT
	POP	P,T2		;GET STRUCTURE NAME BACK
	PUSHJ	P,PRNAME##	;TYPE IT
	MOVEI	T1,[ASCIZ/ missing from the /]
	PUSHJ	P,CONMES##	;TYPE TEXT
	MOVE	T1,BLDTXT	;GET IDENTIFIER
	PUSHJ	P,CONMES##	;TYPE IT
	PJRST	CRLFOP		;APPEND A CRLF AND OUTPUT


;TELL THE OPERATOR A UNIT HAS NO SWAPPING SPACE ALLOCATED
;CALL:	MOVE	U, UDB ADDRESS
;	PUSHJ	P,BLDSWP
;	<RETURN>

BLDSWP:	AOS	PREERR		;FLAG THE ERROR
	MOVEI	T1,[ASCIZ/%No swapping space allocated on /]
	PUSHJ	P,ICONM		;TYPE TEXT
	MOVE	T2,UDBNAM(U)	;GET PHYSICAL UNIT NAME
	PUSHJ	P,PRNAME##	;TYPE IT
	SKIPN	UNIHID(U)	;HAVE A UNIT-ID?
	PJRST	CRLFOP		;NO--APPEND A CRLF AND OUTPUT
	MOVEI	T1,[ASCIZ/ (/]	;SEPARATE FROM
	PUSHJ	P,CONMES##	; PHYSICAL NAME
	MOVE	T2,UNIHID(U)	;GET LOGICAL UNIT NAME
	PUSHJ	P,PRNAME##	;TYPE IT
	MOVEI	T1,[ASCIZ /)/]	;TERMINATE
	PUSHJ	P,CONMES##	;TYPE TEXT
	PJRST	CRLFOP		;APPEND A CRLF AND OUTPUT
	SUBTTL	CORE ALLOCATOR ROUTINES


;ROUTINE TO ALLOCATE BIT MAP CORE
;CALL:	MOVE	T1, NUMBER OF WORDS
;	PUSHJ	P,  INICORE
;	<RETURN>		;T1 UNCHANGED, T2 HAS ADDRESS
;
;ALL ACS PRESERVED

INICOR::PUSH	P,T1		;SAVE NUMBER OF WORDS
	MOVEI	T2,(T1)		;COPY WORD COUNT
	PUSH	P,[EXP 0]	;RESERVE SPACE ON STACK
	PUSH	P,T3		;SAVE T3
	PUSH	P,T4		;SAVE T4
	PUSHJ	P,GETWDS##	;ALLOCATE CORE
	  STOPCD .+1,STOP,NCS,	;++ NO CORE AT SYSINI TIME
	MOVEM	T1,-2(P)	;SAVE START ADDRESS
	SETZM	(T1)		;CLEAR FIRST WORD
	MOVEI	T2,(T1)		;MAKE A COPY
	HRLI	T1,1(T1)	;ADDR+1
	MOVSS	T1		;MAKE A BLT POINTER
	ADD	T2,-3(P)	;COMPUTE END OF BLT
	BLT	T1,-1(T2)	;CLEAR CORE
	POP	P,T4		;RESTORE T4
	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE ADDRESS
	POP	P,T1		;RESTORE NUMBER OF WORDS
	POPJ	P,		;RETURN

	SUBTTL	DATA STORAGE

DEVICE:	BLOCK	1		;MONITOR BOOTSTRAP DEVICE
FNAME:	BLOCK	1		;MONITOR BOOTSTRAP FILE NAME
FEXT:	BLOCK	1		;MONITOR BOOTSTRAP EXTENSION
PPN:	BLOCK	1		;MONITOR BOOTSTRAP PPN
SFDLST:	BLOCK	5		;MONITOR BOOTSTRAP SFDS

PRESSL::BLOCK	1		;NON-ZERO IF USING PRESERVED SSL
PREASL::BLOCK	1		;NON-ZERO IF USING PRESERVED ASL
PRESDL::BLOCK	1		;NON-ZERO IF USING PRESERVED SDL
PRECNT:	BLOCK	1		;COUNT OF ENTRIES FOUND
PREERR:	BLOCK	1		;NON-ZERO IF AN ERROR DETECTED
BLDTXT:	BLOCK	1		;ADDRESS OF IDENTIFYING TEXT
BLDTBL:	BLOCK	1		;ADDRESS OF TABLE IN BOOTSTRAP VECTOR
BLDPTR:	BLOCK	1		;AOBJN POINTER TO TABLE
SAVTBL:	BLOCK	1		;SAVED ADDRESS OF TABLE IN BOOTSTRAP VECTOR
SAVPTR:	BLOCK	1		;SAVED AOBJN POINTER TO TABLE
TXTBUF::BLOCK	<TXTLEN==30>	;RANDOM TEXT BUFFER
TXTPTR:	BLOCK	1		;BYTE POINTER TO TXTBUF
TXTCNT:	BLOCK	1		;BYTE COUNT
CHKDAT:	BLOCK	1		;LOCAL STORAGE FOR DATE (12 BIT)
CRSDAY: BLOCK	1		;DATE OF LAST CRASH
FETFLG:	BLOCK	1		;-1 IF GOT DATE FROM A FE

CHGFLG::BLOCK	1		;CHANGE RATHER THAN DEFINE
GOFLAG:	BLOCK	1		;NON-ZERO IF "GO" TYPED
MMTSIZ:	BLOCK	1		;SIZE OF MEMORY MANAGEMENT TABLES (IN WORDS)
IGNORE::BLOCK	1		;/NOERROR FLAG
SRLNXM:	BLOCK	1		;POINTER TO NXMTAB FOR ERROR.SYS
LODTIM:	BLOCK	1		;TIME OF RELOAD
CRSSAV:	BLOCK	1		;SAVED COPY OF CRSDTM

;CONSTANTS

ONCTIP:	0			;TYPE-IN POINTER
ONCTCH::0			;LAST CHAR TYPED IN.
ONCTOP:	0			;TYPE-OUT POINTER
ONCCNT:	0			;COUNTER FOR TYO
ALTMFL::0			;ALTMODE TYPED FLAG
SAWCMT:	0			;COMMENT CHARACTER SEEN FLAG
LINEP:	POINT	7,LINBUF	;INPUT AND OUTPUT LINE BUFFER
LINBUF:	BLOCK	<BUFLEN==150>	;LINE BUFFER (LONG ENOUGH FOR WHY RELOAD)
   ONCTSZ==<BUFLEN*5>-1		;CHARACTERS WHICH FIT IN OUTPUT BUFFER

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
	SUBTTL	THE END


	RADIX 8

	XLIST			;LITERALS
	LIT
	LIST

	VAR			;JUST IN CASE


SYSEND::END			;END OF SYSINI