Google
 

Trailing-Edge - PDP-10 Archives - dec-10-omona-u-mc9 - daemon.mac
There are 17 other files named daemon.mac in the archive. Click here to see a list.
TITLE DAEMON - PROGRAM TO SERVICE USER REQUESTS V15(574) - 8 APR 77
SUBTTL D BLACK/DAL/RCC/JSL/CER/RLD/SMM/BAH/PMW/WRS

VWHO==0			;WHO LAST UPDATED THIS CUSP
VDAEMON==15
VMINOR==0		;MINOR VERSION NUMBER
VEDIT==574

;COPYRIGHT (C) 1971; 1972; 1973; 1974; 1975; 1976; 1977
; BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

;	UPDATE SUMMARY AS OF VERSION 7(52)

;053	PARAMETER NOT SET UP CORRECTLY FOR GETLCH UUO IN ERROR
;	INTERCEPTING ROUTINE AT INTRES+5 (SPR 10-11,097).

;054	NEW ROUTINES INTRODUCED TO PROVIDE ERROR REPORTING FOR
;	MAGTAPES AS PART OF THE 507/601 RELEASE.  NEW ROUTINES ARE
;	COMPLETELY BACKWARD COMPATIBLE AND WILL NOT BE EXERSIZED FOR
;	MONITORS PRIOR TO  50622.

;055	ERROR.SYS UPTIME INCORRECT BY FACTOR OF 4.  ERRINI+14,
;	MAKE ASHC OPERAND DECIMAL 17 RATHER THAN OCTAL.

;056	RANDOM PROTECTION OF FACT FILES.  APPNDF+4, STORE AC A,
;	RATHER THAN 0.

;057	FT1975, SUPPORT FOR NEW FORMAT FACT FILE ENTRIES, IN WHICH
;	THE DATE LASTS PAST 1975.

;060	FIXES TO MAKE EDIT 54 WORK.

;061	FIX TO TAKE CARE OF AOBJN DIFFERENCE FROM KA TO KI. CLOCK
;	REQUEST FOR HIGHEST JOB NUMBER WAS NOT GETTING SERVICED ON KA.

;062	ADD DEFENSIVE CODE TO HANDLE ERRORS ON ERROR.SYS. DAEMON WILL
;	NOW WRITE ERROR.X01 TO ERROR.X77 IF NECESSARY.

;063	GENERATE CORRECT FORMAT DATE/TIME WORD IN FACT ENTRIES

;064	FIX FOR UNDEFINED SYMBOL NXTWAK IF USING CERTAIN NONSTANDARD
;	FEATURE TEST SETTINGS

;065	CLEAR .JBINT ON EXIT

;066	INSURE THAT DUMP DOESN'T GET DONE IF AN ERROR THAT WILL PREVENT
;	IT FROM WORKING IS DETECTED

;067	QPNTR IS STILL SET UP WRONG (ON KA AND KI).RH NEEDS TO BE
;	-(# OF INTERNAL CLOCK REQUESTS -1). (SINCE 0 REPRESENTS 
;	A QUEUE IN JBTCLK.
;070	IMPLEMENTS 6.01 SUPPORT

;071	COMPLETES IMPLEMENTATION OF 6.01 SUPPORT AND INCLUDES THE
;	SOURCE FOR SCANER AS PART OF DAEMON.MAC.

;072	MINOR EDIT TO CLEAN UP SOME SMALL DEFICIENCIES LEFT OVER FROM 
;	EDIT 71 AND TO PROVIDE A COMMON FATHER FOR SOUPS OF FUTURE
;	DEVELOPMENT AND INTEGRATION OF IPCF STUFF

;073	EDITS PREPARING THE INTEGRATION OF [SYSTEM] INFO
;	ALL [SYSTEM]INFO DEPENDENCIES ARE DETERMINED BY THE
;	FEATURE SWITCH FTIPCF.THIS SWITCH IS DEFINED AS OFF
;	FOR STANDARD RELEASES AND SHOULD NOT BE TURNED ON
;	NOTE: THAT TURNING ON FTIPCF IMPLIES AN IMPURE VERSION.
;	IT MIGHT BE REMARKED THAT A PURE DAEMON IS A RATHER
;	IMPURE IDEA

;074	ADD THE CAPABILITY TO DAEMON TO RESTART ON ILLEGAL UUO'S
;	ILL. MEM.REF ADDRESS CHECK EXTERNAL JOB ERROR,NXM ,PDL
;	OVERFLOW

;075	FIX SOME BUGS AND CHANGE THE FORMAT OF A SAVE FILE SO THAT
;	NON-CONTIGUOUS LOW SEGMENTS CAN BE 'GOTTEN' INTO A CORE IMAGE
;	THAT RESEMBLES THE ORIGINAL.  THIS IS DONE BY OUTPUTTING A NULL
;	IOWD FOR EACH EXISTANT BUT ZERO PAGE.

;076	INSERT A NEW SUBROUTINE 'SCNBRK' TO FORCE TTY SCANNING
;	TO GO TO END OF LINE FOR EACH DAEMON COMMAND.

;077	FIX A BUG INVOLVING USING THE WRONG HALF OF 'SEGSWP' TO STORE
;	A SWAPPING POINTER BEFORE CALL TO REDPEC

;100	A BLIND ATTEMPT TO FIX WHAT MIGHT BE A PROBLEM GETTING UPMP'S
;	OFF THE SWAPPING SPACE.

;101	START DAEMON AT DAEMON +2 WHEN RESTARTING IT,THIS WILL IDENTIFY
;	THAT IT HAS TO DETACH FROM THE CURRENT TERMINAL AND SUPPRESS OTHER OUTPUT
;	NOTE THAT RESTART ALWAYS DEFINED AND ALWAYS IS ZERO WHEN
;	NO IPCF OR RESTART FUNCTIONS ARE WISHED

;102	FIX A SECURITY LEAK IN THE DCORE COMMAND

;103	CHANGE NAME TO DAE AND NO TO DUMMY

;104	INIT DSK:[1,4] INSTEAD OF SYS:[1,4] FOR FACT.SYS UPDATES
;	AS ELSEWISE THE ENABLING OF NEW E.G. WILL LET
;	THE UPDATE MODE ACCESS FAIL

;105	IF ANOTHER DAEMON IS RUNNING THEN JUST EXIT
;	AND LET OPERATOR DECIDE WHAT TO DO

;106	AS 104 ERROR.SYS CANNOT BE UPDATED WITH AMBIGUOUS SYS

;107	A REENTER OF DAEMON FAILED TO EXIT WITH THE TERMINAL ATTACHED
;	THIS WAS DUE TO THE OMISSION OF A JFCL AFTER THE ZAPRUN CALL

;110	EDIT ERROR IN EDIT 102 IN DAEOPN CODE

;110(A)	WHEN A SECOND DAEMON IS RUNNING DAEMON SHOULD CALL
;	DAEREN TO EXIT

;110(B)	GIVE MORE INFORMATION THEN COULD NOT GET AT SWAP POINTER

;EDITS 111-210 RESERVED FOR SPECIAL RELEASES

;VERSION 10(110) RELEASED WITH ALL ABOVE EDITS
;ALL LATER EDITS IN VERSION 11

;211	FIX CODE TO HANDLE NEW SWAPPING POINTERS FOR
;	6.01 CORRECTLY

;212	REMOVE CRLF FROM JOB SAVED MESSAGE TO LOOK LIKE MONITOR

;213	FIX EXAMINE AND DEPOSIT COMMANDS FOR HIGH SEGMENTS

;214	CHECK FOR OUTPUT DEVICE OF NUL AND FINISH WITH NO IO IF TRUE

;215	FIX HIGH SEGMENT SAVE TO ONLY WRITE EXACT
;	NUMBER OF WORD IN LAST BLOCK OF HGH OR SHR FILE

;216	FIX TO EDIT 62 TO MAKE DAEMON WRITE IN LAST ERROR.X?? FILE
;	WHICH EXISTS ON ERRDEV

;217	FIX UNDEFINED GLOBALS ILIST AND OLIST IF CHKFCT=0

;220	FIX TO MAKE DAEMON SAVE DO SAME AS MONITOR DEPENDENT ON CONTENTS
;	OF .JBCOR AND .JBHRL.

;221	FIX TO NOT ERROR INTERCEPT ON ALL IO.BKT ERRORS SO WE CAN
;	REPORT THEM ON COMMANDS

;222	FIX 220 AND 215 TO DO THE RIGHT THING TOGETHER

;223	ADD EXTERNAL SYMBOLS SO SYSINF KNOWS START AND END OF DAEMON

;224	FIX TO 220/222 TO NOT SAVE .LOW IF .JBCOR<140

;EDITS 225-324 RESERVED FOR SPECIAL RELEASES.

;VERSION 11(224) RELEASED WITH ALL ABOVE EDITS. ALL LATER EDITS IN
;VERSION 12.

;325	ADD A FEATURE TEST TO CREATE THE ABILITY TO ASSEMBLE AS TWO
;	SEPARATE PROGRAMS, ONE TO DO ALL COMMANDS AND THE DCORE FUNCTION
;	OF THE UUO, AND ONE TO DO ERROR REPORTING, CHECKPOINTING,
;	ACCOUNTING, OTHER UUO FUNCTIONS, AND SYSTEM INFO.  THE FEATURE
;	TEST IS FTSAVE, EQUAL -1 FOR SAVE ONLY, 0 FOR BOTH, AND +1
;	FOR DAEMON ONLY.  NOTE THAT FTIPCF=-1 OR FTRSTR=-1 WILL NOT 
;	WORK WITH FTSAVE=-1.

;326	ADD SUPPORT FOR RH10 DEVICES. THIS IMPLEMENTS THE SPECIAL DRIVE
;	REGISTERS ON MASSBUS DEVICES. THIS EDIT IS ONLY INTENDED FOR
;	RP04'SAND RS04'S ON SYSTEMS WITH THE RP04 LIR. IT WILL HAVE NO
;	EFFECT ON SYSTEMS WITHOUT THE RP04 LIR.


;327	FIX SOME INCONSISTENCIES IN BEHAVIOR ON SAVE

;330	SAVE ADDRESS OF DDB ALONG WITH LENGTH SO USER CAN ASSOCIATE
;	DDB'S WITH CHANNELS (SPR 14451)

;331	FINISH EDIT 325 -- MAKE TYPEOUT SAY THE RIGHT THINGS

;332	FIX BUG IN FINCHK WHICH CAUSED JOB 8 (AC J =8 ) TO BE CHECKED
;	RATHER THAN THE JOB WE WERE INTERESTED IN. THIS BUG CAUSED
;	RANDOM ERROR CODE 3 TO DAEMON UUO'S AND ALSO WRITING IN RANDOM
;	PAGES.

;333	FIX DAEMON TO TAKE ADVANTAGE OF THE GETTABS ADDED IN 507/601
;	FOR ITS BENEFIT.

;334	ADD CODE TO DUMP UNILOG AS LAST ITEM IN CODE 10 ENTRY IN
;	ERROR FILE

;335	MAKE UNKNOWN COMMANDS GIVE ERROR MESSAGE, INSTEAD OF DOING
;	DCORE AS IN PREVIOUS VERSIONS

;336	FIX SWAPPING POINTERS FOR 507. THEY ARE THE SAME ON
;	BOTH 507 AND 601, NOT DIFFERENT AS PREVIOUSLY CODED
;	SEE EDIT 211 FOR SIMILAR CHANGE FOR 601.

;337	FIX BUGS ADDED BY CHANGE TO DAEMON/SAVER(EDIT 325), AND
;	IN USING NEW GETTABS(EDIT 333)
;340	FIX RACE ADDED BY EDIT 325

;341	SPEED UP COMPRS (IGNORE NONEXISTENT PAGES, DON'T LOOK AT EVERY
;	WORD ON THEM)

;EDITS 342-441 RESERVED FOR SPECIAL EDITS

;342	ADD SUPPORT FOR TAPSER MAGTAPE ERROR REPORTING.

;VERSION 12A(342)RELEASED WITH TAPSER LIR.
;VERSION 12(341) RELEASED WITH ALL ABOVE EDITS
;ALL LATER EDITS IN VERSION 13

;442	ADD CODE TO USE ERRPT. UUO INSTEAD OF SCANNING FOR ERRORS

;443	FIX HSVADR TO NOT NEED UPMP IN CORE. ALSO FIX CALLS TO NOT READ
;	UPMP IF NOT NECESSARY FOR OTHER REASONS.

;444	FIX DCORE TO DO CORRECT THING WITH FIRST PAGE OF HIGH SEG

;445	CHANGE ALL SUPER I/O TO USE SUSET.

;446	CHANGE REFERENCES TO SYMBOLS IN UPMP TO USE GETTABS, NOT DEFINED
;	SYMBOLS

;447	FIX SETUP OF PARAMETERS FOR SWAPPING TO USE GETTABS
;	AND WIN WITH UNITS MISSING

;450	FIX CODE FOR HANDLING ERROR FILE TO ADD WORD AT START
;	OF EACH BLOCK POINTING AT FIRST COMPLETE ENTRY
;	IN BLOCK.  ALSO, PAD LAST BLOCK WITH ZEROS.

;451	ADD SUPPORT FOR CODE 50 IN ERROR.SYS, DL10 ERRORS
;	602 AND LATER MONITORS ONLY.

;452	ADD FUNCTION 5 TO DAEMON UUO, APPEND TO ERROR.SYS

;453	ADD SUPPORT FOR OSAVE AND OSSAVE COMMANDS FOR 6.02

;454	ADD CODE TO GET JOB # FROM DDB ON BOTH 602 AND EARLIER MONITORS
;	JOB # WAS MOVED TO NEW WORD IN 602

;455	ADD CODE TO SYNCHRONIZE ERROR REPORTING WITH STOPPED JOBS. NO
;	JOBS WILL NOW BE STARTED AT THE JOB LOOP -- ALL WILL NOW BE 
;	STARTED AFTER THE ERROR THAT STOPPED THEM IS REPORTED

;456	ADD CODE TO SUPPORT SOME NEW ERRORS REPORTED IN 6.02
;	NEW ERRORS ARE: .ESCSC (CONFIGURATION STATUS CHANGE) = 15
;			ER.MSE (MONITOR SOFTWARE ERROR)      =  2
;			.ESNXM (NON-EX-MEM, NEVER BEFORE SUPPORTED) = 4

;457	CORRECT IMPLEMENTATION OF ER.MSE

;460	FIX BUG IN IMPLEMENTATION OF DL10 (ER.DLE) ERRORS

;461	FIX TAPSER ERROR REPORTING TO USE TAPOP'S TO GET THE POINTERS
;	TO THE INITIAL AND FINAL ERROR STATUS AREAS, RATHER THAN
;	ABSOLUTE OFFSETS RELATIVE TO TUBRID

;462	FIX UP MASSBUSS ERRORS TO REPORT USER'S PPN AND FILENAME CORRECTLY

;463	ADD USERS ID ETC TO CODE 3 & 10,ADD BAD BLOCKS SLOTS
;	TO CODE 10 & 11, ADD EXPECTED TERM. WD TO CODE 6 (RLD)

;464	CHANGE ERROR FILE HEADER LENGTH TO 4 AND INCLUDE SYS SER. # AND
;	CHAGE HEADER VERSION TO 1, INCREASE MAX ENTRY SIZE TO 777 VICE
;	77 BY MOVING HEADER LENGTH LEFT 3 PLACES (RLD)

;465	ANSWER TO SPR#15908

;466	MODIFICATIONS TO CORRECT FOR VERSION 1 HEADERS IN ERROR FILE

;467	ADD CODE TO REPORT NXM AND SET MEMORY OFFLINE TYPE ERRORS.
;	THIS ALSO CHANGES THE WHY RELOAD ERROR ENTRY SINCE IT
;	KEEPS A COPY OF THE ORIGINAL NXM TABLE IN OUR CORE.

;470	FIX CODE TO USE SUPER USETI./O IF SUSET. FAILS.

;471	(16349)MAKE DCORE, DUMP, AND SAVE ABORT ON DSK ERRORS

;472	FIX BUGS IN CODE 4(NXM), CODE 15(MEMORY ON/OFF LINE), AND IN 
;	EDIT 466.

;473	FIX SOME USES OF MONITOR VERSION NUMBER TO BE USES OF "VMMON"
;	INSTEAD

;474	FIX BYTE POINTER TO STORE ENTRY LENGTH IN ERROR FILE HEADER
;	TO STORE 9 BITS, NOT 6. PART OF EDIT 466

;EDITS 475-507 RESERVED FOR SPECIAL RELEASES
;VERSION 13(474) RELEASED WITH ALL ABOVE EDITS
;ALL LATER EDITS IN VERSION 14

;510	FIX BUG IN COMPUTING POINTER TO PARITY SUBTABLE IN CODE 3
;	ERROR FILE ENTRY

;511	DON'T REPORT MEMORY ON-LINE AT RELOAD ON 507/601 AND EARLIER
;	MONITORS

;512	ALLOW ERROR FILE ENTRIES TO SPAN MORE THAN ONE BLOCK, I.E.
;	DO THE RIGHT THING IF AN ENTRY HAS TWO BLOCK BOUNDARIES
;	IN IT

;513	ADD SUPPORT FOR KL10 PROCESSOR ERRORS, CODE 60-AR/ARX PARITY
;	TRAP, CODE 61- PARITY INTERRUPT, CODE 67-ADDRESSING FAILURE
;VERSION 14(513) RELEASED WITH ALL ABOVE EDITS
;ALL LATER EDITS IN VERSION 15

;EDITS 514-517 RESERVED FOR SPECIAL RELEASES

;520	PERFORM PROPER ADDRESS CHECKING FOR ALLOCATED BUT ZERO PAGE

;521	CORRECT ADDRESS CHECK CODE TO PREVENT POSSIBLE
;	OVERWRITING OF JOB DATA AREA

;522	SET UP JBINT TO PREVENT HANG IN TO STATE ON OPR
;	ACTION REQUESTED CONDITIONS

;523	UUOSYMIZE DAEMON

;524	IN CASE OF STRUUO FAILURE WHEN RESETTING DAEMON SEARCH LIST,
;	PURGE INVALID STRUCTURES AND RETRY STRUUO.

;525	FIX ERRORS IN WRTSWP (ROUTINE TO WRITE SWAPPING SPACE)

;526	FIX IMPROPER ADDI AT UADOLD-2 (FROM EDIT 521)

;527	ELLIMINATE MILLIONS OF  HRRI T1,.GTSTS 'S

;530	USE XOR IN PLACE OF ANDCA TO SEE IF A BLOCK CROSSES PAGE BOUNDARIES

;531	FIX POTENTIAL LOOP IN FINCHK BY CHECKING FOR PROPER SEGMENTS

;532	GET RID OF UNNEEDED  MOVSI T1,(J) 'S

;533	MAKE DAEMON FUNCTION TO APPEND TO ERROR.SYS WORK

;534	ZERO TRAILING SPACE ON ERROR.SYS ON OUTPUT

;535	REASSIGN CHANNELS TO OUR JOB ON RELEASE OF CHANNEL.  THUS IF
;	WE ARE ASKED TO LOG AN ERROR FOR THAT FILE, THE DDB WILL STILL
;	EXIST.

;536	RIP OUT SCANER AND REPLACE WITH REASONABLE COMMAND SCANNER.
;	MAKE MINOR NECESSARY CHANGES TO THE DEVIL HIMSELF, INCLUDING
;	REMOVAL OF EDIT 76

;537	FIX UP INTERRUPT ROUTINE SO IT WON'T DESTROY T1 OR SELF-DESTRUCT

;540	WRITE DAEMON FILES ON SYS ONCE AGAIN.  DISENABLE NEW TO AVOID
;	ANY PROBLEMS.  HACK OUT CODE WHICH RESETS DAEMON SEARCH LIST,
;	SINCE THIS ISN'T NECESSARY WHEN WRITING ON ERSATZ DEVICES

;541	FIX IMPROPER INDEX AC TO PREVENT PROBLEMS WHEN READING ARG
;	BLOCK FROM USER WHICH IS SPLIT ACROSS PAGES.

;542	MAKE SURE USER HAS RENAME PRIV'S WHEN DELETING .SAV, .HGH, ETC.
;	ALSO FIX CHCACC FUNCTION IN ACCCHK TO CHECK WRITE PRIV'S INSTEAD
;	OF RENAME PRIV'S WHEN TRYING TO WRITE

;543	PUT PATCHING SPACE AND JUNK UNDER FTDEBG

;544	SET UP INTADR SO WE CAN'T LEAVE USER IN DAEMON ERROR PAUSE
;	IF WE BLOW UP WHILE RECORDING ERROR

;545	ON DISK ERROR, DON'T GIVE EXPECTED CHANNEL TERMINATION WORD
;	UNLESS HAVE A 601 OR GREATER MONITOR, SINCE THIS VALUE IS NOT
;	STORED FOR THE LAST ERROR ON PREVIOUS MONITORS, AND THE BEST
;	WE CAN DO IS PICK UP THE LAST EXPECTED CHANNEL TERMINATION WORD,
;	WHICH MAY BE FOR A MORE RECENT TRANSFER THAN THE LAST ERROR.

;546	ADD SUPPORT FOR KL10 CPU ERROR INFORMATION OBTAINED FROM
;	RSX20 FRONT END -11

;547	CHANGE FORMAT OF KL ERROR ENTRY IN ERROR.SYS TO INCLUDE
;	COUNT OF 8 BIT DATA BYTES
;550	ADD DEFINITION OF %CVPTR&.ESDRE UNTIL UUOSYM GETS
;	UPDATED.  ALSO ADD SUPPORT FOR LP100-CODE 71
;551	ADD FUNCTION TO SUPPORT READING PENDING ENTRIES AND OTER INFO
;	FROM CRASH.EXE FILES.
;552	FIXES TO CORRECTLY RECORD OVER 200 WORD ERROR FILE ENTRIES
;553	FIX PREV.CHANGES & MAKE UNUSED AND ILLEGAL ERROR CODES
;	GO TO JOBFIN VOCE CPOPJ

;554	FIX EDIT 545 SO THAT MONVER GETS SET UP CORRECTLY
;555	MAKE WORK CORRECTLY FOR RPO6'S

;556	FIX KLERR STUFF


;557 PUT CRASH STUFF IN FTSAVE CONDITIONALS
;560 FIX EDIT 557

;561	SAVE PDBPTR AROUND CRASH CHECK STUFF AND FIX TYPO'S

;562	GET UDT FROM %CNDTM NOT %CNDAT

;563	FIX GTUPMP CODE

;564	DON'T SMASH TWO PACK STRUCTURES WITH CRASH STUFF

;565	FIX EDIT 544

;566	FIX MAGTAPE ERROR REPORTING

;567	FIX REDSWP ON VM

;570	MAKE DAEMON EXIT GRACEFULLY ON RE-ENTER

;571	DCORE SPOOLED DDB'S CORRECTLY.

;572	HANDLE AN ARGUMENT BLOCK SPLIT ACROSS FRAGMENTED PAGES
;	ON THE SWAPPING SPACE CORRECTLY ON A VM SYSTEM.

;573	FIX MAGTAPE STATISTICS REPORTING.  THE UNIT NAME WAS BEING
;	OUTPUT AS GARBAGE.
;574	FIX MAGTAPE STATISTICS SO THAT THERE IS SOME USEFUL INFORMATION
;	IN THE ERROR.SYS FILE.

SUBTTL SYMBOL DEFINITIONS

	.JBVER==137
	LOC	.JBVER
	BYTE	(3)VWHO(9)VDAEMON(6)VMINOR(18)VEDIT
	RELOC

	SEARCH UUOSYM

	DEFINE	ND(SYMBOL,VALUE),<
	IFNDEF SYMBOL,<SYMBOL==VALUE>
	SYMBOL==SYMBOL	>

ND	FTSAVE,0	;DEFAULT IS TO ASSEMBLE FOR BOTH DAEMON AND SAVE
ND	PURESW,0	;NOT NORMALLY HIGH SEG
ND	FTIPCF,0	;**[73] DEFAULT IS OFF
ND	FTRSTR,0	;ON WHEN RESTART LOGIC IS USED
	IF2,	<	;**[73]
	IFN	FTIPCF,<PURESW==0>>	;**[73]

ND	FTSPY,1		;NON-ZERO TO ALLOW SPY FOR GETTABS AND PEEKS
ND	FTDET,1		;NON-ZERO TO RUN DAEMON DETACHED
ND	FTDEBG,0	;ON FOR DEBUGGING FEATURES
IFGE	FTSAVE,<	;THESE ARE WRONG DEFAULTS IF WE ONLY DO SAVES
ND	FTERR,1		;NON-ZERO TO LOG HARDWARE ERRORS
ND	FTCLCK,1	;NON-ZERO TO SUPPORT .CLOCK FUNCTION
ND	FTUSCN,0	;NON-ZERO TO ENABLE PERIODIC ERROR.SYS SAMPLING OF ALL UNITS
ND	CPUN,2		;MAX NO OF CPU'S TO LOG ERRORS ON
ND	CHNN,10		;NO OF CHANNELS  TO LOG ERRORS
ND	UNITN,40	;MAX NO OF UNITS TO LOG ERRORS
ND	MTAN,20		;MAX NUMBER OF MTA'S TO LOG ERRORS
>	;END IFGE FTSAVE
ND	FT1975,1	;ENABLES UNIVERSAL DATE/TIME STANDARD IN FACT FILE[7(57)]
IFGE	FTSAVE,<	;THESE ARE WRONG DEFAULTS IF WE ONLY DO SAVES
ND	ERRDEV,SIXBIT/SYS/	;**[540] SYS IS THE RIGHT PLACE
	IFE <ERRDEV-'DSK   '>,<
		ND	FTSVSL,1	;SAVE SEARCH LIST IF USING DISK>
ND	ERRPPN,<0>	;UFD (DEFAULT SYS:) FOR HARDWARE ERROR LOG FILE
ND	ERRSIZ,777	;LARGEST ERROR-FILE TRANSACTION
ND	FTFACT,1	;0 TO SUPPRESS FACT FILE AND CALLS
			;-1 TO RETURN ERROR ON .FACT FUNCTION
IFE FTFACT,<ND FTCHKPNT,0>	;RE-DEFAULT CHKPNT IF FACT TURNED OFF
ND	FTCHKPNT,1	;0 TO SUPPRESS CHKPNT FCN
ND	FCTDEV,SIXBIT/SYS/	;**[540] SYS IS UNAMBIGUOUS
	IFE <FCTDEV-'DSK   '>,<
		ND	FTSVSL,1	;SAVE SEARCH LIST IF USING DSK>
ND	FCTPPN,<0>	;UFD (DEFAULT SYS:) FOR FACT.SYS
ND	TRNSIZ,20	;LARGEST SINGLE FACT-FILE TRANSACTION
>	;END IFGE FTSAVE
ND	FTSVSL,0	;DON'T SAVE SEARCH LIST UNLESS WE HAVE TO
ND	MAXUCR,1000	;MAXIMUM BLOCK TO READ FROM USER CORE
ND	MAXUPM,^D512	;SIZE OF BLOCK TO USE AS UPMP BUFFER
ND	SLPCNT,^D60	;TIME TO SLEEP IF NO WORK
ND	PDLEN,50	;LENGTH OF PUSH DOWN LIST
ND	MAXSWP,10	;MAXIMUM NUMBER OF UNITS FOR SWAPPING
ND	DPTHLN,10	;MAX LENGTH OF PATH SPEC
IFGE	FTSAVE,<	;THESE ARE WRONG DEFAULTS IF WE ONLY DO SAVES
ND	MAXFCT,^D800	;WORDS IN FACT BUFFER
			; - ADJUST TO BRING DAEMON CLOSE TO EVEN K BOUNDARY
ND	MAXAGE,^D600	;MAX TIME (SECS) A FACT ENTRY MAY SIT IN DAEMON
ND	CHKTIM,^D600	;SECONDS BETWEEN CHECKPOINTS
ND	USCTIM,^D3600	;SECONDS BETWEEN UNIT SCANS
ND	ERRTIM,^D60	;[62]SECONDS BETWEEN RETRIES ON ERROR.SYS
ND	ICLKRQ,4	;[62]NO OF INTERNAL CLOCK REQUEST TYPES
ND	CHKRQ,0		;CHECKPOINT REQUEST DUMMY JOB #
ND	USCRQ,-1	;UNIT SCAN REQUEST DUMMY JOB #
ND	AGERQ,-2	;DUMMY JOB TO FORCE OUT OLD FACT ENTRIES
ND	IOERQ,-3	;[62]TIMER TO RETRY ERRORS ON ERROR.SYS
>	;END IFGE FTSAVE
;NEW DEFAULTS IF WE ONLY DO SAVES,ETC.
IFL	FTSAVE,<
ND	FTERR,0
ND	FTFACT,0
ND	FTCHKPNT,0
ND	FTRSTR,0
ND	FTIPCF,0
ND	FTCLCK,0
ND	FTUSCN,0
ND	ICLKRQ,0
ND	CPUN,0
ND	CHNN,0
ND	UNITN,0
ND	MTAN,0
>	;END IFL FTSAVE
;AC'S

SF=0		;SCANNER FLAGS
S1=1		;SCANNER PARAM REG
T1=1		;TEMP AC'S
T2=2
T3=3
T4=4
P1=5		;PERMANENT AC'S
P2=6
P3=7
J=10		;JOB NUMBER BEING SERVICED
P4=11		;PERMANENT AC
S=12		;SEGMENT NUMBER OF HIGH SEGMENT IF ANY
F=13		;FLAGS
SN=14		;SCANER'S NAME OR NUMBER ACCUMULATOR
BP=15		;BYTE POINTER FOR OUTPUT
SC=16		;16 USED AS CHAR AC IN COMMAND SCANNER
P=17		;PUSH DOWN LIST PTR


;I/O CHANNELS

DSK==6
SWP==7
FCT==10

;**[73] DEFIMNE GLOBALS IN SYSTEM[IPCF]

	IFN	FTIPCF,<
	EXTERN	SCHINF,INIDAE,SETSTA
	EXTERN	TYPOPR,DOWN
>			;**[73] END OF FTIPCF EDIT

;EXTERNS IN COMMAND SCANNER

	EXTERN	.ISCAN,MAKPJN,FILIN,TOCT,TPPN,TSIXN,TYIA
	EXTERN	OCTINW,SAVE1,SAVE2
;FLAGS IN F

L.DUMP==(1B0)		;SET IF DUMP, NOT IF DCORE
L.ANY==(1B1)		;SET IF ANY JOBS REQUIRING DAEMON SERVICE FOUND DURING SCAN
L.WJ==(1B2)		;SET IF WANT GETTAB FOR JOB
L.WS==(1B3)		;SET IF WANT GETTAB FOR HIGH SEGMENT
L.TTYA==(1B4)		;SET IF TTY IS ATTACHED
L.UUO==(1B5)		;SET IF DAEMON STARTED BY UUO
L.OPRA==(1B6)		;SET IF OPR WANTS TO KEEP IN TOUCH
L.FORC==(1B7)		;SET TO FORCE DUMP OF FACT.SYS BUFFER
L.FACT==(1B8)		;SET TO SUPPRESS FACT UUO FUNCTION
L.CHK==(1B9)		;SET TO SUPPRESS CHECKPOINT FUNCTION
L.ERR==(1B10)		;SET TO SUPPRESS LOGGING HARDWARE ERRORS
L.USC==(1B11)		;SET TO SUPPRESS UNIT SCANS
L.STOP==(1B12)		;SET IF OPR WANTS TO SHUT DOWN
L.SAVE==(1B13)		;SET IF SAVE (AS OPPOSED TO DUMP OR DCORE)
L.UPMP==(1B14)		;SET IF USER'S UPMP IS IN USRUPM
L.ZPGF==(1B15)		;SET TO INDICATE CURRENTLY SCANNING A POTENTIAL ZERO PAGE IN COMPRS
L.NHRL==(1B16)		;SET IF WE ARE SAVING A HIGH SEG WHERE LH(115)=0
R.SWIN==1B18		;SET BY FINCHK IF JOB BEING SWAPPED IN
R.UNLO==1B19		;ON IF PROCESSING UNLOAD MTA STATISTICS

;FLAGS IN SF (SCANER'S FLAGS)

S.EOF==1B33		;EOF ON INPUT
DSKX=11

FL.DSK==1

EXESIZ==^D512		;[551]SIZE OF EXE DIRECTORY
GT.PDB==4		;PDB ENTRY IN NUMTAB
GT.PRC==1B9		;BIT IN NUMTAB MEANING DATA IN PDB
LN.BUF==200
ABSTB1==151
ABSTB2==410
DV.FIL==15
DV.EXT==16
DV.PPN==17
DV.UNI==23
CRSBLK==5	;BLOCK # WHICH CONTAINS 1ST 200 WDS OF CORE IMAGE
CRSWRD==36	;IF NON-ZERO, THIS FILE HASN'T BEEN PROCESSED BY DAEMON


;GETTAB ITEM FOR VARIOUS TABLES

DACODE=='JD'	;STSTBL - QUEUE CODE FOR DAEMON QUEUE
GT.PRC==1B9	;BIT IN A GETTAB ENTRY IN NUMTAB WHICH SAYS DATA IS IN PDB

;BITS IN JBTSTS WORD - LH

JSHR==200000	;MEANS HIGH SEGMENT IS SHARABLE
JNSWP==10000	;JOB IS NOT TO BE SWAPPED
JSWP==2000	;SWAPPED OR SWAPPING BIT
JLOG==4		;LOGGED IN
JACCT==1	;THE GODLY BIT
RUN==400000	;RUNNING(ACTUALLY, NOT IN MONITOR MODE)

;BITS IN JBTSTS WORD - RH

JRDC==100000	;SET IF JOB REQUIRES SERVICE BY DAEMON
JDEP==10000	;JOB WAITING IN DAEMON ERROR PAUSE

;GOBSTR ARGUMENTS

GOBLEN==5	;LENGTH OF BLOCK
;DDB ENTRIES

DEVNAM==0	;NAME OF DEVICE
.DVCHR==1	;CONTAINS JOB NUMBER
DEVSER==3	;LH POINTS TO NEXT DDB
DEVMOD==4	;CONTAINS DEVCHR BITS
DEVUNI==6	;OFFSET OF DEVUNI FROM END OF SHORT DDB
TDVUDB==0	;OFFSET OF TDVUDB FROM END OF SHORT DDB IN TAPSER DDB
DEVSTA==12	;[571] DEVSTA WORDS OD DDB
DEPSPL==1B0	;[571] THIS IS A SPOOLED DB.

;CHANNEL DATA BLOCK ITEMS

.CHSYS==1	;LH - POINTER TO NEXT CHAN DATA BLOCK
.CHLUE==1	;RH - POINTER TO UDB WITH MOST RECENT ERROR
.CHICW==2	;INITIAL CONTROL WORD FROM LAST ERROR
.CHFCW==3	;FINAL C W AS STORED BY CHANNEL
.CHCW2==4	;ERROR CONTROL WORD -2
.CHCW1==5	;ERROR CONTROL WORD -1
.CHCW0==6	;CONTROL WORD POINTED TO BY .CHFCW
.CHDW2==7	;ERROR DATA WORD -2
.CHDW1==10	;ERROR DATA WORD -1
.CHDW0==11	;DATA WORD POINTED TO BY .CHFCW
.CHMPE==12	;COUNT OF MEM PAR ERRS ON THIS CHANNEL
.CHDPE==13	;COUNT OF DEVICE PARITY ERRORS ON THIS CHANNEL
.CHNXM==14	;COUNT OF NON-EX MEMS ON THIS CHANNEL
.CHTCW==16	;EXPECTED CHANNEL TERMINATION WORD OF LAST ERROR
		; THIS VALUE IS GETTABED, BUT DEFINED FOR GETTAB FAILURE

;CONTTROLLER DATA BLOCK ITEMS


;UNIT DATA BLOCK ITEMS

UNINAM==0	;UNIT NAME
UNILOG==1	;LOGICAL UNIT WITHIN STR
UNIHID==2	;SIXBIT HOME-BLOCK ID NAME (PACK ID)
UNISYS==3	;LH - ADDR OF NEXT UNIT DATA BLOCK IN SYSTEM
		;0 = NO MORE
UNISTR==4	;LH - ADDR OF NEXT UNIT DATA BLOCK IN STRUCTURE
		;RH - UP POINTER TO STR DATA BLOCK
UNICHN==5	;LH - ADDR OF NEXT UDB ON SAME CHANNEL (RING)
		;RH - UP POINTER TO CHAN DATA BLOCK
UNIKON==6	;POINTER TO CONTROLLER DATA BLOCK FOR THIS UNIT
UNISWP==7	;POINTER TO NEXT SWAPPING UNIT
UNIHCT==10	;HARD (UNRECOVERABLE) ERRORS ON THIS UNIT
		;LH - DEVICE & SEARCH ERRORS
		;RH - DATA ERRORS
UNISCT==11	;SOFT (RECOVERABLE) ERRORS - INCREMENTED WHEN
		;RECOVERY SUCCEEDS. HALVES SAME AS UNIHCT.
UNIMCT==12	;SOFTWARE-DETECTED ERRORS (3 FIELDS OF 12 BITS)
		;SAT FAILURES, RIB REDUNDANCY ERRORS, FOLDED CHKSUM
UNIERR==13	;LAST ERROR STATUS ON DEVICE AFTER FIRST RECOVERY ATTEMPT
UNISOF==14	;ERROR STATUS BEFORE RECOVERY ATTEMPT
UNIHBN==15	;LOGICAL BLOCK NO OF LAST HARD ERROR
UNIBRC==16	;BLOCKS READ IN BUFFERED MODE
UNIBWC==17	;BLOCKS WRITTEN IN BUFFERED MODE
UNIDRC==20	;BLOCKS READ IN DUMP MODE (INCLUDING GET'S)
UNIDWC==21	;BLOCKS WRITTEN IN DUMP MODE (INCLUDING SAVE'S)
UNIMRC==22	;BLOCKS READ FOR MONITOR (SAT,UFD,MFC,BAT,SWAP)
UNIMWC==23	;BLOCKS WRITTEN FOR MONITOR
UNIICT==24	;SWAP READS (ALSO COUNTED IN UNIMWC)
UNIOCT==25	;SWAP WRITES (ALSO IN UNIMWC)
UNIMSC==26	;NO OF MONITOR & SWAPPING SEEKS
UNIUSC==27	;NO OF USER (INCLUDING GET & SAVE) SEEKS
UNIPCT==30	;SEEK INCOMPLETE ERRORS
UNISDI==32	;DATAI WORD ON LAST ERROR BEFORE RECOVERY ATTEMPT
UNIHDI==33	;DATAI WORD AFTER FAILURE OF FIRST RECOVERY ATTEMPT
UNIECT==34	;NO OF RETRIES+INITIAL ATTEMPT WHICH FAILED
		;BIT 0 SET IF SUCCESSFUL OPERATIONS SINCE ERROR
UNIHNG==35	;HUNG RECOVERYS (4 FIELDS OF 9 BITS)
		;# NOT RECOVERED BY STOPPING UNIT IN TRANSFER STATE
		;# RECOVERED BY STOPPING UNIT IN TRANSFER STATE
		;# CAUSED BY UNIT IN POSITION STATE AND RECOVERED AUTOMATICALLY
		;# RECOVERED BY RESTARTING UNIT, WHICH WAS IDLE OR TRANSFER WAIT
UNICDA==40	;RH - ADDR OF DDB FOR CURRENT FILE
UNIDES==55	;[551] UNIT DESCRIPTION(FOR DSKCHR)
		;[551] BOTH UNICDA AND UNIDES ARE GETTABED, BUT ARE DEFINED
		;HERE IN CASE OF GETTAB FAILURE
;MAGTAPE DEVICE DATA BLOCK ITEMS (MTXSER)

MTXNAM==0		;UNIT NAME
MTXRID==0

MTXSRE==MTXRID-16+21	;COUNT OF SOFT READ ERRORS SINCE LAST UNLOAD
MTXHRE==MTXRID-16+22	;COUNT OF HARD READ ERRORS SINCE LAST UNLOAD
MTXSWE==MTXRID-16+23	;COUNT OF SOFT WRITE ERRORS SINCE LAST UNLOAD
MTXHWE==MTXRID-16+24	;COUNT OF HARD WRITE ERRORS SINCE LAST UNLOAD
MTXTUN==MTXRID-16+27	;TOTAL MTAPE 11'S (UNLOADS) SINCE SYSTEM LOADED
MTXNFB==MTXRID-16+30	;NUMBER OF FILES FROM BOT
MTXNRF==MTXRID-16+31	;NUMBER OF RECORDS FROM LAST EOF
MTXICC==MTXRID-16+32	;INITIAL CONI MTC FOR LAST ERROR
MTXICS==MTXRID-16+33	;INITIAL CONI MTS FOR LAST ERROR
MTXFCC==MTXRID-16+34	;FINAL CONI MTC AT RESOLUTION OF LAST ERROR
MTXFCS==MTXRID-16+35	;FINAL CONI MTS AT RESOLUTION OF LAST ERROR
MTXTRY==MTXRID-16+36	;NUMBER OF RETRIES TO RESOLVE LAST ERROR
MTXFLG==MTXRID-16+37	;DAEMON FLAG TO SAY NO MORE SOFT REPORTS FOR THIS REEL
MTDRID==MTXRID-16+40	;DAEMON SHADOW REELID USED TO CREATE SUMMARY
MTDWRD==MTXRID-16+41	;COUNT OF WORDS READ SINCE LAST UNLOAD
MTDWWT==MTXRID-16+42	;COUNT OF WORDS WRITTEN SINCE LAST UNLOAD
MTDSRE==MTXRID-16+43	;COUNT OF SOFT READ ERRORS SINCE LAST UNLOAD
MTDHRE==MTXRID-16+44	;COUNT OF HARD READ ERRORS SINCE LAST UNLOAD
MTDSWE==MTXRID-16+45	;COUNT OF SOFT WRITE ERRORS SINCE LAST UNLOAD
MTDHWE==MTXRID-16+46	;COUNT OF HADR WRITE ERRORS SINCE LAST UNLOAD


;TAPSER UNIT DATA BLOCK ITEMS (TUB)
;ALL ARE RELATIVE TO OFFSET OF TUBRID IN TUB, SINCE GETTAB RETURNS
;OFFSET OF TUBRID IN TUB
;AREA FROM TUBRID TO TUBDDA IS STATIC IN MONITOR, I.E. NO NEW WORDS
;WIIL BE ADDED. ALL WORDS ARE DEFINED HERE, EVEN IF NOT USED

;***************THESE TWO ITEMS ARE NOT RELATIVE TO TUBRID BUT SHOULD
;***************REMAIN STATIC. IF THEY CHANGE, A GETTAB SHOULD BE ADDED
;***************TO THE MONITOR TO RETURN THEM
TUBKDB==1	;OFFSET OF UPWARD POINTER TO CONTROLLER DATA BLOCK IN TUB
TKBCDB==11	;OFFSET OF UPWARD POINTER TO CHANNEL DATA BLOCK IN KDB
;**********************************

TUBRID==0	;REELID OF CURRENT TAPE
TUBFIL==1	;# OF FILES FROM BOT
TUBREC==2	;# OF RECORDS FROM EOF
TUBCRD==3	;# OF CHARACTERS READ SINCE LAST UNLOAD
TUBCWR==4	;# OF CHARACTERS WRITTEN SINCE LAST UNLOAD
TUBSRE==5	;# OF SOFT READ ERRORS SINCE LAST UNLOAD
TUBHRE==6	;# OF HARD READ ERRORS SINCE LAST UNLOAD
TUBSWE==7	;# OF SOFT WRITE ERRORS SINCE LAST UNLOAD
TUBHWE==10	;# OF HARD WRITE ERRORS SINCE LAST UNLOAD
TUBTME==11	;# OF TOTAL MEDIA ERRORS SINCE LAST UNLOAD
TUBTDE==12	;TOTAL DEVICE ERRORS SINCE MONITOR RELOAD
TUBTUN==13	;TOTAL UNLOADS
TUBTRY==14	;# OF RETRIES TO RESOLVE ERROR
TUBCCR==15	;CHARACTER COUNT ON LAST RECORD
TUBPBE==16	;POSITION BEFORE ERROR (FILE,,RECORD)
TUBFES==17	;FINAL ERROR STATE
TUBCHR==20	;STATISTICS FOR MTCHR. UUO
TUBDDA==21	;BEGINNING OF SHADOW BLOCK FOR STATISTICS ON UNLOAD
;CODES IN ERROR.SYS

EL.HED==4	;LENGTH OF STANDARD HEADER[464]
EL.VER==1	;FORMAT VERSION OF ERROR.SYS[464]
EL.CRS==2	;[551]ENTRY EXTRACTED FROM CRASH.EXE

FE.INF==10	;START OF ERROR INFORMATION IN FRONT END DETECTED ERROR BLOCK


;DEFINITIONS IN KL ERROR BLOCK

.KEDEV==0	;DEVICE, LINE
.KECNT==0	;COUNT
.KECPU==1	;CPU
.KEDTE==1	;DTE NUMBER
.KELNK==1	;LINK
.KEDAT==2	;FIRST DATA WORD

;SPECIAL DEFINITIONS FOR MASSBUS ERROR PROCESSING

RH10CD==1
RH20CD==2
MAXREG==20	;MAXIMUM NUMBER OF DRIVE REGISTERS ON A MASSBUS DEVICE


;MISC

BLKSPK==3	;BITS TO SHIFT TO CONVERTS K TO BLOCKS
BLKSPP==2	;BITS TO SHIFT TO CONVERT PAGES TO BLOCKS
WRDSPB==7	;BITS TO SHIFT TO CONVERT BLOCKS TO WORDS
WRDSPK==WRDSPB+BLKSPK
C.CR==15	;ASCII CARRIAGE RETURN
C.LF==12	;ASCII LINE FEED
;**;[536] DELETE	F.DEV==0	;INDEX IN FILE DESCRIPTOR FOR DEVICE
;**;[536] DELETE	F.NAM==1	;INDEX FOR NAME
;**;[536] DELETE	F.EXT==3	;INDEX FOR EXTENSION
;**;[536] DELETE	F.DIR==4	;INDEX FOR DIRECTORY
;**;[536] DELETE	F.PROT==6	;INDEX FOR PROTECTION

;LOCATIONS SET UP BY SAVGET CODE IN COMCON

SGAEXT==1
SGAHGH==16
IFN PURESW,<
	TWOSEG		;IF HE REALLY WANTS IT,
	RELOC	400000	;MAKE IT SHARABLE
FTSPY==0		;CAN'T SPY WITH CODE IN HIGH SEG
>
CHKFCT==0		;THIS CONTROLS CODE USED BOTH BY FACT AND CHKPNT
IFG FTFACT,<CHKFCT==1>		;SET IF ASSEMBLING FACT UUO CODE
IFN FTCHKPNT,<CHKFCT==1>	;OR IF ASSEMBLING CHKPNT
IFG MAXUCR-1000,<MAXUCR==1000>	;IMPOSE JOBPEK LIMIT
IFL MAXUCR-<1_WRDSPB>,<MAXUCR==<1_WRDSPB>>	;AT LEAST ONE BLOCK
MAXUCR==MAXUCR&<-1_WRDSPB>	;FORCE BLOCK BOUNDARY
IFE FTERR,<	IFN FTUSCN,<
PRINTX	% FTUSCN IMPOSSIBLE WITH FTERR OFF
FTUSCN==0	>>

	OPDEF	PJRST	[JRST]
	OPDEF	PJSP	[JSP]
	OPDEF	PJUMPE	[JUMPE]
	OPDEF	DIAG.	[CALLI 163]
SUBTTL INITIALIZE

DAEMON::	IFE	FTRSTR!FTIPCF,<
	JFCL			;IN CASE OF CCL ENTRY
>
	IFN	FTIPCF!FTRSTR,<	;**[73] [SYSTEM] INFO
	JFCL			;A NORMAL START
	SKIPA			;A CCL START LET RSTART ZERO
	SETOM	RESTART		;RESTART ENTRY USE NO ACCUS
	JSR	SETSTA##	;MAKE IT RESTARTABLE
	SKIPL	RESTART		;DID WE RESTART?
	JRST	DAEMO0		;(NO) ALL AS USUAL
	GETLIN	T1,		;FOR LINE CHARACTERISTICS
	TLNN	T1,-1		;ARE WE ATTACHED?
	JRST	DAEMO0		;(NO) FORGET IT
	SETOM	T1		;GET LINE NUMBER
	GETLCH	T1		;GET LINE NUMBER
	HRLZS	T1		;SWAP HALVES
	ATTACH	T1,		;AND DETACH
	JRST	E.NATT		;NOT IMPLEMENTED
DAEMO0:
>
	RESET			;GET ALL RESET
	MOVE	P,PDL		;GET A STACK POINTER(IS A RUN UUO ACCU!!)
	MOVEI	T1,DAEREN	;REENTER FOR [SYSTEM]INFO SHUT DOWN
	MOVEM	T1,.JBREN	;STORE IN REENTER ADDRESS
	IFN	FTIPCF,<
	PUSHJ	P,INIDAE	;INITIALIZE RESTARTING AND [SYSTEM]INFO
>
	IFN	FTRSTR,<	;**[74]	EDIT 74
	IFE	FTIPCF,<
	PUSHJ	P,STDAEM##	;CALL THE INTERRUPT AND CRASH LOGIC
>>	;**[74] END OF EDIT
	SETZB	J,ZER		;J=VALUE OF QUEUE CODE FOR DAEMON QUEUE
REPEAT 0,<		;I DON'T THINK THIS IS NECESSARY (JSL)
	MOVE	T1,.JBREL	;GET .JBREL
	ADDI	T1,2000		;BUMP BY 1K (WILL RETURN LATER)
	CORE	T1,		;RESET USRREL
	  EXIT			;NEED THIS MEMORY
>; END OF REPEAT 0 ON EXTRA CORE REQUEST
	MOVE	T1,[ZER,,ZER+1]
	BLT	T1,EZER		;CLEAR STORAGE LOCATIONS
	MOVSI	F,L.TTYA	;CLEAR FLAGS, NOTE TTY ATTACHED
	MOVEI	T1,E.EINT	;REENTER ADDRESS TO START WITH
	MOVEM	T1,INTADR
	MOVE	T1,[XWD 4,INTRES]	;ROUTINE TO RESTART AFTER ERROR INTERCEPTS
	MOVEM	T1,INTBLK	;STORE IN INTERCEPT BLOCK
	MOVEI	T1,777747		;ENABLE FOR ALL ERRORS
;DAEMON+16 [522]
	TLO	T1,400000	;SUPRESS ERROR TYPEOUTS
	MOVEM	T1,INTBLK+1	;STORE CONDITIONS IN INTERCEPT BLOCK
	MOVEI	T1,INTBLK
	MOVEM	T1,.JBINT	;SET UP JOB INTERCEPT BLOCK
;**[73]	MOVE	P,PDL	;SET UP PUSH DOWN LIST
	HRROI	T1,.GTPPN
	GETTAB	T1,		;GET OUR PPN
	  SETO	T1,
	MOVE	T2,[%LDFFA]
	GETTAB	T2,		;GET FULL FILE ACCESS PPN
	  SETZ	T2,
	MOVEM	T2,OPRPPN	;STORE AWAY FOR LATER
	CAME	T1,T2		;SKIP IF HAVE FULL FILE ACCESS
	JRST	E.NFSF		;NO GOOD - SINCE JACCT ON, MUST VERIFY
				;THAT THE JOB HAS THE SYSTEM'S BLESSING
				;(MUST PROBABLY BE LOCAL TO KEEP UNDER CONTROL)

	PJOB	T1,		;OUR JOB NUMBER
	MOVEM	T1,THSJOB	;SAVE FOR LATER

	SETOM	THSLIN		;INDICATE OUR LINE
	GETLCH	THSLIN		;GET CONTROLLING LINE NO & BITS

	MOVE	T1,[%CNSJN]
	GETTAB	T1,		;GET LOWEST HIGH SEG NUMBER
	  MOVEI	T1,100		;ASSUME 64 IF PRE-GETTAB MONITOR
	SOJ	T1,		;DECR TO HIGHEST JOB NUMBER
	HRRZM	T1,HJOB		;SAVE FOR JOB SCANS
;HERE TO BUILD COPY OF GETTAB TABLE FOR GTBSPY
IFN FTSPY,<
	MOVE 	T1,[%CNPDB]	;FIND WHERE JBTPDB IS
	GETTAB	T1,		; FROM MONITOR
	  SETZ	T1,		;CLEAR IF NOT THERE
	MOVEM	T1,PDBPTR	;STORE FOR USE IN GETTAB SIMULATOR
	SETZB	T4,T3		;CLEAR T4 IN CASE CANT SPY (STORED IN MAXGTB)
	MOVE	T1,[%CNSIZ]	;GET SIZE OF SYSTEM
	GETTAB	T1,
	  JRST	NOSPY
	SUBI	T1,1		;HIGHEST LOC IN MONITOR
	SPY	T1,		;SET SPY
	  JRST	NOSPY		;CANT
	MOVE	T1,.JBFF	;FIRST AVAILABLE LOC
	MOVEM	T1,GTBST	;START OF GETTAB PTRS

NXTGTB:	AOS	T4,.JBFF	;NEW FIRST FREE
	CAMG	T4,.JBREL	;SKIP IF MUST EXPAND CORE
	JRST	NXTGT1		;NO, OK
	MOVE	T1,T4
	CORE	T1,		;EXPAND CORE
	  HALT	.		;HAS TO BE THERE
NXTGT1:	HRLZ	T1,T3		;NEXT TABLE PTR
	HRRI	T1,.GTSLF
	GETTAB	T1,		;GET NEXT TABLE PTR
	  JRST	ENDGTB		;THAT'S ALL
	TLZE	T1,37		;CLEAR MONITOR XR AND INDIRECT
	TLO	T1,T1		;SET OUR AC IF TABLE EXISTS
				; (IE, IF POINTER WAS INDEXED)
	TRO	T1,400000	;SET SPY BIT
	MOVEM	T1,-1(T4)	;STORE IN TABLE OF TABLE PTRS
	AOJA	T3,NXTGTB	;LOOP FOR ALL POSSIBLE GETTABS

ENDGTB:	SUB	T4,GTBST	;CURRENT-START=NUMBER+1
	SOJ	T4,		;NUMBER OF LEGAL GETTABS
NOSPY:	MOVEM	T4,MAXGTB	;SAVE NUMBER OF LEGAL GETTABS

>;END FTSPY COND
;HERE TO FIND QUEUE # FOR DAEMON WAIT

	SETZ	T2,
FNDDAQ:	HRLZ	T1,T2		;LH T1=NEXT WORD IN TABLE
	HRRI	T1,.GTWSN	;RH=QUEUE CODES TABLE
	PUSHJ	P,GTBSPY	;GET NEXT WORD IN QUEUE CODES TABLE
	  AOJA	J,NODAEQ	;NOT THERE, MAKE DAEMON QUEUE UNFINDABLE
	MOVE	T3,[POINT 12,T1]
FNDDA1:	TLNN	T3,770000	;SKIP IF MORE CODES IN THIS WORD
	AOJA	T2,FNDDAQ	;NO MORE, TRY NEXT WORD
	ILDB	T4,T3		;T4=NEXT CODE IN SIXBIT
	CAIE	T4,DACODE	;SKIP IF FOUND DAEMON QUEUE CODE
	AOJA	J,FNDDA1	;NO, TRY NEXT, COUNT CODES SKIPPED

;HERE WHEN FOUND DAEMON QUEUE CODE, NOW FIND CTY LINE NUMBER

NODAEQ:	MOVEM	J,DAQNAM	;SAVE DAEMON QUEUE CODE
	MOVE	T1,[%CNPTY]
	PUSHJ	P,GTBSPY	;GET OFFSET FOR PTY'S
	  SETO	T1,		;CANT GET IT
	HLRES	T1		;T1=OFFSET FOR PTY=LINE NUM OF CTY+1
	SUBI	T1,1		;LINE NUMBER OF CTY
	MOVEM	T1,CTYLIN	;STORE LINE NUMBER OF CTY
	JUMPGE	T1,GETVM	;GET SWAPPING PARAMETERS IF OK
	SKIPL	RESTART		;NO TYPING WE ARE DETACHED
	OUTSTR	[ASCIZ .% DONT KNOW CTY LINE NUMBER
.]

;HERE TO SEE IF MONITOR HAS VIRTUAL MEMORY (VMSER)

GETVM:	MOVE	T1,[%CNST2]	;GET SECOND STATES WORD
	PUSHJ	P,GTBSPY	
	  JRST	NOST2		;CAN'T GET IT, USE VERSION NUMBER
	TRNN	T1,ST%VMS	;TEST BIT FOR VM
	TDZA	T1,T1		;[536] NO VM, SAVE A ZERO
	SETO	T1,		;VM, SAVE A -1
	MOVEM	T1,VMMON	;IN WORD TO SAVE WE HAVE VM
	MOVE T1,[%CNVER]	;GET MONITOR VERSION
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;??
	MOVEM	T1,MONVER	;[545] SAVE VERSION
	JRST	GETUPS		;GET NEW OFFSET FOR WORDS IN UPMP

NOST2:	MOVE T1,[%CNVER]	;GET MONITOR VERSION
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;??
;**;[545] INSERT @NOST2+2 1/2
	MOVEM	T1,MONVER	;[545] SAVE VERSION
	ANDI	T1,-1		;CLEAR CUSTOMER STUFF
	CAIGE	T1,60000	;PRE 601?
	TDZA	T1,T1		;[536] YES, SAVE 0
	SETO	T1,		;NO, SAVE -1
	MOVEM	T1,VMMON	;FLAG WHETHER WE HAVE VM

GETUPS:	MOVE	T1,[%VMUPJ]	;GETTAB OFFSET OF UPJOB
	PUSHJ	P,GTBSPY
	  MOVEI	T1,707		;MUST BE MONITOR BEFORE GETTAB ADDED
	MOVEM	T1,.UPJOB	;AND SAVE OFFSET FOR LATER

GETNER:	MOVE	T1,[%CNST2]	;GET SECOND STATES WORD AGAIN
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;OH WELL, MUST NOT DO NEW ERROR REPORTING
	TRNN	T1,ST%EER	;TEST BIT FOR NEW ERROR REPORTING
	TDZA	T1,T1		;NOT ON, SAVE 0
	SETO	T1,		;ON, SAVE -1
	MOVEM	T1,NERRPT	;AND REMEMBER FOR LATER

;FALL THROUGH TO GET SWAP STUFF
;HERE TO SET UP SWAPPING TABLES
; OUGHT TO TRY SUPER USETI TO SEE IF IT WORKS

GETSWP:	MOVEI	T2,BLKSPK	;SETUP SHIFT VALUE FOR KA10'S AND EARLY
				;KI10 MONITORS
	MOVE	T3,[LSH T1,BLKSPK-BLKSPP] ;INSTR TO CONVERT K OF SWAP SPACE TO PAGES
;**;[545] DELETE	MOVE	T1,[%CNVER]
;**;[545] DELETE	PUSHJ	P,GTBSPY	;GET MONITOR VERSION #
;**;[545] DELETE	  SETZ	T1,		;??
	HRRZ	T4,MONVER	;[545] CLEAR CUSTOMER VERSION FIELD
	CAIGE	T4,50700	;507 OR LATER ?
	JRST SETBP1		;NO, USE OLD STYLE SWAP POINTERS
	MOVE	T1,[POINT 3,SEGSWP,4]	;SET UP 507/601 SWAP UNIT POINTER
	MOVEM	T1,JBYSUN	;AND SAVE IT FOR LATER
	MOVE 	T1,[POINT 13,SEGSWP,17]	;SET UP 507/601 SWAP BLOCK POINTER
	MOVEM	T1,JBYLKS	;AND SAVE IT FOR LATER
SETBP1:	SETO	T1,
	AOBJN	T1,.+1		;TEST FOR KI10 PROCESSOR
	JUMPN	T1,SETBPG	;KA - GO USE BLKSPK
	CAIGE	T4,50510	;IS IT PRE 5.05 OR ANY SOUP THEREOF?
	JRST	SETBPG		;YES, SWAPPING SPACE IS IN K
	MOVEI	T2,BLKSPP	;POST 505 COUNT SWAPPING SPACE IN PAGES
	MOVSI	T3,(JFCL)	;NO NEED TO CONVERT PAGES TO PAGES
SETBPG:	MOVEM	T2,BLKPAG	;STORE SHIFT COUNTER
	MOVEM	T3,PKLSH	;STORE INSTR TO CONVERT SWAP CHUNKS TO PAGES
	MOVSI	T3,-MAXSWP	;MAXIMUM NUMBER OF UNITS FOR SWAPPING
	MOVE	T1,[%LDSLP]	;GET POINTER TO %LDSLP
	PUSHJ	P,GTBSPY
	  SKIPA	T1,[%LDSWP]	;[536] SET UP SWAP INFO OLD WAY
	JRST	NSWLST	;GO DO ALL THIS NEW WAY
	PUSHJ	P,GTBSPY	;GET ADDR OF FIRST SWAP UNIT, UNISWP
	  JRST	E.NSWP		;CANT GET SWAPPING PTR
	TRNN	T1,-1		;SKIP IF UNISWP SPECIFIED
	HRRI	T1,UNISWP	;NO, USE DEFAULT
	MOVS	T2,T1		;RH=ADDR OF UNIT, LH=UNISWP
GETSW1:	TRNN	T2,-1		;SKIP IF ANOTHER UNIT FOR SWAPPING
	JRST	GETSWE		;NO MORE SWAPPING UNITS
	MOVEI	T1,UNINAM(T2)	;ADDRESS OF NAME OF UNIT
	PUSHJ	P,PEKSPY	;GET NAME OF UNIT
	MOVEM	T1,.SWPUN(T3)	;STORE IN NAME TABLE
	MOVEM	T1,DAEBUF	;AND IN BLOCK FOR DSKCHR
	MOVE	T1,[.DCUFS+1,,DAEBUF]
	DSKCHR	T1,		;GET FIRST BLOCK FOR SWAPPING
	  JRST	E.DSWP		;DISK ERROR?
	MOVE	T1,DAEBUF+.DCUFS	;FIRST BLOCK FOR SWAPPING
	MOVEM	T1,.UNSLB(T3)	;STORE IN TABLE
	HLRZ	T1,T2		;INDEX IN UNIT DATA BLOCK FOR NEXT SWAP UNIT
	ADDI	T1,(T2)		;ADDR OF PTR TO NEXT SWAPPING UNIT
	PUSHJ	P,PEKSPY	;GET ADDRESS OF NEXT SWAPPING UNIT
	HLR	T2,T1		;STORE IN RH T2
	AOBJN	T3,GETSW1	;LOOP FOR MAXIMUM NUMBER OF SWAP UNITS
NSWPTB:	SKIPE	RESTART		;ARE WE ATTACHED
	JRST	GETSWE		;(NO) DON'T TYPE
	TRNE	T2,-1		;SKIP IF END OF LINE
	OUTSTR	[ASCIZ .% NOT ENOUGH TABLE SPACE FOR SWAPPING UNITS
.]
	JRST	GETSWE		;ALL DONE
NSWLST:	MOVE	T2,T1		;SAVE AOBJN WORD FOR %LDSLP
UNILUP:	HRRZ	T1,T2		;GET POINTER TO ENTRY IN %LDSLP IN T1
	PUSHJ	P,PEKSPY		;GO GET FIRST ENTRY IN %LDSLP
	JUMPE	T1,NXTUNI	;IF 0, GO ON TO NEXT UNIT
	PUSHJ	P,PEKSPY	;NOW GET NAME OF UNIT
	MOVEM	T1,.SWPUN(T3)	;AND SAVE IT IN TABLE
	MOVEM	T1,DAEBUF	;AND IN BLOCK FOR DSKCHR
	MOVE	T1,[.DCUFS+1,,DAEBUF]
	DSKCHR	T1,		;GET FIRST BLOCK FOR SWAPPING
	  JRST	E.DSWP		;DISK ERROR?
	MOVE	T1,DAEBUF+.DCUFS	;FIRST BLOCK FOR SWAPPING
	MOVEM	T1,.UNSLB(T3)	;STORE IN TABLE
NXTUNI:	AOBJN	T2,.+2		;INCREMENT TO NEXT UNIT
	JRST	GETSWE	;ALL DONE WITH %LDSLP
	AOBJN	T3,UNILUP	;INCREMENT OUT TABLE
	JRST	NSWPTB		;NOT ENOUGH TABLE SPACE
;GET, SAVE ORIGINAL FILE STRUCTURE SEARCH LIST FOR THIS JOB

GETSWE:	MOVE	T1,[2,,[.PTFSL	;DEFINE ADDITIONAL PATH TO BE SEARCHED
			0]]	;NO LIB, NO SYS, NO NEW, NO PROBLEMS
	PATH.	T1,		;SET UP
	  JFCL			;WHAT ISN'T IMPLEMENTED CAN'T HURT US
	MOVEI	T1,.FSDSL	;DEFINE SEARCH LIST FUNCTION
	MOVEM	T1,USRLST	;[540] STORE IN FUNCTION BLOCK
	SETOM	USRLST+1	;[540] OUR JOB
	SETOM	USRLST+2	;[540] OUR PPN
IFN .FSDSL-1,<MOVEI T1,1>
	MOVEM	T1,USRLST+3	;[540] SET TO REMOVE UNLISTED STR'S,
				;RATHER THAN PUTTING INTO PASSIVE LIST
IFN FTSVSL,<	;ONLY CARE ABOUT OUR SEARCH LIST IF WE SAVE IT
	MOVE	T1,[XWD USRLST,SRCLST]	;[540]
	BLT	T1,SRCLST+3	;[540] COPY SAME TO SEARCH LIST AREA
	MOVEI	T3,SRCLST+3	;AND USE THIS AREA, PLEASE
	SETOB	T1,T2		;OUR JOB, PPN
	PUSHJ	P,GETSRC	;GET OUR SEARCH LIST
	SUBI	T3,SRCLST-1	;END MINUS BEGINNING=LENGTH
	MOVSI	T3,(T3)		;THATS IN LEFT HALF
	HRRI	T3,SRCLST	;WITH ADDR IN RIGHT
	MOVEM	T3,PSRCH	;SAVE SO WE CAN GET THIS BACK
	STRUUO	T3,		;TRY TO SET THIS SEARCH LIST TO SEE IF IT WORKS
	  SKIPE	RESTART		;DO NOT TYPE IF RESTARTING
	JRST	GETSW0		;SKIP TYPE OUT
	OUTSTR [ASCIZ .% CANT DEFINE OUR OWN SEARCH LIST
.]
>	;END CONDITIONAL ON FTSVSL

GETSW0:	MOVE	T1,[%LDMFD]
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	MOVEM	T1,MFDPPN

;HERE TO FIND OUT IF JOBPEK UUO WORKS

TSTJPK:	MOVEI	T1,T2
	HRLZ	T2,THSJOB	;OUR JOB NUMBER
	HRRI	T2,1		;1 WORD FROM OUR JOB TO OUR JOB
	MOVE	T3,[SECBUF,,SECBUF]
	JOBPEK	T1,		;TRANSFER A WORD FROM US TO US
	  JRST	E.JPEK		;NOT IMPLEMENTED
;HERE TO CHECK FOR OTHER DAEMON'S RUNNING AROUND

DAECHK:	HRLZ	T1,THSJOB
	HRRI	T1,.GTPRG	;GET OUR NAME
	PUSHJ	P,GTBSPY
IFGE	FTSAVE,<
	  JRST	GETJIF		;THIS IS POINTLESS
	CAME	T1,[SIXBIT/DAEMON/]
	JRST	GETJIF		;IF THIS ISN'T DAEMON, NO PROBLEM
>
IFL	FTSAVE,<
	  JRST	GETET1		;THIS IS POINTLESS, AS ABOVE!
	CAME	T1,[SIXBIT/SAVER/]	;IF WE HAVE WRONG NAME,
	JRST	GETET1			; IGNORE
>
	MOVE	J,HJOB		;HIGHEST JOB IN SYSTEM
DAELUP:	CAMN	J,THSJOB	;DO NOT LOOK AT OUR JOB
	SOJG	J,DAELUP
IFGE	FTSAVE,<
	JUMPLE	J,GETJIF	;QUIT AFTER LOOKING AT ALL JOBS
>
IFL	FTSAVE,<
	JUMPLE	J,GETET1	;QUIT AFTER LOOKING AT ALL JOBS
>
	HRROI	T1,.GTPRG	;GETTAB POINTER FOR PROGRAM NAME
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;RATHER UNLIKELY, BUT...
IFGE	FTSAVE,<
	CAME	T1,[SIXBIT /DAEMON/]
>
IFL	FTSAVE,<
	CAME	T1,[SIXBIT/SAVER/]	;CHECK FOR OTHER SAVERS!
>
	SOJA	J,DAELUP	;THAT'S NOT DAEMON, TRY NEXT
	HRROI	T1,.GTSTS	;GETTAB TABLE FOR JOB STATUS
	PUSHJ	P,GTBSPY	;MUST CHECK JACCT, SINCE ANYBODY
	  SETZ	T1,		;  CAN USE A NAME
	TLNN	T1,JACCT	;IS THIS THE SYS:DAEMON?
	SOJA	J,DAELUP	;NO--AREN'T YOU GLAD WE CHECKED?
	IFGE	FTSAVE,<
	IFE	FTIPCF!FTRSTR,<
	OUTSTR	[ASCIZ	/% DAEMON ALREADY RUNNING
PLEASE KILL ONE OF US
/]
>
	IFN	FTRSTR!FTIPCF,<
;NOTE P2 AND V ARE IDENTICAL ACCUS IN SYSINF  CODE AND DAEMON!!

	MOVEI	P2,[ASCIZ /% DAEMON ALLREADY RUNNING 
PLEASE KILL ONE OF US WITH A REENTER COMMAND
/]
	PUSHJ	P,TYPOPR##	;TYPE ON CTY
	JFCL			;IGNORE THE FAILLURE
>
>;END IFGE FTSAVE
	IFL FTSAVE,<
	OUTSTR	[ASCIZ /%SAVER ALREADY RUNNING
PLEASE KILL ONE OF US
/]
>;END IFL FTSAVE
	JRST	DAEREN		;**[111] TAKE DAEMON NICELY DOWN
;HERE TO GET SYSTEM CLOCK RATE (JIFFIES/SECOND)

IFGE	FTSAVE,<	;DON'T INITIALIZE CLOCK STUFF
GETJIF:	MOVE	T1,[%CNTIC]
	PUSHJ	P,GTBSPY
	  MOVEI	T1,^D60		;DEFAULT 60 HZ
	MOVEM	T1,JIFSEC	;STORE JIFFIES PER SECOND
	IMULI	T1,^D24*^D3600	;JIFFIES PER DAY
	MOVEM	T1,JIFDAY	;HOLD FOR DIVIDE
	MOVEI	T1,^D1000	;MILLISECONDS PER SECOND
	IDIV	T1,JIFSEC	;GET MILLISECONDS PER JIFFY
	MOVEM	T1,MILJIF	;STORE THAT, TOO

IFG	FTSAVE,<

;HERE TO SET UP TABLE OF JOBS WAITING FOR SAVER AFTER WAKE IS DONE

	MOVSI	T1,J		;SETUP UP INDEX IN TABLE POINTER
	HRR	T1,.JBFF	;AND GET FIRST ADDRES OF TABLE
	MOVEM	T1,SAVWAT	;SAVE AS TABLE POINTER
	HRRZ	T1,HJOB		;GET LENGTH OF TABLE
	ADDB	T1,.JBFF	;AND SAY WE NEED THE CORE
	CAMG	T1,.JBREL	;ALREADY HAVE ENOUGH?
	JRST	.+3		;YES,KEEP GOING
	CORE	T1,		;ASK FOR WHAT WE NEED
	SKIPE	RESTART		;IGNORING TYPEOUT?
	SKIPA			;YES, OR WE WON
	   OUTSTR	[ASCIZ .?CAN'T GET CORE FOR TABLE OF JOBS DOING SAVES
.]
	HRRZ	T1,SAVWAT	;GET START OF TABLE
	SETZM	(T1)		;CLEAR FIRST LOCATION
	HRLI	T1,1(T1)	;MAKE A BLT POINTER
	HRRI	T2,(T1)		;AND GET START IN T2
	ADD	T2,HJOB		;MAKE T2 LAST LOCATION OF TABLE
	BLT	T1,(T2)		;CLEAR THE TABLE

>;END IFG FTSAVE

;HERE TO SET UP CLOCK FUNCTION TABLE

IFN ICLKRQ!FTCLCK,<
	MOVEI	T2,ICLKRQ-1	;[67]GET NUMBER OF  QUEUES LESS THAN 0
	MOVNM	T2,QPNTR	;[67]SAVE IN QPNTR AS MOST NEG. QUEUE NO
	ADD	T2,.JBFF	;[67]POINT TO JOB 0
	HRRM	T2,JBTCLK	;STORE THE POINTER
IFN FTCLCK,<
	HRRZ	T1,HJOB		;HIGHEST JOB # IN SYSTEM
	MOVNI	T3,ICLKRQ+1(T1)	;-VE LENGTH OF TABLE
>
IFE FTCLCK,<
	MOVNI	T3,ICLKRQ	;INTERNAL REQUESTS ONLY
>
	HRLOI	T4,-2		;[61]GET -2,-1 IN AC TO TEST FOR KA/KI
	AOBJN	T4,.+2		;[61]DO TEST FOR KA
	SUBI	T3,1		;[61]HERE IF KA, NEED TO BUMP COUNT BY 1
	HRLM	T3,QPNTR	;STORE IN POINTER
IFN FTCLCK,<
	ADDI	T2,1(T1)	;NEW .JBFF
>
	MOVEM	T2,.JBFF	;STORE BACK
	CAMG	T2,.JBREL	;DO WE ALREADY HAVE ENOUGH?
	JRST	.+3		;YES, DON'T ASK FOR MORE
	CORE	T2,		;IN CASE WE NEED IT
	SKIPE	RESTART		;IGNORING TYPE OUT
	SKIPA			;(YES) OR NO ERROR
	  OUTSTR [ASCIZ .? CANT GET CORE FOR CLOCK TABLE
.]
	MOVE	J,QPNTR		;QUEUE POINTER
	SETZM	@JBTCLK		;CLEAN OUT THE JUNK
	AOBJN	J,.-1		;SLOW BLT
>;END FTCLCK!ICLKRQ CONDITIONAL
IFN CHKFCT,<

;HERE TO SAVE RELOAD INFORMATION IN FACT.SYS

	PUSHJ	P,BUFAGE	;DON'T LET THIS ENTRY SIT TOO LONG
IFE FT1975,<			;[7(57)]
	MOVE	T1,[XWD 370000,3] ;GET BASIC RELOAD ENTRY HEADER
>
IFN FT1975,<			;[7(57)]
	MOVE	T1,[XWD 371000,3] ;GET NEW FORMAT RELOAD ENTRY[7(57)]
>
	HRRZM	T1,FACTSZ	;NOTE 3 WORDS IN BUFFER
	MOVE	T2,THSJOB	;GET OUR JOB NO
	DPB	T2,[POINT 9,T1,17]
	MOVE	T2,THSLIN	;GET OUR LINE & CHARACTERISTICS
	TLNE	T2,(GL.CTY)	;IS IT THE CTY?
	SETO	T2,		;YES, SPECIAL CODE FOR THAT
	DPB	T2,[POINT 12,T1,29]
	MOVEM	T1,FACTBF	;(0) HEADER WORD
	MOVE	T1,OPRPPN	;(1) THIS JOB'S PPN
	MOVEM	T1,FACTBF+1
	PUSHJ	P,FACTIM	;12 BITS DATE, 24 BITS TIME
	MOVEM	T1,FACTBF+2	;(2) DATE AND TIME

;ADD HERE OTHER RELOAD INFORMATION AS DESIRED
>

;HERE TO START INTERNAL TIMERS

IFN FTCHKPNT,<
IFN CHKTIM,<
	MOVEI	J,CHKRQ		;INSERT THE CHECKPOINT REQUEST
	MOVEI	T1,CHKTIM	;INTERVAL
	MOVEM	T1,CCTIM	;SAVE CURRENT CHECKPOINT INTERVAL
	PUSHJ	P,CLKREQ	;PUT IN THE REQUEST
>;END OF CHKTIM COND
>;END OF FTCHKPNT COND
IFN FTUSCN,<
IFN USCTIM,<
	MOVEI	T1,USCTIM	;START A UNIT SCAN EVERY HOUR
	MOVEM	T1,CUTIM	;SAVE CURRENT UNIT SCAN INTERVAL
	MOVEI	J,USCRQ		;APPROPRIATE DUMMY JOB #
	PUSHJ	P,CLKREQ	;STORE THE REQUEST
>;END USCTIM COND
>;END FTUSCN COND
;HERE TO GET CREATE COPY OF NXMTAB IN CORE
IFN FTERR,<

	SKIPN	NERRPT			;SKIP IF WE DO NEW ERROR REPORTING
	JRST	NONXMT			;NO, DON'T GET NXMTAB
	MOVE	T1,[%CNNXM]	;GETTAB POINTER TO NXMTAB
	PUSHJ	P,GTBSPY
	  JRST	NONXMT			;NOT THERE, DON'T DO THIS
	HLRE	T2,T1		;GET LENGTH OF NXMTAB
	MOVMS	T2		;MAKE IT POSITIVE
	MOVEM	T2,NXMLEN	;REMEMBER LENGTH
	MOVE	T3,.JBFF	;GET LAST ADDRESS
	ADD	T3,T2		;ADD IN EXTRA NEEDED
	CAMG	T3,.JBREL	;IF ITS LESS THAN .JBREL, DON'T DO CORE UUO
	JRST	.+3		;DON'T NEED MORE CORE
	CORE	T3,		;TRY TO GET MORE CORE
	  JRST	[OUTSTR [ASCIZ/?CAN'T GET CORE FOR NXMTAB
/]
		JRST NONXMT]
	MOVE	T2,.JBFF	;GET OLD LAST ADDRESS
	MOVEM	T2,NXMTAB	;SAVE AS START OF D NXMTAB
	HLRE	T3,T1		;AND GET LENGTH OF NXMTAB
	MOVMS	T3		;MAKE IT POSITIVE
	ADD	T2,T3		;ADD IT 
	MOVEM	T2,.JBFF	;REMEMBER IT AS .JBFF
	MOVE	T3,T1		;USE T3 AS AOBJN POINTER
	MOVE	T2,NXMTAB	;AND T2 AS WHERE TO SAVE
NXMLUP:	HRRZ	T1,T3	;GET CURRENT ADDR INTO T1
	PUSHJ	P,PEKSPY	;GO PICK IT UP FROM MONITOR
	MOVEM	T1,(T2)		;STASH IT AWAY
	AOS	T2		;INCREMENT T2
	AOBJN	T3,NXMLUP	;INCREMENT T3 AND LOOP
	JRST	RELSTR		;NO GO WRITE RELOAD ENTRY
NONXMT:	SETOM	NXMLEN		;FLAG THAT WE HAVE NO NXMTAB
	JRST	RELSTR		;AND GO WRITE WHY RELOAD ENTRY
;HERE TO SAVE WHY-RELOAD CODE AND OPR COMMENTS IN ERROR.SYS
ND (.ESDRE,7)	;[550]USE THIS UNTIL UUOSYM IS UPDATED

RELSTR:	PUSHJ	P,ERRSTR	;SET UP EXTENSION FOR ERROR FILE
	MOVSI	T1,.ESDRE_9	;[550]SET UP RESTART CODE
	PUSHJ	P,ERRINI	;[550]STORE HEADER, SET P4 AND CLR BUFF
	PUSH	P4,.JBVER	;[550]GET JBVER
	PUSHJ	P,ERRFIN	;[550]AND STUFF IT
;HERE TO FIND OUT IF MONITOR HAS RP04 SUPPORT, HENCE CAN DO
;MASSBUS DEVICE ERROR REPORTING

	MOVE	T1,[%CNST2]	;GET SECOND STATES WORD
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;IF CAN'T, NO MASSBUS ERRORS
	TRNN	T1,ST%MBE	;IS OUR BIT ON?
	SKIPA	T1,[0]		;NO, DO OLD STYLE STUFF
	SETO	T1,		;YES, FLAG WE DO MASSBUS ERRORS
	MOVEM	T1,RP4MON	;SAVE CODE TO SEE IF WE HAVE RP04'S
	JUMPE	T1,GETET1	;IF NO MASSBUS CODE, DON'T NEED OTHER NUMBERS
	MOVE	T1,[%LDMBR]	;GETTAB KONREG+UNISCR
	PUSHJ	P,GTBSPY
	  JRST	NMASER		;OOPS
	HRRZM	T1,UNISCR	;RH IS UNISCR
	HLRZM	T1,KONREG	;LH IS KONREG
	MOVE	T1,[%LDBBP]	;[463]
	PUSHJ	P,GTBSPY
	 MOVEI	T1,37		;DEFAULT VALUE
	MOVEM	T1,UNICCT	;[463] OFFSET TO UNICCT IN UDB
	HRRZ	T2,MONVER	;[545] GET MONITOR VERSION
	CAIGE	T2,60200	;[545] IS 602 OR GREATER
	  TDZA	T2,T2		;[545] NOT SO, DON'T HAVE .CHTCW
	  MOVEI	T2,.CHTCW	;[545] GET DEFAULT VALUE OF .CHTCW
	MOVE	T1,[%LDEXP]
	PUSHJ	P,GTBSPY
;**;[545] @NMASER-3
;**;[545] DELETE	 MOVEI	T1,33		;DEFAULT VALUE
	  MOVEI	T1,(T2)		;[545] NOT GETTAB, WHAT DID WE FIGURE?
;**;[545] DELETE	MOVEM	T1,.CHTCW	;[463]	OFFSET TO EXP. TERM WD IN CDB
	MOVEM	T1,CHNTCW	;[545] OFFSET TO EXP TERM WD IN CDB
	JRST	GETET1		;OK, ALL DONE
NMASER:	MOVEI	T1,64		;OLD (PRE GETTAB) OFFSET OF KONREG
	MOVEM	T1,KONREG	;SAVE IT AWAY
	MOVEI	T1,63		;NON-VM, PRE GETTAB UNISCR
	SKIPE	VMMON		;DO WE HAVE VM?
	ADDI	T1,2		;YES, FIX UNISCR
	TLO	T1,400000	;FLAG PRE-GETTAB SO WE DON'T LOOK FOR  RH10 DATAI'S AND CONI'S
	MOVEM	T1,UNISCR	;THIS IS REALLY UNIEBK

>;END COND ON FTERR
>	;END IFGE FTSAVE

;HERE TO GET ADDRESS OF EXECT1 IN JOB DATA AREA

GETET1:	MOVE	T1,[%CNET1]	;GETTAB THE ADDRESS OF EXEC T1
	PUSHJ	P,GTBSPY
	  MOVEI	T1,26		;IF GETTAB LOSES, USE BEST WE KNOW
	MOVEM	T1,EXECT1	;AND SAVE FOR LATER

;HERE TO GET DDB LENGTHS

	MOVE	T1,[%CNLSD]	;GETTAB SHORT DDB LENGTH
	PUSHJ	P,GTBSPY
	  MOVEI	T1,15		;USE OLD NUMBER(PRE THIS GETTAB)
	MOVEM	T1,LDDBSH	;AND SAVE AS LENGTH OF SHORT DDB
	MOVE	T1,[%CNLLD]	;NOW GET LONG LENGTH
	PUSHJ	P,GTBSPY
	  MOVEI	T1,17		;USE OLD LENGTH
	MOVEM	T1,LDDBLN	;AND SAVE FOR UUO'S, ETC.
	MOVE	T1,[%CNLDD]	;AND LAST, GET DISK DDB LENGTH
	PUSHJ	P,GTBSPY
	  MOVEI	T1,44		;USE LAST NON-GETTABED NUMBER
	MOVEM	T1,LDDBDS	;AND SAVE FOR DCORE OF DDB'S

IFN FTERR,<
	PUSH	P,PDBPTR	;SAVE PDBPTR
	PUSHJ	P,CRSCHK	;[551]BEFORE WRITING ANY OTHER ENTRIES
				;FOR THIS MONITOR LOAD, GO LOOK AT CRASH
				;FILES
	POP	P,PDBPTR	;AND RESTORE IT

>

;HERE TO DETACH TTY

DETTTY:	SKIPE	RESTART		;THE FIRST TIME?
	JRST	NODET		;(NO) THAT'S IT
	HRLZ	T1,THSLIN	;LH IS NOW LINE NUMBER, RH=0 TO DETACH
	HRRZ	T2,.JBDDT	;GET ADDR OF DDT IF ANY
	JUMPN	T2,NODET	;DONT DETACH IF DDT
	OUTSTR	[ASCIZ /DETACHING
./]
	ATTACH	T1,		;DETACH OUR TTY
	  JRST	E.NATT		;CAN'T, MUST NOT BE IMPLEMENTED
NODET:	TLZ	F,L.TTYA	;NOTE NO TTY ATTACHED
;**;[544] DELETE	MOVEI	T1,DALOOK	;NEW RESTART ADDRESS
;**;[544] DELETE	MOVEM	T1,INTADR
	SETOM	WTUERR		;INIT FLAG TO CATCH RECURSIVE EXIT ATTEMPTS
SUBTTL	CHECK FOR MONITOR-INITIATED DAEMON REQUEST

;HERE WHEN DAEMON AWAKENED
; IF A HARDWARE ERROR HAS BEEN DETECTED BY THE MONITOR, RECORD THE INFO
;COLLECTED INTO ERROR.SYS.  MONITOR COUNTERS GET BUMPED ON EVERY ERROR

IFGE	FTSAVE,<
DALOOK:	CAMN	P,PDL		;VERIFY STACK CORRECTNESS
	JRST	.+3		;IT'S OK, CONTINUE
	MOVEM	P,PDLGUF	;OR SAVE THE BAD GUY
	MOVE	P,PDL		;RESTORE GOODNESS
IFE FTDET,<
	TLNE	F,L.ERR		;HAS OPR SUPPREED ERROR LOGGING?
	JRST	DALOKJ		;YES, DO NOT LOG
>;END FTDET COND
	SKIPN	NERRPT		;DO WE DO NEW ERROR REPORTING?
	JRST	OLDLOK		;NO, PROCEED OLD WAY
NEWLOK:	MOVEI	T1,ERPTBK	;GET ADDRESS OF BLOCK FOR ERRPT. UUO
	ERRPT.	T1,		;ASK MONITOR FOR NEXT ERROR TO REPORT
	  JRST	DALOKJ		;NO MORE, GO LOOK AT JOBS
	PUSHJ	P,DSPERR	;DISPATCH TO CORRECT ROUTINE OFF CODE IN T1
	JRST	NEWLOK		;AND LOOP BACK FOR MORE
OLDLOK:	MOVEI	T1,%SYERR	;GETTAB FOR SYSERR
	PUSHJ	P,GTBSPY	;PICK UP SYSERR WORD
	  JRST	DALOKJ		;WELL, WHAT CAN YOU DO?
	CAMN	T1,SERCNT	;HAS THE COUNT CHANGED?
	JRST	DALOKJ		;NO, CANT BE SYSTEM REQUEST. LOOK FOR JOB
	MOVEM	T1,SERCNT	;YES, SAVE THIS VALUE, AND LOOK FOR CAUSE
	AOS	DERCNT		;COUNT THE NUMBER OF TIMES WE SAW CHANGES IN SYSERR
	JRST	SRCHER		;AND GO SEARCH FOR THE ERROR
>	;END IFGE FTSAVE

IFL	FTSAVE,<
DALOOK:	CAME	P,PDL		;PUSHDOWN LIST STILL OK?
	MOVE	P,PDL		;NO, BETTER FIX IT
	JRST	DALOKJ		;IF WE'RE SAVE, ONLY LOOK AT JOBS
>

IFGE FTSAVE,<

;ROUTINE TO SET UP AND DISPATCH TO APPROPRIATE REPORTING
;ROUTINE FROM CODE RETURNED IN T1 BY
;ERRPT. UUO.  

DSPERR:	LDB	T2,[POINT 9,(T1),35]	;GET CODE INTO T2
;**;[544] DSPERR+1	DBR	AUG 20,1976
	LDB	J,[POINT 9,(T1),26]	;[544] GET JOB NUMBER, IF ANY
	JUMPLE	T2,JOBFIN		;IGNORE IF OUT OF
	CAILE	T2,DSPMAX		; RANGE
	JRST	JOBFIN
	JRST	@DSPTAB(T2)		;DISPATCH ON CODE

DSPTAB:	PJRST	JOBFIN		;0-ILLEGAL CODE
	SRLERR		;1-SYSTEM RELOAD
	SCNSTD		;2-CONTINUABLE MONITOR ERROR
	SCPERR		;3-CPU MEMORY PARITY (NOT KL)
	SNXMER		;4-NON-EXISTENT MEMORY (NOT KL10)
	PJRST	JOBFIN		;5-NOT IMPLEMENTED (PAGE FAIL)
	PJRST	JOBFIN		;6-CHANNEL ERRORS -- NOT REPORTED THIS WAY
	PJRST	JOBFIN	;7-DAEMON STARTED-NOT REPORTED THIS WAY
	SDVERR		;10-RP10,RC10 DISK ERROR
	SDVERR		;11-MASS BUS DEVICE ERROR
	PJRST	JOBFIN	;12-NOT IMPLEMENTED
	PJRST	JOBFIN	;13-NOT IMPLEMENTED
	PJRST	JOBFIN	;14-NOT IMPLEMENTED
	SCSCER		;15-CONFIGUATION STATUS CHANGE
	PJRST	JOBFIN	;16-NOT IMPLEMENTED
	SDIERR		;17-[550] DUMP LIKE SDLERR (50)
	PJRST	JOBFIN		;20-TM10,MTXSER MAGTAPE ERROR
	STPERR		;21-TAPSER MAGTAPE ERROR
	PJRST	JOBFIN	;22-NOT IMPLEMENTED
	PJRST	JOBFIN	;23-NOT IMPLEMENTED
	PJRST	JOBFIN	;24-NOT IMPLEMENTED
	PJRST	JOBFIN	;25-NOT IMPLEMENTED
	PJRST	JOBFIN	;26-NOT IMPLEMENTED
	PJRST	JOBFIN	;27-NOT IMPLEMENTED
	KLEERR		;30-KL10 FRONT END ERROR DATA
	PJRST	JOBFIN	;31-NOT IMPLEMENTED
	PJRST	JOBFIN	;32-NOT IMPLEMENTED
	PJRST	JOBFIN	;33-NOT IMPLEMENTED
	PJRST	JOBFIN	;34-NOT IMPLEMENTED
	PJRST	JOBFIN	;35-NOT IMPLEMENTED
	PJRST	JOBFIN	;36-NOT IMPLEMENTED
	PJRST	JOBFIN	;37-NOT IMPLEMENTED
	PJRST	JOBFIN		;40-UNIT SCAN, NOT REPORTED THIS WAY!
	PJRST	JOBFIN	;41-NOT IMPLEMENTED
	STPERR		;42-MAGTAPE STATISTICS
	PJRST	JOBFIN	;43-NOT IMPLEMENTED
	PJRST	JOBFIN	;44-NOT IMPLEMENTED
	PJRST	JOBFIN	;45-NOT IMPLEMENTED
	PJRST	JOBFIN	;46-NOT IMPLEMENTED
	PJRST	JOBFIN	;47-NOT IMPLEMENTED
	SDLERR		;50-DL10 ERROR
	PJRST	JOBFIN	;51-NOT IMPLEMENTED
	PJRST	JOBFIN	;52-NOT IMPLEMENTED
	PJRST	JOBFIN	;53-NOT IMPLEMENTED
	PJRST	JOBFIN	;54-NOT IMPLEMENTED
	PJRST	JOBFIN	;55-NOT IMPLEMENTED
	PJRST	JOBFIN	;56-NOT IMPLEMENTED
	PJRST	JOBFIN	;57-NOT IMPLEMENTED
	SCPERR		;60-KL10 CPU PARITY ERROR
	SKLTRP		;61-KL10 DATA PARITY TRAP
	PJRST	JOBFIN	;62-NOT IMPLEMENTED
	PJRST	JOBFIN	;63-NOT IMPLEMENTED
	PJRST	JOBFIN	;64-NOT IMPLEMENTED
	PJRST	JOBFIN	;65-NOT IMPLEMENTED
	PJRST	JOBFIN	;66-NOT IMPLEMENTED
	SNXMER		;67-KL10 ADDRESSING FAILURE
	PJRST	JOBFIN	;70-NOT IMPLEMENTED
	SDLERR		;71-LP100 REPORT [550]
DSPMAX=.-DSPTAB
;INITIALLY PUSHJ HERE IF A JOB IS PAUSED FOR US
;THIS WILL FREE THAT JOB IN CASE OF FATAL ERROR OR WHEN WE POPJ
;**;[544] DBR

PROTJB:	PUSH	P,[PROTJ1]	;[544] [565] GET PLACE TO GO ON CRASH
	POP	P,INTADR	;[544] AND PUT IT IN INTADR
	POP	P,(P)		;[544] TAKE RETURN ADDR OFF STACK
	PUSHJ	P,@1(P)		;[544] AND CALL CALLER
;AUTOMATICALLY RETURN HERE WHEN DONE.  THE USER IF FREED.
;	PJRST	JOBFIN		;[544] FINISH UP


;SUBROUTINE TO RESTART JOB WAITING FOR ERROR TO BE REPORTED
;ARGS	J=JOB NUMBER

JOBFIN:	HRLZI	T1,(J)		;[527] GET JOB NUMBER INTO LH OF T1
	IFN .GTSTS,<HRRI T1,.GTSTS>	;SET UP TO GET JOBS JBTSTS WORD
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;OH WELL
	TRNN	T1,JDEP		;IS JOB WAITING?
;**;[544] DELETE AT JOBFIN+4	POPJ	P,		;NOPE, RETURN
	POPJ	P,		;[565 -PUT IT BACK] NOPE, RETURN
	MOVEI	T1,J		;GET ADDR OF ARGUMENT FOR DAEFIN
	DAEFIN	T1,		;AND SET JOB FREE
	  AOS	FINGUF		;REMEMBER # OF LOSSAGES
	POPJ	P,
;**;[544] JOBFIN+7	DBR	AUG 20,1976


;HERE IF DAEMON CRASH BEFORE USER FREED

PROTJ1:	PUSHJ	P,JOBFIN	;[544] FINISH UP
	JRST	DALOOK		;[544] CONTINUE
IFN	FTERR,<

;HERE TO LOOK FOR MEMORY PARITY ERROR INFO IN CPU DATA BLOCKS

SRCHER:	MOVEI	T1,DALOKJ
	MOVEM	T1,INTADR	;SET INTERCEPT ADDRESS
IFN CPUN,<
	MOVSI	P1,-CPUN	;AOBJN WORD FOR CPU TABLES
CPLOOP:	MOVEI	P2,(P1)		;COPY CPU #
	LSH	P2,1		;DOUBLE TO INDEX GETTAB CDBS
	MOVE	T3,[%CCPAR]	;LOOK AT PARITY SWEEP COUNT
	ADD	T3,P2		;IN THIS CPU POINTER TO TABLE
	MOVSI	T2,.GTC0V(P2)	;TABLE CONTAINING TABLE
	HRRI	T2,%CVPSC	;SWEEP COUNT IN SUBTABLE
	PUSHJ	P,GSUBTB
	  JRST	.+2		;TABLE MUST NOT BE THERE
	JRST	CPCMLT		;COMPARE TO LAST TOTAL
	MOVE	T1,[%CVTPE]	;LOOK AT PARITY ERROR COUNT
	ADD	T1,P2		;IN APPROPRIATE CPU DATA BLOCK
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;SEEMS PRETTY UNLIKELY
	MOVE	T2,T1		;HOLD FOR ADDING IN "SPURIOUS"
	MOVE	T1,[%CVSPE]	;LOOK AT SPURIOUS ERRROR COUNT
	ADD	T1,P2		;IN THIS CPU'S BLOCK
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;UNLIKELY, BUT BETTER ALLOW FOR IT
	ADD	T1,T2		;ADD NON-REPRODUCABLE TO TOTAL
CPCMLT:	CAMN	T1,$CPPAR(P1)	;COMPARE TO LAST TOTAL
	JRST	NXTCPU		;NO PARITY ERRORS FOUND
	MOVEM	T1,$CPPAR(P1)	;SAVE NEW VALUE
	MOVSI	T1,.ESMPE_9	;INDICATE ERROR TYPE
	PUSHJ	P,GCPERR	;AND LOG ERROR INFO
NXTCPU:	AOBJN	P1,CPLOOP	;GO LOOK AT NEXT
>;END CPUN COND

;STILL IN FTERR CONDITIONAL
;HERE TO LOOK FOR I/O ERRORS (INCLUDING CHANNEL-DETECTED MEMORY PROBLEMS)

IFN CHNN,<
	MOVSI	P1,-CHNN
	MOVE	T1,[%CNCHN]
	PUSHJ	P,GTBSPY	;GET START OF CHAIN OF CHANNELS
	  JRST	MTASCN		;CAN'T --IGNORE
CHELUP:	HLRZ	P2,T1		;ADDR OF CHANNEL DATA BLOCK
	JUMPE	P2,MTASCN	;END OF CHAIN
	MOVEI	T1,.CHMPE(P2)	;COUNT OF MEM PAR'S ON THIS CHAN
	PUSHJ	P,PEKSPY
	MOVE	T2,T1		;HOLD TO ACCUMULATE TOTAL CHAN ERR'S
	MOVEI	T1,.CHNXM(P2)	;COUNT OF NON-EX MEM'S
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,.CHDPE(P2)	;DEVICE PARITY ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;TOTAL ERRORS DETECTED BY CHANNEL
	CAMN	T2,$CHERR(P1)	;COMPARE TO OLD TOTAL
	JRST	NXTCHN		;SAME AS LAST TIME
	MOVEM	T2,$CHERR(P1)	;SAVE NEW VALUE
	MOVSI	T1,.ESCPE_9	;CODE FOR CHANNEL ERROR
	PUSHJ	P,GCHERR	;RECORD IT
NXTCHN:	MOVEI	T1,.CHSYS(P2)	;POINT TO POINTER TO NEXT CHANNEL BLOCK
	PUSHJ	P,PEKSPY	;GET POINTER
	AOBJN	P1,CHELUP	;GO TO NEXT CHANNEL

>;END OF CHNN CONDITIONAL
;STILL IN FTERR COND
;HERE TO LOOK FOR MAGTAPE ERRORS

MTASCN:
IFN MTAN,<
	MOVE	T1,[%CNST2]
	PUSHJ	P,GTBSPY	;GET SECOND STATES WORD
	  JRST	DVESCN		;??
	TRNN	T1,ST%MER	;DOES MONITOR HAVE MAGTAPE ERROR REPORTING?
	JRST	DVESCN		;YES, NO MAGTAPE ERROR REPORTING
	TRNE	T1,ST%TAP	;DOES MONITOR HAVE TAPSER?
	JRST	TAPSCN		;YES, DO THIS DIFFERENTLY
	MOVSI	P1,-MTAN	;NUMBER OF UNITS WE HAVE TABLES FOR
	MOVE	T1,[%CNMER]
	PUSHJ	P,GTBSPY	;GET POINTER TO LIST OF DDB'S
	  JRST	DVESCN		;WE CAN'T GET HERE!!
	HLRZ	P2,T1		;GET INDEX OF MTARID INTO P2
	SKIPA	P3,T1		;AND GET POINTER TO FIRST MTADDB INTO P3
MTASC0:	HLRZ	P3,T1		;PUT POINTER IN P3
	JUMPE	P3,DVESCN	;IF END OF LIST, LOOK FOR DSK STUFF
	ADDI	P2,(P3)		;MAKE POINTER TO DAEMON INFORMATION IN DDB
	MOVEI	T1,DEVMOD(P3)	;ADDRESS OF DEVMOD WORD
	PUSHJ	P,PEKSPY	;GET THE WORD
	TLNN	T1,(DV.MTA)	;SKIP IF MTA
	JRST	MTASC3		;NOT, GET NEXT DDB
	MOVEI	T1,MTXSRE(P2)	;DEVICE IS MTA
	PUSHJ	P,PEKSPY	;GET SOFT READ ERROR COUNT
	MOVE	T2,T1		;HOLD FOR ACCUMULATION
	MOVEI	T1,MTXHRE(P2)	;GET COUNT OF HARD READ ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,MTXSWE(P2)	;COUNT OF SOFT WRITE ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,MTXHWE(P2)	;COUNT OF HARD WRITE ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	CAMN	T2,$MTAER(P1)	;SAME AS LAST TIME?
	JRST	MTASC1		;YES, LOOK FOR UNLOAD
	MOVEM	T2,$MTAER(P1)	;STORE NEW COUNT
	JUMPE	T2,MTASC1	;IF RESET TO ZERO, MUST BE A NEW REEL
	MOVSI	T1,.ESMAG_9	;SYSERR ERROR CODE
	PUSHJ	P,GMTERR	;LOG ERROR
MTASC1:	MOVEI	T1,MTXTUN(P2)	;COUNT OF UNLOADS FOR THIS UNIT
	PUSHJ	P,PEKSPY
	CAMN	T1,$MTAUN(P1)	;COMPARE TO TOTAL SAVED UNLOADS
	JRST	MTASC2		;NOT AN UNLOAD
	MOVEM	T1,$MTAUN(P1)	;SAVE NEW UNLOAD COUNT
	MOVSI	T1,.ESMSC_9	;SYSERR ERROR CODE
	PUSHJ	P,GMTSTS	;RECORD MAGTAPE STATUS
MTASC2:	AOBJP	P1,DVESCN	;GET OUT IF NO MORE ROOM IN TABLES
MTASC3:	SUBI	P2,(P3)		;RESTORE P2 TO JUST AN INDEX
	MOVEI	T1,DEVSER(P3)	;ADDRESS OF POINTER TO NEXT DDB
	PUSHJ	P,PEKSPY
	JRST	MTASC0		;LOOP IF MORE ROOM IN TABLES

;STILL IN MTAN CONDITIONAL
;STILL IN FTERR CONDITIONAL
	JRST	DVESCN		;FALL THROUGH TO DVESCN
TAPSCN:	MOVSI	P1,-MTAN	;SET UP NUMBER OF UNITS WE HAVE TABLES FOR
	MOVE	T1,[%CNMER]	;GET THE APPROPRIATE POINTERS FROM THE MONITOR
	PUSHJ	P,GTBSPY
	  JRST	DVESCN		;OOPS
	HLRZ	P2,T1		;LH IS OFFSET FOR TUBRID
	SKIPA	P3,T1		;RH IS POINTER TO FIRST MTA DDB
TAPSC0:	HLRZ	P3,T1		;GET NEXT DDB ADDR IN P3
	JUMPE	P3,DVESCN	;IF ZERO, END OF DDB CHAIN
	MOVEI	T1,DEVMOD(P3)	;GET DEVMOD WORD
	PUSHJ	P,PEKSPY
	TLNN	T1,(DV.MTA)	;AND SEE IF DEVICE IS A MAGTAPE
	JRST	TAPSC3		;NOPE, TRY NEXT DDB
	TLNE	T1,(DV.DSK)	;IS IT ALSO A DISK?
	JRST	TAPSC3		;YES,MUST BE NUL -- GO TO NEXT DDB
	MOVE	T1,LDDBSH	;GET LENGTH OF SHORT DDB
	ADD	T1,P3		;AND OFFSET THAT FAR INTO DDB
	PUSHJ	P,PEKSPY	;TO PICK UP POINTER TO TUB
	HLRZ	P4,T1		;GET START OF TUB IN P4
	ADD	P4,P2		;AND TURN IT INTO OFFSET FOR TUBRID
	MOVEI	T1,TUBSRE(P4)	;PICK UP SOFT READ ERROR COUNT
	PUSHJ	P,PEKSPY
	MOVE	T2,T1		;REMEMBER IT IN T2
	MOVEI	T1,TUBHRE(P4)	;NOW GET HARD READ ERROR COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;ADD IT TO COUNT
	MOVEI	T1,TUBSWE(P4)	;AND NEXT SOFT WRITE ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;COUNT THEM ALSO
	MOVEI	T1,TUBHWE(P4)	;AND LAST, HARD WRITE ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;PRODUCE TOTAL ERROR COUNT
	CAMN	T2,$MTAER(P1)	;HAS IT CHANGED?
	JRST	TAPSC1		;NO, NO ERROR TO REPORT
	MOVEM	T2,$MTAER(P1)	;ITS CHANGED, REMEMBER IT
	JUMPE	T2,TAPSC1	;IF TO ZERO, JUST NEW TAPE
	MOVSI	T1,.ESTAP_9	;GET CODE FOR ERROR.SYS
	PUSHJ	P,GTPERR	;AND GO WRITE ENTRY
TAPSC1:	MOVEI	T1,TUBTUN(P4)	;PICK UP NUMBER OF UNLOADS
	PUSHJ	P,PEKSPY
	CAMN	T1,$MTAUN(P1)	;HAS IT CHANGED?
	JRST	TAPSC2		;NO, GO TRY NEXT UNIT
	MOVEM	T1,$MTAUN(P1)	;REMEMBER IT FOR LATER
	MOVSI	T1,.ESTPS_9	;CODE FOR ERROR SYS
	PUSHJ	P,GTPSTS	;REPORT THE UNLOAD
TAPSC2:	AOBJP	P1,DVESCN	;LOOP FOR ALL UNITS WE HAVE TABLES FOR
TAPSC3:	MOVEI	T1,DEVSER(P3)	;GET LINK TO NEXT DDB
	PUSHJ	P,PEKSPY
	JRST	TAPSC0		;AND LOOP OVER ALL DDBS

>;END MTAN CONDITONAL
;HERE TO PICK UP UNIT ERRORS

DVESCN:
IFN UNITN,<
	MOVSI	P1,-UNITN	;# OF UNITS WE HAVE TABLES FOR
	MOVE	T1,[%LDUNI]
	PUSHJ	P,GTBSPY	;GET POINTER TO ALL UNIT DATA BLOCKS
	  JRST	DALOKJ		;FRUITLESS
DVELUP:	HLRZ	P3,T1		;ADDRESS OF NEXT UNIT DATA BLOCK
	JUMPE	P3,DALOKJ	;THAT'S ALL
	MOVEI	T1,UNIHCT(P3)	;UNIT HARD ERR COUNT
	PUSHJ	P,PEKSPY
	MOVE	T2,T1		;HOLD FOR ACCUMULATION
	MOVEI	T1,UNISCT(P3)	;UNIT SOFT ERR COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIMCT(P3)	;UNIT SOFTWARE ERR COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIPCT(P3)	;UNIT SEEK ERROR COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIHNG(P3)	;UNIT HUNG COUNTS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	CAMN	T2,$UNIER(P1)	;SAME AS LAST TIME FOR THIS UNIT?
	JRST	NXTDEV		;YES, GO ON TO NEXT
	MOVEM	T2,$UNIER(P1)	;SAVE NEW VALUE
	SKIPL	RP4MON		;DOES MONITOR HAVE RP04 SUPPORT?
	JRST	DVELP1		;NO, DO THESE OLD WAY
	MOVEI	T1,UNIKON(P3)	;ADDRESS OF CONTROLLER DATA BLOCK
	PUSHJ	P,PEKSPY
	ADD	T1,KONREG	;NUMBER OF DRIVE REGS ON THIS CONTROLLER
	PUSHJ	P,PEKSPY
	JUMPN	T1,MBSDEV	;IF NON-ZERO, MASSBUS DEVICE
DVELP1:	MOVSI	T1,.ESHDE_9
	PUSHJ	P,GDVERR	;LOG DEVICE ERROR
NXTDEV:	MOVEI	T1,UNISYS(P3)	;POINTER TO NEXT UNIT DATA BLOCK
	PUSHJ	P,PEKSPY
	AOBJN	P1,DVELUP	;LOOP IF MORE TABLES FOR CHECKING
	JRST	DALOKJ		;GO LOOK AT JOBS NEEDING SERVICE

MBSDEV:	MOVE	T2,T1		;SAVE NUMBER OF REGS IN T2
	MOVSI	T1,.ESMDE_9	;AND ENTRY CODE IN T1
	PUSHJ	P,GMDVER	;AND GO REPORT ERROR
	JRST	NXTDEV		;AND LOOP FOR NEXT DEVICE

>;END UNITN COND

;;ROUTINES TO SET UP FOR CALL TO ROUTINE TO PUT ACTUAL ENTRY INTO ERROR
; FILE
;ALL HAVE SAME CALLING SEQUENCE
;ARGS:	T2 -- CODE FOR ERROR SYS ENTRY
;	T1 -- ADDRESS OF BLOCK RETURNED BY ERRPT. UUO
;RETURNS CPOPJ, NO AC'S PRESERVED


;THIS CODE MOVED HERE [550]

SRLERR:	MOVSI	T1,.ESWHY_9	;CODE FOR WHY RELOAD
	PUSHJ	P,ERRINI	;(0-2) STORE HEADER, SETUP P4 AND CLEAR BUFFER
	MOVE	T2,[%CNFG0]	;5 WORDS OF SYSTEM NAME, 2 DATE
	SUB	T2,[%CNDT1+<1,,0>]
	HLR	T2,[%CNFG0]
CNFLUP:	MOVEI	T1,.GTCNF	;FROM CNFTBL
	HRLI	T1,(T2)
	PUSHJ	P,GTBSPY	;PICK UP NEXT WORD
	  SETZ	T1,		;HIGHLY UNLIKELY
	PUSH	P4,T1		;(3-11) SYSTEM NAME AND DATE
	AOBJN	T2,CNFLUP	;GET IT ALL
	MOVE	T1,[%CNSTS]
	PUSHJ	P,GTBSPY	;STATES WORD
	  SETZ	T1,
	PUSH	P4,T1		;(12) STATES WORD
;**;[545] DELETE	MOVE	T1,[%CNVER]
;**;[545] DELETE	PUSHJ	P,GTBSPY	;MONITOR VERSION
;**;[545] DELETE	  SETZ	T1,
;**;[545] DELETE	PUSH	P4,T1		;(13) MON VER
	PUSH	P4,MONVER	;[545] MONITOR VERSION
	MOVE	T1,[%CNSER]
	PUSHJ	P,GTBSPY	;CPU 0 SERIAL NUMBER
	  SETZ	T1,
	PUSH	P4,T1		;(14) SERIAL NUMBER
	MOVE	T1,[%CNWHY]
	PUSHJ	P,GTBSPY	;GET WHY RELOAD CODE IN SIXBIT
	  JRST	WHYOUT		;? VERY STRANGE
	JUMPE	T1,WHYOUT	;0 MEANS FTWHY OFF
	PUSH	P4,T1		;(15) ELSE SAVE THE ANSWER
	AOBJN	P4,.+1		;(16) LEAVE SPACE FOR POINTER WORD
EW%COM==17			;[EDIT 466(RLD)]RELATIVE LOC'N OF POINTER WORD
	SKIPGE	NXMLEN		;IF NXMLEN LE 0, NO NXMTAB
	JRST	WHYLUP		;JUST WRITE REST OF ENTRY
	HRRZ	T1,BLKPAG	;GET SHIFT COUNTER FOR WAP ALLOCATION
	TRC	T1,3		;TURN IT INTO FLAG WHICH SAYS 1 FOR P AND 0 FOR K
	HRLI	T1,707070	;ADD A STRANGE CODE FOR SYSERR TO RECOGNIZE THIS WORD
	PUSH	P4,T1		;AND SAVE IN ERROR BUFFER
	MOVN	T1,NXMLEN	;GET NEGATIVE LENGTH OF NXMTAB
	HRLZS	T1		;IN LH OF T1
	PUSH	P4,T1		;SAVE THAT - RIGHT HALF WILL BE SET UP LATER
EW%NPT==21		;OFFSET FOR POINTER TO NXMTAB IN ENTRY
	SETZ	T2,		;START AT FIRST WORD
WHYLUP:	MOVEI	T1,.GTWHY	;GETTAB FOR WHY-RELOAD COMMENTS IN ASCIZ
	HRLI	T1,(T2)		;DESIRED WORD THEREOF
	PUSHJ	P,GTBSPY	;GET IT
	  JRST	WHYCLS		;MUST NOT BE ONE
	JUMPE	T1,WHYCLS	;STOP AT END OF STRING
	PUSH	P4,T1		;SAVE 5 CHARACTERS
	AOJA	T2,WHYLUP	;GO FOR NEXT WORD
WHYCLS:	MOVEI	T1,ERABUF+EW%NPT
	SUBI	T1,(P4)		;NEG LENGTH OF COMMENTS
;**;[536] DELETE	JUMPN	T1,.+2		;IF ANY, STORE POINTER
;**;[536] DELETE	JRST	WHYOUT		;BUT IF NONE, BACK UP END POINTER
	JUMPE	T1,WHYOUT	;[536] IF NONE, BACK UP END PTR
	HRLI	T1,EW%NPT+1	;(SWAPPED) AOBJN POINTER TO COMMENTS
	MOVSM	T1,ERABUF+EW%COM
WHYOUT:	MOVEI	T1,1(P4)		;GET CURRENT LOC IN BUFFER
	SUBI	T1,ERABUF	;MAKE IT RELATIVE
	HRRM	T1,ERABUF+EW%NPT	;SAVE AS RIGHT HALF OF POINTER
	HLLZ	T2,ERABUF+EW%NPT	;GET BACK NEG LENGTH
	HRR	T2,NXMTAB	;AND GET POINTER TO TABLE
	PUSH	P4,(T2)		;PUSH WORD OF NXMTAB INTO BUFFER
	AOBJN	T2,.-1		;STEP TO NEXT WORD
	PJRST	ERRFIN	;CLOSE THE ERROR FILE
;STILL IN  IFN FTERR AND IFGE FTSAVE

;ROUTINE TO REPORT DISK AND MASSBUS ERRORS, CODES 10 AND 11
SDVERR:	PUSHJ	P,PROTJB	;[544] PROTECT JOB FROM DAEMON CRASH
;**;[544] DELETE	LDB	J,[POINT 9,(T1),26]	;SET UP JOB NUMBER
	HRRZ	P3,1(T1)	;GET UDB ADDR INTO P3 FOR GIVE ROUTINE
	HLRZ	P2,1(T1)	;ADDR OF DDB INTO P2 
;**;[544]	JUMPE	P2,JOBFIN	;IF NO DDB, EXIT
;**;[544]	JUMPE	P3,JOBFIN	;LIKEWISE IF NO UDB
	JUMPE	P2,CPOPJ	;[544] IF NO DDB, EXIT
	JUMPE	P3,CPOPJ	;[544] LIKEWISE IF NO UDB
	MOVEI	T1,UNIKON(P3)	;ADDRESS OF KONTROLLER DATA BLOCK
	PUSHJ	P,PEKSPY
	ADD	T1,KONREG	;NUMBER OF DRIVE REGS ON THIS CONTROLLER
	PUSHJ	P,PEKSPY
	MOVE	T3,T1		;PUT NUMBER OF REGS INTO T3
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT CODE INTO T1
	JUMPN	T3,SMDVER	;IF NUMBER OF REGS=0, CODE 10
	PUSHJ	P,GDVERR	;GO LOG ERROR
	JRST	DCHNCK		;GO CHECK FOR CHANNEL ERROR
SMDVER:	ADDI	T2,1		;CHANGE CODE 10 TO CODE 11
	DPB	T2,[POINT 9,T1,8]	;AND PUT IT IN T1
	MOVE	T2,T3		;PUT NUMBER OF REGS INTO T2
	PUSHJ	P,GMDVER	;AND GO REPORT ERROR
DCHNCK:	MOVEI	T1,UNICHN(P3)	;GET POINTER TO CDB
	PUSHJ	P,PEKSPY
	PJRST	CHNERR		;[544] GO REPORT CHANNEL ERROR IF ONE EXISTS
;**;[544] DELETE @STPERR-2	PUSHJ	P,CHNERR	;GO REPORT CHANNEL ERROR IF ONE EXISTS
;**;[544] DELETE	PJRST	JOBFIN		;AN DLET JOB CONTINUE

;ROUTINE TO REPORT TAPE ERRORS, CODE 21 AND TAPE STATS, CODE 41
STPERR:	PUSHJ	P,PROTJB	;[544] ASSURE JOB WILL BE FREED FROM ^D
;**;[544] DELETE	LDB	J,[POINT 9,(T1),26]	;SET UP JOB NUMBER
	HLRZ	P3,1(T1)		;GET DDB ADDR IN P3
	HRRZ	P4,1(T1)		;MAKE P4 A POINTER TO THE TUB
	MOVE	T1,[%CNMER]		;GETTAB FOR MAGTAPE INFO
	PUSHJ	P,GTBSPY
	  JRST	CPOPJ		;OOPS
	HLRZ	P2,T1		;GET OFFSET  OFTUBRID IN RH OF P2
	ADDI	P4,(P2)		;AND MAKE P4 POINTER TO CURR. TUBRID
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT ERROR CODE IN T1
	CAIN	T2,.ESTPS	;IS THIS MAG TAPE STATS?
;**;[544] @STPERR+13 DELETE	JRST	STPSTS		;YES, RECORD THEM
	PJRST	GTPSTU		;[544] YES, RECORD THEM
	PUSHJ	P,GTPERR	;GO REPORT TAPE ERROR
	SUB	P4,P2		;CONVERT P4 BACK TO POINTER TO TUB
	MOVEI	T1,TUBKDB(P4)	;GET POINTER TO KDB
	PUSHJ	P,PEKSPY
	MOVEI	T1,TKBCDB(T1)		;NOW GET POINTER TO CHANNEL DATA BLOCK
	PUSHJ	P,PEKSPY
;**;[544] @STPSTS-3 DELETE	JUMPE	T1,JOBFIN	;IF NO CDB, TM10A, SO EXIT NOW
	JUMPE	T1,CPOPJ	;[544] IF NO CDB, TM10A, SO EXIT NOW
;**;[544] DELETE		PUSHJ	P,CHNERR	;CHECK AND REPORT ERROR
;**;[544] DELETE		SKIPA
;**;[544] DELETE	STPSTS:	PUSHJ	P,GTPSTS	;GO REPORT MAG TAPE STATISTICS
;**;[544] DELETE		PJRST	JOBFIN		;AND LET JOB CONTINUE
	PJRST	CHNERR		;[544] CHECK AND REPORT ERROR

;STILL IN IFN FTERR AND IFGE FTSAVE
;ROUTINE TO REPORT DEBUG DUMP, CODE 17
;JUST LIKE SDLERR BUT SEPERATE CODE FOR DEBUGGING USE

SDIERR:	PUSHJ	P,PROTJB	;[544] [550] MAKE SURE JOB WILL BE FREED
	HLRZ	T1,(T1)	;GET  POINTER TO AOBJN WORD INTO RH  OF T1
	PUSHJ	P,PEKSPY	;GET AOBJN WORD
	MOVE	P1,T1		;PUT IT INTO P1
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT CODE INTO T1
	PUSHJ	P,ERRINI	;INITIALIZE ERROR ENTRY
DLELP:	HRRZ	T1,P1		;GET POINTER  PART INTO T1
	PUSHJ	P,PEKSPY	;GET NEXT WORD
	PUSH	P4,T1		;AND SAVE IT IN BUFFER
	AOBJN	P1,DLELP	;STEP POINTER
	PJRST	ERRFIN		;[544] [550] ALL DONE, WRITE ENTRY AND CLOSE FILE


;ROUTINE TO REPORT DL10 ERRORS, CODE 50
SDLERR:	PUSHJ	P,PROTJB	;[544] MAKE SURE JOB WILL BE FREED
;**;[544] DELETE	LDB	J,[POINT 9,(T1),26]	;SET UP JOB NUMBER
	HLRZ	T1,(T1)	;GET  POINTER TO AOBJN WORD INTO RH  OF T1
	PUSHJ	P,PEKSPY	;GET AOBJN WORD
	MOVE	P1,T1		;PUT IT INTO P1
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT CODE INTO T1
	PUSHJ	P,ERRINI	;INITIALIZE ERROR ENTRY
DLELUP:	HRRZ	T1,P1		;GET POINTER  PART INTO T1
	PUSHJ	P,PEKSPY	;GET NEXT WORD
	PUSH	P4,T1		;AND SAVE IT IN BUFFER
	AOBJN	P1,DLELUP	;STEP POINTER
;**;[544] @DLELUP+4
	PJRST	ERRFIN		;[544] ALL DONE, WRITE ENTRY AND CLOSE FILE
;**;[544] DELETE	PUSHJ	P,ERRFIN	;ALL DONE, WRITE ENTRY AND CLOSE FILE
;**;[544] DELETE	JRST	JOBFIN

;HERE TO REPORT CONFIGURATION STATUS CHANGE, CODE = 15

SCSCER:	LDB	T3,[POINT 6,(T1),17]	;GET BYTE WHICH TELLS US WHAT CHANGE
	CAIL	T3,10			;MEMORY ON/OFFLINE?
	JRST	MEMOFL			;YES
	CAIN	T3,2			;EXCHANGE?
	JRST	XCHNGE			;YES
	HRRZ	P1,1(T1)		;ATT OR DET- GET UDB ADDR
	HLLZ	P2,(T1)			;AND GET COMMENT+COD INTO P2
	SETZ	T1,			;CLEAR T1
	DPB	T2,[POINT 9,T1,8]		;PUT ERROR CODE INTO T1
	PUSHJ	P,ERRINI		;AND CALL ERROR INITIALIZER
	MOVEI	T1,UNINAM(P1)			;GET UDB ADDR INTO T1
	PUSHJ	P,PEKSPY		;AND GET FIRST WORD (UNINAM)
	PUSH	P4,T1			;STOREIT AWAY FOR ERROR FILE
	PUSH	P4,[0]			;STORE SECOND NAME OF ZERO
	PUSH	P4,P2			;AND STORE COMMENTS+CODE
	PJRST	ERRFIN			;CLOSE ERROR FILE AND RETURN
XCHNGE:	HLRZ	P1,1(T1)		;GET FIRST UDB ADDR INTO P1
	HRRZ	P2,1(T1)		;AND SECOND UDB ADDR INTO P2
	HLLZ	P3,(T1)			;GET COMMENTS+CODE INTO P3
	SETZ	T1,			;NOW CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;AND PUT .ESCSC INTO T1
	PUSHJ	P,ERRINI		;INITIALIZE FOR ERROR
	MOVEI	T1,UNINAM(P1)			;ADDR OF FIRST UDB
	PUSHJ	P,PEKSPY		;PICK UP UNIT NAME
	PUSH	P4,T1			;AND PUT IT INTO ERROR BUFFER
	MOVEI	T1,UNINAM(P2)			;NOW SAME FOR SECOND UNIT
	PUSHJ	P,PEKSPY		;...
	PUSH	P4,T1			;...
	PUSH	P4,P3			;AND NOW COMMENTS+CODE
	PJRST	ERRFIN			;CLOSE FILE AND RETURN
MEMOFL:	HLLZ	P3,(T1)			;COMMENTS+CODE INTO P3
	SETZ	T1,			;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;AND PUT .ESCSC INTO T1
	PUSHJ	P,ERRINI		;INITIALIZE FOR ERROR
	MOVN	T1,NXMLEN		;GGET NEGATIVE LENGTH OF NXMTAB
	HRLZS	T1			;AND PUT IN LH FOR POINTER
	HRRI	T1,7			;AND OFFSET OF FIRST TABLE IN THIS ENTRY
	PUSH	P4,T1			;SAVE AS FIRST WORD
	ADD	T1,NXMLEN		;ADD LENGTH OF TABLE
	PUSH	P4,T1			;AND SAVE AS POINTER TO SECOND COPY
	HRRI	P3,BLKPAG		;GET SWAP SPACE ALLOC 
	TRC	P3,3			;AND TURN INTO FLAG FOR SYSERR
	PUSH	P4,P3			;COMMENTS+CODE
	MOVN	T1,NXMLEN		;GET LENGTH OF NXMTAB INTO T1
	HRLZS	T1			;SET UP AN AOBJN POINTER
	HRR	T1,NXMTAB		;TO NXMTAB
	PUSH	P4,(T1)			;PUSH A WORD ONTO THE BUFFER
	AOBJN	T1,.-1			;AND STEP TO NEXT WORD
	MOVE	T1,[%CNNXM]	;GETTAB POINTER TO NXMTAB
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;CAN'T HAPPEN
	MOVE	T3,T1		;USE T3 AS AOBJN POINTER
	MOVE	T2,NXMTAB	;AND T2 AS WHERE TO STORE
MOFLOP:	HRRZ	T1,T3	;GET CURRENT ADDR INTO T1
	PUSHJ	P,PEKSPY	;GO PICK IT UP FROM MONITOR
	MOVEM	T1,(T2)		;STASH IT AWAY
	PUSH	P4,(T2)		;PUT IT INTO ERROR BUFFER ALSO
	AOS	T2		;INCREMENT T2
	AOBJN	T3,MOFLOP	;INCREMENT T3 AND LOOP
	PJRST	ERRFIN			;CLOSE FILE AND RETURN

;STILL IN IFN FTERR AND IFGE FTSAVE
;HERE TO REPORT NXM ERROR - CODE 4 OR 67

SNXMER:	HLRZ	P3,(T1)		;GET CDB ADDR FOR CDB WITH ERROR
	PUSHJ	P,FNDCPU	;GOT FIND WHICH CPU ERROR WAS ON
	  POPJ	P,		;NOT ANY CPU, GIVE IT UP
CPNXM:	MOVMI	P2,(P1)		;GET CPU NUMBER
	LSH	P2,1		;DOUBLE IT
	PUSHJ	P,ISKL10	;IS THIS A KL10?
	  SKIPA			;NO
	MOVEI	T2,67		;FUDGE CODE FOR KL10 NXM
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT ERROR CODE INTO T1 FOR ERRINI
	PUSHJ	P,ERRINI	;INITIALIZE THE ERROR BUFFER
	MOVE	T1,[%CCPHY]	;PHYSICAL CPU NAME
	ADD	T1,P2		;IN THIS CPU'S CONSTANTS TABLE
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1		;(4)SAVE FOR ERROR FILE
	MOVE	T1,[%CVTNE]	;COUNT OF ERROR ON SWEEP OF CORE
	PUSHJ	P,GCPVAR	;(5)STASH IT
	MOVE	T1,[%CVSNE]	;(6)NOT REPRODUCIBLE ERROR COUNT
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVMPP]	;(7)PC AT TIME OF ERROR
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVNJA]	;(10)NUMBER OF JOBS AFFECTED BY THIS NXM
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVMNA]	;(11)FIRST BAD ADDR FROM SWEEP
	PUSHJ	P,GCPVAR
	MOVE	T3,[%CCNXT]	;GET POINTER TO NXM SUBTABLE
	ADD	T3,P2		;POINTER IS IN CONSTANTS TABLE
	MOVSI	T2,.GTC0V(P2)	;SUBTABLE IS IN VARIABLES TABLE
NXMSLP:	PUSHJ	P,GSUBTB	;GET AN ITEM FROM THE SUBTABLE
	  JRST	ENXSTB		;END OF THE SUBTABLE
	PUSH	P4,T1		;STICK IT IN THE BUFFER
	AOJA	T2,NXMSLP	;LOOP OVER ENTIRE SUBTABLE
ENXSTB:	HRRZ	T1,BLKPAG	;GET SWAP SPACE ALLOC
	TRC	T1,3		;CONVERT TO FLAG FOR SYSERR
	PUSH	P4,T1		;SAVE IT
	MOVN	T2,NXMLEN	;GET NEGTIVE LENGTH OF NXMTAB
	HRLZS	T2		;PUT IT IN LH OF T2 FOR POINTER
	PUSH	P4,T2		;SAVE AS POINTER TO FIRST COPY OF NXMTAB
	PUSH	P4,T2		;SAVE AS POINTER TO SECOND COPY OF NXMTAB
EN%BEF==23			;OFFSET OF FIRST POINTER TO NXMTAB
	AOBJN	P4,.+1		;(25)SPACE FOR BAD ADDRESS SUBTABLE
EN%BAT==25			;OFFSET FOR POINTER TO BAD ADDR SUBTABLE
	MOVE	T1,[%SYSPP]	;(26)GETTAB FOR PPN OF USER CRASHED BY NXM
	PUSHJ	P,GTBSPY	;GET IT
	  SETZ	T1,		;OOPS
	PUSH	P4,T1		;SAVE IT
	MOVE	T1,[%SYSPN]	;(27)PROGRAM NAME ON NXM
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	PUSHJ	P,KLCPU			;REPORT CONI APR, AND RDERA IF KL10
	MOVEI	T1,1(P4)		;GET CURRENT LOC IN BUFFER
	SUBI	T1,ERABUF	;MAKE IT RELATIVE
	HRRM	T1,ERABUF+EN%BEF	;SAVE AS RIGHT HALF OF POINTER
	HLLZ	T2,ERABUF+EN%BEF	;GET BACK NEG LENGTH
	HRR	T2,NXMTAB	;AND GET POINTER TO TABLE
	PUSH	P4,(T2)		;PUSH WORD OF NXMTAB INTO BUFFER
	AOBJN	T2,.-1		;STEP TO NEXT WORD
	MOVEI	T1,1(P4)		;GET CURRENT LOC OF BUFFER
	SUBI	T1,ERABUF	;MAKE IT RELATIVE
	HRRM	T1,ERABUF+EN%BEF+1	;SAVE IT AS RIGHT HALF OF POINTER
	MOVE	T1,[%CNNXM]	;GETTAB POINTER TO NXMTAB
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;CAN'T HAPPEN
	MOVE	T3,T1		;USE T3 AS AOBJN POINTER
	MOVE	T2,NXMTAB	;AND T2 AS WHERE TO STORE
NXELOP:	HRRZ	T1,T3	;GET CURRENT ADDR INTO T1
	PUSHJ	P,PEKSPY	;GO PICK IT UP FROM MONITOR
	MOVEM	T1,(T2)		;STASH IT AWAY
	PUSH	P4,(T2)		;PUT IT INTO ERROR BUFFER ALSO
	AOS	T2		;INCREMENT T2
	AOBJN	T3,NXELOP	;INCREMENT T3 AND LOOP
	MOVEI	T1,1(P4)	;GET CURRENT LOC IN BUFFER
	SUBI	T1,ERABUF		;MAKE IT RELATIVE
	HRRZM	T1,ERABUF+EN%BAT	;AND SAVE AS POINTER OFFSET
	MOVE	T3,[%CCNXT]	;SUBTABLE POINTER FOR NXM
	ADD	T3,P2		;IN THE CONSTANTS TABLE
	MOVSI	T2,.GTC0V(P2)	;THE SUBTABLE IS IN VARIABLES TABLE
	HRRI	T2,%CVNTS	;ITEM FOR # OF NXM'S FOUND ON SWEEP
	PUSHJ	P,GSUBTB	;GO GET IT
	  JRST	NBATNX	;NONE OF THIS IF NO POINTER
	JUMPE	T1,NBATNX	;OR IF POINTER IS ZERO
	MOVE	T4,T1		;GET COUNT INTO T4
	HLL	T3,[%CCMPT]	;LOOK IN BAT SUBTABLE NOW
	HLLZS	T2		;AND START AT ITEM 0
NBTSLP:	PUSHJ	P,GSUBTB	;GET A WORD
	  JRST	ENBTTB		;ALL DONE
	PUSH	P4,T1		;SAVE IT IN BUFFER
	AOJ	T2,		;STEP TO NEXT ENTRY
	SOJG	T4,NBTSLP	;LOOP BACK FOR NUMBER OF ENTRIES
ENBTTB:	MOVNI	T2,(T2)		;GET NEGATIVE NUMBER OF ITEMS STORED
	JUMPE	T2,NBATNX	;IF NONE, JUST FINISH
	HRLM	T2,ERABUF+EN%BAT	;SAVE THE COUNT
	PJRST	KLSBDG		;WRITE SBDIAG SUBTABLE IF KL10, THEN CLOSE ERROR FILE

NBATNX:	SETZM	ERABUF+EN%BAT	;CLEAR TEH POINTER
	PJRST	KLSBDG	;WRITE SBDIAG SUBTABLE, THEN CLOSE ERROR FILE
;HERE TO REPORT CPU PARITY ERROR - CODE 3 OR 61

SCPERR:	HLRZ	P3,(T1)		;GET CDB ADDR FOR CDB WITH ERROR
	PUSHJ	P,FNDCPU	;FIND CPU WHICH HAD ERROR
	  POPJ	P,		;NOT ANY CPU, GIVE IT UP
	MOVEI	P2,(P1)		;COPY CPU #
	LSH	P2,1		;DOUBLE IT
	PUSHJ	P,ISKL10	;IS THIS A KL10?
	  SKIPA			;NO
	MOVEI	T2,60		;YES, FUDGE CODE FOR KL10 PARITY INTERRUPT
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT ERROR CODE INTO T1 FOR ERRINI
	PJRST	GCPERR		;LOG THE ERROR

;HERE TO REPORT CONTINUABLE STOPCD - CODE =2
SCNSTD:	MOVSI	P1,-21		;NUMBER OF CRASH AC'S + CRASH PI
	HLR	P1,(T1)		;LOCATION SAVED AT IN MONITOR
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT ERROR CODE INTO T1
	PUSHJ	P,ERRINI	;AND INITIALIZE ERROR
	MOVE	T2,[%CNFG0]	;5 WORDS OF SYSTEM NAME, 2 DATE
	SUB	T2,[%CNDT1+<1,,0>]
	HLR	T2,[%CNFG0]
MONLUP:	MOVEI	T1,.GTCNF	;FROM CNFTBL
	HRLI	T1,(T2)
	PUSHJ	P,GTBSPY	;PICK UP A WORD
	  SETZ	T1,		;LETS HOPE NOT
	PUSH	P4,T1		;STASH IT AWAY
	AOBJN	T2,MONLUP	;GO GET NEXT WORD
	MOVE	T1,[%CNSER]	;GET CPU0 SERIAL NUMBER
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1			;SAVE IT
;**;[545] DELETE	MOVE	T1,[%CNVER]	;GET MONITOR VERSION NUMBER
;**;[545] DELETE	PUSHJ	P,GTBSPY
;**;[545] DELETE	  SETZ	T1,
;**;[545] DELETE	PUSH	P4,T1			;SAVE IT
	PUSH	P4,MONVER	;[545] SAVE MONITOR VERSION
	MOVE	T1,[%SYSPC]	;GET NAME OF LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1		;SAVE IT
	MOVE	T1,[%SYSJN]	;JOB # ON LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYSTN]	;TTY NAME ON LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYSPN]	;PROG NAME ON LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYSPP]	;PPN OF USER, LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYNDS]	;NUMBER OF DEBUG STOPCDS
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYNJS]	;NUMBER OF JOB STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
CACLUP:	MOVEI	T1,(P1)		;ADDRESS OF NEXT CRASH AC (OR PI STATUS)
	PUSHJ	P,PEKSPY
	PUSH	P4,T1
	AOBJN	P1,CACLUP		;NOW GO TO NEXT ONE
	PJRST	ERRFIN			;ALL DONE, CLOSE FILE AND RETURN

;STILL IN IFN FTERR AND IFGE FTSAVE
;SUBROUTINE TO LOOK FOR AND REPORT A CHANNEL ERROR
;ARGS	T1=ADDR OF CDB TO CHECK FOR ERROR
;DESTROYS P2,T1,T2
CHNERR:	HRRZ	P2,T1		;GET CDB ADDRESS INTO P2
	MOVSI	P1,-CHNN	;GET NUMBER OF CHANNELS WE HAVE TABLES FOR
	MOVE	T1,[%CNCHN]	;GETTAB START OF CDBS
	PUSHJ	P,GTBSPY
	  POPJ	P,		;OOPS??
CHNLUP:	HLRZS	T1		;MAKE T1 POINTER TO CHANNEL
	CAIN	P2,(T1)		;IS THIS THE ONE WE'RE LOOKING FOR?
	JRST	SCHERR		;YES, CHECK IT FOR ERRORS
	MOVEI	T1,.CHSYS(T1)	;GET LINK TO NEXT CDB IN SYSTEM
	PUSHJ	P,PEKSPY
	AOBJN	P1,CHNLUP	;AND LOOP TO SEE IF IT THE ONE WE'RE LOOKING FOR
	POPJ	P,		;COULDN'D FIND THIS CHANNEL
SCHERR:	MOVEI	T1,.CHMPE(P2)	;COUNT OF MEM PAR'S ON THIS CHAN
	PUSHJ	P,PEKSPY
	MOVE	T2,T1		;HOLD TO ACCUMULATE TOTAL CHAN ERR'S
	MOVEI	T1,.CHNXM(P2)	;COUNT OF NON-EX MEM'S
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,.CHDPE(P2)	;DEVICE PARITY ERRORS
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;TOTAL ERRORS DETECTED BY CHANNEL
	CAMN	T2,$CHERR(P1)	;COMPARE TO OLD TOTAL
	POPJ	P,		;SAME AS LAST TIME
	MOVEM	T2,$CHERR(P1)	;SAVE NEW VALUE
	MOVSI	T1,.ESCPE_9	;CODE FOR CHANNEL ERROR
;**;[544] @SKLTRP-1
	PJRST	GCHERR		;[544] RECORD IT
;**;[544] DELETE	PUSHJ	P,GCHERR	;RECORD IT
;**;[544] DELETE	POPJ	P,	;AND RETURN

;HERE TO REPORT KL10 DATA PARITY TRAP -- CODE 60

SKLTRP:	PUSHJ	P,PROTJB	;[544] MAKE SURE JOB IS FREED
	HLRZ	P3,(T1)		;GET CPU DATA BLOCK ADDR INTO P3
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8]	;PUT ERROR CODE INTO T1
	PUSHJ	P,ERRINI		;(0-3)WRITE ENTRY HEADER
	PUSHJ	P,FNDCPU	;GOT FIND WHICH CPU ERROR WAS ON
	  POPJ	P,		;NOT ANY CPU, GIVE IT UP
	MOVEI	P2,(P1)		;COPY CPU NUMBER 
	LSH	P2,1		;AND DOUBLE IT FOR GETTABS
	MOVE	T1,[%CVPFW]	;(4)PAGE FAIL WORD
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVTBD]	;(5)BAD DATA
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVTGD]	;(6)GOOD DATA
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVBPA]	;(7)BAD PHYSICAL ADDR
	PUSHJ	P,GCPVAR
ND	(%CVPTR,(XWD 103,56))
	MOVE	T1,[%CVPTR]	;(10)RETRY WORD
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVSPT]	;(11)NUMBER OF SOFT TRAPS
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVHPT]	;(12)NUMBER OF HARD TRAPS
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVPPC]	;(13)PC AT TIME OF TRAP
	PUSHJ	P,GCPVAR
;**;[544] SKLTRP+24. DELETE	PUSHJ	P,JOBFIN	;LET JOB CONTINUE
	PJRST	ERRFIN		;CLOSE FILE AND RETURN

;STILL IN IFN FTERR AND IFGE FTSAVE
;HERE TO REPORT FRONT END SUPPLIED KL CPU ERROR INFORMATION

KLEERR:	HLRZ	P1,(T1)		;GET ADDRESS OF FIRST ERROR BLOCK IN MONITOR
	PUSH	P,T2		;SAVE CODE ON STACK

KLEER1:	JUMPE	P1,KLEER4	;DONE IF ZERO
	MOVE	T1,[.DTERT,,T3]
	SETZ	T3,		;CPU NUMBER IS ZERO
	DTE.	T1,		;RESET THE TIMER SO THE KL ERROR DATA DOESN'T GO AWAY
	  JRST	KLEER4		;SORRY, IT'S ALREADY GONE.
	MOVE	T2,(P)		;GET CODE OFF STACK
	SETZ	T1,		;CLEAR T1
	DPB	T2,[POINT 9,T1,8] ;PUT CODE IN T1
	PUSHJ	P,ERRINI	;SETUP P4 (0-2)
	PUSH	P4,[-1]		;(3)JOB NUMBER
	PUSH	P4,[0]		;(4)DIRECTORY
	PUSH	P4,[0]		;(5)FRONT END SOFTWARE VERSION
	PUSH	P4,[0]		;(6)SIXBIT NAME OF PROGRAM (NONE)
	MOVEI	T1,.KEDEV(P1)	;GET ADDRESS IN BLOCK WHERE PROTOCOL DEVICE IS
	PUSHJ	P,PEKSPY	;GET THE DATA
	LDB	T2,KLEDEV	;GET PROTOCOL DEVICE CODE
	LDB	T3,KLEUNI	;AND UNIT NUMBER
	HRL	T2,T3		;UNIT#,,PROTOCOL DEVICE CODE
	PUSH	P4,T2		;(7)PROTOCOL DEVICE CODE
	LDB	T1,KLECNT	;GET SIZE OF ERROR DATA IN 8 BIT BYTES
	PUSH	P,T1		;SAVE FOR LATER
	ADDI	T1,^D36/^D8-1	;ROUND UP TO NEAREST 36 BIT WORD
	ASH	T1,-2		;CONVERT TO 36 BIT WORD COUNT
	MOVNS	T1		;GET MINUS COUNT
	HRLS	T1		;-COUNT,,
	HRRI	T1,FE.INF	;RELATIVE POINTER TO DATA
	PUSH	P4,T1		;(10)-LENGTH,,START OF DATA
	HLLZ	P3,T1		;GET -COUNT,,0 IN P3 FOR AOBJN LATER
	MOVEI	T1,.KECPU(P1)	;WORD WITH CPU, DTE, LINK
	PUSHJ	P,PEKSPY	;GET NEXT WORD IN T1
	LDB	T2,KLEDTN	;GET DTE NUMBER
	LDB	T3,KLECPN	;AND CPU NUMBER
	HRL	T2,T3		;CPU#,,DTE#
	PUSH	P4,T2		;(11)CPU#,,DTE#
	POP	P,T2		;GET SAVED COUNT OF 8 BIT DATA BYTES
	PUSH	P4,T2		;(12)COUNT OF 8 BIT DATA BYTES
	LDB	P2,KLELNK	;GET LINK ADDRESS
	JUMPE	P3,KLEER3	;GO IF NO DATA TO STORE
	HRRI	P3,.KEDAT(P1)	;GET ADDRESS OF DATA

KLEER2:	HRRZ	T1,P3		;GET ADDRESS IN MONITOR IN T1
	PUSHJ	P,PEKSPY	;GET THE DATA
	PUSH	P4,T1		;(12+N)SAVE THE DATA
	AOBJN	P3,KLEER2	;LOOP FOR ALL WORDS
KLEER3:	PUSHJ	P,ERRFIN	;OK, CLOSE OFF ENTRY
	MOVE	P1,P2		;GET NEW NEXT BLOCK
	JRST	KLEER1		;GO SEE IF THERE IS MORE
KLEER4:	MOVE	T1,[.DTERC,,T3]	;RELEASE THE ERROR CORE NOW
	SETZ	T3,		;CPU#,,0
	DTE.	T1,		;DO IT
	  JFCL			;GIVES NO ERROR RETURN
	POP	P,T1		;TAKE CODE OFF STACK
	POPJ	P,		;NO, RETURN


KLEDEV:	POINT	9,T1,8		;PROTOCOL DEVICE CODE
KLEUNI:	POINT	9,T1,17		;UNIT NUMBER
KLECNT:	POINT	18,T1,35	;COUNT OF 8 BIT BYTES
KLECPN:	POINT	9,T1,8		;CPU NUMBER
KLEDTN:	POINT	9,T1,17		;DTE NUMBER
KLELNK:	POINT	18,T1,35	;LINK TO NEXT BLOCK IF ANY

>	;END IFN FTERR
>	;END IFGE FTSAVE
SUBTTL LOOK FOR A JOB REQUIRING DAEMON SERVICE

DALOKJ:	IFN	FTIPCF,<	;**[73] [SYSTEM]INFO INTEGRATION
	PUSHJ	P,SCHINF	;CALL SCHEDULER OF [SYSTEM]INFO
>				;**[73] END OF EDIT 73
	HRRZ	J,HJOB		;J=HIGHEST JOB NUMBER IN SYSTEM
DALOO1:	TLZ	F,L.DUMP!L.SAVE!L.NHRL	;CLEAR DUMP FLAG AND SAVE FLAG
IFG	FTSAVE,<
	SKIPGE	@SAVWAT		;ALREADY WOKEN SAVER FOR THIS GUY?
	JRST	DALOO2		;YES, GO ON TO NEXT GUY
>;END IFG FTSAVE
	MOVEM	J,CURJOB	;SAVE LAST JOB EXAMINED FOR DEBUG
	HRROI	T1,.GTSTS
	PUSHJ	P,GTBSPY	;GET JBTSTS WORD FOR JOB
	  JRST	DALOO2		;CANT GET IT?
	TRNE	T1,JRDC		;SKIP IF DOESN'T WANT DAEMON SERVICE(FOR A COMMAND)
	JRST	DASERV		;DOES, GO PROCESS REQUEST
	MOVE	T2,NERRPT	;GET WORD WHICH SAYS WHETHER WE DO NEW ERROR REPORTING
	TRNE	T1,JDEP		;JOB WANT SERVICE FOR ERROR?
	JUMPE	T2,DASERV	;SERVICE IT IF OLD ERROR REPORTING
	LDB	T1,QUECOD	;GET CODE FOR DAEMON QUEUE
	CAMN	T1,DAQNAM	;SKIP IF NO IN DAEMON QUEUE
	JRST	UUSERV
DALOO2:	SOJG	J,DALOO1	;LOOP FOR ALL JOBS IN SYSTEM
	TLZE	F,L.ANY		;SKIP IF NO JOBS FOUND
	JRST	DALOOK		;DID SOMETHING, GO THROUGH AGAIN

IFN CHKFCT,<
	MOVE	T1,[%NSKTM]
	PUSHJ	P,GTBSPY	;CHECK FOR KSYS SOON
	  SETZ	T1,		;IF CAN'T GET IT, ASSUME NOT
	JUMPE	T1,.+2		;NO KSYS--CHECK FORCE BIT
	SOJLE	T1,.+2		;IF PAST, OR LESS THAN 1 MINUTE, FORCE
	TLZE	F,L.FORC	;SHOULD WE FORCE OUT THE FACT BUFFER?
	SKIPN	T1,FACTSZ	;YES, IF ANYTHING IN IT
	JRST	NXTWAK		;NO, OR NOTHING THERE
	HRLZI	P1,(T1)		;SIZE IN P1 LEFT
	HRRI	P1,FACTBF	;POINTER
	PUSHJ	P,APPEND	;GET RID OF IT
	JRST	DALOOK
NXTWAK:				;[64]
>;END OF CHKFCT COND
;HERE TO CHECK FOR EXPIRED CLOCK REQUESTS

IFN FTCLCK!ICLKRQ,<
	SKIPN	T2,NEXTUP	;[64]GET THE NEXT JOB TO WAKE
	JRST	ZZZ		;THERE WAS NONE
	MOVE	T1,[%NSUPT]
	PUSHJ	P,GTBSPY	;GET THE UPTIME
	  JRST	WAKJOB		;UNLIKELY, WE HOPE
	SUB	T2,T1		;GET THE DIFFERENCE
	JUMPLE	T2,WAKJOB	;WAKE ANY JOBS THAT NEED IT,
				; AND RESCAN FROM DALOOK
	IMUL	T2,MILJIF	;CONVERT TO MILLISECONDS
	TLNE	T2,-1		;IS LEFT HALF EMPTY?
	MOVEI	T2,-1		;NO, SET MAX SLEEP TIME
>;END FTCLCK!ICLKRQ COND

ZZZ:
IFE FTDET,<
	TLZE	F,L.STOP	;TEST (ONLY ONCE) FOR STOP COMMAND
	JRST	ZZZXIT		;WE GOT ONE, QUIT NOW
>; END FTDET COND
	MOVEI	T1,SLPCNT	;TIME TO SLEEP
	IFE	FTIPCF,<	;**[73] SLLEEP MORE WHENO [SYSTEM]INFO
	IFGE	FTSAVE,<	;DIFFERENT CONDITIONS IF SAVES ONLY
	HRLI	T2,(HB.RWJ!HB.RTL)	;ONLY MONITOR CAN WAKE US
>
IFL	FTSAVE,<
	HRLZI	T2,(HB.RWT!HB.RWP)	;ONLY OUR PPN CAN WAKE US IF SAVE
>>
	IFN	FTIPCF,<
	HRLI	T2,(HB.RWJ!HB.RTL!HB.IPC)	;WAKE ON IPCF ACTIVITY TOO
>				;**[73] END OF EDIT 73

	HIBER	T2,		;HIBERNATE
	  SLEEP	T1,		;ON SECOND THOUGHT SLEEP
	JRST	DALOOK		;NOW LOOK AGAIN

IFE FTDET,<
ZZZXIT:	PUSHJ	P,ATTCHK	;ARE WE ATTACHED?
	  JRST	.+2		;NO, DO NOT TYPE
	OUTSTR	[ASCIZ .DAEMON shutdown
.]
	EXIT	1,		;QUIT, BUT ALLOW RESTART
	JRST	DALOOK		;NOW CONTINUE
>;END FTDET COND
DAEREN:	SETZM	.JBINT		;DO NOT INTERCEPT EXIT(ESTOP2 CODE)
	MOVSI	T1,(SIXBIT /DAE/)	;**[103] MAKE NAME DAE
	SETNAM	T1,		;CHANGE THE NAME TO CHEAT THE SYSTEM
	RESET			;KILL PSI INTERRUPTS IF ANY
	IFN	FTIPCF!FTRSTR,<
	PUSHJ	P,ZAPRUN##	;FORGET THE HISTORY
	JFCL			;**[107] IGNORE FAILLURES
>
	IFN	FTIPCF,<
	JRST	INFREN##	;**[107] JRST IS CLEARLY A NO RETURN
				;STOP THE BEAST
>
	EXIT			;FORGET THE THING


;HERE TO PROCESS JOB ISSUING DAEMON UUO

;FOR DAEMON UUO'S:
;P1=USER LOCATION EXECT1=EXEC AC T1, AND CONTAINS FUNCTION REQUESTED
;P2=USER LOCATION EXECT2=EXEC AC T2, AND CONTAINS +LENGTH,ADDR OF ARGUMENT LIST

;DAEMON RETURNS BY STORING AN ERROR CODE (OR THE ORIGINAL CONTENTS OF EXECT2)
;IN EXECT1 (NOTE, T1), WHICH WILL BE PASSED BACK TO THE USER IN HIS
;CALLING REGISTER, AND 0 IN EXECT2 FOR A SUCCESSFUL (SKIP) RETURN,
;OR NON-ZERO IN EXECT2 FOR A NON-SKIP RETURN.

UUSERV:	TLO	F,L.ANY!L.UUO	;SOMETHING HAPPENED, A UUO
	MOVEI	T1,DETUSR	;NEW RESTART ADDRESS
	MOVEM	T1,INTADR
	SETZM	THSOFF		;OFFSET=0 FORLOW SEGMENT
	MOVSI	T1,.JBDA	;GET JOB DATA AREA
	MOVE	T2,J		;JOB NUMBER
	PUSHJ	P,GTUCOR	;GET JOB'S JOB DATA AREA
	MOVE	T1,EXECT1	;GET ADDRESS IN JOBDAT OF EXEC T1
	MOVE	P1,USRCOR(T1)	 ;EXEC AC T1=FUNCTION REQUESTED
	JUMPLE	P1,UUERR1	;- OR 0 IS ILLEGAL
	CAILE	P1,MAXFNC	;SKIP IF LEGAL FUNCTION
	JRST	UUERR1		;TOO BIG
	MOVE	P2,USRCOR+1(T1) ;P2=XWD
	MOVEM	P2,SAVXWD	;SAVE XWD
	JRST	@FNCADR-1(P1)	;CALL ROUTINE TO PROCESS REQUEST

FNCADR:
	EXP	DMPUUO		;.DCORE WRITE A DCORE FILE
	EXP	CLKUUO		;.CLOCK WAKE A JOB IN THE FUTURE
	EXP	FCTUUO		;.FACT APPEND TO FACT FILE
	EXP	UUERR1		;4 (.DMQUE) RESERVED FOR QUEUE FUNCTION
	EXP	EAPUUO		;5 (.DMERR) APPEND TO ERROR.SYS
	EXP	UUERR1		;6 (.DMCTL) ENABLE/DISABLE DAEMON FUNCTIONS
IFG	FTSAVE,<
	EXP	DONUUO		;7 FUNCTION FOR SAVER TO SAY DONE
>;END IFG FTSAVE
MAXFNC==.-FNCADR
IFL	FTSAVE,<
EAPUUO:CLKUUO:
FCTUUO:	TLZ	F,L.ANY!L.UUO	;WE HAVEN'T DONE ANYTHING YET
	JRST	NULEXT		;TAKE NULL EXIT FOR CLK AND FCT UUO FUNCTIONS
>
IFG	FTSAVE,<
;ROUTINE TO MAKE US LOOK AT JOB AGAIN WHEN SAVER SAYS ITS DONE
;UUO HAS JOB SAVER FINISHED AS ONLY ARG

DONUUO:	MOVE	T1,P2		;READ 2 WORDS AS POINTED TO BY P2
	PUSHJ	P,UADCHK	;CHECK THE ADDRESS
	  JRST	UUERR2		;INVALID-HOPE THIS ISN'T FROM SAVER
	PUSHJ	P,GTUCOR	;GO READ THEM
	EXCH	J,USRCOR+1	;GET JOB WE FINISHED
	SETZM	@SAVWAT		;AND SAY HE CAN REQUEST AGAIN
	MOVE	J,USRCOR+1	;AND RESTORE J
	JRST	UUOKX		;AND GIVE SAVER A GOOD RETURN
>;END IFG FTSAVE
;HERE FOR .DCORE FUNCTION
;CALL:
;	MOVE	AC,[XWD ARGLEN,ARGLST]
;	DAEMON	AC,
;	  ERROR RETURN
;	GOOD RETURN
;ARGLST:1	;.DCORE
;	DEVICE	;0 IMPLIES DSK
;	FILNAM	;0 IMPLIES NNNDAE WHERE NNN IS JOB # ISSUEING UUO
;	EXT	;0 IMPLIES TMP
;	PROT	;0 IMPLIES MONITOR DEFAULT
;	PPN	;OR POINTER TO PATH SPEC. 0 IMPLIES DEFAULT PATH.
;		;RESERVED FOR JOB # TO DUMP

DMPUUO:
IFG	FTSAVE,<
	TLZ	F,L.ANY!L.UUO	;WE DIDN'T REALLY DO ANYTHING
	JRST	WAKSAV		;GO WAKE THE SAVE PROGRAM
>
IFLE	FTSAVE,<
REPEAT 0,<			;I DON'T THINK THIS IS NEEDED (JSL)
	SETZM	USRCOR		;CLEAR RESULT
	MOVE	T3,[USRCOR,,USRCOR+1] ;BLT POINTER
	BLT	T3,USRCOR+5	;ZAP
>;END OF REPEAT 0 ON CLEARING USRCOR
	HRROI	T1,.GTSTS	;GET THIS GUY'S JOB STATUS
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;OOPS
	LDB	T1,QUECOD	;GET WAIT STATE CODE
	CAME	T1,DAQNAM	;IF NOT IN DAEMON QUEUE, FUNNY RACE
	JRST	NULEXT		;JUST FINISH QUIETLY
	MOVE	T1,P2		;T1=XWD
	TLNN	T1,-1		;WAS LENGTH GIVEN?
	HRLI	T1,1		;NO, DEFAULT EVERYTHING
	HLRZ	T2,T1		;COPY NUMBER OF ARGUMENTS
	CAILE	T2,6		;MORE THAN 6 ARGUMENTS
	JRST	UUERR3		;YES--WRONG NUMBER OF ARGS
	PUSHJ	P,UADCHK	;CHECK ADDRESS
	  JRST	UUERR2		;INVALID ADDRESS
	PUSHJ	P,GTUCOR	;COPY  HIM INTO ME
GOTSPC:	SKIPN	T1,USRCOR+1	;GET DEVICE NAME
	MOVSI	T1,'DSK'	;NONE--USE DSK:
	MOVEM	T1,D.DEV	;STORE AWAY
	SKIPE	T4,USRCOR+2	;GET FILE NAME
	JRST	WASFNM		;THER WAS ONE SO DO NOT REINVENT
	MOVEI	T2,(J)		;JOB NUMBER
	PUSHJ	P,MAKPJN	;MAKE CCL NUMBER
	HRRI	T4,'DAE'	;DEFAULT FILENAME
WASFNM:	MOVEM	T4,D.NAM	;STORE FILENAME
	SKIPN	T1,USRCOR+3	;GET EXTENSION
	MOVSI	T1,'TMP'	;DEFAULT EXTENSION
	MOVEM	T1,D.EXT	;STORE EXTENSION
	LDB	T1,[POINT 9,USRCOR+4,8] ;GET PROTECTION
	MOVEM	T1,D.PROT		;STORE PROTECTION
	SKIPE	T1,USRCOR+5	;GET PPN
	JRST	CHKPTH		;HANDLE PATH OR PPN
	PUSHJ	P,GETPTH	;READ USER'S DEFAULT PATH
	JRST	STOPPN		;STORE THE PPN

;STILL IN IFLE FTSAVE
CHKPTH:	TLNE	T1,-1		;IS THIS A PATH POINTER, OR A PPN?
	JRST	STOPPN		;PPN, STORE IT DIRECTLY
	ADDI	T1,2		;PATH POINTER, IGNORE FIRST 2 WORDS
	HRLI	T1,DPTHLN-2	;READ UP TO MAX LENGTH
	PUSHJ	P,UADCHK	;VALIDATE PATH ADDRESS
	  JRST	UUERR2		;BOMB NOW
	PUSHJ	P,GTUCOR	;READ PATH SPEC
	MOVSI	T1,-DPTHLN+2	;READ THIS MANY WORDS
CPYPTH:	SKIPN	T2,USRCOR(T1)	;PICK NEXT WORD OF PATH SPEC
	JRST	ENDPTH		;ZERO MARKS END
	MOVEM	T2,D.DPTH+2(T1)	;STORE FOR OUR PURPOSES
	AOBJN	T1,CPYPTH	;COPY MORE IF WE HAVE ROOM
	JRST	UUER10		;NOTE INVALID PATH TO USER

ENDPTH:	SETZM	D.DPTH+2(T1)	;FLAG END OF PATH
	MOVEI	T1,D.DPTH	;SETUP DIRECTORY POINTER
STOPPN:	MOVEM	T1,D.DIR	;STORE DIRECTORY

;HERE CHECK PRIVILEGES IF JOB # TO DUMP SPECIFIED

	JRST	NODEFT		;DUMP. NO NEED TO SETUP DEFAULTS

>	;END IFLE FTSAVE
;HERE FOR .CLOCK FUNCTION
;CALL:
;	MOVE	AC,[XWD ARGLEN,ARGLST]
;	DAEMON	AC,
;	  ERROR RETURN
;	GOOD RETURN
;ARGLST:2	;.CLOCK
;	# SECS BEFORE WAKE ;OVERRIDES ANY PENDING REQUEST, 
;			; 0 IMPLIES IMMEDIATE WAKE

IFN FTCLCK,<

CLKUUO:	MOVE	T1,P2		;T1=XWD
	TLNN	T1,-1		;LENGTH GIVEN?
	HRLI	T1,2		;NO, DEFAULT TO 2
	HLRZ	T2,T1		;COPY THE LENGTH
	CAILE	T2,2		;NEED 2 ARGS, 0 IMPLIES 2
	JRST	UUERR3		;WRONG NUMBER OF ARGUMENTS
	PUSHJ	P,UADCHK	;CHECK THE ADDRESS
	  JRST	UUERR2		;ADDRESS CHECK
	PUSHJ	P,GTUCOR	;READ HIS CORE IMAGE
	MOVE	T1,USRCOR+1	;GET THE TIME
	PUSHJ	P,CLKREQ	;PUT IN QUEUE
	JRST	UUOKX		;EXIT

>;END FTCLCK COND
;HERE FOR .FACT FUNCTION
IFG FTFACT,<

FCTUUO:
IFE FTDET,<
	TLNE	F,L.FACT	;IS FACT SUPPRESSED?
	JRST	UUOKX		;YES, GIVE GOOD RETURN, BUT DO NOTHING
>;END FTDET COND
	HRROI	T1,.GTSTS	;GET JOB'S STATUS
	PUSHJ	P,GTBSPY	;GO READ THE MONITOR
	  JRST	UUERR4		;YOU CAN'T WIN THEM ALL
	TLNE	T1,JACCT	;LOGIN OR LOGOUT
	JRST	GTFACT		;YES--WIN
	PUSHJ	P,GETPPN	;GET CALLER'S PPN
	CAME	T1,OPRPPN	;ARE YOU A GOOD GUY?
	JRST	UUERR6		;NO--GET LOST
GTFACT:	PUSHJ	P,BUFAGE	;MARK TIME OF FIRST FACT ENTRY
	MOVE	T1,P2		;PICK UP XWD
	TLNN	T1,-1		;WAS LENGTH GIVEN?
	HRLI	T1,1		;NO, DEFAULT TO TEST NOP
	PUSHJ	P,UADCHK	;VALIDATE THE BLOCK AND SET UP FOR GTUCOR
	  JRST	UUERR2		;INVALID
	HLRZ	T4,T1		;COPY LENGTH
	SOJL	T4,UUERR3	;TOO SHORT
	CAILE	T4,TRNSIZ	;TOO LONG
	JRST	UUERR3		;YES--WRONG NUMBER OF ARGS
	JUMPE	T4,UUOKX	;ALLOW A 0-LENGTH WRITE, AS A TEST NOP UUO
	HRL	T1,T4		;PUT BACK NEW LENGTH
	AOJ	T1,		;BUMP POINTER PAST FUNCTION
	PUSHJ	P,GTUCOR	;GET USER'S ARGUMENT LIST=FACT FILE ENTRY IN USRCOR
	SKIPE	USRCOR+2	;DID USER PROVIDE DATE AND TIME?
	JRST	GTFHED		;[63]YES, DO NOT RE-SPECIFY
	MOVSI	T1,(1B8)	;[63]GET FORMAT BIT
	TDNN	T1,USRCOR	;[63]NEW OR OLD FORMAT?
	JRST	GTFODT		;[63]OLD FORMAT
	PUSHJ	P,NBSDAT	;[63]NEW FORMAT
	SKIPA			;[63]
GTFODT:	PUSHJ	P,ODATIM	;[63]GET TIME IN OLD FACT FILE FORMAT
	MOVEM	T1,USRCOR+2	;AND INSERT IT IN BUFFER
GTFHED:	HLRZ	T1,P2		;[63]GET LENGTH OF ARG LIST
	MOVE	T2,USRCOR	;PICK UP HEADER WORD FOR VALIDITY CHECKING
	TLZE	T2,777000	;CHECK FOR AND CLEAR TYPE IDENTIFIER
	TLZN	T2,777		;SAME FOR JOB #.  WERE BOTH GIVEN?
	JRST	UUERR7		;NO, REFUSE REQUEST
	ANDI	T2,77		;REMOVE LINE NO
	CAIE	T2,-1(T1)	;AND VERIFY LENGTH ACCURACY
	JRST	UUERR7		;REFUSE ON ANY SUCH ERROR
	HRRZ	T1,FACTSZ	;ADDR IN FACT FILE BUFFER TO STORE
	ADDB	T2,FACTSZ	;NEW SIZE OF BUFFER CONTENTS
	MOVEI	T1,FACTBF(T1)	;"TO" ADDR IN FACT FILE BUFFER
	HRLI	T1,USRCOR	;"FROM" IS CORE COPIED FROM CALLER
	BLT	T1,FACTBF-1(T2)	;TRANSFER TO FACT FILE BUFFER
	CAIG	T2,MAXFCT	;TOO MUCH IN BUFFER?
	JRST	UUOKX		;NO--GIVE OK RETURN
	HRLZI	P1,(T2)		;SIZE OF WHOLE MESS
	HRRI	P1,FACTBF	;POINTER TO BEGINING
	PUSHJ	P,APPEND	;UPDATE FACT.SYS
	JRST	UUOKX		;RETURN TO USER

>;END COND ON FTFACT
;HERE FOR APPEND TO ERROR.SYS FUNCTION
IFN FTERR,<

;CALL:
;	MOVE AC,[XWD ARGLEN,ARGLST]
;	DAEMON	AC,
;	  ERROR RETURN
;	GOOD RETURN
;ARGLST:5	;.DMERR
;	CODE		;CODE FOR ENTRY IN ERROR FILE
;	BODY		;BLOCK OF ARGLEN-2 WORDS TO PUT IN ERROR FILE

EAPUUO:	HRROI	T1,.GTSTS	;GET JOB'S STATUS
	PUSHJ	P,GTBSPY	;GO READ THE MONITOR
	  JRST	UUERR4		;YOU CAN'T WIN THEM ALL
	TLNE	T1,JACCT	;PRIVLEGED?
	JRST	EAPUU1		;YES--WIN
	PUSHJ	P,GETPPN	;GET CALLER'S PPN
	CAME	T1,OPRPPN	;ARE YOU A GOOD GUY?
	JRST	UUERR6		;NO--GET LOST
EAPUU1:	MOVE	T1,P2		;GET XWD INTO T1
;**;[533] FIX AT EAPUU1+1
	HLRE	T2,T1		;[533] GET LENGTH INTO T2
	JUMPLE	T2,UUERR3	;WRONG NUMBER  OF ARGS
;**;[533] INSERT AT EAPUU1+3
	CAIN	T2,1		;[533] ONLY 1 ARG (NULL ENTRY)?
	  JRST	UUOKX		;[533] YES, GOOD RETURN BUT DO NOTHING
	CAILE	T2,MAXUCR	;[533] ARG BIGGER THAN OUR BUFFER?
	  JRST	UUERR3		;[533] YES, WRONG NUMBER OF ARGS
	PUSHJ	P,UADCHK	;CHECK ADDRESS
	  JRST	UUERR2		;ILLEGAL ADDRESS
	PUSHJ	P,GTUCOR	;GO READ HIS CORE
	MOVE	T1,USRCOR+1	;GET CODE FOR ERROR FILE INTO T1
;**;[533] FIX AT EAPUU1+7
	LSH	T1,^D27		;[533] AND SHIFT IT TO GOOD PLACE
	PUSHJ	P,ERRINI	;GO PUT HEADER IN BUFFER
	HLRZ	T2,P2		;[533] RESTORE LENGTH OF ARG BLOCK
	SUBI	T2,2		;MAKE T2 NUMBER OF DATA WORDS OF ENTRY
	JUMPE	T2,EAPUU2	;[533] SKIP ON IF NO DATA
	HRLS	T2		;PUT IT INTO BOTH HALVES
	HRRZI	T1,1(P4)	;[533] GET FIRST WORD TO TRANSFER TO INTO  T1
	HRLI	T1,USRCOR+2	;AND FROM INTO LH
	ADD	P4,T2		;UPDATE PUSHDOWN PONTER TO ERROR BUFFER
	JUMPG	P4,UUERR3	;[533] CHECK FOR OVERFLOW OF IOWD
	BLT	T1,(P4)		;AND BLT STUFF TO BUFFER
EAPUU2:	PUSHJ	P,ERRFIN	;WRITE ENTRY AND CLOSE FILE
	JRST	UUOKX		;GIVE GOOD RETURN

>;END IFN FTERR
UUER10:	MOVEI	T1,DMPTH%	;INVALID PATH SPEC
	JRST	UUERRX

UUERR7:	MOVEI	T1,DMFFB%	;FACT FORMAT BAD
	JRST	UUERRX

UUERR6:	MOVEI	T1,DMNPV%	;NO PRIVS TO DO THAT UUO
	JRST	UUERRX		;EXIT

UUERR5:	MOVEI	T1,DMCWF%	;CAN'T WRITE FILE
	JRST	UUERRX		;EXIT

UUERR4:	MOVEI	T1,DMSNH%	;SHOULD NEVER HAPPEN
	JRST	UUERRX		; BUT...

UUERR3:	MOVEI	T1,DMWNA%	;WRONG NUMBER OF ARGS
	JRST	UUERRX

UUERR2:	MOVEI	T1,DMACK%	;ADDRESS CHECK
	JRST	UUERRX		;ERROR EXIT

IFGE	FTSAVE,<

IFE FTCLCK,<CLKUUO:	>
IFL FTFACT,<FCTUUO:	>

>
IFGE FTSAVE,<	

UUERR1:	MOVEI	T1,DMILF%	;ILLEGAL FUNCTION ERROR CODE
;	JRST	UUERRX

>	;END IFGE FTSAVE

IFL FTSAVE,<	;IF WE ONLY DO SAVES, JUST IGNORE ILLEGAL FUNCTIONS

UUERR1:	TLZ	F,L.UUO!L.ANY	;WE DIDN'T DO ANYTHING
	JRST	NULEXT		; SO JUST FINISH AND GO TO NEXT JOB

>	;END IFL FTSAVE

;HERE FOR DAEMON UUO ERRORS, T1=ERROR CODE

UUERRX:	SETOM	USRCOR+1	;NOTE ERROR IN FUNCTION
	MOVE	P,PDL		;RESTORE P, SINCE ERROR MAY HAVE BEEN
				;AT ANY LEVEL ON THE STACK
	JRST	UUEXIT		;AND EXIT UUO

;HERE WHEN FUNCTION COMPELETED PROPERLY, T1=RETURN CODE

IFGE	FTSAVE,<

IFE FTFACT,<FCTUUO:	>

>
UUOKX:	SETZM	USRCOR+1	;NOTE FUNCTION COMPLETED PROPERLY
	MOVE	T1,SAVXWD	;GET OLD CONTENTS OF USERS REG
UUEXIT:	MOVEM	T1,USRCOR	;STORE CODE TO RETURN TO USER
	MOVSI	T1,2		;WRITE 2 WORDS
	HRR	T1,EXECT1	;AT EXEC T1 IN USER'S JOBDAT
	MOVE	T2,J		;WRITE IN JOB'S LOW SEGMENT
	SETZM	THSOFF		;NO OFFSET
	AOSG	WTUERR		;CHECK FOR RECURSION IN EXIT PROCESS
	PUSHJ	P,WTUCOR	;WRITE USER'S CORE
	SETOM	WTUERR		;RESET FLAG
	JRST	DETUSR		;AND FINISH USER'S REQUEST
IFG	FTSAVE,<

;ROUTINE TO WAKE SEPARATE JOB FOR SAVE IF WE ARE RUNNING AS 2 JOBS

WAKSAV:	TLO	F,L.ANY		;SAY WE DID SOMETHING
	PUSH	P,J		;SAVE THE USER'S JOB
	MOVE	J,HJOB		;GET HIGHEST JOB IN SYSTEM
WAKSV1:	CAMN	J,THSJOB	;DON'T LOOK AT OURSELF
	SOJG	J,WAKSV1	;TRY NEXT JOB
	JUMPLE	J,NOSAVR	;QUIT IF LOOKED AT ALL JOBS
	HRROI	T1,.GTPRG	;GETTAB POINTER FOR (J) PROGRAM NAME
;**;[532] DELETE	HRLI	T1,(J)		;FOR THIS JOB
	PUSHJ	P,GTBSPY	;TRY TO GET IT
	  SETZ	T1,		;I HOPE NOT!!!
	CAME	T1,[SIXBIT/SAVER/]	;IS THIS WHO WE ARE LOOKING FOR?
	SOJA	J,WAKSV1	;GO TRY NEXT JOB
	HRLZI	T1,(J)	;[527] NOW SEE IF HE'S RUNNING WITH JACCT
	IFN .GTSTS,<HRRI T1,.GTSTS>
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;NOT OUR GUY
	TLNE	T1,JACCT	;DOES HE HAVE JACCT??
	TLNN	T1,RUN		;HE BETTER BE RUNNING ALSO!
	SOJA	J,WAKSV1	;CLOSE, BUT THIS GUY ISN'T IT
	WAKE	J,		;OK, WAKE HIM
	  JRST	EDCORE		;CAN'T WAKE HIM???
	POP	P,J		;FIX UP THE STACK
	SETOM	@SAVWAT		;IGNORE THIS JOB UNTIL SAVER SAYS DONE
	JRST	NULEXT		;ALL DONE, EXIT QUIETLY

;HERE IF NO SAVE PROGRAM FOUND -- ATTACH AND TELL USER

NOSAVR:	MOVEI	T1,DETUSR	;SET UP NEW
	MOVEM	T1,INTADR	; RESTART ADDRESS
	POP	P,J		;GET BACK THE JOB WE TRIED TO HELP
	TLZE	F,L.UUO		;IS THIS A UUO?
	JRST	DETUSR		;YES, DON'T CHANGE ANYTHING
	PUSHJ	P,GETTTY	;COMMAND, GET HIS TTY NUMBER
	  JRST	DETUSR		;CAN'T GET HIS LINE
	JUMPGE	T1,GOTLIN	;GO IF NOT CTY
	SKIPGE	T1,CTYLIN	;USE CTY LINE IF KNOWN
	JRST	DETUSR		;GIVE UP IF WE DON'T KNOW CTY LINE
GOTLIN:	HRLM	T1,LINE		;SAVE LINE FOR EXIT
	HRLOS	T1		;LH=LINE NO, RH=OURSELF(-1)
	ATTACH	T1,		;GO GET HIM
	  JRST	DETUSR		;CAN'T ATTACH, GIVE UP
	TLO	F,L.TTYA	;NOTE TTY ATTACHED
	MOVEI	T1,EDCORE	;NEW RESTART ADDRESS
	MOVEM	T1,INTADR	;
	OUTSTR	[ASCIZ .?SAVER NOT RUNNING
.]
	JRST	EDCORE		;NOW GIVE HIM BACK HIS TTY

>	;END IFG FTSAVE
SUBTTL PROCESS JOB REQUESTING DAEMON SERVICE

;HERE OUGHT TO RECORD STATUS OF JOB INTO ERROR.SYS IF JDEP SET

DASERV:	TLZ	F,L.UUO!L.UPMP	;NOT A UUO, NO UPMP IN CORE
IFGE	FTSAVE,<
	TRNE	T1,JDEP		;IF IN ERROR PAUSE,
	AOS	JDPCNT		;NOTE WE NOTICED
	TRNN	T1,JRDC		;IF NOT COMMAND REQUEST,
	JRST	EDUMP1		;RESTART THE JOB

>
IFG	FTSAVE,<
	JRST	WAKSAV	;GO WAKE SAVER
>

;HERE TO PROCESS COMMAND WHICH INVOKED DAEMON

IFLE	FTSAVE,<
	MOVEI	T1,DETUSR	;NEW RESTART ADDRESS
	MOVEM	T1,INTADR
	TLO	F,L.ANY		;NOTE THAT WE DID SOMETHING
	PUSHJ	P,GETTTY	;GET JOB'S TTY NUMBER
	  JRST	DETUSR		;CAN'T FIND IT
	JUMPGE	T1,HAVLIN	;GO UNLESS CTY
	SKIPGE	T1,CTYLIN	;GET CTY LINE NO IF KNOWN
	JRST	DETUSR		;OTHERWISE, MUST GIVE UP

HAVLIN:	HRLM	T1,LINE		;SAVE LINE NUMBER, IT MAY BE USEFUL

;HERE SHOULD CHECK FOR CTL/C IN JOB STATUS, DETUSR IF SET

	HRLOS	T1		;LH=LINE NUMBER, RH=DAEMON JOB
	ATTACH	T1,		;ATTACH USER TTY TO US
	  JRST	DETUSR		;GIVE UP IF CANT ATTACH USER'S TTY
	TLO	F,L.TTYA	;NOTE TTY ATTACHED
	MOVEI	T1,EDUMP	;NEW RESTART ADDRESS
	MOVEM	T1,INTADR

	HRROI	T1,.GTWCH	;WATCH BITS TABLE
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;FEATURE PROBABLY OFF
	TLNE	T1,(JW.WVR)	;IS VERSION WATCHING ENABLED?
	PUSHJ	P,PDAEVR	;YES, PRINT DAEMON VERSION

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE TO SET UP DEFAULTS FOR CORE-IMAGE FILE NAME

	MOVSI	T1,'DSK'	;DEVICE DSK
	MOVEM	T1,D.DEV
	MOVE	T2,J
	PUSHJ	P,MAKPJN	;COMPUTE SIXBIT JOB NUMBER IN LH
	MOVEM	T4,CCLFIL	;SAVE SIXBIT JOB NUMBER
	HRRI	T4,'DAE'	;NAME DAE
	MOVEM	T4,D.NAM	;IS FILE NAME
	MOVSI	T1,'TMP'	;EXTENSION
	MOVEM	T1,D.EXT
;**;[536] DELETE	SETZM	D.PROT		;DEFAULT PROTECTION IS STANDARD
;**;[536] INSERT AT NODEFT-2
	HRROI	T1,.GTDFL	;[536] GETTAB DEFAULT PROTECTION
	PUSHJ	P,GTBSPY	;[536] GET IT
	  SETZ	T1,		;[536] NOT IMPLEMENTED
	ROT	T1,^D9		;[536] MOVE PROTECTION TO LOW ORDER 9 BITS
	SKIPL	T1		;[536] CODE VALID IF BIT 9 SET
	  TRZ	T1,777		;[536] NOT VALID, USE DEFAULT
	HRRZM	T1,D.PROT	;[536] SAVE FOR LATER
	PUSHJ	P,GETPTH	;READ USER'S PATH
	MOVEM	T1,D.DIR	;STORE POINTER AS DIRECTORY

;HERE ON, CODE IS COMMON TO UUO AND COMMAND

NODEFT:	PUSHJ	P,GETPPN	;PICK UP USER'S PPN
	MOVEM	T1,USRPPN	;SAVE FOR ACCESS CHECKING

;HERE TO SET SEARCH LIST TO BE SAME AS USER'S JOB

	MOVE	T2,T1		;USER'S PPN
	MOVE	T1,J		;JOB NUMBER
	MOVEI	T3,USRLST+3	;SPACE RESERVED FOR USER'S SEARCH LIST
	PUSHJ	P,GETSRC	;GET USER'S SEARCH LIST
	HRRZS	T3		;LAST ADDRESS STORED IN
	MOVEI	T1,USRLST	;RE-GET USER LIST ADDRESS
	SUBI	T3,USRLST-1	;T3=LENGTH-1 OF LIST
	HRLI	T1,(T3)		;FUNCTION, ETC, ALREADY SET UP IN USRLST
	STRUUO	T1,		;SET OUR SEARCH LIST TO BE SAME AS USER'S
	  PUSHJ	P,E.USTR	;NOTE FAILURE OF STRUUO, TRY TO CONTINUE

;HERE TO INITIALIZE COMMAND SCANNER

;**;[536] DELETE AT INISCN-6	SETZ	SF,		;CLEAR SCANNER FLAGS
	TLNE	F,L.UUO		;IS THIS THE UUO
	JRST	DAEOPN		;YES--THEN AVOID SCANER
	PUSHJ	P,ATTCHK	;JUST MAKE SURE USER DIDN'T MANAGE TO DETACH
	  JRST	DAEOPN		;IF HE DID, ASSUME DCORE AND DON'T GO INTO TI WAIT
	MOVE	S1,[IOWD COMLEN,COMLST] ;TABLE OF MONITOR COMMANDS
INISCN:	PUSHJ	P,.ISCAN	;INITIALIZE COMMAND SCANNER
	JUMPL	S1,E.NCOM	;NOT A MONITOR COMMAND, GIVE ERROR
	JRST	@COMDSP(S1)	;DISPATCH

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE IF E COMMAND.  CALLED ONLY IF VIRTUAL MEMORY USER ON 6.01 AND LATER MONITORS

ECOM:;**;[535] DELETED	PUSHJ	P,SCNBRK	;FORCE SCAN TO END OF LINE (BREAK CHAR)
	JSP	T4,SAVE4	;SAVE P1-P4
	MOVE	T2,J		;GET JOB NUMBER INTO T2
	MOVSI	T1,1_WRDSPB	;SIZE OF BLOCK ON SWAPPING SPACE
	SETZM	THSOFF		;CLEAR OFFSET OF SEGMENT
	PUSHJ	P,GTUCOR	;GET JOB DATA AREA+
	MOVE	T1,[%CNEXM]
	PUSHJ	P,GTBSPY	;GET ADDRESS OF JOBEXM
	  JRST	EDUMP		;???
	HRRZ	P4,USRCOR(T1)	;GET ADDRESS TO EXAMINE(ALREADY UPDATED BY COMCON)
ECOM1:	PUSHJ	P,HSVADR	;GO GET START AND END ADDRESSES OF HIGHSEG
	SETZM	THSOFF		;CLEAR OFFSET IN CASE OF LOW SEG
	CAML	P4,HGHOFF	;ADDRESS BELOW START OF HIGH SEG?
	CAMLE	P4,HGHREL	;OR ABVE END OF HIGH SEG?
	JRST	ECOM2		;ADDRESS IS IN LOW SEG,WE'RE ALL SET
	MOVE	T1,HGHOFF	;NO, ADDRESS IS IN HIGH SEG
	MOVEM	T1,THSOFF	;STORE OFFSET FOR SEGMENT TO EXAMINE
	SUB	P4,THSOFF	;MAKE P4 RELATIVE TO BEGINNING OF SEGMENT
;**;[532] DELETED	MOVS	T1,J		;EXAMINE IS TO HIGH SEG
;**;[532] DELETED	HRRI	T1,.GTSGN	;JBTSGN
	HRROI	T1,.GTSGN	;[532] JBTSGN FOR JOB IN J
	PUSHJ	P,GTBSPY	;GET HIGH SEGMENT NUMBER
	  JFCL			;???
	SKIPA	T2,T1		;GET SEGMENT NUMBER TO T2
ECOM2:	MOVE	T2,J		;LOW SEGMENT, USE JOB NUMBER
	MOVSI	T1,1		;SET TO GET ONE WORD
	HRRI	T1,(P4)		;ADDRESS TO EXAMINE
	PUSHJ	P,GTUCOR	;GET THE WORD
	HRRZ	T1,P4		;GET ADDRESS TO EXAMINE
	PUSHJ	P,TOCTAL	;OUTPUT TO TTY
	OUTSTR	[ASCIZ */	*]
	HLRZ	T1,USRCOR	;GET LH TO TYPE
	PUSHJ	P,TOCTAL	;
	OUTSTR	[ASCIZ / /]	;PRINT A SPACE
	HRRZ	T1,USRCOR	;GET RH
	PUSHJ	P,TOCTAL	;OUTPUT
	PUSHJ	P,TABDOT	;TYPE A TAB AND A DOT
	JRST	EECOM		;AND EXIT

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE IF D COMMAND.  USED ONLY FOR VIRTUAL MEMORY JOBS IF 6.01 AND LATER MONITOR

DCOM:	JSP	T4,SAVE4	;SAVE P1-P4
	MOVE	T2,J		;GET JOB NUMBER INTO T2
	MOVSI	T1,1_WRDSPB	;GET SIZE OF DISK BLOCK
	SETZM	THSOFF		;CLEAR OFFSET OF SEGMENT
	PUSHJ	P,GTUCOR	;GET JOB DATA AREA+
;**;[536] DELETE FROM DCOM+5	PUSHJ	P,TYIA		;PRIME THE PUMP
	PUSHJ	P,OCTINW	;GET LH TO DEPOSIT
	MOVSI	P4,(SN)		;AND SAVE IN P4
	PUSHJ	P,OCTINW	;GET RH TO DEPOSIT
;**;[536] DELETED	PUSHJ	P,SCNBRK	;AND FORCE SCAN TO END OF LINE
	HRRI	P4,(SN)		;STORE IN RH(P4)
	PUSH	P,P4		;AND SAVE ON STACK
	MOVE	T1,[%CNEXM]
	PUSHJ	P,GTBSPY	;GET ADDRESS OF JOBEXM
	  JRST	EDUMP		;???
	HRRZ	P4,USRCOR(T1)	;GET ADDRESS TO DEPOSIT INTO
DCOM1:	PUSHJ	P,HSVADR	;SET UP START AND END OF HIGH SEG
	SETZM	THSOFF		;CLEAR OFFSET IN CASE LOW SEG
	CAML	P4,HGHOFF	;ADDRESS BELOW START OF HIGH SEG?
	CAMLE	P4,HGHREL	;OR ABOVE END OF HIGH SEG?
	JRST	DCOM2		;ADDRESS IS IN LOW SEG, WE'RE ALL SET
	MOVE	T1,HGHOFF	;GET OFFSET FOR HIGH SEG
	MOVEM	T1,THSOFF	;AND SAVE IT AS OFFSET FOR THIS SEGMENT
	SUB	P4,T1		;MAKE P4 RELATIVE TO START OF HIGH SEG
;**[532] DELETED	MOVS	T1,J		;DEPOSIT IS IN HIGH SEG
	HRROI	T1,.GTSGN	;[532] JBTSGN
	PUSHJ	P,GTBSPY	;GET HIGH SEGMENT NUMBER FOR JOB
	  JFCL			;???
	SKIPA	T2,T1		;GET INTO T2 FOR WTUCOR
DCOM2:	MOVE	T2,J		;JOB NUMBER FOR LOW SEGMENT
	MOVSI	T1,1		;SET TO WRITE ONE WORD
	HRRI	T1,(P4)		;ADDRESS TO WRITE TO T1
	POP	P,USRCOR	;GET CONTENTS OFF STACK
	PUSHJ	P,WTUCOR	;WRITE THE WORD
	JRST	EDCORE		;AND RETURN

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE ON VERSION COMMAND FOR HIGH SEGMENT THAT IS NOT IN CORE.  USED
;ONLY FOR VIRTUAL MEMORY JOBS ON 6.01 AND LATER MONITORS.

VERCOM:;**;[535] DELETED	PUSHJ	P,SCNBRK	;FORCE SCAN TO END OF LINE
	JSP	T4,SAVE4	;SAVE P1-P4
	MOVE	T2,J		;GET JOB NUMBER
	MOVSI	T1,1-WRDSPB	;SIZE OF DISK BLOCK
	SETZM	THSOFF		;SET UP TO LOOK AT LOW SEGMENT
	PUSHJ	P,GTUCOR	;GET JOB DATA AREA INTO CORE
	MOVE	P4,USRCOR+.JBVER ;GET LOW SEGMENT VERSION NUMBER INTO P4
	HRROI	T1,.GTPRG	;[532] PROGRAM NAME FOR JOB IN J
	PUSHJ	P,GTBSPY	;GET JBTNAM
	  JFCL			;???
	MOVE	P3,T1		;SAVE LOW SEGMENT VERSION NUMBER IN P3
;**[532] DELETED	MOVS	T1,J
	HRROI	T1,.GTSGN	;[532]
	PUSHJ	P,GTBSPY	;GET JOB'S HIGH SEGMENT NUMBER
	  JFCL			;???
	MOVE	P2,T1		;SAVE HIGH SEGMENT NUMBER IN P2
	PUSHJ	P,HSVADR	;GET RELOC/PROT FOR HIGH SEG
	MOVE	T1,HGHOFF	;GET ADDRESS OF START OF HIGH SEGMENT
	MOVEM	T1,THSOFF	;AND SAVE IN THSOFF
	MOVE	T1,HGHREL	;GET TOP ADDRESS OF HIGH SEGMENT
	MOVEM	T1,SEGREL	;AND SAVE
	MOVE	T2,P2		;GET SEGMENT NUMBER
	MOVSI	T1,1_WRDSPB	;GET SIZE OF DISK BLOCK
	PUSHJ	P,GTUCOR	;READ IN LOW 128 WORDS OF HIGH SEG
	MOVS	T1,P2		;GET HIGH SEG NUMBER
	HRRI	T1,.GTPRG	;JBTNAM
	PUSHJ	P,GTBSPY	;GET NAME OF HIGH SEG
	  JFCL			;???
	SKIPN	T2,T1		;WAS THERE ONE
	MOVEI	P1,USRCOR	;GET ADDRESS OF  BUFFER 
	MOVE	T2,.JBHNM(P1)	;NO, GET FROM USER'S CORE IMAGE
	SKIPE	T1,.JBHVR(P1)	;GET HIGH SEG VERSION
	CAMN	T1,P4		;COMPARE TO LOW IF PRESENT
	CAME	T2,P3		;COMPARE LOW NAME
	JRST	VERCM1		;DIFFERENT, MUST PRINT
	JRST	VERCM5		;SAME, JUST GET OUT

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE WHEN IT IS DETERMINED THAT WE MUST TYPE SOMETHING TO USER

VERCM1:	MOVE	P1,T1		;SAVE VERSION
	PUSHJ	P,TSIXN		;PRINT HIGH SEGMENT NAME
	OUTSTR	[ASCIZ / /]	;FOLLOWED BY A SPACE
	MOVE	T1,P1		;RESTORE VERSION
	LSH	T1,-^D24	;GET MAJOR VERSION NUMBER
	ANDI	T1,777		;ELIMINATE GARBAGE
	SKIPE	T1
	PUSHJ	P,TOCT		;PRINT MAJOR VERSION NUMBER
	HLRZ	T1,P1		;GET MINOR VERSION NUMBER
	ANDI	T1,77		;REMOVE GARBAGE
	JUMPE	T1,VERCM3	;JUMP IF NO MINOR 
	SUBI	T1,1
	IDIVI	T1,^D26
	JUMPE	T1,VERCM2
	PUSH	P,T2
	MOVEI	T3,"A"-1(T1)
	OUTCHR	T3
	POP	P,T2
VERCM2:	MOVEI	T3,"A"(T2)
	OUTCHR	T3
VERCM3:	HRRZ	T1,P1		;GET EDIT NUMBER
	JUMPE	T1,VERCM4	;NO EDIT NUMBER?
	OUTSTR	[ASCIZ /(/]	;PRINT LEFT PAREN
	PUSHJ	P,TOCT		;PRINT EDIT NUMBER
	OUTSTR	[ASCIZ /)/]	;PRINT RIGHT PAREN
VERCM4:	LSH	P1,-^D33	;GET CUSTOMER VERSION NUMBER
	JUMPE	P1,VERCM5	;IF NONE, CRLF.
	OUTSTR	[ASCIZ / - /]
	MOVEI	T3,"0"(P1)	;GET VERSION NUMBER
	OUTCHR	T3
VERCM5:	JRST	EDCORE		;AND EXIT
	
;STILL IN IFLE FTSAVE CONDITIONAL
;HERE IF DUMP COMMAND - REWRITE COMMAND AS DUMP CCL FILE
;NOTE: FILE MUST BE ON DSK, NOT TMPCOR, BECAUSE TMPCOR
; CANNOT COMMUNICATE ACROSS JOBS.

DUMP:	TLO	F,L.DUMP	;NOTE DUMP INSTEAD OF DCORE
	MOVE	T2,D.DEV
	SETZ	T1,
	MOVSI	T3,C.BH		;BUFFER HEADER
	OPEN	DSK,T1		;OPEN SAID FILE STRUCTURE
	  JRST	E.OPN		;CANT OPEN FILE STRUCTURE
	DEVPPN	T2,		;**[102] GET PPN OF DEVICE
	JRST	NOTDSK		;**[102] NO A DISK
	GETPPN	T1,		;**[102] GET USERS PPN
	JFCL			;**[102] IGNORE FAILLURE
	CAME	T1,T2		;**[102] IF PPN'S DIFFER THEN
	MOVEM	T2,D.DIR	;**[102] CHANGE THE DIRECTORY PPN
NOTDSK:	MOVE	T1,CCLFIL	;CCL NAME
	HRRI	T1,'DMP'	;FILE DMP
	MOVSI	T2,'TMP'	;EXT TMP
	SETZ	T3,
	MOVE	T4,D.DIR	;USER'S DIRECTORY
	PUSHJ	P,ACCCHK	;SEE IF USER ALLOWED TO WRITE THE STR
	  JRST	E.CCLP		;DONT HAVE PRIVILEGE TO WRITE
	ENTER	DSK,T1
	  JRST	E.DENT
	PUSH	P,.JBFF
	MOVEI	T1,SECBUF
	MOVEM	T1,.JBFF	;SET ADDR OF BUFFER FOR I/O
	OUTBUF	DSK,1
	POP	P,.JBFF
	JUMPL	SC,QUIKIE	;USE QUICKIE DUMP IF DUMP CR
CLOOP:	PUSHJ	P,TYIA		;GET NEXT CHAR FROM COMMAND
	JUMPL	SC,CDONE	;ALL DONE IF END OF LINE
	CAIN	SC,"/"		;SKIP IF NOT /
	JRST	CVSLSH		;CONVERT TO CRLF
	PUSHJ	P,CCOUT		;OUTPUT THE CHAR
	JRST	CLOOP		;AND LOOP

CVSLSH:	PUSHJ	P,CCCRLF	;OUTPUT CRLF INSTEAD OF /
	JRST	CLOOP

QUIKIE:	MOVE	T1,[POINT 7,QIKNAM]
QUIKI1:	ILDB	SC,T1		;NEXT CHARACTER OF NAME
	JUMPE	SC,CDONE
	PUSHJ	P,CCOUT		;OUTPUT CHARACTER
	JRST	QUIKI1

CDONE:	PUSHJ	P,CCCRLF	;END THE LAST LINE
;**;[536] DELETE	CLOSE	DSK,
;**;[535] DELETE AT CDONE+2	RELEAS	DSK,
	MOVEI	T1,DSK		;[535] SET UP CHANNEL
	PUSHJ	P,RELDSK	;[535] AND GO RELEASE IT
	JRST	DAEOPN		;GO WRITE DAEMON FILE

;STILL IN IFLE FTSAVE CONDITIONAL
;HERE IF SAVE OR SSAVE COMMAND.  CALLED ONLY IF VIRTUAL MEMORY
;USER ON 6.01 OR LATER MONITORS.

SAVE:;**;[536] DELETED	PUSHJ	P,SCNBRK	;FORCE SCAN TO END OF LINE
	TLO	F,L.SAVE	;NOTE SAVE IN PROGRESS
	JSP	T4,SAVE4	;SAVE P1-P4
	MOVE	T2,J		;GET JOB NUMBER INTO T2
	MOVSI	T1,MAXUCR	;FILL THE INPUT BUFFER
	SETZM	WRDCNT		;CLEAR COUNT OF OUTPUT FILE
	SETZM	REMBLK		;CLEAR REGISTER TO HOLD BLOCK FOR LAST IOWD
	SETZM	REMWRD		;LAST ADDRESS FOR IOWD
	SETZM	THSOFF		;CLEAR OFFSET FOR THIS SEGMENT
	PUSHJ	P,GTUCOR	;GET JOB DATA AREA +
	MOVEI	P1,USRCOR	;SET UP INDEX TO JOB DATA AREA
	MOVE	T1,.SGDEV(P1)	;GET DEVICE TO DO THE SAVE ON
	MOVEM	T1,D.DEV	;AND SAVE ON ARGUMENT LIST
	MOVE	T1,.SGNAM(P1)	;GET NAME OF SAVED FILE
	MOVEM	T1,D.NAM	;AND SAVE
;**;[536] DELETE FROM SAVE+16	SKIPN	T1,.SGPPN(P1)	;ANY USER SUPPLIED PPN?
;**;[536] DELETE FROM SAVE+17	PUSHJ	P,GETPPN	;NO, USE THE USER'S
	SKIPE	T1,.SGPPN(P1)	;[536] DON'T USE DEFAULT PATH IF USER GAVE PPN
	MOVEM	T1,D.DIR
	MOVE	P3,SGAHGH(P1)	;GET HIGH SEGMENT EXTENSION
	HLLZM	P3,D.EXT	;AND SAVE FOR HIGH SEGMENT SAVE
	MOVE	P4,.SGLOW(P1)	;SAVE LOW SEGMENT EXTENSION FOR LATER
;**;[532] DELETED	MOVS	T1,J		;GET JOB NUMBER
	HRROI	T1,.GTSGN	;[532] GETTAB INDEX TO JBTSGN
	PUSHJ	P,GTBSPY	;GET THE HIGH SEGMENT NUMBER FOR THIS JOB
	  JFCL			;???
	MOVE	P2,T1		;SAVE SEGMENT NUMBER FOR LATER
	PUSHJ	P,HSVADR	;GET RELOC/PROT FOR HIGH SEG
	JUMPLE	P2,SAVE04	;JUMP IF NO HIGH SEGMENT
	TLNE	P2,JSHR		;SHARABLE HIGH SEGMENT?
	JRST	SAVE01	;YES, DONT SAVE DATA FOR VESTIGIAL JOB DATA AREA
	MOVS	T1,P2		;NO, GET DATA FOR VESTIGIAL JOB DATA AREA
	HRRI	T1,.GTUPM	;INDEX TO JBTUPM
	PUSHJ	P,GTBSPY	;GET POINTER TO UPMP
	  JFCL			;???
	LDB	T2,[POINT 9,T1,8] ;GET JBYHSO BYTE
	PUSH	P,T2		;AND SAVE ON STACK
	PUSH	P,D.NAM		;SAVE .SGNAM
	PUSH	P,.JBVER(P1)	;SAVE VERSION NUMBER
	HRR	T2,.JBREN(P1)
	HLL	T2,.JBHRL(P1)
	PUSH	P,T2
	PUSH	P,.JBCOR(P1)
	PUSH	P,.JB41(P1)
	PUSH	P,.JBSA(P1)	;ALL DATA FOR VESTIGIAL JOB DATA AREA NOW SAVED

;STILL IN IFLE FTSAVE CONDITIONAL
SAVE01:	MOVE	T1,HGHOFF	;GET ADDRESS OF START OF HIGH SEGMENT
	MOVEM	T1,THSOFF	;AND STORE FOR CALL TO GTUCOR
	MOVE	T1,HGHREL	;GET LAST ADDRESS OF HIGH SEG
	HLRZ	T2,.JBHRL(P1)	;GET LENGTH OF HIGH SEG
	MOVEM	T1,SEGREL	;SAVE SIZE OF HIGH SEGMENT
	SKIPE	T2		;IF LH(.JBHRL)NON ZERO,
	MOVEM	T2,SEGREL	;THEN THATS WHAT WE USE
	SKIPN	T1		;IF LH(.JBHRL)=0,
	TLO	F,L.NHRL	; THEN REMEMBER FOR LATER
	MOVE	T2,P2		;GET SEGMENT NUMBER TO T2
	MOVSI	T1,MAXUCR	;SET UP TO GET FIRST BLOCK OF HIGH SEG INTO CORE
	PUSHJ	P,GTUCOR	;GET THE BLOCK
	TLNE	P2,JSHR		;SHARABLE HIGH SEGMENT??
	JRST	SAVE02		;YES, NO NEED TO SET UP VESTIGIAL JOB DATA AREA
	MOVEI	T1,USRCOR-1	;SET UP POINTER
	POP	P,T2		;GET BACK .JBSA
	PUSH	T1,T2		;AND STORE IN VESTIGIAL JOB DATA AREA
	POP	P,T2		;GET BACK .JB41
	PUSH	T1,T2		;AND STORE
	POP	P,T2		;GET .JBCOR
	PUSH	T1,T2
	POP	P,T2		;GET .JBREN & .JBHRL
	PUSH	T1,T2
	POP	P,T2		;GET .JBVER
	PUSH	T1,T2
	POP	P,T2		;GET .SGNAM
	PUSH	T1,T2
	AOBJN	T1,.+1
	PUSH	T1,[EXP 0]
	POP	P,T2		;GET BACK JBYHSO BYTE
	DPB	T2,[POINT 9,(T1),17] ;AND STORE
SAVE02:	JRST	DAEOPN		;AND GO OPEN HIGH SEGMENT SAVE FILE


;STILL IN IFLE FTSAVE CONDITIONAL
;HERE TO PROCESS DCORE COMMAND

DCORE:	JUMPL	SC,DAEOPN	;USE DCORE DEFAULTS IF NO NAME SPECIFIED
	PUSHJ	P,FILIN		;GET FILE NAME TO WRITE
	  JRST	EDCORE		;[536] COMMAND ERROR, FINISH UP
;**;[536] DELETE AT DCORE+3	SKIPE	T1,F.ZER+F.DEV	;SKIP IF NO DEVICE SPECIFIED
	SKIPE	T1,F.DEV##	;[536] SKIP IF NO DEVICE
	MOVEM	T1,D.DEV
;**;[536] DELETE	SKIPE	T1,F.ZER+F.NAM	;SKIP IF NO NAME SPECIFIED
	SKIPE	T1,F.NAM##	;[536] SKIP IF NO NAME SPECIFIED
	MOVEM	T1,D.NAM
	JUMPE	T1,DCORE1	;JUMP IF NO NAME SPECIFIED
	MOVSI	T1,'DAE'	;IF FILE NAME SPECIFIED, DEFAULT EXT IS DAE
	MOVEM	T1,D.EXT
DCORE1:;**;[536] DELETE	SKIPE	T1,F.ZER+F.EXT	;SKIP IF NO EXT SPECIFIED
	SKIPE	T1,F.EXT##	;[536] SKIP IF NO EXT SPECIFIED
	MOVEM	T1,D.EXT
;**;[536] DELETE	SKIPE	T1,F.ZER+F.DIR	;SKIP IF NO DIRECTORY SPECIFIED
	SKIPE	T1,F.DIR##	;SKIP IF NO DIRECTORY SPECIFIED
	MOVEM	T1,D.DIR
;**;[536] DELETE	SKIPE	T1,F.ZER+F.PROT	;SKIP IF NO PROTECTION SPECIFIED
;**;[536] DELETE	MOVEM	T1,D.PROT
;**;[535] DELETED	SCNEND:	JUMPL	SC,DAEOPN	;EXIT IF ALREADY TO BREAK CHAR
;**;[535] DELETED	PUSHJ	P,TYIA		;IGNORE REST OF LINE
;**;[535] DELETED	JUMPGE	SC,.-1

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL WRITE CORE-IMAGE FILE

;HERE TO OPEN CORE-IMAGE FILE

DAEOPN:	MOVE	T1,D.DEV	;DEVICE TO WRITE ON
	MOVE	T2,T1		;AND SAVE IN T2
	DEVCHR	T1,		;GET DEVICE CHARACTERISTICS
	TLNN	T1,(DV.DSK)	;SKIP IF IT IS A DISK
	JRST	E.NDSK		;CANT GO ON
	TLNE	T1,(DV.MTA)	;IS IT ALSO A MAG TAPE?
	JRST	[TLNE F,L.SAVE	;YES, MUST BE NULL
		 JRST SAVE10	;FINISH SAVE
		 TLNE F,L.DUMP	;DUMP OR DCORE?
		 JRST EDUMP	;FINISH DUMP
		 JRST EDCORE	;FINISH DCORE
		]
	MOVEI	T1,17		;USE DUMP MODE
	SETZB	T3,CURWRD	;START AT WORD 0
	OPEN	DSK,T1		;OPEN DEVICE
	  JRST	E.OPN		;CANT OPEN IT
	DEVPPN	T2,		;**[102] GET PPN OF DEVICE
	JRST	DAEOP0		;**[102] NO A DISK
	GETPPN	T1,		;**[102] GET USERS PPN
	JFCL			;**[102] IGNORE FAILLURE
	CAME	T1,T2		;**[102] IF PPN'S DIFFER THEN
	MOVEM	T2,D.DIR	;**[102] CHANGE THE DIRECTORY PPN
DAEOP0:	MOVEI	P1,5		;NUMBER OF TIMES TO RETRY IF FILE BEING MODIFIED
	MOVE	T1,D.NAM	;FILE NAME
	HLLZ	T2,D.EXT	;EXT
	HRLZ	T3,D.PROT	;PROTECTION
	LSH	T3,^D9
	MOVE	T4,D.DIR	;DIRECTORY TO WRITE IN
	PUSHJ	P,ACCCHK	;SEE IF USER IS ALLOWED TO WRITE THE FILE
	  JRST	E.DAEP		;DONT HAVE PRIVILEGES
RE1:	MOVE	T4,D.DIR	;DIRECTORY
	ENTER	DSK,T1		;CREATE THE FILE
	  JRST	E.F1		;CANT WRITE IT
	CLOSE	DSK,		;MAKE SURE FILE EXISTS FOR UPDATING
	MOVE	T4,D.DIR	;RESET THE PPN
	LOOKUP	DSK,T1		;LOOKUP
	  JRST	E.NOUL		;WHAT?
RE2:	MOVE	T4,D.DIR	;AND ONCE AGAIN FOR UPDATE ENTER
	ENTER	DSK,T1
	  JRST	E.F2		;SIGH
	SETZB	BP,CURBLK	;START AT FIRST BLOCK OF FILE
	MOVEI	T1,NOHGH1	;NEW RESTART ADDR
	MOVEM	T1,INTADR
	TLNE	F,L.SAVE	;SKIP IF NOT DOING A SAVE
	JRST	SAVE03		;ARE, CONTINUE

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL WRITE JOB INFORMATION

;HERE TO WRITE JOB INFORMATION

	MOVEI	T1,.CAJOB	;CATEGORY NUMBER FOR JOB INFORMATION
	PUSHJ	P,CATSTA	;START UP CATEGORY
	MOVE	T1,.JBVER	;(0)DAEMON VERSION NUMBER
	PUSHJ	P,DWRITE	;WRITE IT
	DATE	T1,		;(1)TODAY'S DATE
	PUSHJ	P,DWRITE	;WRITE THAT
	MSTIME	T1,		;(2)TIME OF DAY IN MILLISECONDS
	PUSHJ	P,DWRITE	;WRITE IT
	HRROI	T1,.GTSGN	;SEGMENT TABLE
	PUSHJ	P,GTBSPY	;GET HIGH SEGMENT NUMBER IF ANY
	  SETZ	T1,
	MOVE	S,T1		;SAVE SEGMENT NUMBER IN S
	HRL	T1,J		;(3)LH=JOB NUMBER, RH=SEGMENT NUMBER
	PUSHJ	P,DWRITE	;WRITE THAT
	HLRZ	T1,LINE		;(4)LH=RESERVED, RH=LINE NUMBER
	PUSHJ	P,DWRITE	;AND WRITE THAT

;HERE TO WRITE GETTAB ENTRIES FOR JOB

	SKIPL	P1,[-GTTBLN,,GTTABL] ;SKIP IF ANY GETTABS WANTED
	JRST	GTTBJE		;NO GETTABS DESIRED
GTTBLP:	HLRZ	T2,(P1)		;T2=INDEX INTO ROUTINE
	HRRZ	T1,(P1)		;T1=GETTAB TABLE
	PUSHJ	P,WGTBTH(T2)	;GET JOB OR SEGMENT OR BOTH
	AOBJN	P1,GTTBLP	;LOOP FOR GETTABS DESIRED

;HERE AFTER ALL GETTABS FOR JOB WRITTEN - WRITE SYSTEM GETTABS

GTTBJE:	PUSHJ	P,CATEND	;END OF JOB INFORMATION CATEGORY

;HERE TO WRITE CONFIGURATION TABLE

	MOVEI	T1,.CACNF	;BEGIN CONFIGURATION TABLE CATEGORY
	PUSHJ	P,CATSTA
	MOVEI	P1,.GTCNF
	PUSHJ	P,GTTBAL	;WRITE ALL OF TABLE
	PUSHJ	P,CATEND	;END OF CONFIGURATION CATEGORY

;HERE TO WRITE FEATURE TABLE

	MOVEI	T1,.CAFET	;BEGIN FEATURE TABLE CATEGORY
	PUSHJ	P,CATSTA	;INITIALIZE IT
	MOVEI	P1,.GTFET	;THE TABLE WE WANT
	PUSHJ	P,GTTBAL	;DUMP IT ALL
	PUSHJ	P,CATEND	;END OF CATEGORY

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL WRITE DDB'S FOR JOB

;THIS IS BAD--WE SHOULD LOOK AT JOB DEVICE ASSIGNMENT TABLE
;HERE TO WRITE DDB'S FOR JOB

	MOVE	T1,[%CNDEV]
	PUSHJ	P,GTBSPY	;GET PTR TO LIST OF DDB'S
	  JRST	EDDBS		;FORGET IT
	HLRZ	P1,T1		;SAVE IN P1
	MOVEI	T1,.CADDB	;CATEGORY NUMBER FOR DDB'S
	PUSHJ	P,CATSTA	;START UP THE CATEGORY

;HERE FOR NEXT DDB

DDBLOP:	MOVE	T1,P1		;GET ADDRESS OF DDB INTO T1
	PUSHJ	P,DDBJOB	;GET OWNER'S JOB NUMBER FROM DDB
	CAIE	T1,(J)		;SKIP IF USER'S JOB
	JRST	NXTDDB		;NO, SKIP IT

;HERE TO WRITE DDB

	MOVN	T2,LDDBSH	;[571] ASSUME SHORT DDB
	MOVEI	T1,DEVSTA(P1)	;[571] ADDRESS OF DEVSTA
	PUSHJ	P,PEKSPY	;[571] GET IT
	TLNE	T1,(DEPSPL)	;[571] IS IT SPOOLED DEVICE?
	MOVN	T2,LDDBDS	;[571] YES, REALLY A DISK
	MOVEI	T1,DEVMOD(P1)	;[571] GET DEVMOD WORD
	PUSHJ	P,PEKSPY	;[571]     FROM DDB
	TLNE	T1,(DV.LNG)	;[571] LONG DDB?
	MOVN	T2,LDDBLN	;[571] YES.
	TLNE	T1,(DV.DSK)	;[571] DISK DDB?
	MOVN	T2,LDDBDS	;[571] YES
DDBWRT:	HRLI	P1,(T2)		;P1=-LENGTH,ADDR
	PUSHJ	P,WRTDDB	;WRITE OUT THE DDB

;HERE TO FIND NEXT DDB

NXTDDB:	MOVEI	T1,DEVSER(P1)	;ADDR OF PTR TO NEXT DDB
	PUSHJ	P,PEKSPY	;GET PTR TO NEXT DDB
	HLRZ	P1,T1		;SAVE IN P1
	JUMPN	P1,DDBLOP	;JUMP IF MORE DDB'S
	PUSHJ	P,CATEND	;END OF DDB CATEGORY

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL WRITE LOW SEGMENT AND HIGH SEGMENT IF ANY

;HERE WHEN ALL DDB'S DONE, GATHER CORE FROM JOB'S LOW SEGMENT

EDDBS:	MOVEI	T1,.CACOR	;CATEGORY NUMBER FOR USER CORE
	PUSHJ	P,CATSTA	;START UP CATEGORY
	SETZM	THSOFF		;OFFSET FOR THIS SEGMENT=0
	HRLZI	T1,MAXUCR	;GET FIRST BLOCK OF USER CORE
	HRRZ	T2,J		;SEGMENT NUMBER=JOB NUMBER
	PUSHJ	P,GTUCOR	;GET THE CORE
	MOVE	T1,J		;GET JOB NUMBER INTO T1
	PUSHJ	P,JSSIZE	;GET SIZE OF LOW SEGMENT
	  JRST	EDUMP		;???
	MOVEM	T1,SEGREL	;=SIZE OF THIS SEGMENT
	PUSHJ	P,HSVADR	;GET START AND END OF HI SEG
	MOVEI	T1,.JBHRL	;ADDR OF .JBHRL
	SKIPN	USRCOR(T1)	;GET SIZE OF HI SEG FROM .JBHRL IN JOBDAT
			;IF ITS ZERO,EDIT 465
	SETZM	HGHREL		;REMEMBER FOR LATER
	MOVE	T1,J
	SETZB	T2,USRADR	;START COMPRESSION AT LOCATION 0
	PUSHJ	P,COMPRS	;OUTPUT LOW SEGMENT AS ZERO-COMPRESSED DATA

;HERE TO WRITE HIGH SEGMENT IF ANY

	SKIPN	T1,HGHREL	;SKIP IF ANY HIGH SEGMENT
	JRST	NOHIGH
	JUMPLE	S,NOHIGH	;EVEN IF HIGH SEG MUST KNOW ITS NUMBER
	MOVEM	T1,SEGREL	;SIZE OF HIGH SEGMENT
	MOVE	T1,HGHOFF	;OFFSET FOR HIGH SEGMENT
	MOVEM	T1,THSOFF	;=SIZE OF THIS SEGMENT
	HRLZI	T1,MAXUCR
	HRRZ	T2,S		;SEGMENT NUMBER FOR HIGH SEGMENT
	PUSHJ	P,GTUCOR	;GET FIRST BLOCK OF HIGH SEGMENT
	SETZB	T2,USRADR	;START COMPRESSION AT ADDRESS 0 IN SEGMENT
	MOVE	T1,S
	PUSHJ	P,COMPRS	;WRITE HIGH SEGMENT AS ZERO-COMPRESSED DATA

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL CLOSE OUT CORE-IMAGE FILE AND FINISH UP

;HERE WHEN ALL DATA WRITTEN

NOHIGH:	MOVE	T1,PATTERN	;END FILE WITH STANDARD PATTERN
	PUSHJ	P,DWRITE
	PUSHJ	P,CATEND
	JUMPGE	BP,NOHGH1	;JUMP IF NEVER WROTE ANYTHING
	PUSHJ	P,BLKWRT	;WRITE LAST PARTIAL BUFFER
NOHGH1:;**;[536] DELETE	CLOSE	DSK,		;AND CLOSE FILE

;HERE WHEN CORE-IMAGE FILE WRITTEN
	;FALL INTO RELEASE

;HERE TO FINISH OFF DCORE

>	;END OF IFLE FTSAVE

EDCORE:	MOVEI	T1,DSK		;[536] SET UP CHANNEL
	PUSHJ	P,RELDSK	;[536] RELEASE IT
IFLE FTSAVE,<
	TLNE	F,L.DUMP	;SKIP IF DCORE, NOT IF DUMP
	JRST	EDUMP>
	TLNE	F,L.UUO		;SKIP IF COMMAND
	JRST	UUOKX		;IF UUO, QUIT NOW
	PUSHJ	P,CRLFPD	;PRINT <CR><LF>. TO INDICATE MONITOR MODE
EECOM:	MOVSI	T2,(AT.UMM)	;ENSURE RE-ATTACH IS AT MONITOR LEVEL
	IORM	T2,LINE		;BY SETTING BIT IN ATT FUNCTION

EDUMP:	TLNE	F,L.UUO		;ATTACHED?
	JRST	UUOKX		;NO--RETURN TO UUO.
	HLLZ	T2,LINE		;LH=LINE NUMBER OF USER'S TTY
	HRRI	T2,(J)		;RH=USER'S JOB NUMBER
	ATTACH	T2,		;GIVE USER BACK HIS TTY
	  PUSHJ	P,E.ATUJ	;NOTE RE-ATTACH FAILED, USER MUST GET
				;BACK TO HIS JOB HIMSELF
	TLZ	F,L.TTYA	;NOTE TTY NO LONGER ATTACHED

;HERE TO UUO USER OUT OF DAEMON REQUEST

DETUSR:	HRRZ	T1,.JBDDT	;ADDR OF DDT IF ANY
IFE FTDET,<
	TLNN	F,L.OPRA	;RE-ATTACH IF OPR WANTS CONTACT
>;END FTDET COND
	JUMPE	T1,NOREAT	;DONT REATTACH ORIGINAL TTY IF NO DDT
	HRLZ	T1,THSLIN	;LH T1=OUR ORIGINAL LINE NUMBER
	HRR	T1,THSJOB	;RH=OUR JOB NUMBER
	TLO	T1,(AT.UUM)	;SET TO USER LEVEL
	ATTACH	T1,		;REATTACH TO OUR ORIGINAL LINE
	  AOS	ATTGUF
NOREAT:	MOVEI	T1,DALOOK	;NEW RESTART ADDR
	MOVEM	T1,INTADR
	TLNN	F,L.DUMP	;SKIP IF DUMP - MUST FORCE CCL RUN OF DUMP
	JRST	EDUMP1		;NO, DONT BOTHER
	MOVEI	T1,T2		;ADDRESS OF ARGUMENT LIST
	MOVE	T2,[SIXBIT /.DUMP/] ;COMMAND TO FORCE
	MOVE	T3,J		;JOB NUMBER
	FRCUUO	T1,		;FORCE COMMAND TO RUN DUMP AT CCL ENTRY POINT
	  AOS	FRCGUF		;DEBUG - COUNT SHOULD NEVER HAPPEN'S
EDUMP1:	MOVEI	T1,J		;T1=ADDRESS OF ARGUMENT LIST=JOB NUMBER
	DAEFIN	T1,		;ALL DONE, REQUE USER'S JOB
	  AOS	FINGUF		;DEBUG - NOTE AN SNH
IFL	FTSAVE,<
	MOVEI	T1,7	;FUNCTION FOR UUO
	MOVE	T2,J		;JOB WE FINISHED
	MOVE	T3,[XWD	2,T1]	;ARGBLK POINTER FOR UUO
	DAEMON	T3,		;TELL REAL DAEMON WE FINISHED HIM!
	  JFCL			;WELL, WE TRIED
>;END IFL FTSAVE
	JRST	NULEXT		;FINISH UP
;HERE TO RESET SEARCH LIST TO ORIGINAL STATE

IFE FTSVSL,<	NULEXT=DALOO2	;IF DON'T CARE ABOUT SEARCH LIST, FORGET THIS>


IFN FTSVSL,<	;IF PRESERVING OUR SEARCH LIST
NULEXT:	MOVE	T1,PSRCH	;POINTER TO ORIGINAL SEARCH LIST
	STRUUO	T1,		;RESTORE ORIGINAL SEARCH LIST
;**;[524]  INSERT AT NULEXT + 2		DBR
	  AOSA	STRGUF		;[524] COUNT ERROR, SKIP
	    JRST DALOO2		;[524] I HAVE NO PROBLEMS WITH CRUMMY STRUUO!
	CAIE	T1,FSSNF%	;[524] RECOVERABLE IF FAILED BECAUSE UNIT NOT FOUND
	CAIN	T1,FSSSA%	;[524] OR IF FAILED BECAUSE UNIT SINGLE ACCESS
	  SKIPA	T1,PSRCH	;[524] THIS IS RECOVERABLE!  PICK UP POINTER
	    JRST DALOO2		;[524] GIVE UP
	HLRZ	T2,T1		;[524] GET LENGTH OF ARG LIST (=4+(3*# OF STR'S))
	IDIVI	T2,3		;[524] GETS # OF STR'S + 1 IN T2
	SOJE	T2,DALOO2	;[524] SNH -- CHECK FOR NO STR'S
NULEX1:	ADDI	T1,3		;[524] INCREMENT PTR BY ONE STR
NULX1A:	MOVEI	T3,1(T1)	;[524] T3 POINTS TO SIXBIT STR NAME
	HRLI	T3,.DCNAM+1	;[524] LH SHOWS SINGLE ARG FOR DSKCHR
	DSKCHR	T3,		;[524] GET BITS ABOUT THIS STR IN AC
	  JRST	NULEX2		;[524] STR MUST HAVE BEEN DISMOUNTED
	TLNN	T3,(DC.OFL!DC.SAF!DC.STS!DC.NNA)	;[524] CHECK FOR
				;[524]  ANYTHING BAD ABOUT THIS FILE STR
	  JRST	NULEX3		;[524] NO REASON IT SHOULD NOT BE ON OUR SEARCH LIST
NULEX2:	MOVSI	T3,-3		;[524] HERE TO REMOVE STR -- GET -3
	ADDB	T3,PSRCH	;[524] DECREMENT LENGTH OF ARG LIST, GET IN T3
	MOVEI	T4,1(T1)	;[524] T4 PNTS TO START OF BAD 3 WORD BLOCK
	SUBI	T4,(T3)		;[524] SUBTRACT BASE TO GET OFFSET
	HLRZ	T3,T3		;[524] GET NEW LENGTH IN T3
	SUBI	T3,(T4)		;[524] NOW SUBTRACT OFFSET TO SEE HOW MUCH TO BLT
	MOVEI	T4,1(T1)	;[524] NOW POINT TO BLOCK TO REMOVE
	HRLI	T4,3(T4)	;[524] LH OF BLT PTR SHOWS WHERE TO READ FROM
	ADDI	T3,-1(T4)	;[524] POINT TO LAST WORD TO WRITE TO
	CAIE	T2,1		;[524] IF THIS IS LAST STR, NOTHING TO WRITE
	  BLT	T4,(T3)		;[524] MOVE END OF STR LIST
	SOJG	T2,NULX1A	;[524] IF REMOVED STR, DON'T INCREMENT PTR
NULEX3:	SOJG	T2,NULEX1	;[524] LOOP FOR ALL STR'S
	MOVE	T1,PSRCH	;[524] NOW GET NEW (SHOULD BE, ANYWAY) PTR
	STRUUO	T1,		;[524] SET OUR SEARCH LIST
	  JRST	DALOO2		;[524] CAN'T DO IT
	SOS	STRGUF		;[524] WE ARE SAVED -- DON'T COUNT ERROR
	JRST	DALOO2		;[524] MOVING RIGHT ALONG ...
>	;END OF FTSVSL CONDITIONAL
IFLE	FTSAVE,<

SAVE03:	SKIPN	THSOFF		;HIGH SEGMENT SAVE?
	JRST	SAVE09		;NO,
	MOVE	T1,P2		;YES, GET SEGMENT NUMBER
	PUSHJ	P,SAVHGH	;SAVE THE HIGH SEGMENT
	CLOSE	DSK,		;AND CLOSE THE SAVE HIGH SEGMENT
	HRLZM	P3,D.EXT	;GET EXTENSION TO TRY TO DELETE
	PUSHJ	P,DELETE	;AND GO TRY
	MOVSI	T1,'SAV'	;GET EXTENSION .SAV
	MOVEM	T1,D.EXT	;AND SET UP TO DELETE
	PUSHJ	P,DELETE	;AND WIPE OUT ANY OLD .SAV FILES
	MOVE	T2,J
	MOVSI	T1,MAXUCR	;SIZE OF BLOCK ON SWAPPING SPACE
	SETZM	THSOFF		;CLEAR OFFSET FOR LOW SEGMENT
	PUSHJ	P,GTUCOR	;GET JOB DATA AREA
	JRST	SAVE05		;THEN GET DO LOW SEGMENT

SAVE04:	PUSHJ	P,DELETE	;NO HIGH SEGMENT, DELETE .SHR
	HRLZM	P3,D.EXT		;GET EXTENSION .HGH
	PUSHJ	P,DELETE	;AND WIPE OUT ANY OF THOSE
SAVE05:	MOVEI	P1,USRCOR	;SET UP POINTER TO JOB DATA AREA
	SKIPE	T1,SGAEXT(P1)	;DID USER SUPPLY AN EXTENSION?
	JRST	SAVE06		;YES, USE IT
	JUMPE	P2,SAVE07	;JUMP IF NO HIGH SEGMENT SAVED
	MOVSI	T1,'LOW'	;WAS A HIGH SEG, DELETE .LOW
SAVE06:	MOVEM	T1,D.EXT	;SAVE EXTENSION TO DELETE
	PUSHJ	P,DELETE	;AND TRY TO WIPE IT OUT
	JRST	SAVE08		;THEN DO LOW SEG
SAVE07:	SKIPN	T1,.SGLOW(P1)	;USER SUPPLIED A LOW EXTENSION?
	MOVSI	T1,'SAV'	;NO, USE .SAV
	MOVEM	T1,D.EXT	;STORE
SAVE08:	HLRZ	T1,.JBCOR(P1)	;GET LH OF JOBCOR
	CAIGE	T1,.JBDA	;IF NOT GREATER THAN END OF  JOBDAT
	JUMPN	SAVE11		;AND NOT 0,NO LOWSEG TO SAVE
	JRST	DAEOPN		;AND GO OPEN LOW SEGMENT SAVE FILE

SAVE09:	MOVEI	P1,USRCOR	;SET UP POINTER TO INPUT BUFFER
	MOVE	T1,.JB41(P1)	;GET USER'S UUO DISPATCH
	MOVEM	T1,.SG41(P1)	;AND SAVE
	MOVE	T1,.JBDDT(P1)	;GET DDT STARTING ADDRESS
	MOVEM	T1,.SGDDT(P1)	;AND SAVE
	MOVE	T1,.JBSA(P1)	;GET STARTING ADDRESS
	HRRZM	T1,STRADR	;AND SAVE FOR JRST WORD
	MOVEI	T2,.SGDDT	;ADDRESS AT WHICH TO START SAVE
	SETZM	USRADR
	JUMPE	P2,SAVE1A	;HAVE A HIGH SEGMENT?
	MOVE	T1,HGHREL	;GET END OF HIGH SEG
	HRLI	T1,1(T1)	;SET UP T1 LIKE .JBHRL
	ADD	T1,HGHOFF	; IS SET UP BY MONITOR
	HLRZ	T2,.JBHRL(P1)	;GET LH OF .JBHRL
	SKIPN	T2		;ONLY SAVE IF NOTHING THERE
	MOVEM	T1,.JBHRL(P1)	;NOT SET UP, SAVE IT AWAY
	MOVEI	T2,.SGDDT	;ADDRESS AT WHICH TO START SAVE
	MOVE	T1,HGHOFF	;GET START ADDRESS
	SUBI	T1,1		;POINT TO LAST ADDRESS OF PREVIOUS PAGE
	MOVEM	T1,SEGREL	;STORE HIGHEST ADDRESS TO COMPRESS
	MOVE	T1,J		;GET JOB NUMBER
	PUSHJ	P,COMPRS	;GO COMPRESS LOW PART OF LOW SEG
	MOVE	T2,J		;GET JOB NUMBER
	MOVSI	T1,MAXUCR
	HRR	T1,HGHREL	;GET TOP ADDRESS OF HIGH SEG
	ADD	T1,HGHOFF	;AND ADD OFFSET
	AOS	T1		;POINT TO START OF POTENTIAL HIGH PART OF LOW SEG
	PUSHJ	P,GTUCOR	;GET IT INTO BUFFER
	MOVE	T2,HGHREL	;GET END OF HIGH SEG AGAIN
	ADD	T2,HGHOFF	;AND ADD OFFSET
	AOS	T2
	MOVEM	T2,USRADR	;START COMPRESSION OF HIGH PART HERE
SAVE1A:	MOVEI	T1,-1		;AND SAVE TO TOP OF IMAGE
	MOVEM	T1,SEGREL
	MOVE	T1,J		;GET JOB NUMBER INTO T1 AGAIN
	PUSHJ	P,COMPRS	;WRITE OUT ZERO-COMPRESSED LOW SEG
	SKIPE	T1,STRADR	;WAS THERE A NON-ZERO START ADDRESS
	TLOA	T1,(JRST)	;YES, MAKE A JRST WORD
	MOVSI	T1,(HALT)	;NO, MAKE A HALT
	PUSHJ	P,DWRITE	;PUT IT IN OUTPUT FILE
	JUMPGE	BP,SAVE10	;JUMP IF NEVER WROTE ANYTHING
	PUSHJ	P,BLKWRT	;OUT ANY PARTIAL BUFFER REMAINING
SAVE10:	CLOSE	DSK,		;CLOSE FILE
SAVE11:	CLOSE	DSK,CL.DAT	;[536] CLOSE FILE BUT DON'T WRITE IT
;**;[536] DELETE	MOVEI	T1,DSK	;HERE IF WE DON'T WANT CLOSE
;**;[536] DELETE	RESDV.	T1,		;SO DON'T CLOSE
;**;[536] DELETE	  JFCL		;WELL, WE TRIED
;**;[536] DELETE	OUTSTR	[ASCIZ /JOB SAVED/]	;PRINT REASSURING MESSAGE
	MOVE	T2,D.NAM	;[536] GET FILE NAME
	PUSHJ	P,TSIXN		;[536] TYPE IT
	OUTSTR	[ASCIZ/ SAVED/]	;[536] PRINT REASSURING MESSAGE
	JRST	EDCORE		;END EXIT


>	;END IFLE FTSAVE
SUBTTL ERRORS

IFLE	FTSAVE,<
E.NCOM:	JSP	T2,SNH
	  JRST EDCORE		;OOPS, NOT IN CONTACT
	OUTSTR	[ASCIZ /?UNKNOWN DAEMON COMMAND
/]
	JRST	EDCORE
E.NPPN:	JSP	T2,SNH
	  JRST	E.NPV1		;[66]OOPS, WE LOST CONTACT
	OUTSTR	[ASCIZ .
? CANT GET USER'S PPN
.]
	JRST	E.NPV1			;[66]

E.OPN:	JSP	T2,CWF
	  JRST	E.NPV1		;[66]NO LONGER ATTACHED
	OUTSTR	[ASCIZ .
? CANT OPEN DEVICE .]
	MOVE	T2,D.DEV
	PUSHJ	P,TSIXN		;TYPE DEVICE
	JRST	E.NPV1
E.DAEP:	MOVEI	T1,[ASCIZ .DAEMON.]
	JRST	E.NPV2

E.CCLP:	MOVEI	T1,[ASCIZ .CCL.]
E.NPV2:	JSP	T2,CWF
	  JRST	E.NPV1		;CAN'T TYPE, WE'RE NOT ATTACHED
	OUTSTR	[ASCIZ .
? YOU DONT HAVE PRIVILEGES TO WRITE .]
	OUTSTR	(T1)
	OUTSTR	[ASCIZ . FILE.]
E.NPV1:	TLZ	F,L.DUMP	;DO NOT PROCEED WITH DUMP
	JRST	EDCORE		;END DUMP OR DCORE AS DCORE

E.DENT:	HRRZ	T1,T2		;ERR CODE TO T1 BEFORE DESTROYING T2
	JSP	T2,CWF
	  JRST	E.DNT1		;OOPS, LOST THE ATTACH
	OUTSTR	[ASCIZ .
? ENTER FAILURE .]
	PUSHJ	P,TOCT
	OUTSTR	[ASCIZ . ON CCL FILE
.]
E.DNT1:	TLZ	F,L.DUMP
	JRST	DCORE
E.NDSK:	JSP	T2,CWF
	  JRST	E.NPV1			;[66]
	OUTSTR	[ASCIZ .
? DAEMON FILE MUST BE WRITTEN ON A DISK
.]
	JRST	E.NPV1		;[66]

;STILL IN IFLE FTSAVE
E.F1:	PUSHJ	P,FBMTRY
	  JRST	RE1
	JRST	E.NOUE

E.F2:	PUSHJ	P,FBMTRY
	  JRST	RE2

E.NOUE:	HRRZ	T1,T2		;SAVE ERROR CODE FOR PRINTING
	JSP	T2,CWF
	  JRST	E.NPV1		;[66]		;NO LONGER ATTACHED, MUST QUIT
	OUTSTR	[ASCIZ .
? ENTER FAILURE .]
	JRST	LEERR		;LOOKUP OR ENTER ERROR
E.NOUL:	HRRZ	T1,T2		;SAVE ERROR CODE FOR PRINTING
	JSP	T2,CWF
	  JRST	E.NPV1		;[66]		;STRANGE, WHAT?
	OUTSTR 	[ASCIZ .
? LOOKUP FAILURE .]
LEERR:	PUSHJ	P,TOCT
	OUTSTR	[ASCIZ . ON DAEMON FILE
.]
	JRST	E.NPV1		;[66]


>	;END IFLE FTSAVE

E.NATT:	PUSHJ	P,ATTCHK	;CHECK TO MAKE SURE WE AREN'T DETACHED
	  AOSA	OUTGUF		;THINGS ARE VERY STRANGE, TODAY
	OUTSTR	[ASCIZ .
? DETACH UUO FAILED.]
	JRST	E.EXIT	;[65]

E.JPEK:	OUTSTR	[ASCIZ .
? JOBPEK UUO REQUIRED, NOT IMPLEMENTED.]
	JRST	E.EXIT	;[65]

E.NSWP:	OUTSTR	[ASCIZ .
? CANT GET SWAPPING PARAMETERS.]
	JRST	E.EXIT	;[65]
E.DSWP:	OUTSTR	[ASCIZ .
? DSKCHR FAILURE .]
	CAME	T1,[.DCUFS+1,,DAEBUF]
	PUSHJ	P,TOCT
	OUTSTR	[ASCIZ . UNIT .]
	MOVE	T2,DAEBUF
	PUSHJ	P,TSIXN
	OUTSTR	[ASCIZ .
.]
	JRST	E.EXIT	;[65]

;E.MVNM E.HSTS E.UPMP ARE ADDED IN EDIT 110(B)

E.MVNM:	JSP	T2,SNH	;IN CONTACT
	POPJ	P,
	OUTSTR	[ASCIZ .
?CAN'T GET MONITOR VERSION NUMBER.]
	PJRST	PCRLF

E.HSTS:	JSP	2,SNH
	POPJ	P,
	OUTSTR	[ASCIZ .
?CAN'T GET HIGH SEGMENT STATUS FOR JOB.]
	PJRST	PCRLF

E.UPMP:	JSP	T2,SNH
	POPJ	P,
	OUTSTR	[ASCIZ .
?CAN'T GET UPMP FOR JOB.]
	PJRST	PCRLF

E.SOPN:	POP	P,T2		;RESTORE STACK
	JSP	T2,SNH
	  POPJ	P,		;CAN'T TYPE, WERE DETACHED
	OUTSTR	[ASCIZ .
? CANT OPEN SWAP UNIT .]
	MOVE	T2,T3		;GET SWAP UNIT NAME
	PUSHJ	P,TSIXN
PCRLF:	OUTSTR	[ASCIZ .
.]
CPOPJ:	POPJ	P,

E.SPTR:	JSP	T2,SNH
	  POPJ	P,		;WHAT CAN YOU DO WHEN DETACHED?
	OUTSTR	[ASCIZ .
? CANT GET SWAPPING POINTER FOR JOB.]
	PJRST	PCRLF

E.NFSF:	OUTSTR	[ASCIZ .
? PLEASE LOG IN AS .]
	PUSHJ	P,TPPN
E.EXIT:	SETZM	.JBINT		;[65]DON'T LET EXIT TRAP
	IFN	FTIPCF,<	;**[73]
	PUSHJ	P,DOWN		;CLOSE [SYSTEM]INFO DOWN
	MOVEI	P2,DAEXIT	;GET TEXT
	PUSHJ	P,TYPOPR	;WARN ABOUT CLOSE DOWN
>				;**[73] END OF EDIT
	EXIT
	IFN	FTIPCF,<	;**[73]
DAEXIT:	ASCIZ	/CLOSED DOWN DUE TO DAEMON EXIT
/
>				;**[73]

E.USTR:	PUSHJ	P,ATTCHK	;ARE WE ATTACHED?
	  AOSA	OUTGUF		;LOSE
	OUTSTR	[ASCIZ	.
?CAN'T SET TO USER SEARCH LIST
.]
	AOS	STRGUF		;NOTE STRUUO FAILURE
	POPJ	P,		;TRY TO CONTINUE

E.ATUJ:	PUSHJ	P,ATTCHK	;CHECK THAT WE'RE ATTACHED TO SOMETHING
	  AOSA	OUTGUF		;NOTE WE WANTED TO TYPE BUT COULDN'T
	OUTSTR	[ASCIZ	.
?CAN'T RE-ATTACH TTY TO USER JOB
.]
	AOS	ATTGUF		;NOTE ATTACH FAILURE
	POPJ	P,

FBMTRY:	SOJLE	P1,CPOPJ1	;EXIT IF FINISHED RETRYING
	HRRZI	T4,(T2)		;ERROR CODE
	CAIE	T4,ERFBM%	;SKIP IF FILE BEING MODIFIED
	JRST	CPOPJ1		;NO, SOME OTHER ERROR
	MOVEI	T1,1
	SLEEP	T1,
	POPJ	P,
CWF:	TLNE	F,L.UUO
	JRST	UUERR5
	PUSHJ	P,ATTCHK	;NOT A UUO, ARE WE PROPERLY ATTACHED?
	  AOSA	OUTGUF		;NO, FLAG ERROR
	AOJ	T2,		;YES, SKIP RETURN
	JRST	(T2)		;RETURN

SNH:	TLNE	F,L.UUO
	JRST	UUERR4
	PUSHJ	P,ATTCHK	;COMMAND--ARE WE ATTACHED?
	  AOSA	OUTGUF		;NO, NOTE ERROR, AND TAKE NON-SKIP RETURN
	AOJ	T2,
	JRST	(T2)		;GO BACK

ATTCHK:	PUSH	P,T1		;SAVE T1
	GETLIN	T1,		;GET OUR LINE NO
	TLNN	T1,-1		;DO WE HAVE ONE?
	JRST	TPOPJ		;NO, TAKE NON-SKIP RETURN
TPOPJ1:	POP	P,T1		;YES, RESTORE T1
	JRST	CPOPJ1		;AND SKIP

CRLFPD:	PUSHJ	P,ATTCHK	;IF WE'RE ATTACHED.
	  AOSA	OUTGUF		;BUT WE AREN'T, SO DON'T
	OUTSTR	[ASCIZ	/
./]				;PRINT TO SHOW COMMAND LEVEL AGAIN
	POPJ	P,

TABDOT:	PUSHJ	P,ATTCHK
	  AOSA	OUTGUF
	OUTSTR	[ASCIZ	/	./]
	POPJ	P,
;**;[535] DELETED	SCNBRK:	JUMPL	SC,CPOPJ	;EXIT IF AT END OF LINE
;**;[535] DELETED		PUSHJ	P,TYIA		;IGNORE REST OF LINE
;**;[535] DELETED		JRST	SCNBRK		;AND CHECK IF THIS IS BREAK CHARACTER
PDAEVR:	PUSHJ	P,ATTCHK
	  AOSA	OUTGUF
	OUTSTR	DAEVER		;PRINT DAEMON VERSION STRING
	POPJ	P,

DEFINE	.ADCHR	(CHR),<
.STRG==.STRG+<<CHR>_.SHFT>
.SHFT==.SHFT-7
IFL .SHFT,<EXP	.STRG
.STRG==0
.SHFT==^D29	>>

DEFINE	.ADSTR	(STR),<
IRPC STR,<.ADCHR	("STR")	>>

DEFINE	VERSTR	(NAME,MAJOR,MINOR,EDIT,WHO),<
	XLIST
.STRG==0
.SHFT==^D29
	.ADSTR	(['NAME' )
	.ADSTR	(\MAJOR)
IFN MINOR,<.ADCHR	(MINOR+"A"-1)>
IFN EDIT,<.ADCHR	"("
	.ADSTR	(\EDIT)
	.ADCHR	")">
IFN WHO,<.ADCHR	("-")
	.ADSTR	(\WHO)>
	.ADCHR	("]")
	.ADCHR	(15)
	.ADCHR	(12)
	EXP	.STRG
LIST>

DAEVER:
IFGE FTSAVE,<
	VERSTR	(DAEMON,VDAEMON,VMINOR,VEDIT,VWHO)
>
IFL FTSAVE,<
	VERSTR	(SAVER,VDAEMON,VMINOR,VEDIT,VWHO)
>

	PURGE	.ADCHR,.ADSTR,VERSTR,.STRG,.SHFT

IFLE	FTSAVE,<

SUBTTL SUBROUTINES

;SUBROUTINE TO START A CATEGORY
;ARGS	T1=CATEGORY NUMBER

CATSTA:	PUSHJ	P,DWRITE	;WRITE THE CATEGORY NUMBER
	PJRST	MRKSPT		;AND MARK THE SPOT FOR THE LENGTH TO BE WRITTEN LATER

;SUBROUTINE TO END A CATEGORY

CATEND:	MOVE	T1,WRDCNT	;WORDS WRITTEN
	PJRST	WRTSPT		;REWRITE THE SPOT MARKED FOR THE LENGTH OF THE CAT

;SUBROUTINE TO GET VALUES FOR JOB AND SEGMENT AND WRITE
;ARGS	T1=GETTAB TABLE
;	J=JOB NUMBER
;	S=SEGMENT NUMBER
;ENTER	WGTJOB TO WRITE JOB ENTRY
;	WGTSEG TO WRITE SEGMENT ENTRY
;	WGTBTH TO WRITE JOB THEN SEGMENT ENTRIES

WGTBTH:	TLO	F,L.WS		;WRITE JOB AND SEGMENT
WGTJOB:	TLOA	F,L.WJ		;WRITE JOB
WGTSEG:	TLO	F,L.WS		;WRITE SEGMENT
	TLZN	F,L.WJ		;SKIP IF WANT JOB ENTRY
	JRST	WGTSG1		;NO, TRY FOR SEGMENT
	HRLM	T1,(P)		;SAVE GETTAB TABLE
	HRLI	T1,(J)		;LH=JOB NUMBER
	PUSHJ	P,GTBSPY	;GET VALUE
	  SETZ	T1,		;0 OTHERWISE
	PUSHJ	P,DWRITE	;WRITE THAT
	HLRZ	T1,(P)		;RESET THE GETTAB TABLE
WGTSG1:	TLZN	F,L.WS		;SKIP IF SEGMENT ENTRY WANTED
	POPJ	P,		;NO, EXIT
	JUMPLE	S,WGTSG2	;DON'T TRY IF NO HIGH SEG (INCLUDING SPY)
	HRLI	T1,(S)		;LH=SEGMENT NUMBER
	PUSHJ	P,GTBSPY	;GET VALUE
WGTSG2:	  SETZ	T1,		;0 OTHERWISE
	PJRST	DWRITE		;WRITE AND EXIT

;STILL IN IFLE FTSAVE CONDITIONAL
;TABLE OF GETTAB'S TO WRITE FOR JOB INFORMATION
;RH=TABLE NUMBER
;LH=0 IF BOTH JOB AND SEGMENT ENTRIES WANTED
;  =1 IF JOB ONLY
;  =2 IF SEGMENT ONLY
;G MACRO HAS PARAMETERS TABLE NAME, B OR J OR S FOR BOTH OR JOB OR SEGMENT
 
	DEFINE G(X,Y)<
	XLIST
..Z==3
IFIDN <Y> <B>,<..Z==0>
IFIDN <Y> <J>,<..Z==1>
IFIDN <Y> <S>,<..Z==2>
	XWD	..Z,X
	LIST
>

GTTABL:	G	.GTSTS,B
	G	.GTPPN,B
	G	.GTPRG,B
	G	.GTTIM,J
	G	.GTKCT,J
	G	.GTPRV,J
	G	.GTSWP,B
	G	.GTRCT,J
	G	.GTWCT,J
	G	.GTTDB,J
	G	.GTDEV,S
	G	.GTNM1,J
	G	.GTNM2,J
	G	.GTCNO,J
	G	.GTTMP,J
	G	.GTWCH,J
	G	.GTSPL,J
	G	.GTRTD,J
	G	.GTLIM,J
	G	.GTSPS,J
	G	.GTRSP,J
	G	.GTTRQ,J
	G	.GTUPM,B
	G	.GTCVL,J
	G	.GTMVL,J
	G	.GTIPA,J
	G	.GTIPP,J
	G	.GTIPI,J
	G	.GTIPQ,J
	G	.GTDVL,J
	G	.GTABS,J
	G	.GTVRT,J
GTTBLN==.-GTTABL

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO OUTPUT ALL ENTRIES OF A GETTAB TABLE
;ARGS	P1=TABLE NUMBER

GTTBAL:	MOVSS	P1		;LH=TABLE NUMBER, RH=0
GTTBA1:	MOVS	T1,P1		;T1=ENTRY NUMBER,TABLE NUMBER
	PUSHJ	P,GTBSPY
	  POPJ	P,		;NO MORE
	PUSHJ	P,DWRITE	;WRITE THE WORD
	AOJA	P1,GTTBA1	;LOOP TIL END OF TABLE

;SUBROUTINE TO OUTPUT A DDB
;ARGS	P1=XWD -WORDS, ADDR OF BEGINNING OF DDB
;VALUES	P1=ADDR OF DDB

WRTDDB:	HRLM	P1,(P)		;SAVE ADDR OF DDB
	HLRE	T1,P1		;T1=MINUS LENGTH OF DDB
	MOVNS	T1		;POSITIVE LENGTH OF DDB
	HRL	T1,P1		;SAVE ADDR ALONG WITH LENGTH
	PUSHJ	P,DWRITE	;WRITE OUT LENGTH OF NEXT DDB
WRTDD1:	MOVEI	T1,(P1)		;ADDR OF NEXT WORD
	PUSHJ	P,PEKSPY	;GET NEXT WORD FROM DDB
	PUSHJ	P,DWRITE	;WRITE THE WORD
	AOBJN	P1,WRTDD1	;LOOP FOR THE DDB
	HLRZ	P1,(P)		;RESET ADDR OF DDB
	POPJ	P,		;AND EXIT

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL SUBROUTINE TO COMPRESS AND OUTPUT A SEGMENT

;SUBROUTINE TO COMPRESS AND OUTPUT A SEGMENT
;ARGS	T1=INDEX OF SEGMENT=JOB OR SEGMENT NUMBER
;	T2=ADDRESS AT WHICH TO START COMPRESSION
;	SEGREL=ADDRESS AT WHICH TO END COMPRESSION
;	THSOFF=OFFSET FOR ADDR OF FIRST WORD OF THE SEGMENT
;	USRADR=ADDRESS OF START OF BLOCK IN USRCOR
;	USRCOR=FIRST BLOCK OF USER'S CORE FOR SEGMENT

COMPRS:	JSP	T4,SAVE4	;SAVE P1-P4
	PUSH	P,REMBLK	;SAVE POINTER TO BEGINNING OF CATAGORY
	PUSH	P,REMWRD
	PUSH	P,WRDCNT
	MOVE	P1,T2		;GET ADDRESS AT WHICH TO START
	MOVE	P2,T2		;AND ALSO INTO P2
	ANDI	P2,777		;GET START MODULO PAGE SIZE
	MOVEM	T1,THSSEG	;SAVE SIZE OF THIS SEGMENT
COMPR1:	SKIPE	USRCOR(P2)
	JRST	COMPR2		;FOUND NEXT NON-ZERO WORD
	SETCM	T1,P1		;GET COMPLEMENT OF ADDRESS
	TRNE	T1,777		;SKIP IF END OF PAGE
	JRST	COMP1A		;NOT END, PROCEED
	TLZN	F,L.ZPGF	;SKIP IF JUST FINISHED A ZERO PAGE
	JRST	COMP1B		;NO, PROCEED ON TO NEXT PAGE
	HRRO	T1,P1		;GET CURRENT ADDRESS
	SUBI	T1,1000		;MAKE AN IOWD FOR START OF PAGE
	PUSHJ	P,DWRITE	;WRITE IT
	SETZ	T1,		;THEN MAKE A ZERO WORD
	PUSHJ	P,DWRITE	;AND WRITE IT
COMP1A:	TRNE	P1,777		;START OF NEW PAGE?
	JRST	COMP1B		;NO, JUST KEEP ROLLING ALONG
	TLNN	F,L.UPMP	;HAVE UPMP IN CORE?
	JRST	COMP1B		;NO, PROBABLY MEANS WE JUST GOT PAGE VIA JOBPEK
	MOVE	T1,P1		;YES, MEANS PAGE COULD BE NON-EXISTANT
	PUSHJ	P,VIRADR	;GET UPMP ENTRY FOR THE PAGE
	JUMPE	T1,COMP1C	;IF NON-ZERO, PAGE EXISTS
	TLO	F,L.ZPGF	;PAGE EXISTS, SET ZERO PAGE FLAG
COMP1B:	CAML	P1,SEGREL	;SKIP IF MORE IN SEGMENT
	JRST	CPREND		;NO, END OF COMPRESSING
	ADDI	P1,1		;BUMP COUNTER TO NEXT ADDR
	CAIGE	P2,MAXUCR-1	;SKIP IF END OF BUFFER
	AOJA	P2,COMPR1	;NO, KEEP GOING
	PUSHJ	P,NXTUBK	;GET NEXT BLOCK OF USER CORE
	SETZ	P2,		;RESET PTR TO BEGINNING OF BUFFER
	JRST	COMPR1		;AND KEEP GOING

;HERE FOR NON EXISTENT PAGE
COMP1C:	ADDI	P1,777		;BUMP TO END OF PAGE
	ADDI	P2,777		;AND STEP THAT FAR IN BUFFER
	JRST	COMP1B		;AND CONTINUE

;STILL IN IFLE FTSAVE CONDITIONAL
COMPR2:	HRRZM	P1,PTRADR	;SAVE ADDR OF BEGINNING OF NON-ZERO REGION
	TLZ	F,L.ZPGF	;FOUND A NON-ZERO WORD, CLEAR FLAG
	PUSHJ	P,MRKSPT	;MARK THE SPOT SO CAN WRITE IOWD LATER
COMP2A:	ADDI	P2,1		;BUMP PTR IN BUFFER, LOOK AT NEXT WORD
	SKIPE	T1,USRCOR-1(P2)	;SKIP IF FOUND A ZERO WORD
	JRST	COMPR3		;NO, JUST WRITE AND KEEP ON
	CAML	P1,SEGREL	;SKIP IF MORE IN SEGMENT
	JRST	CPREND		;END OF COMPRESSING
	CAIGE	P2,MAXUCR	;SKIP IF THE FIRST ZERO WAS THE END OF THE BUFFER
	JRST	COMP2B		;NO, GO AHEAD
	PUSHJ	P,NXTUBK	;YES, GET NEXT BLOCK
	SETZB	P2,T1		;RESET TO BEGINNING OF BUFFER AND REMEMBER ZERO DATA
COMP2B:	SKIPN	USRCOR(P2)	;IF ONLY 1 ZERO, PRETEND REGULAR DATA
	JRST	COMPR4		;2 CONSECUTIVE ZEROS END THIS PIECE
COMPR3:	PUSHJ	P,DWRITE	;WRITE THE WORD
	CAML	P1,SEGREL	;SKIP IF NOT END OF SEGMENT
	JRST	COMPR4		;END OF SEGMENT, END OF THIS PIECE
	ADDI	P1,1		;BUMP ADDR
	CAIGE	P2,MAXUCR	;SKIP IF NOW OFF END OF BUFFER
	JRST	COMP2A		;NO, LOOK AT NEXT WORD
	PUSHJ	P,NXTUBK	;YES, GET NEXT BLOCK OF USER CORE
	SETZ	P2,		;RESET PTR TO BEGINNING OF BUFFER
	JRST	COMP2A		;AND KEEP GOING
COMPR4:	SOS	T1,PTRADR	;T1=ADDR-1 IN SEGMENT OF BEGINNING OF THIS PIECE
	ADD	T1,THSOFF	;ADD OFFSET FOR SEGMENT
	MOVN	T2,WRDCNT	;-WORDS WRITTEN
	HRL	T1,T2		;T1=IOWD PTR FOR PIECE
	PUSHJ	P,WRTSPT	;REWRITE THE IOWD IN THE FILE
	AOS	T1,WRDCNT	;WORDS WRITTEN INCLUDING THE IOWD
	ADDM	T1,(P)		;COUNT WORDS IN THIS CATEGORY
	CAMGE	P1,SEGREL	;SKIP IF END OF THIS SEGMENT
	AOJA	P1,COMPR1	;NO, LOOK FOR NEXT NON-ZERO PIECE
CPREND:	POP	P,WRDCNT	;RESTORE WORDS WRITTEN
	POP	P,REMWRD	;AND THE REST OF THE CATAGORY POINTERS
	POP	P,REMBLK
	POPJ	P,

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO SET UP HGHOFF AND HGHREL FOR ANY JOB WITH HIGH SEGMENT
;ARGS	J=JOB NUMBER
;	USRUPM=USER'S UPM IF KI10
;VALUES	HGHOFF=STARTING ADDRESS OF HIGH SEGMENT
;	HGHREL=LAST ADDRESS IN HIGH SEGMENT

HSVADR:	HRROI	T1,.GTSGN	;[532] GETTAB INDEX TO JBTSGN
	PUSHJ	P,GTBSPY	;GET SEGMENT NUMBER
	  JFCL			;???
	JUMPLE	T1,HSVAD1	;SPY SEG (ALWAYS STARTS AT 400000)
	MOVE	T4,T1		;SAVE HIGH SEGMENT NUMBER
	MOVSS	T1
	HRRI	T1,.GTUPM	;JBTUPM
	PUSHJ	P,GTBSPY
	  JFCL			;???
	LDB	T3,[POINT 9,T1,8] ;GET JBYHSO BYTE
	JUMPE	T3,HSVAD1	;IF JBYHSO=0, GO TRY KA STYLE
	LSH	T3,11		;MAKE AN ADDRESS
	JRST	HSVAD2		;NOW STORE T3 AS START OF HI SEG
HSVAD1:	HRROI	T1,.GTADR	;[532] GETTAB INDEX TO JBTADR
	PUSHJ	P,GTBSPY	;GET LOW SEG PROT,,RELOC
	  JFCL			;???
	MOVEI	T2,377777	;ASSUME START AT 400000
	TRNE	T1,400000	;DOS IT START HIGHER?
	MOVE	T2,T1		;NO, START AT NEXT K ABOVE LOW END
	MOVEI	T3,1(T2)	;T3=START OF HI SEG
HSVAD2:	MOVE	T1,T4		;RESTORE HIGH SEGMENT NUMBER
	MOVEM	T3,HGHOFF	;STORE START OF HIGH SEGMENT
	JUMPL	T1,HSVAD3	;SPY SEG?
	MOVS	T1,T1		;NO, GET SIZE OF HIGH SEG
	HRRI	T1,.GTADR	;INDEX OF JBTADR
	PUSHJ	P,GTBSPY	;
	  JFCL			;???
	HLRZ	T1,T1		;SIZE OF HIGH SEGMENT
	JUMPN	T1,HSVAD3	;JUMP	IF IN CORE
	MOVS	T1,T4		;GET HIGH SEGMENT NUMBER
	HRRI	T1,.GTSWP	;JBTSWP
	PUSHJ	P,GTBSPY	;GET SIZE IN SOME FORM
	  JFCL			;???
	MOVE	T2,T4		;GET HIGH SEGMENT NUMBER AGAIN
	TLNN	T2,JSHR		;SHARABLE HIGH SEG?
	MOVSS	T1		;NO,GET LEFT HALF
	ANDI	T1,777		;NUMBER OF PAGES IN HIGH SEG
	LSH	T1,11		;CONVERT TO WORDS
	SUBI	T1,1	;AND GET HIGHEST ADDRESS
HSVAD3:	HRRZS	T1		;CLEAR POSSIBLE SPYSEG BIT
	MOVEM	T1,HGHREL	;AND STORE HIGHEST ADDRESS
	POPJ	P,		;AND RETURN

;STILL IN IFLE FTSAVE CONDITIONAL
SUBTTL	SUBROUTINE TO OUTPUT A NON-COMPRESSED HIGH SEGMENT

;SUBROUTINE TO OUTPUT A NON-COMPRESSED HIGH SEGMENT
;ARGS	T1=SEGMENT NUMBER
;	SEGREL=LENGTH OF SEGMENT
;	THSOFF=OFFSET FOR ADR OF FIRST WORD OF SEGMENT
;	USRCOR=FIRST BLOCK OF USER'S CORE FOR SEGMENT

SAVHGH:	JSP	T4,SAVE4	;SAVE P1-P4
	PUSH	P,REMBLK
	PUSH	P,REMWRD
	PUSH	P,WRDCNT
	SETZB	P1,USRADR	;START AT ADDRESS 0 IN SEGMENT
	SETZ	P2,		;POINTER TO BUFFER OF USER'S CORE
	MOVEM	T1,THSSEG	;SAVE SEGMENT NUMBER
SAVHG1:	ADDI	P2,1		;BUMP POINTER IN BUFFER
	MOVE	T1,USRCOR-1(P2)	;GET PREVIOUS WORD
	PUSHJ	P,DWRITE	;WRITE THE WORD
	CAML	P1,SEGREL	;SKIP IF NOT END OF SEGMENT
	JRST	SAVHG2		;END OF SEGMENT, EXIT
	ADDI	P1,1		;BUMP ADDR
	CAIGE	P2,MAXUCR	;SKIP IF NOW OFF END OF BUFFER
	JRST	SAVHG1		;NOT, GET NEXT WORD
	PUSHJ	P,NXTUBK	;GET NEXT BLOCK OF USER CORE
	SETZ	P2,		;RESET POINTER TO START OF BUFFER
	JRST	SAVHG1		;AND CONTINUE
SAVHG2:	ANDI	P1,177		;COMPUTE NUMBER OF WORDS IN LAST BLOCK
	TLZE	F,L.NHRL	;WAS LH(.JBHRL)=0
	MOVEI	P,200		;YES, THEN LAST IS ALWAYS FULL BLOCK
	MOVNS	P1,P1		;SET UP IOWD FOR
	HRLS	P1,P1		;EXACT NUMBER OF WORDS
	HRR	P1,DLIST	;IN P1
	EXCH	P1,DLIST	;AND SET UP TO USE IT FOR OUTPUT
	PUSHJ	P,BLKWRT	;OUTPUT LAST PARTIAL BLOCK
	EXCH	P1,DLIST	;RESTORE OLD IOWD FOR FULL BLOCK
	POP	P,WRDCNT
	POP	P,REMWRD
	POP	P,REMBLK
	POPJ	P,

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO DELETE THE FILE NAMED IN D.XXX

DELETE:	MOVEI	T1,17		;MODE 17
	MOVE	T2,D.DEV	;DEVICE NAME
	SETZ	T3,		;BUFFERS DON'T MATTER
	OPEN	DSK,T1		;OPEN!!!!
	  POPJ	P,		;WELL, WE TRIED
	MOVE	T1,D.NAM	;FILE NAME
	HLLZ	T2,D.EXT	;AND EXTENSION
	SETZ	T3,
	MOVE	T4,D.DIR	;PPN
	LOOKUP	DSK,T1		;SEE IF FILE EXISTS
	  POPJ	P,		;SIGH
	MOVEI	T1,T2		;[542] SET UP POINTER
	LSHC	T2,^D9		;[542] SHIFT PRIV BITS INTO LOW ORDER T2
	HRLI	T2,.ACREN	;[542] CHECK RENAMES PRIVILEGES
	MOVE	T3,D.DIR	;[542] DIRECTORY OF FILE
	TLNN	T3,-1		;[542] POINTER?
	  MOVE	T3,2(T3)	;[542] YES, GET REAL DIRECTORY
	MOVE	T4,USRPPN	;[542] GET PPN OF USER WHO WOULD DELETE
	CHKACC	T1,		;[542] OK BY YOU, BOSS?
	  SETZ	T1,		;[542] OUT TO LUNCH ... ASSUME OK
	JUMPN	T1,CPOPJ	;[542] HE DOESN'T APPROVE
	SETZB	T2,T3		;[542] CLEAR MORE SPACE FOR RENAME
	RENAME	DSK,T1		;ZOT!
	  POPJ	P,
	POPJ	P,

;STILL IN IFLE FTSAVE CONDITIONAL
>	;END IFLE FTSAVE
SUBTTL SUBROUTINES TO WRITE USER CORE

;SUBROUTINE TO WRITE IN USER'S CORE - MAKES NO ADDRESS CHECKS
;ARGS	T1=+LENGTH, ADDR IN SEGMENT
;	T2=INDEX OF SEGMENT=JOB OR SEGMENT NUMBER
;	J=JOB NUMBER
;	THSOFF=OFFSET FOR BEGINNING OF SEGMENT
;	USRCOR CONTAINS CORE TO BE WRITTEN OUT

WTUCOR:	JSP	T4,SAVE4	;SAVE P1-P4
	MOVEM	T2,SEGSWP	;SAVE SEGMENT NUMBER
	HLRZ	T3,T1		;NUMBER OF WORDS
	HRL	T3,J		;JOB NUMBER
	TLO	T3,400000	;SET WRITE FLAG
	HRRZ	T4,T1		;ADDR IN SEGMENT
	ADD	T4,THSOFF	;PLUS OFFSET FOR BEGINNING=ACTUAL ADDRESS
	HRLI	T4,USRCOR	;SOURCE=USRCOR
	MOVEI	T2,T3		;ADDR OF JOBPEK BLOCK
	PUSHJ	P,FINCHK	;WAIT A SEC IF HE'S BEING SWAPPED
WRTPEK:	JOBPEK	T2,		;TRY TO WRITE USER'S CORE
	  JRST	WRTSWP		;NOT IN CORE, MUST REWRITE SWAPPING SPACE
	POPJ	P,

;HERE IF MUST REWRITE SWAPPING SPACE

WRTSWP:	PUSHJ	P,FINCHK	;IF LOST BECAUSE HE'S BEING SWAPPED, WAIT
	TRZE	F,R.SWIN	;DID HE JUST COME IN?
	JRST	WRTPEK		;YES, GO PEEK AGAIN
	PUSH	P,T3		;SAVE JOBPEK ARGS
	PUSH	P,T4		; ..
	MOVE	P1,T1		;SAVE PTR TO CORE TO BE WRITTEN
	MOVEI	P2,USRCOR	;CURRENT ADDR IN OUR BUFFER
	HRRZ	T3,P1		;ADDR OF USER'S CORE TO BE WRITTEN
	IDIVI	T3,<1_WRDSPB>	;T3=BLOCKS TO SKIP, T4=WORDS TO SKIP IN BLOCK
	MOVE	P3,T3		;REMEMBER BLOCKS TO SKIP
	MOVE	P4,T4		;SAVE T4, (CLOBBERRED BY GTUPMP)
	SKIPL	VMMON		;DOES MONITOR HAVE VM?
	JRST	WRTSW2		;NO, PROCEED BY OLD METHOD
	PUSHJ	P,GTUPMP	;GET THE JOBS UPMP
	  JRST	E.SPTR		;???
	MOVE	T4,P4		;RESTORE T4
;**;[525] INSERT LABEL AT WRTSWP+20
WRTSW3:	MOVEI	T1,(P1)		;GET ADDRESS TO WRITE
	PUSHJ	P,VIRADR	;GET UPMP ENTRY FOR THIS PAGE
	HRLM	T1,SEGSWP	;SAVE SWAPPING POINTER
;**;[525] DELETE AT WRTSWP+23
;**;[525] DELETED	HLRZ	T1,P1		;GET LENGTH TO WRITE
;**;[525] DELETED	ADDI	T1,(P1)		;GET LAST ADDRESS
;**;[525] DELETED	ANDCA	T1,P1		;CANCEL ALL BITS WHICH AGGREE
;**;[525] DELETED	MOVEI	T3,(P3)		;GET START ADDRESS
;**;[525] DELETED	ANDI	T3,600		;GET BLOCK RELATIVE TO PAGE START
;**;[525] DELETED	ROT	T3,-7		;GET INTO PROPER POSITION
;**;[525] DELETED	TRNE	T1,777000	;SKIP IF ALL ADDRESSES ARE ON ONE PAGE
;**;[525] DELETED	JRST	E.SPTR		;SHOULD BE!!
	MOVEI	T3,(P3)		;[525] GET BLOCK OFFSET FROM PAGE 0
	ANDI	T3,3		;[525] MAKE BLOCK OFFSET FROM THIS PAGE
	JRST	WRTSW0		;GO WRITE THE WORDS
WRTSW2:	HRLZ	T1,SEGSWP	;SEGMENT NUMBER
	HRRI	T1,.GTSWP
	PUSHJ	P,GTBSPY	;GET SWAPPING PTR
	  JRST	E.SPTR		;CANT GET IT
	HLLM	T1,SEGSWP	;REMEMBER SWAPPING PTR
	JUMPL	T1,OFRAG	;JUMP IF FRAGMENTED (HOW BAD CAN IT GET?)


;HERE IF NOT FRAGMENTED

WRTSW0:	SKIPA	P3,T3		;REMEMBER BLOCKS SKIPPED
WRTSW1:	AOS	T3,P3		;SKIP ANOTHER BLOCK THIS TIME
;**;[525] INSERT AT WRTSW1+1
	SKIPL	VMMON		;[525] ONLY IF VIRTUAL
	  JRST	WRTSW4		;[525] NOT THE CASE, SKIP
	TRNE	T3,4		;[525] ABOUT TO CROSS PAGE BOUNDARY?
	  JRST	WRTSW3		;[525] YES, FIND NEW PAGE ON SWAP SPACE
WRTSW4:	PUSHJ	P,WRTPEC	;DO WHAT YOU CAN IN THIS BLOCK
	SETZ	T4,		;SKIP NO MORE WORDS IN BLOCKS
	TLNE	P1,-1		;SKIP IF ALL DONE
	JRST	WRTSW1		;NO, DO NEXT BLOCK
	JRST	REDEN1		;ALL DONE, RELEASE SWP AND EXIT
;HERE IF FRAGMENTED ON SWAPPING SPACE

OFRAG:	TLZ	T1,400000	;CLEAR FRAGMENTED BIT
	HLRZ	T2,T1		;T2=ADDR OF SWP PTRS
	PUSH	P,T4		;SAVE WORDS TO SKIP
	PUSHJ	P,FRGFND	;FIND FIRST BLOCK TO REWRITE
	POP	P,T4		;RESTORE WORDS TO SKIP IN BLOCK
	JUMPE	T1,REDEN1	;EXIT IF NO MORE
OFRAG1:	HRLM	T1,SEGSWP	;STORE SWAP PTR FOR BYTE PTRS
	HLRZ	P4,T1		;P4=K IN THIS PIECE
	LSH	P4,@BLKPAG	;P4=BLOCKS IN THIS PIECE
	SKIPA	P3,T3		;P3=BLOCKS TO SKIP
OFRAG2:	AOS	T3,P3		;SKIP ONE MORE BLOCK THIS TIME
	CAMGE	T3,P4		;SKIP IF END OF THIS PIECE
	JRST	OFRAG4		;NO, DO THIS BLOCK
	AOS	T1,SWPADR	;ADDR OF NEXT SWAP PTR
OFRAG3:	PUSHJ	P,PEKSPY	;GET NEXT SWAP PTR
	JUMPE	T1,REDEN1	;EXIT IF NO MORE
	SETZ	T3,		;SKIP NO BLOCKS AT FIRST
	TLC	T1,-1		;SET TO TEST FOR NEW PTR TO PTRS
	TLCE	T1,-1		;SKIP IF PTR TO NEW PTRS
	JRST	OFRAG1		;DO THIS PIECE
	MOVEM	T1,SWPADR	;STORE ADDR OF NEW PTRS
	JRST	OFRAG3		;AND CHASE THE NEW PTRS
OFRAG4:	PUSHJ	P,WRTPEC	;DO WHAT YOU CAN FOR THIS BLOCK
	SETZ	T4,		;SKIP NO MORE WORDS IN FURTHER BLOCKS
	TLNE	P1,-1		;SKIP IF ALL DONE
	JRST	OFRAG2		;NO, DO NEXT BLOCK
	JRST	REDEN1		;RELEASE SWP AND EXIT
;SUBROUTINE TO REWRITE ONE BLOCK ON THE SWAPPING SPACE
;ARGS	T3=BLOCKS TO SKIP IN THIS PIECE OF THE SWAPPING SPACE
;	T4=WORDS TO SKIP IN THIS BLOCK
;	SEGSWP=SWAPPING PTR
;	P1=XWD +WORDS LEFT, ADDR IN USER'S SEGMENT
;	P2=ADDR IN USRCOR OF CURRENT BEGINNING OF DATA

WRTPEC:	PUSH	P,T4		;SAVE WORDS TO SKIP
	MOVE	T2,UPDLST	;IOWD TO AVAILABLE UPDATE BUFFER
	PUSHJ	P,REDPEC	;READ IN THE BLOCK
	POP	P,T2		;RESTORE WORDS TO PRESERVE IN THIS BLOCK
	MOVEI	T3,<1_WRDSPB>	;WORDS IN THE BLOCK
	SUB	T3,T2		;T3=WORDS AVAILABLE IN THIS BLOCK
	HLRZ	T4,P1		;T4=WORDS YET TO TRANSFER
	CAMLE	T3,T4		;MINIMUM OF AVAILABLE, LEFT TO TRANSFER
	MOVE	T3,T4		;=WORDS TO WRITE IN THIS BLOCK
	MOVE	T4,T3		;SAVE IN T4
	ADDI	T2,SECBUF	;ADDR OF FIRST AVAILABLE WORD
	HRL	T2,P2		;ADDR OF NEXT DATA WORD
	ADDI	T3,(T2)		;+WORDS TO TRANSFER=LAST WORD+1
	BLT	T2,-1(T3)	;TRANSFER NEW DATA INTO BUFFER
	MOVEI	T2,SWP+4000	;SET UP LH FOR SUSET.
	PUSH	P,T1		;SAVE T1 IN CASE SUSET. LOSES
	DPB	T2,[POINT 13,T1,12]
	SUSET.	T1,
	  USETO	SWP,(P)		;TRY SUPER USETO
	POP	P,T1		;GET T1 BACK
	OUTPUT	SWP,UPDLST	;REWRITE BLOCK
	HLRZ	T2,P1		;WORDS LEFT
	SUB	T2,T4		;-WORDS DONE=NEW WORDS LEFT
	HRL	P1,T2
	ADDI	P1,(T4)		;NEW ADDR IN USER'S SEGMENT
	ADDI	P2,(T4)		;AND NEW ADDR IN USRCOR
	STATO	SWP,740000	;SKIP IF ERRORS
	POPJ	P,
	AOS	SWWGUF		;NOTE SWAP WRITE ERROR
	JSP	T2,SNH		;NO RETURN IF UUO
	  PJRST	SWPIO1		;IF NO LONGER ATTACHED
	OUTSTR	[ASCIZ .
% SWAP WRITE ERROR UNIT .]
	PJRST	SWPIO1		;REPORT REST OF ERROR
SUBTTL SUBROUTINES TO READ USER CORE

;SUBROUTINE TO GET NEXT BLOCK OF USER CORE

NXTUBK:	MOVEI	T1,MAXUCR	;SIZE OF BLOCK TO GET
	ADDB	T1,USRADR	;ADDR OF THIS BLOCK IN SEGMENT
	MOVEI	T2,MAXUCR	;MAXIMUM TRANSFER POSSIBLE
	ADDI	T2,-1(T1)	;T2=ADDR OF LAST POSSIBLE WORD
	CAMLE	T2,SEGREL	;SKIP IF WITHIN SEGMENT
	MOVE	T2,SEGREL	;LAST WORD OF SEG IS LAST WORD OF TRANSFER
	SUBI	T2,(T1)		;MINUS START OF TRANSFER=WORDS-1
	HRLI	T1,1(T2)	;WORDS THIS TRANSFER TO LEFT HALF
	MOVE	T2,THSSEG	;SEGMENT NUMBER
;	PJRST	GTUCOR		;FALL INTO GTUCOR

;SUBROUTINE TO GET CORE FROM USER'S JOB - MAKES NO ADDRESS CHECKS
;ARGS	T1=+LENGTH, ADDR IN SEGMENT
;	T2=INDEX OF SEGMENT=JOB OR SEGMENT NUMBER
;	J=JOB NUMBER
;	THSOFF=OFFSET FOR BEGINNING OF THIS SEGMENT

GTUCOR:	JSP	T4,SAVE4	;SAVE P1-P4
	SETZM	USRCOR		;FIRST CLEAR THE BUFFER IN CASE SOMETHING GOES WRONG
	MOVE	T3,[USRCOR,,USRCOR+1]
	BLT	T3,USRCOR+MAXUCR-1
	HRRZM	T2,SEGSWP	;SAVE SEGMENT NUMBER
	HLRZ	T3,T1		;RH=NUMBER OF WORDS
	HRL	T3,J		;LH=JOB NUMBER
	HRRZ	T4,T1		;ADDR IN SEGMENT
	ADD	T4,THSOFF	;ADD OFFSET FOR BEGINNING OF SEGMENT
	HRLZS	T4		;LH=ADDR
	HRRI	T4,USRCOR	;RH=ADDR OF OUR BUFFER
	MOVEI	T2,T3
	MOVE	P1,T1		;SAVE POINTER TO CORE WANTED
	TLNN	F,L.UPMP	;HAVE UPMP IN CORE?
	JRST	GTUCR1		;NO, PROCEED
	TLZ	T1,-1		;CLEAR LH OF T1
	PUSHJ	P,VIRADR	;GET UPMP ENTRY
	JUMPE	T1,CPOPJ	;EXIT WITH EMPTY BUFFER IF NO PAGE
	CAIN	T1,40000	;ALLOCATED BUT ZERO?
	POPJ	P,		;YES, EXIT
GTUCR1:	PUSHJ	P,FINCHK	;WATCH OUT FOR HIS GETTING SWAPPED
REDPEK:	JOBPEK	T2,		;TRY TO READ CORE
	  JRST	REDSWP		;NOT IN CORE, READ SWAPPING SPACE
	POPJ	P,		;THAT WAS NICE

;HERE TO CHECK WHETHER JOB IN J IS BEING SWAPPED NOW.
; IF SO, WAIT UNTIL HE GETS IN OR OUT, AND GIVE
; NON-SKIP RETURN IF HE JUST CAME IN
;READS THSOFF AND ASSUMES HI SEG WANTED IF NON-ZERO

FINCHK:	PUSH	P,T1		;SAVE WORK REG
	TRZ	F,R.SWIN	;ASSUME NO KNOWLEDGE
FINCK1:	HRROI	T1,.GTSGN	;[531] GET SEGMENT NUMBER FOR JOB
	SKIPE	THSOFF		;[531] SKIP IF EXAMINING LOW SEG
	 PUSHJ	P,GTBSPY	;[531] DON'T COME BACK WITHOUT IT!
	  MOVEI	T1,(J)		;[531] IF NO HI SEG, USE JOB NUMBER
	MOVSI	T1,(T1)		;[531] INDEX IN LH
	HLLM	T1,-1(P)	;[531] REMEMBER THIS!
	IFN .GTSTS,<HRRI T1,.GTSTS>	;[531] PLAN AHEAD
	PUSHJ	P,GTBSPY	;[531] GET STATUS
	  JRST	TPOPJ		;[531] WE TRIED
	TLNN	T1,JNSWP	;[531] RETURN IF SEGMENT LOCKED
	TLNN	T1,JSWP		;[531] LEARN MORE IF SWAPPED OR SWAPPING
	  JRST	TPOPJ		;[531] GO HOME, BOY
	HLL	T1,-1(P)	;[531] RESTORE INDEX
	HRRI	T1,.GTADR	;[531] GET PROTECTION AND RELOCATION
	PUSHJ	P,GTBSPY	;[531] FIND IT
	  JRST	TPOPJ		;[531] LOSE
	JUMPE	T1,FINCK2	;JUMP IF SWAPPED AND QUIESCENT
	TRO	F,R.SWIN	;SWAPPING NOW, ASSUME COMING IN
	MOVEI	T1,1		;GET A SMALL CONSTANT
	HIBER	T1,		;WAIT A JIFFIE
	  SLEEP	T1,		;OR A SECOND IF NO HIBER
	JRST	FINCK1		;LOOK AGAIN
FINCK2:	TRZ	F,R.SWIN	;ON SWAPPING SPACE, CAN'T BE COMING IN
	JRST	TPOPJ		;AND PROCEED

;SUBROUTINE TO GET UPMP ENTRY FOR VIRTUAL ADDRESS
;ARGS	T1=VIRTUAL ADDRESS
;	THSOFF=START OF THIS SEGMENT
;	USRUPM=USER'S PAGE MAP PAGE
;VALUES	T1=UPMP ENTRY FOR PAGE

VIRADR:	ADD	T1,THSOFF	;GET START OF SEGMENT
	ROT	T1,-^D10	;GET (PAGE NUMBER)/2
	SKIPGE	T1		;IF NEGATIVE, USE RH(POINTER) FROM UPMP
	SKIPA	T1,USRUPM(T1)	;GET RH (POINTER) AND SKIP
	MOVS	T1,USRUPM(T1)	;GET LH(POINTER)
	TLZ	T1,-1		;CLEAR LH
	POPJ	P,		;AND RETURN
;HERE IF MUST READ SWAPPING SPACE

REDSWP:	PUSHJ	P,FINCHK	;DID WE LOSE BECAUSE MON DECIDED TO SWAP?
	TRZE	F,R.SWIN	;DID WE SEE HIM COME IN?
	JRST	REDPEK		;YES, AND HE'S NOW IN CORE
	PUSH	P,T3		;SAVE JOBPEK ARGS
	PUSH	P,T4
	SKIPL	VMMON		;DOES MONITOR HAVE VM?
	JRST	REDSW1		;NO, PROCEED BY OLD METHOD
	HRRZ	T1,SEGSWP	;GET SEGMENT NUMBER
	CAIN	T1,(J)		;HIGH SEGMENT?
	JRST	REDSW7		;NO,PROCEED
	HRLZ	T1,SEGSWP	;YES, GET SEGMENT NUMBER
	IFN .GTSTS,<HRRI T1,.GTSTS>	;JOB STATUS TABLE
	PUSHJ	P,GTBSPY	;GET HIGH SEGMENT STATUS
	  JRST	REDHSE		;???
	TLNE	T1,JSHR		;SHARABLE HIGH SEGMENT?
	JRST	REDSW1		;YES, TREAT AS PER PRE 6.01
REDSW7:	PUSHJ	P,GTUPMP	;GET THE JOB'S UPMP
	  JRST	REDUPE		;???
	MOVEI	T1,(P1)		;GET SOURCE ADDRESS
	PUSHJ	P,VIRADR	;GET UPMP ENTRY FOR ADDRESS
	HRLM	T1,SEGSWP	;SET UP POINTER FOR REDPEC
	HLRZ	T1,P1		;GET LENGTH
	ADDI	T1,-1(P1)	;GET LAST ADDRESS
;**;[530] CHANGE AT REDSW7+7
	XORI	T1,(P1)		;[530] CANCEL ALL BITS WHICH AGREE
	TRNN	T1,777000	;IF LEFTMOST 9 BITS=0, ALL ON ONE PAGE
	JRST	REDSW6		;ON ONE PAGE, CONTINUE

;HERE IF "FRAGMENTED"  I.E. CORE TO GET FLOWS ACROSS PAGE BOUNDARY
	MOVEI	P2,USRCOR-1	;FIRST ADR FOR IOWD
	HLRZ	P3,P1		;GET NUMBER OF WORDS TO GET
	HRRZ	T1,P1		;GET ADDRESS OF FIRST WORD
	TRZ	T1,-<1_WRDSPB>	;WORDS TO BE SKIPPED IN FIRST BLOCK
	ADD	P3,T1		;MUST READ NOT WANTED WORDS TOO
	MOVE	P4,T3		;SAVE POINTER TO UPMP
	MOVE	T4,P1		;GET ADDRESS
	PUSH	P,P1		;SAVE USER ARGUMENT POINTER
REDSW3:	MOVE	T3,-1(P)	;GET JOBPEK ARG
	TRZ	T4,<1_WRDSPB>-1	;[567] ROUND OFF ADR TO BLOCK SIZE
	HRLI	T4,1(P2)	;SET UP DESTINATION ADDRESS
	HRRZ	T1,T4		;[572]GET START ADDRESS
	TRZ	T1,777		;GET FIRST ADDRESS IN PAGE
	ADDI	T1,1000		;GET NEXT PAGE ADDRESS
	HRRZ	T2,T4		;[572]GET START ADDRESS AGAIN
	SUB	T1,T2		;GET WORD COUNT
	CAIL	T1,(P3)		;LESS THAN TOTAL?
	MOVEI	T1,(P3)		;NO, USE SHORTER OF TOTAL OR BOUND
	HRR	T3,T1		;AND SET UP JOBPEC ARG
	MOVEI	T2,T3		;SET UP JOBPEK POINTER AC
	JOBPEK	T2,		;AND TRY TO GET FROM CORE
	  JRST	REDSW4		;FAIL, GET FROM SWAPPING SPACE
	ADDI	P2,(T3)		;UPDATE ADDRESS IN BUFFER
	SUB	P3,T1
	JRST	REDSW5
REDSW4:	SUB	P3,T1
	MOVN	T2,T1
	HRLZS	T2
	HRR	T2,P2
	ADDM	T1,P2
	HLRZ	T4,SEGSWP	;GET SWAPPING POINTER
	JUMPE	T4,REDSW5	;IF DOESN'T EXIST, DON'T TRY TO READ
	HRRZ	T3,P1		;[567] ADDR IN USER SPACE
	LSH	T3,-WRDSPB	;[567] CONVERT TO BLOCKS
	ANDI	T3,<1_BLKSPP>-1	;[567] BLOCK OFFSET WITHIN PAGE
	CAIE	T4,40000	;SKIP IF ALLOCATED BUT ZERO PAGE
	PUSHJ	P,REDPEC	;READ FROM SWAPPING SPACE
REDSW5:	JUMPE	P3,REDSW8	;FINISHED IF ZERO, CLEAN UP BUFFER
	MOVEI	T1,(P1)		;GET ORIGINAL ADDRESS
	ADDI	T1,1000		;BUMP TO NEXT PAGE
	PUSHJ	P,VIRADR
	HRLM	T1,SEGSWP	;SET UP POINTER FOR REDPEC
	ADDI	P1,1000
	TRZ	P1,777
	MOVEI	T4,(P1)		;NEXT ADDRESS IN USER CORE
	JRST	REDSW3		;GET REST OF USER CORE

REDSW8:	POP	P,P1		;RESTORE USER CORE POINTER
	JRST	REDEND		;AND CLEAN UP

REDSW1:	HRLZ	T1,SEGSWP	;LH=SEGMENT NUMBER
	HRRI	T1,.GTSWP	;SWAPPING PTR TABLE
	PUSHJ	P,GTBSPY	;GET SWAP PTR
	  JRST	REDSWE
	HLLM	T1,SEGSWP	;SAVE PTR TO SEGMENT ON SWAPPING SPACE
	HLRE	T3,T1		;T1=SWAP PTR OR -1 IF IN CORE
	AOJE	T3,REDEN2	;EXIT IF IN CORE - TRY JOBPEK AGAIN
	HRRZ	T3,P1		;ADDR DESIRED
	LSH	T3,-WRDSPB	;T3=BLOCKS TO SKIP
	JUMPL	T1,FRAG		;JUMP IF FRAGMENTED
	JRST	REDSW2		;ALL ONE PIECE


REDSW6:	MOVEI	T3,(P1)		;GET START ADDRESS
	ANDI	T3,600		;GET BLOCK RELATIVE TO PAGE START
	ROT	T3,-7		;GET INTO PROPER POSITION FOR REDPEC

;HERE IF NOT FRAGMENTED, ALL ONE PIECE

REDSW2:	HLRZ	T2,P1		;LENGTH IN WORDS
	HRRZ	T1,P1		;ADDR DESIRED
	TRZ	T1,-<1_WRDSPB>	;MAKE WORDS TO SKIP IN FIRST BLOCK
	ADD	T2,T1		;MUST READ THE WORDS TO SKIP TOO
	MOVNS	T2		;MINUS LENGTH
	HRLZS	T2		;IN LH
	HRRI	T2,USRCOR-1	;MAKE IOWD PTR
	HLRZ	T4,SEGSWP	;GET POINTER FROM UPMP
	JUMPE	T4,REDEND
	CAIE	T4,40000	;SKIP IF 'ALLOCATED BUT ZERO' PAGE
	PUSHJ	P,REDPEC	;READ IT
	JRST	REDEND		;ALL DONE

REDSWE:	PUSHJ	P,E.SPTR	;REPORT PROBLEM GETTING SWAP PTR
	JRST	REDEND		;FINISH UP

REDHSE:	PUSHJ	P,E.HSTS
	JRST	REDEND

REDUPE:	PUSHJ	P,E.UPMP
	JRST	REDEND
;HERE IF FRAGMENTED ON SWAPPING SPACE

FRAG:	TLZ	T1,400000	;LH T1=ADDR OF BLOCK OF PTRS
	HLRZ	T2,T1		;IN RH OF T2
	MOVEI	P2,USRCOR-1	;FIRST ADDR FOR IOWD
	HLRZ	P3,P1		;LENGTH OF PIECE DESIRED=WORDS LEFT TO DO
	HRRZ	T1,P1		;ADDR OF FIRST WORD
	TRZ	T1,-<1_WRDSPB>	;WORDS WHICH WILL BE SKIPPED IN FIRST BLOCK
	ADD	P3,T1		;MUST READ THEM TOO
FRAG1:	PUSHJ	P,FRGFND	;FIND FIRST BLOCK TO READ
	JUMPE	T1,REDEND	;EXIT IF NO MORE TO READ
FRAGS1:	HRLM	T1,SEGSWP	;SAVE THE PTR, SWAPPED FOR BYTE PTRS
	HLRZS	T1		;K IN THIS PIECE
	LSH	T1,@BLKPAG	;CONVERT TO BLOCKS
	SUB	T1,T3		;MINUS BLOCKS TO SKIP IN THIS PIECE
	LSH	T1,WRDSPB	;T1=TOTAL DATA WORDS IN THIS PIECE
	CAML	T1,P3		;SKIP IF LESS THAN WORDS STILL NOT READ
	MOVE	T1,P3		;THAT'S ALL WE NEED
	SUB	P3,T1		;SUBTRACT FROM WORDS LEFT TO DO
	MOVN	T2,T1		;T2=-WORDS THIS TRANSFER
	HRLZS	T2
	HRR	T2,P2		;ADDR IN CORE FOR THIS PIECE
	ADDM	T1,P2		;NEW ADDR AFTER THIS PIECE READ
	PUSHJ	P,REDPEC	;READ THIS PIECE
	JUMPE	P3,REDEND	;JUMP IF NO MORE NEEDED
	AOS	T1,SWPADR	;ADDR OF NEXT SWAPPING PTR
FRAG4:	PUSHJ	P,PEKSPY	;GET NEXT PTR
	JUMPE	T1,REDEND	;QUIT NOW IF NO MORE PTRS
	SETZ	T3,
	TLC	T1,-1		;SET TO TEST IF PTR TO NEW PTRS
	TLCE	T1,-1		;SKIP IF PTR TO NEW BLOCK OF PTRS
	JRST	FRAGS1		;COME BACK THROUGH
	MOVEM	T1,SWPADR	;STORE ADDR OF NEW BLOCK OF PTRS
	JRST	FRAG4		;AND LOOK FOR NEXT PTR
;SUBROUTINE TO FIND FIRST BLOCK TO READ
;ARGS	T2=ADDR OF NEXT WORD OF SWAPPING PTRS
;	T3=BLOCKS TO SKIP
;VALUES	T1=NEXT SWAPPING PTR
;	SWPADR=ADDR OF SWAPPING PTR

FRGFND:	HRRZ	T1,T2		;T1=ADDR OF NEXT WORD OF SWAPPING PTRS
	PUSHJ	P,PEKSPY	;T1=NEXT SWAPPING PTR
	JUMPE	T1,CPOPJ	;QUIT NOW IF NO MORE
	TLC	T1,-1		;SET TO TEST IF REAL PTR
	TLCN	T1,-1		;SKIP IF REAL PTR
	JRST	FRAG2		;ADDR OF NEW BLOCK OF PTRS
	JUMPE	T3,FRAGST	;START HERE IF NO MORE BLOCKS TO SKIP
	HLRZ	T4,T1		;T4=K IN THIS PIECE
	LSH	T4,@BLKPAG	;CONVERT TO BLOCKS
	SUB	T3,T4		;T3=BLOCKS LEFT TO SKIP
	JUMPL	T3,FRAG3	;USE THIS IF STARTS IN THIS PIECE
	AOJA	T2,FRGFND	;RH=ADDR OF NEXT PTR
FRAG2:	HRRZ	T2,T1		;RH=ADDR OF NEW BLOCK OF PTRS
	JRST	FRGFND		;START CHASING THAT
FRAG3:	ADD	T3,T4		;T3=BLOCKS TO SKIP IN THIS PIECE
FRAGST:	MOVEM	T2,SWPADR	;SAVE ADDR OF THIS PTR
	POPJ	P,
;HERE WHEN ALL THE PIECES READ

REDEND:	HRRZ	T1,P1		;ADDR DESIRED
	TRZ	T1,-<1_WRDSPB>	;CLEAR OUT ALL BUT ADDR IN 1ST BLOCK
	JUMPE	T1,REDEN0	;JUMP IF FIT EXACTLY AT BEGINNING OF BLOCK
	HRLZI	T1,USRCOR(T1)	;ADDR OF ACTUAL START OF DATA
	HRRI	T1,USRCOR	;BEGINNING OF BUFFER
	HLRZ	T2,P1		;LENGTH OF DATA
	BLT	T1,USRCOR-1(T2)	;MOVE UP DATA TO BEGINNING OF BUFFER
REDEN0:	HLRZ	T2,P1		;RE-GET LEN IN CASE JUMPED HERE
	CAIE	T2,MAXUCR	;UNLESS FULL BUFFER,
	SETZM	USRCOR(T2)	;CLEAR FIRST UNUSED LOC
	CAIL	T2,MAXUCR-1	;MORE THAN 1 UNUSED LOC?
	JRST	REDEN1		;NO, CLEAR NO MORE
	HRLZI	T1,USRCOR(T2)	;FIRST UNUSED LOC
	HRRI	T1,USRCOR+1(T2)	;SECOND "  "
	BLT	T1,USRCOR+MAXUCR-1 ;CLEAR TO END OF BUFFER
REDEN1:	MOVEI	T1,SWP		;[535] SET UP CHANNEL
	PUSHJ	P,RELDSK	;[535] GO RELEASE IT
REDEN2:	POP	P,T4		;RESTORE JOBPEK ARGS
	POP	P,T3
	MOVEI	T2,T3		;ADDR OF JOBPEK BLOCK
	JOBPEK	T2,		;TRY AGAIN IN CASE JUST CAME INTO CORE
	  JFCL			;COULD HAPPEN FOR SHARABLE HIGH SEG
	POPJ	P,

;SUBROUTINE TO READ SWAPPING SPACE
;ARGS	T2=IOWD
;	T3=BLOCKS TO SKIP
;	SEGSWP=SWAPPING PTR
;VALUES	T1=BLOCK NUMBER READ

REDPEC:
;	HLRZ	T1,T2		;T1=LENGTH OF TRANSFER
;	CAILE	T1,-<1_WRDSPB>	;SKIP IF GT ONE BLOCK
;	HRLI	T2,-<1_WRDSPB>	;MUST READ AT LEAST ONE FULL BLOCK, IN CASE
				;READING A FEW WORDS AT THE END OF THE BLOCK
	PUSH	P,T2		;SAVE IOWD
	LDB	T4,JBYSUN	;LOGICAL UNIT IN SWAPPING LIST
	LDB	T1,JBYLKS	;LOGICAL K IN SWAPPING SPACE
	LSH	T1,@BLKPAG	;CONVERT TO BLOCKS
	ADD	T1,.UNSLB(T4)	;+FIRST BLOCK FOR SWAPPING=BEGINNING ON SWAP SPACE
	ADD	T1,T3		;PLUS BLOCKS TO SKIP
	MOVEI	T2,17		;DUMP MODE
	MOVE	T3,.SWPUN(T4)	;NAME OF UNIT
	SETZ	T4,
	OPEN	SWP,T2
	  JRST	E.SOPN
	PUSH	P,T1		;SAVE BLOCK NUMBER
	TLO	T1,SWP_5	;(555) (WAS HRLI)PUT CHANNEL NUMBER IN LH
	SUSET.	T1,		;DO THE SUSET.
	  USETI	SWP,(P)		;TRY SUPER USETI IF SUSET. FAILS
	POP	P,T1		;RESTORE THE BLOCK NUMBER
	POP	P,T2		;RESTORE IOWD
;CONTINUED
	SETZ	T3,
	INPUT	SWP,T2		;READ
SWPIOE:	STATO	SWP,760000	;SKIP IF ERRORS
	POPJ	P,
	AOS	SWRGUF		;COUNT SWAP READ ERROR
	JSP	T2,SNH		;NO RETURN IF UUO
	  JRST	SWPIO1		;NO PRINT IF LOST THE ATTACH
	OUTSTR	[ASCIZ .
% SWAP READ ERROR UNIT .]
SWPIO1:	PUSH	P,T1		;SAVE BLOCK NUMBER READ
	GETSTS	SWP,T1		;READ ERROR STATUS
	HRLM	T1,-1(P)	;SAVE NEXT TO RETURN ADDR
	PUSHJ	P,ATTCHK	;ARE WE STILL ATTACHED?
	  JRST	SWPIO2		;NO, RESET STATUS, BUT NO PRINT
	LDB	T2,JBYSUN	;GET SWAP UNIT NUMBER
	MOVE	T2,.SWPUN(T2)	;T2=UNIT NAME
	PUSHJ	P,TSIXN		;TYPE IT
	OUTSTR	[ASCIZ . STATUS = .]
	HLRZ	T1,-1(P)	;SAVE STATUS
	PUSHJ	P,TOCT		;TYPE STATUS
SWPIO2:	HLRZ	T1,-1(P)	;RESTORE STATUS
	TRZ	T1,760000	;CLEAR ERROR BITS
	SETSTS	SWP,(T1)	;CLEAR ERROR
	JRST	TPOPJ		;RESTORE T1 AND EXIT
SUBTTL SUBROUTINES

;SUBROUTINE TO OUTPUT A CARRIAGE RETURN LINE FEED FOR DUMP CCL FILE

CCCRLF:	MOVEI	SC,C.CR		;CARRIAGE RETURN
	PUSHJ	P,CCOUT		;OUTPUT CHAR TO CCL FILE
	MOVEI	SC,C.LF		;LINE FEED - FALL INTO CCOUT

;SUBROUTINE TO OUTPUT A CHARACTER ON DUMP CCL FILE
;ARGS	SC(=16)=CHAR

CCOUT:	SOSG	C.BH+2
	OUTPUT	DSK,
	IDPB	SC,C.BH+1
	POPJ	P,

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO COPY USER'S SEARCH LIST
;ARGS	T1=JOB NUMBER
;	T2=PPN
;	T3=ADDRESS-1 OF BLOCK TO STORE SEARCH LIST

GETSRC:	MOVEM	T1,GOBBUF+.DFGJN ;USER'S JOB NUMBER
	MOVEM	T2,GOBBUF+.DFGPP
	SETOM	GOBBUF+.DFGNM	;START AT BEGINNING OF JOB'S SEARCH LIST

GETSR1:	MOVE	T1,[GOBLEN,,GOBBUF]
	GOBSTR	T1,		;GET NEXT STR IN JOB'S SEARCH LIST
	  POPJ	P,		;ALL DONE
	MOVE	T1,GOBBUF+.DFGNM ;NEXT STR
	JUMPE	T1,CPOPJ	;EXIT IF FENCE OR
	AOJE	T1,CPOPJ	; IF END OF LIST
	PUSH	T3,GOBBUF+.DFGNM ;STORE NAME
	PUSH	T3,GOBBUF+.DFGNM+1 ;AND UNUSED WORD
	PUSH	T3,GOBBUF+.DFGST ;AND STATUS WORD
	JRST	GETSR1		;LOOP TILL END OF LIST

;SUBROUTINE TO GET JOB'S DEFAULT PATH
;ARGS	J=JOB NUMBER WHOSE PATH TO READ
;VALUE	T1=POINTER TO PATH SPEC, OR PPN IF SFD'S NOT IMPLEMENTED

GETPTH:	HRLOI	T1,(J)		;READ JOB'S PATH FUNCTION
	MOVEM	T1,D.DPTH	;AT TOP OF PATH BLOCK
	MOVE	T1,[XWD DPTHLN,D.DPTH]
	PATH.	T1,
	  PJRST	GETPPN		;NO SFD'S-RETURN PPN
	MOVEI	T1,D.DPTH	;POINT TO PATH LIST
	POPJ	P,

;SUBROUTINE TO GET JOB'S PPN
;ARGS	J=JOB NUMBER
;VALUE	T1=PPN

GETPPN:	HRROI	T1,.GTPPN	;SETUP JBTPPN INDEX
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	POPJ	P,

;SUBROUTINE TO GET JOB # FROM DDB
;ARGS	T1=ADDRESS OF DDB
;VALUES	T1=JOB #

DDBJOB:	PUSH	P,T1	;SAVE DDB ADDRESS FOR LATER
	MOVE	T1,[%CNST2]	;GO GET SECOND STATES WORD
	PUSHJ	P,GTBSPY
	SETZ	T1,
	TRNE	T1,ST%NJN	;DO WE HAVE NEW MAX # OF JOBS?
	JRST	JOB512	;YES,GET JOB NUMBER FROM NEW PLACE
	POP	P,T1	;GET BACK DDB ADDRESS
	ADDI	T1,.DVCHR	;ADD IN OFFSET OF DEVCHR WORD
	PUSHJ	P,PEKSPY	;GO GET DEVCHR WORD
	LDB	T1,[POINT 7,T1,6]	;AND GET JOB # FROM PRE-602 LOCATION
	POPJ	P,		;RETURN
JOB512:	POP	P,T1		;GET BACK DDB ADDRESS
	ADD	T1,LDDBSH	;ADD IN LENGTH OF SHORT DDB
	SUBI	T1,1		;DEVJOB IS LAST WORD IN SHORT DDB
	PUSHJ	P,PEKSPY	;GO PICK IT UP
	ANDI	T1,777		;ONLY RIGHT 9 BITS ARE JOB NUMBER
	POPJ	P,		;RETURN

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO CHECK IF USER ALLOWED TO WRITE THE FILE
;ARGS	T1=FILE NAME
;	T2=EXT
;	T3=PROTECTION
;	T4=DIRECTORY
;	CHANNEL DSK OPEN
;VALUES	T1-T4 PRESERVED
;RETURN CPOPJ IF ACCESS NOT ALLOWED
;	SKIP RETURN IF ACCESS ALLOWED

ACCCHK:	PUSH	P,T1
	PUSH	P,T2
	PUSH	P,T3
	PUSH	P,T4
	LOOKUP	DSK,T1		;LOOKUP FILE
	  JRST	CHKAC1		;DOESN'T EXIST YET
	LSH	T3,-^D27	;EXISTS, WILL SUPERSEDE, SET T3=PROTECTION
	MOVEM	T3,D.PROT	;[542] IF SUPERSEDING, USE OLD PROTECTION
;**;[542] CHANGE .ACREN TO .ACWRI AT ACCCHK+7
	HRLI	T3,.ACWRI	;[542] SUPERSEDE FUNCTION
	JRST	CHKAC2
CHKAC1:	MOVE	T1,(P)		;PPN IS UFD NAME
	TLNE	T1,-1		;UNLESS PATH GIVEN
	JRST	CHKAC3		;IT'S A PROPER PPN
;**;[536] DELETE AT CHKAC1+3	JUMPE	T1,[HALT .]	;PROTECT AGAINST INTERNAL BUGS
	SKIPE	3(T1)		;DOES PATH INCLUDE ANY SFD'S?
	JRST	CHKAC5		;YES, SCAN DOWN TO FIND LAST
	MOVE	T1,2(T1)	;NO, JUST PICK UP PPN (=UFD NAME)
CHKAC3:	MOVSI	T2,'UFD'	;LOOKUP THE UFD
	MOVE	T4,MFDPPN	;DIRECTORY MFD
	LOOKUP	DSK,T1		;SEE IF UFD EXISTS
	  TLO	T3,777000	;[536] LET CHKACC WIN, ENTER ERROR LATER
;**;[536] DELETE AT CHKAC4-1	  SETZ	T3,
CHKAC4:	TLZ	T3,777		;CLEAR OUT GARBAGE
	HLRZS	T3		;UFD PROTECTION TO RIGHT HALF
	HRLI	T3,.ACCRE	;CREATE IN UFD FUNCTION
CHKAC2:	MOVE	T2,T3		;T2=FUNCTION,,PROTECTION
	MOVE	T3,(P)		;T3=DIRECTORY
	TLNN	T3,-1		;IS IT A PATH?
	MOVE	T3,2(T3)	;YES, GET THE UFD PPN
	MOVE	T4,USRPPN	;T4=REQUESTING PPN
	MOVEI	T1,T2		;ADDR OF ACCESS-CHECK BLOCK
	CHKACC	T1,		;CHECK IF LEGAL OPERATION
	  SETZ	T1,		;DONT KNOW, ASSUME OK
	CLOSE	DSK,CL.NMB	;CLOSE SO WONT DO UPDATE ENTER
	POP	P,T4		;  BUT KEEP NAME BLOCKS FOR REFERENCE SOON
	POP	P,T3
	POP	P,T2
	JUMPE	T1,TPOPJ1	;IF GOT OK RETURN, SKIP BACK TO CALLER
TPOPJ:	POP	P,T1
	POPJ	P,

;STILL IN IFLE FTSAVE CONDITIONAL
CHKAC5:	MOVEI	T2,3(T1)	;ADDR OF FIRST SFD NAME
	SKIPE	1(T2)		;IS THERE ANOTHER?
	AOJA	T2,.-1		;YES, CHECK AGAIN
	PUSH	P,0(T2)		;SAVE LAST SFD NAME
	PUSH	P,T2		;AND ITS ADDRESS
	MOVE	T1,0(T2)	;PICK UP LOWEST SFD NAME
	SETZM	0(T2)		;PREPARE TO LOOK IT UP IN NEXT HIGHER
	MOVSI	T2,'SFD'	;NAME AS GIVEN, EXT SFD
	MOVE	T4,-2(P)	;RE-GET POINTER TO PATH
	LOOKUP	DSK,T1		;GET PROTECTION OF SFD
	  SETZ	T3,		;IF NOT THERE, UNPROTECTED I GUESS
	POP	P,T2		;RESTORE POINTER TO LAST SFD IN PATH
	POP	P,0(T2)		;NOW RESTORE LAST SFD NAME
	JRST	CHKAC4		;PROCESS LIKE A UFD


;HERE TO RELEASE A CHANNEL
;ARG=CHANNEL # IN T1		T1,T2,T3 DESTROYED
;THIS ROUTINE KEEPS CHANNEL DDB AROUND IN CASE OF A SOFT ERROR
;  ON OURSELF THAT WE MAY SHORTLY BE ASKED TO RECORD

RELDSK:	DPB	T1,[POINT 4,RELINS,12]	;[535] PUT CHANNEL IN RELEASE INSTR.
	SETZ	T2,		;[535] GIVE TO JOB 0 (DEASSIGN)
	MOVSI	T3,'KLG'	;[535] LOGICAL NAME WE WANT
	REASSI	T2,		;[535] GIVE AWAY IF ALREADY EXISTS
	MOVSI	T2,'KLG'	;[535] SET UP KLUDGE AGAIN
	DEVLNM	T1,		;[535] GIVE OUR CHANNEL THAT LOGICAL NAME
	  JRST	RELDS1		;[535] SNH
	SETO	T1,		;[535] REASSIGN TO OUR JOB
	LDB	T2,[POINT 4,RELINS,12]	;[535] CHANNEL NO. TO ASSIGN
	REASSI	T1,		;[535] GET IT
RELDS1:	XCT	RELINS		;[535] NOW RELEASE FOR REAL
	POPJ	P,		;[535] DONE
;ROUTINE TO RESTART AFTER ERROR INTERCEPT
;ARGS	INTRES CONTAINS ADDRESS TO RESTART AT

INTRES:	PUSH	P,INTBLK+2	;[537] SAVE INT PC
;**;[537] DELETE	MOVE	T1,INTBLK+2	;GET PC OF ERROR
;**;[537] DELETE	MOVEM	T1,INTRPC	;SAVE FOR ANALYSIS OR OUTPUT
IFLE	FTSAVE,<
	PUSH	P,T1		;[537] SAVE AC FOR INT ROUTINE>
	SETZB	T1,INTBLK+2	;[537] AND ENABLE INTERRUPTS AGAIN
IFLE FTSAVE,<
;**;[537] DELETE	HLRZ	T1,INTBLK+3	;PUCK UP BITS FROM INTERUPT
	EXCH	T1,INTBLK+3	;[537] GRAB & CLEAR REASONS
	TLNE	F,L.SAVE	;ARE WE IN THE MIDDLE OF A SAVE?
	TLNN	T1,2		;[537] AND IS THIS A CONTROL-C
	SKIPA			;NO, GO ON
	JRST	TPOPJ		;[537] RESTORE T1 AND RETURN
;**;[537] DELETE	JRST	@INTRPC		;YES, JUST IGNORE THE INTERUPT
>;END IFLE FTSAVE
;**;[537] DELETE	SETZM	INTBLK+2	;CLEAR PC
	GETLIN	T1,		;GET LINE NUMBER
	TLNN	T1,-1		;ATTACHED?
	JRST	REGO		;NO--RESTART
	SETO	T1,		;INDICATE CURRENT LINE "7-53"
	GETLCH	T1		;GET LINE NUMBER
	HRLZI	T1,(T1)		;LH=LINE, RH=DETACH
	ATTACH	T1,		;DO A DET
	  AOS	ATTGUF		;WE TRIED
REGO:	HRRZ	T1,.JBDDT	;ADDR OF DDT IF ANY
IFE FTDET,<
	TLNN	F,L.OPRA	;RE-ATTACH IF SO DESIRED BY OPR
>;END FTDET
	JUMPE	T1,REGO1	;DONT ATTACH ORIGINAL LINE IF NO DDT
	HRLZ	T1,THSLIN	;OUR LINE NUMBER
	HRR	T1,THSJOB	;OUR JOB NUMBER
	TLO	T1,(AT.UUM)	;SET TO USER LEVEL
	ATTACH	T1,		;TRY TO REATTACH OUR TTY
	  AOS	ATTGUF		;DEBUG - COUNT ATTACH FAILURES
REGO1:
IFLE FTSAVE,<
	HRRZ	T1,-1(P)	;[537] RETURN WITH PC IN T1>
IFG FTSAVE,<
	HRRZ	T1,(P)		;[537] NOTHING PUSHED IF NO SAVE>
	MOVE	P,PDL		;RESET PUSH DOWN POINTER
	TLZ	F,L.TTYA!L.DUMP	;NOW DETACHED
				;DUMP BECOMES DCORE, SINCE DUMP INCOMPLETE
	AOS	INTGUF		;COUNT INTERCEPTS
	JRST	@INTADR

;COME HERE ON INTERCEPT DURING STARTUP

E.EINT:	OUTSTR	[ASCIZ	.
? ERROR INTERCEPT @PC .]
;**;[537] DELETE	HRRZ	T1,INTRPC	;GET SAVED PC
	PUSHJ	P,TOCT		;PRINT IN OCTAL
;**;[537] DELETE	OUTSTR	[ASCIZ	., BITS = .]
;**;[537] DELETE	HLRZ	T1,INTBLK+3	;GET TYPE INDICATOR BITS
;**;[537] DELETE	PUSHJ	P,TOCT		;PRINT THEM
	PUSHJ	P,PCRLF
	OUTSTR	DAEVER		;PRINT DAEMON VERSION
	JRST	E.EXIT	;[65]QUIT
;SUBROUTINE TO CHECK USER ADDRESS
;ARGS	T1=XWD +LENGTH,START
;	J=JOB NUMBER
;VALUES	T1=XWD +LENGTH, ADDR IN SEGMENT
;	T2=JOB OR SEGMENT
;	THSOFF SET IF HISEG
;RETURN	CPOPJ IF BAD ADDRESS
;	CPOPJ1 IF ADDRESS IS VALID
;ALL AC'S RESPECTED

UADCHK:	PUSH	P,T1		;PRESERVE LEN,START
	HLRE	T2,T1
	SOJL	T2,TPOPJ	;NEG OR ZERO LEN NO FAIR
	SKIPL	VMMON		;DOES MONITOR HAVE VIRTUAL MEMORY?
	JRST	UADOLD		;NO, CHECK BY OLD METHOD
	PUSHJ	P,GTUPMP	;YES, GET THE UPMP FOR THE JOB
	  JRST	TPOPJ		;CAN'T FIND ONE??
	HLRZ	T2,(P)		;GET LENGTH OF BLOCK
	HRRZ	T1,(P)		;GET STARTING ADDRESS
	SETZ	T4,		;CLEAR STORAGE POINTER
UADCK1:	PUSHJ	P,CHKADR	;CHECH C(T1)+C(T4)
	  JRST	UADCK3		;BAD.. CHECK HIGH SEGMENT
	ADDI	T4,^D512	;ADD SIZE OF PAGE TO STORAGE
	CAIGE	T4,(T2)		;SIZE .GT. 512 WORDS
	JRST	UADCK1		;YES, CHECK START+512
	MOVEI	T4,-1(T2)		;NO, NOW CHECK END OF BLOCK
	PUSHJ	P,CHKADR	;CHECK C(T1)+C(T4)
	  JRST	UADCK3	;DOESN'T CHECK, LOOK AT HIGH SEG
	MOVE	T1,(P)		;RESTORE LEN,START
;**;[526] INSERT AT UADOLD-2
	ADDI	T2,-1(T1)	;[526] ADDR OF LAST WORD IN GROUP
	JRST	UADCK2		;IS IN LOW SEG, CHECK PROTECTED AREA
UADOLD:	MOVE	T1,(P)		;RESTORE T1
	ADDI	T2,(T1)		;ADDR OF LAST WORD IN GROUP
	MOVEI	T1,(J)		;JOB (LOW SEG) NO
	PUSHJ	P,JSSIZE	;GET ITS SIZE
	  JRST	TPOPJ		;SOMEBODY GOOFED
	CAILE	T2,(T1)		;IS LIST END WITHIN LOW SEG?
	AOJA	T1,HADCHK	;NO, CHECK HIGH SEG
UADCK2:	POP	P,T1		;RESTORE LEN,,START
	CAIGE	T2,17		;END IN AC'S?
	JRST	LOSOK		;YES, ITS OK
	MOVEI	T2,(T1)		;GET START
	CAIGE	T2,.JBPFI	;PAST MONITOR RESERVED AREA?
	POPJ	P,		;NO, ERROR
LOSOK:	MOVEI	T2,(J)		;RETURN JOB NUMBER
	SETZM	THSOFF		;AND LOW SEG FLAG
	JRST	CPOPJ1		;GOOD RETURN

;HERE IF BLOCK NOT IN LOW SEGMENT, CHECK HIGH

UADCK3:	ADDI	T2,(T1)		;T2=END OF GROUP
	HRROI	T1,.GTSGN	;SEGMENT TABLE
	PUSHJ	P,GTBSPY	;GET SEGMENT NUMBER FOR JOB
	  JRST	TPOPJ		;VERY STRANGE!!
	JUMPLE	T1,TPOPJ	;NO HIGH SEGMENT, FAIL
	MOVSI	T1,(T1)		;SEGMENT NUMBER AS ITEM
	HLLM	T1,-1(P)	;SAVE ON STACK
	HRRI	T1,.GTUPM	;JBTUPM TABLE
	PUSHJ	P,GTBSPY	;GET ADDRESS
	  JRST	TPOPJ		;???
	HLRZ	T1,T1		;GET LEFT HALF
	TRZ	T1,777		;CLEAR LOW ORDER BITS
	JRST	HADCK1		;AND CHECK SAME AS PRE 6.01
HADCHK:	TRNN	T1,400000	;IS LOW SEG BIGGER THAN 128K?
	MOVEI	T1,400000	;NO, HIGH SEG STARTS HERE
HADCK1:	MOVEM	T1,THSOFF	;USE THAT AS OFFSET
	SUBI	T2,(T1)		;GET END RELATIVE TO HIGH SEG
	JUMPL	T2,TPOPJ	;TOO LOW FOR HIGH SEG
	EXCH	T1,0(P)		;PREPARE TO...
	SUBB	T1,0(P)		;GET ADJUSTED LEN,,START ON STACK
	TRNE	T1,400000	;TROUBLE IF
	JRST	TPOPJ		;START NOT IN HIGH SEG
	HRROI	T1,.GTSGN	;SEGMENT TABLE
	PUSHJ	P,GTBSPY	;FIND SEG NO FOR HI SEG
	  JRST	TPOPJ		;STRANGE INDEED
	JUMPLE	T1,TPOPJ	;BOMB IF NO HIGH SEGMENT
	HRLM	T1,-1(P)	;SAVE WITH RETURN ADDR
	PUSHJ	P,JSSIZE	;GET HIGH SEG SIZE
	  JRST	TPOPJ
	CAILE	T2,(T1)		;IS END WITHIN HIGH SEG?
	JRST	TPOPJ		;NO
	HLRZ	T2,-1(P)	;GET SEG NO
	JRST	TPOPJ1		;RESTORE ADJUSTED LEN,,START AND GIVE GOOD RETURN
;SUBROUTINE TO GET THE LENGTH OF A JOB OR SEGMENT
;ARGS	T1=JOB OR SEGMENT #
;VALUES	T1=0,,HIGHEST LEGAL ADDR RELATIVE TO START OF SEGMENT
;RETURN	CPOPJ IF NO SUCH JOB OR SEG NO
;	CPOPJ1 IF SUCCESSFUL

JSSIZE:	MOVSI	T1,(T1)		;JOB OR SEG NO AS ITEM
	HLLM	T1,0(P)		;SAVE IT
	HRRI	T1,.GTADR	;PROT,,RELOC TABLE IF JOB IN CORE
	PUSHJ	P,GTBSPY
	  POPJ	P,
	HLRZS	T1		;PROT = LEN OF SEGMENT
	JUMPN	T1,CPOPJ1	;RETURN UNLESS SWAPPED OUT
	HLLZ	T1,0(P)		;RE-GET JOB (SEG) NO
	HRRI	T1,.GTSWP	;JOBS SWAPPING PARAMS
	PUSHJ	P,GTBSPY
	  POPJ	P,
	ANDI	T1,777000	;NO OF PAGES ON SWAPPING DEVICE
	XCT	PKLSH		;DO SHIFT IF SWAP CHUNKS = K, NOT PAGES
	SOJA	T1,CPOPJ1	;SUCCESSFUL

;SUBROUTINE TO CHACK AN ADDRESS FOR A 6.01 AND LATER MONITOR
;ARGS	T1=0,,BASE ADDRESS
;	T3=POINTER TO UPMP
;	T4=0,,DISPLACEMENT
;RETURN	CPOPJ IF BAD ADDRESS
;	CPOPJ1 IF OK
;ALL AC'S RESPECTED

CHKADR:	PUSH	P,T1		;SAVE T1
	ADD	T1,T4		;AND BUILD ADDRESS WE WANT
	PUSHJ	P,VIRADR	;GET UPMP ENTRY FOR ADDRESS
	SKIPE	T1		;IF ZERO, BAD CHECK
	CAIN	T1,40000	;SKIP IF NOT AN ALLOCATED BUT ZERO PAGE
	JRST	TPOPJ		;ERROR RETURN
	JRST	TPOPJ1		;GOOD RETURN
;SUBROUTINE TO READ A JOB'S USER PAGE MAP PAGE (UPMP) INTO CORE
;EITHER VIA A JOBPEK OR BY READING THE JOB'S SWAPPING SPACE.
;DEBUGGERS, NOTE:  THIS JOBPEK WORKS INCORRECTLY FOR YOUR OWN JOB!!
;ARGS	J=JOB NUMBER
;VALUES	T3=0,,ADDRESS OF UPMP BUFFER
;RETURN CPOPJ IF CAN'T GET UPMP FOR ANY REASON
;	CPOPJ1 IF SUCCESSFUL
;T1,T2,T4 NOT RESPECTED

GTUPMP:	TLZ	F,L.UPMP	;CLEAR IN CASE WE FAIL
	SETZM	USRUPM		;CLEAR UPMP BUFFER
	MOVE	T3,[USRUPM,,USRUPM+1]
	BLT	T3,USRUPM+MAXUPM-1
	MOVEI	T3,MAXUPM	;GET WORD COUNT
	HRL	T3,J		;GET JOB NUMBER
	TLO	T3,200000	;SET BIT TO READ UPMP
	HRRZI	T4,USRUPM	;SET UP DESTINATION ADDRESS
	MOVEI	T2,T3		;SET UP JOBPEK AC
	JOBPEK	T2,		;TRY TO READ UPMP FROM CORE
	  JRST	GTUPM1		;NOT IN CORE, TRY SWAPPING SPACE
	JRST	GTUPM2		;AND RETURN
GTUPM1:	PUSHJ	P,FINCHK	;MAKE SURE JOB IS NOT CURRENTLY BEING SWAPPED
	HRROI	T1,.GTSWP	;[532] SWAPPING POINTER TABLE
	PUSHJ	P,GTBSPY	;GET SWAPPING POINTER
	  JRST	CPOPJ		;CAN'T FIND IT??
	HLLM	T1,SEGSWP	;SAVE POINTER FOR REDPEC
	HLRE	T2,T1		;GET THE POINTER
	AOJE	T2,CPOPJ	;IF -1, WE HAVE A PROBLEM
	MOVSI	T2,-MAXUPM	;GET WORD COUNT OF BUFFER
	HRRI	T2,USRUPM-1	;MAKE AN IOWD
	SETZ	T3,		;CLEAR BLOCK OFFSET
	PUSHJ	P,REDPEC	;READ THE SWAPPING SPACE
GTUPM2:	MOVE	T1,.UPJOB	;GET OFFSET OF JOB # WORD IN UPMP
	CAME	J,USRUPM(T1)	;GOT THE RIGHT UPMP?
	POPJ	P,		;NO, ERROR
	TLO	F,L.UPMP	;MARK THAT A UPMP IS NOW IN CORE
	MOVEI	T3,USRUPM	;[563]
	JRST	CPOPJ1		;AND GIVE GOOD RETURN
SUBTTL OUTPUT SUBROUTINES

;SUBROUTINE TO MARK THE SPOT FOR DATA TO COME LATER IN THE CORE-IMAGE FILE

MRKSPT:IFLE	FTSAVE,<

	MOVE	T1,PATTERN	;WRITE STANDARD PATTERN
	PUSHJ	P,DWRITE
	MOVE	T1,CURBLK	;CURRENT BLOCK IN FILE
	MOVEM	T1,REMBLK	;SAVE FOR REWRITING LATER
	MOVEM	BP,REMWRD	;AND WORD ADDR
	SETZM	WRDCNT		;START COUNTING WORDS WRITTEN
	POPJ	P,

;SUBROUTINE TO WRITE ONE WORD IN THE CORE-IMAGE FILE
;ARGS	T1=WORD TO WRITE

DWRITE:	AOS	WRDCNT		;COUNT WORDS WRITTEN
	AOBJN	BP,DWRT1	;JUMP IF BUFFER NOT FULL
	SKIPE	CURBLK		;SKIP IF FIRST BLOCK OF FILE
	PUSHJ	P,BLKWRT	;NO, WRITE OUT OLD BLOCK
	SETZM	DAEBUF+1
	MOVE	BP,[DAEBUF+1,,DAEBUF+2]
	BLT	BP,DAEBUF+177
	MOVE	BP,BPSTRT	;RESET BYTE PTR TO BEGINNING OF BLOCK
	ADDI	BP,1		;POINT TO BUFFER
	AOS	CURBLK		;AND BUMP CURRENT BLOCK NUMBER
DWRT1:	MOVEM	T1,(BP)		;STORE WORD IN BLOCK
	POPJ	P,

;SUBROUTINE TO WRITE A BLOCK
;ARGS	CURBLK=BLOCK NUMBER TO WRITE

BLKWRT:	MOVE	T2,CURBLK	;BLOCK NUMBER IN FILE
	SKIPE	UPDFLG		;SKIP IF DON'T NEED TO DO USETO
	USETO	DSK,(T2)	;SET TO WRITE THIS BLOCK
	SETZM	UPDFLG		;NOTE THAT WE DONT NEED USETO NEXT TIME
	OUTPUT	DSK,DLIST	;WRITE THE BLOCK
	STATO	DSK,760000	;SKIP IF ERRORS ON THE WRITE
	POPJ	P,
	JRST	E.OERR

;STILL IN IFLE FTSAVE CONDITIONAL
;SUBROUTINE TO UPDATE THE WORD MARKED BEFORE FOR UPDATING
;ARGS	T1=ACTUAL DATA
;	REMBLK=BLOCK NUMBER IN FILE CONTAINING WORD TO WRITE
;	REMWRD=ADDR IN DAEBUF OF WORD TO WRITE

WRTSPT:	MOVE	T2,REMBLK	;T2=BLOCK WHICH CONTAINS THE WORD
	MOVE	T4,REMWRD	;T4=ADDR OF WORD IN DAEBUF
	CAME	T2,CURBLK	;SKIP IF STILL IN CURRENT BLOCK
	JRST	WRTSP1		;NO, MUST UPDATE PREVIOUSLY WRITTEN BLOCK
	EXCH	T1,(T4)		;STORE IN CORE
	CAME	T1,PATTERN	;AND SEE IF WE FOUND THE RIGHT WORD
	JRST	E.BPT		;NO, SOMETHING WENT WRONG
	POPJ	P,		;BEAUTIFUL!

;HERE TO UPDATE A PREVIOUSLY WRITTEN BLOCK

WRTSP1:	USETI	DSK,(T2)	;SET TO READ THE BLOCK
	INPUT	DSK,UPDLST	;READ THE BLOCK
	STATZ	DSK,760000	;TEST FOR ERRORS
	JRST	E.WRD		;DIDN'T MAKE IT
	ADDI	T4,SECBUF-DAEBUF;CHANGE ADDR TO POINT TO SECBUF
	EXCH	T1,(T4)		;STORE DATA, GET OLD WORD
	CAME	T1,PATTERN	;COMPARE WITH PATTERN
	JRST	E.BPT		;SOMETHING WENT WRONG
	USETO	DSK,(T2)	;NOW SET TO WRITE THE BLOCK BACK OUT
	SETOM	UPDFLG		;NOTE THAT NEXT REGULAR OUTPUT MUST DO USETO
	OUTPUT	DSK,UPDLST	;REWRITE THE BLOCK
	STATO	DSK,760000	;CHECK FOR ERRORS
	POPJ	P,		;OK
E.OERR:	AOS	WRTGUF		;NOTE ERROR
	JSP	T2,SNH		;NO RETURN IF UUO
	  JRST	E.EEND		;[471]QUIT IF GOT DETACHED
	OUTSTR	[ASCIZ .
? OUTPUT.]
	JRST	E.WRD1

;STILL IN IFLE FTSAVE CONDITIONAL
E.WRD:	JSP	T2,SNH		;NO RETURN IF UUO
	  JRST	E.EEND		;[471]DIE IF LOST TTY
	OUTSTR	[ASCIZ .
? INPUT.]
E.WRD1:	OUTSTR	[ASCIZ . ERROR, STATUS = .]
	GETSTS	DSK,T1
	PUSHJ	P,TOCT
	JRST	E.EEND		;[471]CLOSE AND ABORT

E.BPT:	EXCH	T1,(T4)		;RESTORE ORIGINAL WORD
	JSP	T2,SNH		;DON'T COME BACK IF UUO
	  JRST	E.EEND		;[471]RETURN IMMEDIATE IF NOT ATTACHED
	OUTSTR	[ASCIZ .
? TRIED TO OVERWRITE DATA WORD.]

E.EEND:	MOVEI	T2,DSK		;[471]SET UP AND THEN
	RESDV.	T2,		;[471]RELEASE DSK
	  JFCL			;[471]OH WELL...
	POP	P,(P)		;[471]CLEAN UP TE STACK
	JRST	EDCORE		;[471]ABORT THE FUNCTION

;HERE TO OUTPUT A HALF WORD OCTAL NUMBER WITHOUT SUPRESSING LEADING ZEROS

TOCTAL:	HRLI	T1,400000	;PUT A FLAG IN LH(T1)
TOCTA1:	MOVEI	T2,7		;GET MASK TO T2
	AND	T2,T1		;EXTRACT LOW ORDER 3 BITS
	LSH	T1,-3		;SHIFT THREE BITS TO RIGHT
	HRLM	T2,(P)		;SAVE LAST NUMBER ON PUSH DOWN LIST
	TRNN	T1,400000	;FLAG REACHED RH YET?
	PUSHJ	P,TOCTA1	;NO, LOOP BACK ON PDL
	HLRZ	T1,(P)		;GET LAST NUMBER
	MOVEI	SC,"0"(T1)	;CONVERT TO ASCII
	OUTCHR	SC		;TYPE IT
	POPJ	P,		;AND RETURN

>	;END IFLE FTSAVE
;SUBROUTINE TO PERFORM GETTAB VIA SPY IF POSSIBLE
;ARGS	T1=GETTAB ARG
;VALUES	T1=GETTAB VALUE
;THERE IS NO NEED TO SUPPORT -2 ITEM (JOBS HIGH SEG)

GTBSPY:
IFGE	FTSAVE,<
	TLNE	F,FL.DSK	;[551]ARE WE READING FROM DSK?
	 PJRST	GETSIM		;[551]YES-SIMULATE
>
	JUMPGE	T1,.+2		;ENSURE THAT NEG INDEX MEANS JOB (J), NOT US
	HRLI	T1,(J)		;GET THE JOB #
IFN FTSPY,<
	PUSH	P,P1		;SAVE P1
	PUSH	P,P2		;SAVE P2
	HRRZI	P1,(T1)		;P1=TABLE NUMBER
	CAML	P1,MAXGTB	;SKIP IF LEGAL TABLE
	JRST	GTBGTB		;NO, TRY GETTAB ANYWAY
	ADD	P1,GTBST	;ADDR OF PTR FOR THIS TABLE
	MOVE	P2,(P1)		;P2 GETS MODIFIED NUMTAB WORD
	TLNE	P2,(GT.PRC)	;IS DATUM IN THE PDB?
	JRST	GTBPDB		;YES. GO HANDLE DIFFERENT FORMAT
	LDB	P2,[POINT 9,P2,8] ;NO. GET MAX ITEM VALUE
	MOVSS	T1		;AND ITEM NUMBER INTO RH OF T1
	CAIGE	P2,(T1)		;IS LEGAL MAX .GE. DESIRED?
	JRST	GTBGT1		;NO. TRY GETTAB ANYWAY, PROBABLY LOSE.
	MOVE	T1,@(P1)	;GET VALUE
GTBXIT:	POP	P,P2		;RESTORE P2
	POP	P,P1		;RESTORE P1
	JRST	CPOPJ1		;GOOD RETURN

GTBPDB:	SKIPN	PDBPTR		;IS JBTPDB BASE AVAILABLE?
	JRST	GTBGTB		;NO. USE A GETTAB
	HLRZ	P2,T1		;JOB NUMBER
	ADD	P2,PDBPTR	;PLUS JBTPDB ADDRESS
	MOVE	P2,400000(P2)	;GET ADDRESS OF WD 0 OF JOBS PDB
	ADD	P2,0(P1)	;ADD ON SPY OFFSET AND ITEM NUMBER
				; WHICH WERE BOTH IN GTBST TABLE
	MOVE	T1,(P2)		;GET THE WORD FROM THE PDB
	JRST	GTBXIT		;AND EXIT FROM GETTAB SIMULATOR

GTBGT1:	MOVSS	T1		;PUT T1 BACK TO ORIGINAL VALUE
GTBGTB:	POP	P,P2		;RESTORE P2
	POP	P,P1		;RESTORE P1
>	;END CONDITIONAL ON FTSPY

	GETTAB	T1,		;TRY GETTAB
	  POPJ	P,
IFN FTSPY,<
	AOS	GTBGUF		;DEBUG--COUNT TIMES WE THOUGHT GETTAB
>				; WOULD LOSE BUT IT DIDNT
	JRST	CPOPJ1		;WINS
;SUBROUTINE TO GET DATA FROM GETTAB SUB-TABLE
;ARGS	T3= GETTAB ARG FOR SUB-TABLE POINTER
;	T2= SUBTABLE ARG: TABLE# CONTAINING SUBTABLE,,ITEM #
;VALUE	T1= DESIRED ITEM
;SKIP RETURN IF ITEM DEFINED

GSUBTB:	PUSH	P,T3		;SAVE THAT ARG
	MOVE	T1,T3		;GET SUBTABLE POINTER
	PUSHJ	P,GTBSPY
	  JRST	GSUBTX		;TOO BAD, NO SUBTABLE
	JUMPE	T1,GSUBTX	;NO SUBTABLE EXISTS
	LDB	T3,[POINT 9,T1,8] ;GET UPPER LIMIT ON SUBTABLE
	CAIGE	T3,0(T2)	;COMPARE DESIRED ITEM #
	JRST	GSUBTX		;OOPS, OFF THE END
	HRRZS	T1		;SUBTABLE POINTER IS AN ITEM NUMBER
	ADD	T1,T2		;WITH SUB-ITEM AND TABLE
	MOVSS	T1		;SWAP TO GETTAB FORM
	PUSHJ	P,GTBSPY	;GETTAB THAT
	  JRST	GSUBTX		;LOSE
	AOS	-1(P)		;WIN, TAKE SKIP RETURN
GSUBTX:	POP	P,T3		;RESTORE T3
	POPJ	P,


;SUBROUTINE TO PERFORM PEEK VIA SPY IF POSSIBLE
;ARGS	T1=ADDR OF LOCATION DESIRED
;VALUES	T1=CONTENTS OF LOCATION

PEKSPY:
IFGE	FTSAVE,<
	TLNE	F,FL.DSK	;[551]READING FROM DSK?
	 PJRST	DSKA		;[551]YES-SIMULATE
>

IFN FTSPY,<
	SKIPE	MAXGTB		;SKIP IF SPY ILLEGAL
	SKIPA	T1,400000(T1)	;OK, GET CONTENTS OF LOC
>	;END CONDITIONAL ON FTSPY

	PEEK	T1,		;CANT, TRY PEEK
	POPJ	P,
;SUBROUTINE TO SAVE P1-P4

SAVE4:	PUSH	P,P1
	PUSH	P,P2
	PUSH	P,P3
	PUSH	P,P4
	PUSHJ	P,(T4)
	  JRST	.+2
	AOS	-4(P)
	POP	P,P4
	POP	P,P3
	POP	P,P2
	POP	P,P1
	POPJ	P,
SUBTTL	CLOCK QUEUE SUBROUTINES

;HERE WHEN A TIMER RUNS OUT
IFN FTCLCK!ICLKRQ,<

WAKJOB:	HRRE	J,NEXTJB	;GET THE JOB NUMBER
	SETZM	@JBTCLK		;CLEAR OUT ENTRY
	PUSHJ	P,CLEANQ	;CLEAN THE QUEUE
	JUMPLE	J,WAKSLF	;JOBS .LE. 0 ARE INTERNAL
IFN FTCLCK,<
	WAKE	J,		;WAKE THE JOB
	  AOS	WAKGUF		;WE TRIED
>;END FTCLCK COND (THE INNER ONE)
IFE FTCLCK,<AOS CLKGUF>		;NOTE SHOULD NEVER HAPPEN
	JRST	DALOOK		;RESCAN THE QUEUE

WAKSLF:	PUSHJ	P,@CLKDSP(J)	;INVOKE INTERNAL ROUTINE
	JRST	DALOOK

	EXP	IOECLR		;[62](-3)CLEAR I/O ERROR ON ERROR.SYS
	EXP	FRCFCT		;(-2) FORCE OUT THE FACT BUFFER
	EXP	USCAN		;(-1) CHECKPOINT THE DISK STATUS
CLKDSP:	EXP	CHECK		;(0) CHECKPOINT JOBS

	DEFINE	.IFNFT	(FT,LBL),<
IFE FT,<LBL:	..IFFT==1>>
..IFFT==0

.IFNFT	(FTCHKPNT,CHECK)
.IFNFT	(FTUSCN,USCAN)
.IFNFT	(CHKFCT,FRCFCT)
.IFNFT	(MAXAGE,FRCFCT)
IFN ..IFFT,<
	AOS	CLKGUF		;NOTE A REQUEST THAT SNH
	POPJ	P,
>
	PURGE	.IFNFT,..IFFT

;STILL IN FTCLCK!ICLKRQ CONDITIONAL
;SUBROUTINE TO ENTER A REQUEST INTO THE QUEUE
;ARGS	T1=NUMBER OF SEC TO SLEEP
;	J=JOB NUMBER
;USES T1-T4

CLKREQ:	JUMPE	T1,NULREQ	;NULL REQUEST - CLEAN Q AND WAKE IMMEDIATELY
	MUL	T1,JIFSEC	;CONVERT TO JIFFIES IN T2
	MOVE	T1,[%NSUPT]
	PUSHJ	P,GTBSPY	;GET BY SPY
	  JRST	NULREQ		;CAN NOT LOOSE
	ADD	T2,T1		;TIME TO GET UP
	MOVEM	T2,@JBTCLK	;STORE IN QUEUE
	PJRST	CLEANQ		;CLEAN THE QUEUE

NULREQ:	SETZM	@JBTCLK		;CLEAR THE REQUEST
	JUMPLE	J,CLEANQ	;NO WAKE IF INTERNAL REQUEST
IFN FTCLCK,<
	WAKE	J,		;WAKE THE JOB IMMEDIATELY
	  AOS	WAKGUF		;WE TRIED AND FAILED
>;END FTCLCK COND
IFE FTCLCK,<AOS CLKGUF>		;BUMP SNH COUNTER
;	PJRST	CLEANQ		;FALL THROUGH TO RE-SCAN Q

;HERE TO SORT THE QUEUE

CLEANQ:	SETZB	T2,NEXTUP	;FLAG QUEUE EMPTY
				; T2 GETS NEXT JOB TO WAKE
	PUSH	P,J		;SAVE AC J
	MOVE	J,QPNTR		;GET THE AOBJN POINTER
	HRLOI	T1,377777	;T1_UPTIME OF NEXT WAKE
FNDMIN:	SKIPE	T3,@JBTCLK	;GET FIRST TIME
	CAMG	T1,T3		;YES--IS IT BETTER
	JRST	NXTREQ		;NO--TRY NEXT
	MOVE	T1,T3		;T1_SHORTEST TIME
	HRREI	T2,(J)		;T2_JOB WITH THAT TIME
NXTREQ:	AOBJN	J,FNDMIN	;LOOP OVER ALL JOBS
	MOVEM	T1,NEXTUP	;SAVE T1
	MOVEM	T2,NEXTJB	;SAVE JOB NUMBER
	POP	P,J
	POPJ	P,

>;END FTCLCK!ICLKRQ CONDITIONAL
;SUBROUTINE TO ENSURE THAT ANY FACT FILE ENTRY
;GETS OUT IN MAXAGE SECONDS

IFN CHKFCT,<
IFN MAXAGE,<
BUFAGE:	SKIPE	FACTSZ		;IF ANYTHING THERE, REQUEST IS ALREADY IN
	POPJ	P,
	PUSH	P,J		;SAVE J
	HRROI	J,AGERQ		;SET OUR REQUEST TYPE
	MOVEI	T1,MAXAGE	;SET MAX TIME IN BUFFER
	PUSHJ	P,CLKREQ	;MAKE THE REQUEST
	POP	P,J
	POPJ	P,		;DONE

FRCFCT:	TLO	F,L.FORC	;ENSURE IT GETS DUMPED SOON
	POPJ	P,
>;END MAXAGE COND
IFE MAXAGE,<BUFAGE==CPOPJ>
>;END CHKFCT COND

IOECLR:	SETZM	IOERR		;[62]CLEAR FLAG SO ERRFIN RETRIES NOW
	POPJ	P,		;[62]

;SUBROUTINE TO RETURN JOB'S CONTROLLING TTY NUMBER
;ARG	J=JOB NUMBER
;VALUE	T1=TTY NUMBER (-1 IF CTY)
;NON-SKIP RETURN IF JOB DETACHED

GETTTY:	HRROI	T1,.GTTTY	;GET JOB'S TTY DDB ADDR
	PUSHJ	P,GTBSPY	;GET ADDR OF DDB FOR USER JOB
	  POPJ	P,		;CAN'T FIND IT!!!
	JUMPE	T1,CPOPJ	;GIVE UP IF JOB IS DETACHED
IFN DEVNAM,<MOVEI T1,DEVNAM(T1)>
	PUSHJ	P,PEKSPY	;GET TTY NAME FROM DDB
	TLNN	T1,-1		;LEFT HALF 0 IF DETACHED
	POPJ	P,		;LOSE...
	HRLZI	T2,(T1)		;LINE NUMBER IN SIXBIT TO LEFT HALF
	JUMPE	T2,TTYCTY	;ONLY CTY HAS NO LINE NO
	SETZ	T1,
DAGLIN:	LSH	T2,3		;IGNORE 3 BITS OF OCTAL SIXBIT CODE
	LSHC	T1,3		;BUT GET THE NUMERIC QUANTITY
	JUMPN	T2,DAGLIN	;LOOP IF ANY MORE DIGITS
	JRST	CPOPJ1		;THAT'S ALL THERE IS TO IT

TTYCTY:	SETO	T1,		;NOTE CTY
	JRST	CPOPJ1		;AND RETURN SUCCESSFUL
;SUBROUTINE TO SCAN ALL DISK UNIT DATA BLOCKS
; RECORDING STATUS AND ERROR INFORMATION IN ERROR.SYS

IFN FTERR,<
IFN FTUSCN,<

USCAN:
IFE FTDET,<
	TLNE	F,L.USC		;IS SCAN SUPPRESSED?
	POPJ	P,		;YES, IGNORE
>;END FTDET
	MOVE	T1,[%LDUNI]
	PUSHJ	P,GTBSPY	;GET ADDR OF FIRST UNIT DATA BLOCK
	  POPJ	P,		;LOOKS BAD, FOLKS
USCLUP:	HLRZ	P3,T1		;ADDR OF NEXT UNIT DATA BLOCK
	JUMPE	P3,USCEND	;END OF LIST
	MOVSI	T1,.ESUSC_9
	PUSHJ	P,ERRINI	;(0-3) HEADER
	MOVE	T2,XUSCL	;SETUP TO DUMP FROM LIST
	PUSHJ	P,UNIDMP	;DUMP A SET OF UNIT DATA BLOCK ITEMS
	PUSHJ	P,ERRFIN	;WRITE THAT CHUNK
	MOVEI	T1,UNISYS(P3)	;ADDR IN UDB OF POINTER TO NEXT
	PUSHJ	P,PEKSPY	;GET POINTER TO NEXT IN SYSTEM
	JRST	USCLUP		;DUMP IT

USCEND:	MOVE	T1,CUTIM	;PICK UP TIME BETWEEN SCANS
	MOVEI	J,USCRQ		;INTERNAL REQUEST CODE
	PJRST	CLKREQ		;LOG REQUEST AND RETURN
>;END FTUSCN CONDITIONAL


;SUBROUTINE TO DUMP SELECTED MONITOR ITEMS
;ARGS	T2=AOBJN WORD FOR LIST OF ITEMS
;	P3=BASE ADDR OF TABLE FROM WHICH ITEMS COME
;	P4=AOBJN WORD FOR OUTPUT BUFFER
;VALUES	P4=UPDATED BUFFER POINTER
;RETURN	CPOPJ, T1-2 BLOWN, OTHERS INTACT

UNIDMP:	HLRZ	T1,0(T2)	;GET AC CONTAINING BASE ADDRESS
	MOVE	T1,0(T1)	;GET BASE ADDRESS FOR TABLE
	ADD	T1,0(T2)	;ADD INDEX TO BASE
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;STORE IN ERROR.SYS BUFFER
	AOBJN	T2,UNIDMP	;LOOP FOR ALL ITEMS
	POPJ	P,

;STILL IN FTERR COND
;TABLES FOR UNIT DATA BLOCK ITEMS TO BE DUMPED

IFN FTUSCN,<
XUSCL:	XWD	.-ZUSCL,.+1	;AOBJN WORD FOR TABLE OUTPUT BY USCAN
	XWD	P3,UNINAM		;(3) DEV NAM
	XWD	P3,UNIHID		;(4) PACK ID
	XWD	P3,UNIHCT		;(5) HARD ERROR COUNT
	XWD	P3,UNISCT		;(6) SOFT ERROR COUNT
	XWD	P3,UNIPCT		;(7) SEEK ERROR COUNT
	XWD	P3,UNIHNG		;(10) HUNG COUNTS
	XWD	P3,UNIMCT		;(11) SOFTWARE-DETECTED ERRORS
	XWD	P3,UNIBRC		;(12) BUFFERED READS
	XWD	P3,UNIBWC		;(13) BUFFERED WRITES
	XWD	P3,UNIDRC		;(14) DUMP READS
	XWD	P3,UNIDWC		;(15) DUMP WRITES
	XWD	P3,UNIMRC		;(16) MONITOR READS
	XWD	P3,UNIMWC		;(17) MONITOR WRITES
	XWD	P3,UNIICT		;(20) SWAP READS
	XWD	P3,UNIOCT		;(21) SWAP WRITES
	XWD	P3,UNIMSC		;(22) MONITOR SEEKS
	XWD	P3,UNIUSC		;(23) USER SEEKS
ZUSCL==.-1
>;END FTUSCN CONDITIONAL

IFN UNITN,<
XDVEL:	XWD	.-ZDVEL,.+1
	XWD	P3,UNINAM	;(3) PHYSICAL UNIT NAME
	XWD	P3,UNIHID	;(4) PACK (HOME BLOCK) ID
	XWD	P3,UNIHCT	;(5) HARD ERROR COUNT
	XWD	P3,UNISCT	;(6) SOFT ERROR COUNT
	XWD	P3,UNIECT	;(7) RETRY COUNT
	XWD	P3,UNISOF	;(10) 1CONI - ERROR CONI AFTER INITIAL ATTEMPT
	XWD	P3,UNIERR	;(11) 2CONI - ERROR CONI AFTER 1ST RECALIBRATE
	XWD	P3,UNISDI	;(12) 1DATAI - AFTER INITIAL ATTEMPT
	XWD	P3,UNIHDI	;(13) 2DATAI - AFTER 1ST RECALIBRATE
	XWD	P3,UNIHBN	;(14) BLOCK NO OF LAST HARD ERROR
	XWD	P3,UNIMCT	;(15) SOFTWARE-DETECTED ERROR COUNTS
	XWD	P3,UNIPCT	;(16) SEEK INCOMPLETE ERRORS
	XWD	P3,UNIHNG	;(17) HUNG COUNTS
ZDVEL==.-1
>;END UNITN COND

IFN MTAN,<
XMTEL:	XWD	.-ZMTEL,.+1
	XWD	P3,MTXNAM	;(3) DRIVE NAME
	XWD	P2,MTXRID	;(4) REELID
	XWD	P2,MTXNFB	;(5) NUMBER OF FILES FROM BOT
	XWD	P2,MTXNRF	;(6) NUMBER OF RECORDS FROM LAST EOF
	XWD	P2,MTXICC	;(7) INITIAL CONI MTC OF LAST ERROR
	XWD	P2,MTXICS	;(10) INITIAL CONI MTS OS LAST ERROR
	XWD	P2,MTXFCC	;(11) FINAL CONI MTC OF LAST ERROR
	XWD	P2,MTXFCS	;(12) FINAL CONI MTS OF LAST ERROR
	XWD	P2,MTXTRY	;(13) NUMBER OF RETRIES; BIT 1=1 IF SUCCESSFUL
	XWD	P2,MTXFLG	;(14) FLAG (-1) IF LAST REPORT FOR THIS REEL
ZMTEL==.-1

XMTUL:	XWD	.-ZMTUL,.+1
	XWD	P3,MTXNAM	;(3) DRIVE NAME
	XWD	P2,MTDRID	;(4) REELID OF REEL BEING UNLOADED
	XWD	P2,MTDWRD	;(5) NUMBER OF WORDS READ SINCE LAST UNLOAD
	XWD	P2,MTDWWT	;(6) NUMBER OF WORDS WRITTEN SINCE LAST UNLOAD
	XWD	P2,MTDSRE	;(7) NUMBER OF SOFT READ ERRORS SINCE LAST UNLOAD
	XWD	P2,MTDHRE	;(10) NUMBER OF HARD READ ERRORS SINCE LAST UNLOAD
	XWD	P2,MTDSWE	;(11) NUMBER OF SOFT WRITE ERRORS SINCE LAST UNLOAD
	XWD	P2,MTDHWE	;(12) NUMBER OF HARD WRITE ERRORS SINCE LAST UNLOAD
ZMTUL==.-1
>;END MTAN CONDITIONAL


IFN UNITN,<
XMDVEL:	XWD	.-ZMDVEL,.+1
	XWD	P3,UNINAM	;(3)PHYSICAL UNIT NAME
	XWD	P3,UNIHID	;(4)PACK ID (HOME BLOCK ID)
	XWD	P3,UNILOG	;(5)LOGICAL NAME OF UNIT (STR NAME)
	XWD	P3,UNIHBN	;(6)BLOCK OF LAST HARD ERROR
	XWD	P3,UNIECT	;(7)RETRY COUNT
	XWD	P3,UNISOF	;(10)1CONI - ERROR CONI AFTER INITIAL ATTEMPT
	XWD	P3,UNIERR	;(11)2CONI - ERROR CONI AFTER 1ST RECALIBRATE
	XWD	P3,UNIMCT	;(12)SOFTWARE DETECTED ERROR COUNTS
	XWD	P3,UNIPCT	;(13)SEEK INCOMPLETE ERRORS
	XWD	P3,UNIHNG	;(14)HUNG COUNTS
ZMDVEL==.-1
>;END UNITN COND
;STILL IN FTERR COND
IFN MTAN,<
XTPEL:	XWD	.-ZTPEL,.+1
	XWD	P1,TUBRID	;(4)REELID
	XWD	P1,TUBFIL	;(5)FILES FROM BOT
	XWD	P1,TUBREC	;(6)RECORDS FROM LAST EOF
	XWD	P1,TUBTRY	;(7)RETRY COUNT + HARD ERROR BIT
	XWD	P1,TUBCCR	;(10)CHARACTERS INTO CURRENT RECORD
	XWD	P1,TUBPBE	;(11)POSITION BEFORE ERROR
	XWD	P1,TUBFES	;(12)FINAL ERROR STATE
ZTPEL==.-1

XTPUL:	XWD	.-ZTPUL,.+1
	XWD	P3,DEVNAM	;(3)DEVICE NAME
	XWD	P1,TUBRID	;(4)REELID
	XWD	P1,TUBCRD	;(5)CHARACTERS READ
	XWD	P1,TUBCWR	;(6)CHARACTERS WRITTEN
	XWD	P1,TUBSRE	;(7)SOFT READ ERRORS
	XWD	P1,TUBHRE	;(10)HARD READ ERRORS
	XWD	P1,TUBSWE	;(11)SOFT WRITE ERRORS
	XWD	P1,TUBHWE	;(12)HARD WRITE ERRORS
ZTPUL==.-1

>;END IFN MTAN
;STILL IN FTERR COND
SUBTTL	ROUTINES TO RECORD HARDWARE ERROR INFO IN ERROR.SYS

;SUBROUTINE TO RECORD A CPU-DETECTED ERROR
;ARGS	T1=ERROR.SYS CODE IN BITS 0-8
;	P1=CPU #
;	P2=CPU # TIMES 2 (FOR GETTAB CPU TABLES)
;RETURNS CPOPJ, P1 AND P2 INTACT, P4, T1-4 BLOWN

IFN CPUN,<
GCPERR:	PUSHJ	P,ERRINI	;(0-2) SETUP BUFFER AND P4
	MOVE	T1,[%CCPHY]	;PHYSICAL CPU NAME
	ADD	T1,P2		;IN THIS CPU'S CONSTANT TABLE
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;SNH
	PUSH	P4,T1		;(3) DEVICE NAME
	MOVE	T1,[%CVTPE]
	PUSHJ	P,GCPVAR	;(4)TOTAL ERRORS WHICH RECURRED ON SWEEP OF CORE
	MOVE	T1,[%CVSPE]
	PUSHJ	P,GCPVAR	;(5) TOTAL NOT REPRODUCABLE
	MOVE	T1,[%CVMPC]	;MEM PAR CONTINUES
	PUSHJ	P,GCPVAR	;(6)
	MOVE	T1,[%CVMPP]	;PC AT TIME OF ERROR
	PUSHJ	P,GCPVAR	;(7) PC (EXEC OR USER)
	MOVE	T1,[%CVMPW]	;1ST WORD FOUND IN ERROR
	PUSHJ	P,GCPVAR	;(10)
	MOVE	T1,[%CVMPA]	;FIRST BAD ADDRESS
	PUSHJ	P,GCPVAR	;(11)
	AOBJN	P4,.+1		;(12) SPACE FOR
EC%PAR==13			;[EDIT 466]PARITY DATA SUBTABLE POINTER
	AOBJN	P4,.+1		;(13) SPACE FOR
EC%BAT==14			;[EDIT 466]BAD ADDRESS SUBTABLE POINTER
	MOVE	T1,[%SYSPP]	;[463]PPN OF USER, LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1
	MOVE	T1,[%SYSPN]	;PROG NAME ON LAST STOPCD
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1	;END [463]
	PUSHJ	P,KLCPU		;REPORT KL10 CONI AND RDERA
;****KLCPU SET UP P3 WITH LOCATION OF POINTER TO SBDIAG SUBTABLE FOR
;	CALL TO KLSBDG
	HRRZM	P4,ERABUF+EC%PAR	;SAVE START ADDRESS OF SUBTABLE
	MOVE	T3,[%CCPAR]	;SUB-TABLE POINTER FOR OTHER PAR STUFF
	ADD	T3,P2		;FROM THIS CPU CONSTANTS TABLE
	MOVSI	T2,.GTC0V(P2)	;SUBTABLE IS IN CPU VAR TABLE
PARSLP:	PUSHJ	P,GSUBTB	;GET ENTRY FROM SUBTABLE
	  JRST	EPARTB		;END OF PARITY SUBTABLE
	PUSH	P4,T1		;GIVE
	AOJA	T2,PARSLP	;GET WHOLE SUBTABLE
EPARTB:	MOVE	T1,ERABUF+EC%PAR	;START LOC OF PAR ENTRY 
	MOVEI	T2,(T1)	;SAVE ABSOLUTE START OF SUBTABLE IN T2 ALSO
	SUBI	T1,(P4)		;-LENGTH WRITTEN
	JUMPE	T1,NPARTB	;IF NONE, THEN NO BAD ADDR'S EITHER
	SUBI	T2,ERABUF-1	;RELOCATE START OF SUBTABLE
	HRLI	T2,(T1)		;AND PUT LENGTH INTO LH
	MOVEM	T2,ERABUF+EC%PAR	;SAVE AS POINTER TO SUBTABLE
	HRRZM	P4,ERABUF+EC%BAT

;STILL IN FTERR COND AND CPUN COND
;HERE TO RECORD BAD ADDRESSES

GBATBL:	HRRI	T2,%CVPTS	;OTHER POINTERS ARE ALREADY SET
	PUSHJ	P,GSUBTB	;NO OF BAD ADDRESSES SAVED
	  JRST	NBATTB		;NONE IF NO TABLE FOR THEM
	MOVEI	T4,(T1)		;KEEP THE COUNT
	JUMPE	T4,NBATTB	;QUIT IF NONE
	HLL	T3,[%CCMPT]	;LOOK IN BAT SUBTABLE NOW
	HLLZS	T2		;START AT BEGINNING OF TABLE
BATSLP:	PUSHJ	P,GSUBTB	;GET NEXT BAD ADDRESS
	  JRST	EBATTB		;END OF SUB-TABLE
	MOVEM	T1,1(P4)	;SAVE THE BAD ADDR
	AOBJP	P4,EBATTB	;CHECK FOR BUFFER OVERFLOW
	AOJ	T2,		;READY FOR NEXT ENTRY
	SOJG	T4,BATSLP	;GET IT IF ONE WAS STORED
EBATTB:	MOVE	T1,ERABUF+EC%BAT
	MOVEI	T2,(T1)
	SUBI	T1,(P4)
	JUMPE	T1,NBATTB	;IN CASE SUB-TABLE LENGTH = 0
	SUBI	T2,ERABUF-1	;REL LOC OF FIRST WORD OF BAD ADDR TABLE
	HRLI	T2,(T1)
	MOVEM	T2,ERABUF+EC%BAT
	PJRST	KLSBDG	;WRITE SBDIAG SUBTABLE AND RETURN

NBATTB:	SETZM	ERABUF+EC%BAT
	PJRST	KLSBDG	;WRITE SBDIAG SUBTABLE AND RETURN

NPARTB:	SETZM	ERABUF+EC%PAR	;NO SUBTABLES, SO CLEAR POINTERS
	SETZM	ERABUF+EC%BAT		;CLEAR BAT POINTER ALSO
	PJRST	KLSBDG	;WRITE SBDIAG SUBTABLE AND RETURN

GCPVAR:	ADD	T1,P2		;CUT DOWN THE TYPING BY PUTTING THIS
	PUSHJ	P,GTBSPY	; ALL IN ONE PLACE
	  SETZ	T1,
	PUSH	P4,T1		;SAVE AN ITEM IN THE ERROR FILE
	POPJ	P,

;HERE TO FIND CPU NUMBER CORRESPONDING TO CDB ADDRESS
;CALLED WITH P3 CONTAINING CDB ADDR
;RETURNS WITH P1 CONTAINING CPU # IN RIGHT HALF
;NON SKIP RETURN MEANS NO CPU MATCHED
FNDCPU:	MOVSI	P1,-CPUN	;GET NUMBER OF CPUS WE KNOW ABOUT
FNDCP1:	HRRZ	T1,P1		;GET CPU NUMBER INTO T1
	LSH	T1,1		;DOUBLE IT FOR .GTC0C, ETC.
	HRLI	T1,.GTC0C(T1)	;GET .GTCNC FOR THIS CPU
	HRRI	T1,.GTSLF	;SET UP TO GETTAB START OF .GTCNC
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;OOPS
	CAIN	P3,(T1)		;IS THIS THE CPU
	JRST	CPOPJ1		;YES, GIVE SKIP RETURN
	AOBJN	P1,FNDCP1	;NO, TRY NEXT
	POPJ	P,		;NONE MATCH, GIVE ERROR RETURN

;HERE TO DETERMINE IS THIS IS A KL10 PROCESSOR
;ALL REGS PRESERVED
;SKIPS IF CPU IS A KL10
ISKL10:	PUSH	P,T1		;SAVE T1
	MOVEI	T1,0		;CLEAR AN AC
	BLT	T1,0		;AND DO A ZERO LENGTH BLT
	SKIPE	T1		;IF NON-ZERO, NO KL10
	AOS	-1(P)		;IF KL, SKIP
	POP	P,T1		;GET OLD T1 BACK
	POPJ	P,		;AND RETURN

;HERE TO PUT SPECIAL STUFF INTO ERROR FILE ENTRY IF THIS IS A KL10
KLCPU:	SKIPN	NERRPT		;IF WE DON'T DO NEW STYLE REPORTING
	  POPJ	P,		;JUST RETURN
	PUSHJ	P,ISKL10	;IS THIS A KL10?
	  POPJ	P,		;NO, EXIT
	MOVE	T1,[%CVPCN]	;RESULTS OF CONI APR,
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVAER]	;RESULTS OF RDERA
	PUSHJ	P,GCPVAR
	AOBJN	P4,.+1	;RESERVE THE SPACE ALSO
	HRRZ	P3,P4		;SAVE CURRENT ERROR FILE LOC FOR LATER
	POPJ	P,		;AND RETURN

;HERE TO WRITE SBDIAG SUBTABLE IF PROCESSOR IS A KL10
KLSBDG:	SKIPN	NERRPT		;RETURN IF NO NEW ERROR REPORTING
	PJRST	ERRFIN		;MUST CLOSE FILE
	PUSHJ	P,ISKL10	;IS THIS A KL10?
	  PJRST	ERRFIN		;NO, EXIT CLOSING FILE
	MOVEI	T1,(P4)		;GET CURRENT ERROR FILE LOC
	SUBI	T1,ERABUF-1	;MAKE IT RELATIVE
	HRLI	T1,-2		;ALWAYS TWO WORDS LONG
	MOVEM	T1,(P3)	;KLCPU POINTED P3 AT SUBTABLE POINTER
	MOVE	T1,[%CVS0A]	;RESULTS OF SBDIAG FUNCTION 1
	PUSHJ	P,GCPVAR
	MOVE	T1,[%CVS1A]	;RESULTS OF SBDIAG FUNCTION 1
	PUSHJ	P,GCPVAR
	PJRST	ERRFIN		;CLOSE FILE AND RETURN

>;END CPUN CONDITIONAL
;STILL IN FTERR COND
;SUBROUTINE TO RECORD A CHANNEL-DETECTED PARITY ERROR OR NON-EX MEM
;ARGS	P2=ADDRESS OF CHANNEL DATA BLOCK
;RETURN	CPOPJ, P1-P3 INTACT; P4, T1-4 BLOWN

IFN CHNN,<
GCHERR:	PUSHJ	P,ERRINI	;(0-2) HEADER, SET UP P4, CLEAR BUFFER
	MOVEI	T1,.CHLUE(P2)	;GET POINTER TO LAST UNIT WITH ERROR
	PUSHJ	P,PEKSPY
	ANDI	T1,-1		;RH ONLY
	JUMPE	T1,NODVNM	;STORE 0 IF DEVICE UNKNOWN
IFN UNINAM,<ADDI T1,UNINAM>	;ADDR OF NAME OF ERROR UNIT
	PUSHJ	P,PEKSPY	;PICK UP UNIT NAME
NODVNM:	PUSH	P4,T1		;(3) UNIT NAME
	MOVEI	T1,.CHNXM(P2)
	PUSHJ	P,PEKSPY	;GET NXM COUNT FOR THIS CHANNEL
	PUSH	P4,T1		;(4) NON-EX MEM COUNT
	MOVEI	T1,.CHMPE(P2)
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;(5) MEM PAR ERR COUNT THIS CHANNEL
	MOVEI	T1,.CHDPE(P2)
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;(6) DEVICE PARITY ERRORS
	MOVSI	T2,<.CHICW-.CHDW0-1>	;SETUP AOBJN WORD
	HRRI	T2,.CHICW(P2)	;WITH POINTER TO CHAN DATA BLOCK
GCHLUP:	MOVEI	T1,(T2)		;GET ADDR TO EXAMINE
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;(7-16) CONTROL AND DATA WORDS
	AOBJN	T2,GCHLUP
;**;[545] @GCHLUP+4
;**;[545] DELETE	MOVE	T1,.CHTCW	;[463]
	SKIPN	T1,CHNTCW	;[545] GET OFFSET IF ANY
	  JRST	GCHER1		;[545] NONE, STORE ZERO
	ADDI	T1,0(P2)	;ADD OFFSET
	PUSHJ	P,PEKSPY
GCHER1:	PUSH	P4,T1		;EXPECTED TERM WD[463]
	PJRST	ERRFIN		;WRITE THE STUFF AND RETURN

>;END CHNN COND
;STILL IN FTERR COND
;SUBROUTINE TO RECORD MAGTAPE ERRORS (MTXSER)
;ARGS	P1=AOBJN WORD FOR ALL DRIVES IN SYS
;	P2=ADDRESS OF MTXRID IN DDB
;	P3=DDB ADDRESS
;RETURN CPOPJ, P1-P3 INTACT, P4,T1-Y4 BLOWN

IFN MTAN,<
GMTERR:	PUSHJ	P,ERRINI	;(0-2) HEADER, SETUP P4, CLEAR BUFFER
	MOVE	T2,XMTEL	;LIST OF ITEMS TO DUMP
	PUSHJ	P,UNIDMP	;(3-14) DUMP THEM
	PJRST	ERRFIN		;CLOSE AND RETURN

;SUBROUTINE TO RECORD MAGTAPE ERROR STATISTICS (MTXSER)
;ARGS SAME AS GMTERR ABOVE

GMTSTS:	PUSHJ	P,ERRINI	;(0-2) HEADER
	MOVE	T2,XMTUL	;LIST OF THINGS TO DUMP
	PUSHJ	P,UNIDMP	;(3-12) DUMP THEM
	MOVE	T1,P3		;DDB ADDR TO T1
	PUSHJ	P,DDBJOB	;GO GET OWNER'S JOB NUMBER
	MOVE	J,T1		;AND PUT IT INTO J
	PUSHJ	P,GETPPN	;GET PPN OF OWNER
	PUSH	P4,T1		;(13) STORE IN THE BUFFER
	PJRST	ERRFIN		;CLOSE AND RETURN

;SUBROUTINE TO RECORD MAGTAPE STATISTICS ON UNLOAD (TAPSER)
;ARGS	P1=AOBJN WORD FOR ALL DRIVES IN SYS
;	P2=OFFSET OF TUBRID IN TUB
;	P3=DDB ADDRESS
;	P4=POINTER TO TUBRID IN CURRENT TUB
;RETURN CPOPJ,P1-P4 INTACT,T1-T4 BLOWN

;CALL GTPSTU IF FROM UNLOAD COMMAND.  IN THIS CASE, THE DATA IS
;STORED IN THE SHADOW AREA OF THE TAPE UNIT BLOCK, SO THE SHADOW
;OFFSET MUST BE USED TO FIND THE DATA.

GTPSTU:	TRO	F,R.UNLO	;NOTE THIS IS AN UNLOAD ENTRY
GTPSTS:	PUSH	P,P1	;PRESERVE P1
	MOVEI	P1,0(P4)	;GET ADDRESS OF SHADOW AREA FOR CURRENT
				; TUB INTO P1
	PUSH	P,P4		;PRESERVE P4
	PUSHJ	P,ERRINI	;(0-2) HEADER, SETUP P4 AND BUFFER
	MOVE	T2,XTPUL	;LIST OF ITEMS TO DUMP
	PUSH	P,P3		;SAVE IT 
	MOVE	T1,[%CNTDB]	;FIND TUBDDB
	PUSHJ	P,GTBSPY
	 JRST	GTPST1		;NOT THERE, USE OLD STYLE
	ADD	T1,P1		;COMPUTE TUBDDB
	SUB	T1,P2
	PUSHJ	P,PEKSPY
	HRRZM	T1,P3
GTPST1:	TRZE	F,R.UNLO	;NEED SHADOW DATA?
	ADDI	P1,TUBDDA-TUBRID;YES, GET CORRECT OFFSET
	PUSHJ	P,UNIDMP	;(3-12)DUMP THEM
	POP	P,P3		;RESTORE P3
	MOVE	T1,P3		;DDB ADDR TO T1
	PUSHJ	P,DDBJOB	;GET OWNER'S JOB NUMBER
	MOVE	J,T1		;AND PUT IT INTO J
	PUSHJ	P,GETPPN	;GET PPN
	PUSH	P4,T1		;(13)SAVE IT IN BUFFER
	PUSHJ	P,ERRFIN	;FINISH OFF AND WRITE ENTRY IN ERROR FILE
	POP	P,P4		;RESTORE ADDR OF TUB+TUBRID
	POP	P,P1		;RESTORE AOBJN WORD FOR ALL UNITS
	POPJ	P,		;RETURN

;STILL IN MTAN CONDITIONAL
;STILL IN FTERR CONDITIONAL
;SUBROUTINE TO RECORD A MAGTAPE ERROR (TAPSER)
;ARGS AS IN GTPSTS ON LAST PAGE

GTPERR:	PUSH	P,P1		;PRESERVE POINTER TO BLOCK FOR TAPES
	MOVEI	P1,0(P4)	;GET OFFSET TO TUBRID IN TUB INTO P1
	PUSHJ	P,ERRINI	;(0-2)SET UP P4, PRODUCE HEADER
	MOVE	T1,[%CNTDB]	;FIND TUBDDB
	PUSHJ	P,GTBSPY
	 JRST	GTPER1		;NOT THERE, USE OLD STYLE
	ADD	T1,P1		;COMPUTE TUBDDB
	SUB	T1,P2
	PUSHJ	P,PEKSPY
GTPER1:	MOVEI	T1,DEVNAM(T1)
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;(3)PUT IT INTO BUFFER
	MOVEM	T1,ERPTBK+1		;REMEMBER DEVICE NAME IN ERPTBK TO USE FOR TAPOP
	MOVE	T2,XTPEL	;SET UP LIST OF ITEMS TO DUMP
	PUSHJ	P,UNIDMP	;(4-12)DUMP THEM
	HRLZI	T1,2		;NUMBER OF AGRS FOR TAPOP.
	HRRI	T1,ERPTBK		;WHERE THEY ARE
	MOVEI	T2,1002		;FUNCTION FOR TAPOP.
	MOVEM	T2,ERPTBK	;SAVE IT IN BLOCK FOR UUO
	TAPOP.	T1,		;WHAT KIND OF DEVICE?
	  SETZ	T1,		;OOPS
	DPB	T1,[POINT 3,ERABUF+10,14]	;AND SAVE TYPE IN RETRY WORD
	MOVE	T1,[2,,T2]	;SET UP FOR DIAG.
	MOVEI	T2,7		;GET CONTROLLER NUMBER
	MOVE	T3,ERPTBK+1	;UNIT NAME
	DIAG.	T1,		;WHAT CONTROLLER?
	  SETZ	T1,		;BEFORE 603, ASSUME RH10
	CAMGE	T1,[540,,0]	;RH10?
	TDZA	T1,T1		;YES
	MOVSI	T1,(1B11)	;NO
	IORM	T1,ERABUF+10	;1B11 IF RH20
	MOVEI	T1,ERPTBK	;GET ADDR FOR TAPOP. ARGS INTO T1
	HRLI	T1,2		;NUMBER OF ARGS
	MOVEI	T2,1017		;AND GET ARG FOR POINTER TO INITIAL
	MOVEM	T2,ERPTBK	; ERROR AREA INTO BLOCK FOR TAPOP.
	TAPOP.	T1,		;GO GET IT
	  SETZ	T1,	;OOPS
	MOVE	T3,T1		;REMEMBER POINTER IN BUFFER
ET%IEP==16
	HRRI	T1,ET%IEP	;PUT FILE OFFSET OF INITIAL AREA INTO RH OF T1
	PUSH	P4,T1		;(13)PUT IT IN BUFFER
	HLRE	T4,T3		;GET LENGTH OF INITIAL AREA INTO T4
	MOVNS	T4		;MAKE IT POSITIVE
	ADDI	T4,ET%IEP	;ADD IN START OF INITIAL AREA TO MAKE START OF FINAL AREA
	ADDI	T3,(P1)		;ADD OFFSET OF TUBRID+START OF TUB
	SUBI	T3,(P2)		;SUBTRACT OFFSET OF TUBRID IN TUB
	MOVE	T2,T3		;AND REMEMBER IN T2
	MOVEI	T1,1020		;FUNCTION FOR TAPOP. TO GET POINTER
	MOVEM	T1,ERPTBK	; TO FINAL ERROR STATUS AREA
	HRLZI	T1,2		;NUMBER OF ARGS FOR TAPOP.
	HRRI	T1,ERPTBK	;WHERE THEY ARE
	TAPOP.	T1,		;GO GET FINAL ERROR POINTER
	  SETZ	T1,	;OOPS
	MOVE	T3,T1		;REMEMBER IN T3 FOR LATER
	HRR	T1,T4		;GET FILE OFFSET OF FINAL AREA IN RH(T1)
	PUSH	P4,T1		;(14)PUT IN BUFFER
IERLUP:	MOVEI	T1,(T2)		;GET NEXT WORD TO RECORD
	PUSHJ	P,PEKSPY	;PICK IT UP
	PUSH	P4,T1		;AND PUT IT IN THE BUFFER
	AOBJN	T2,IERLUP	;LOOP ON INITIAL ERROR AREA
	ADDI	T3,(P1)		;ADD OFFSET OF TUBRID+START OF TUB
	SUBI	T3,(P2)		;SUBTRACT OFFSET OF TUBRID IN TUB
	MOVE	T2,T3		;AND REMEMBER IN T2
FERLUP:	MOVEI	T1,(T2)		;GET NEXT WORD TO RECORD
	PUSHJ	P,PEKSPY	;PICK IT UP
	PUSH	P4,T1		;AND PUT IT IN THE BUFFER
	AOBJN	T2,FERLUP	;LOOP ON FINAL ERROR AREA
	PUSHJ	P,ERRFIN	;CLOSE ERROR FILE
	MOVE	P4,P1		;RESTORE P4
	POP	P,P1		;RESTORE POINTER TO MAGTAPE ERROR AREA
	POPJ	P,

>;END IFN MTAN CONDITIONAL
;SUBROUTINE TO RECORD A DISK ERROR
;ARGS	P1=AOBJN WORD FOR ALL UNITS IN SYS
;	P2=ADDR OF DDB WITH ERROR, IFF WE DO NEW ERROR REPORTING, AND
;	    WE STOPPED THE JOB, UNDEFINED IF WE DO OLD ERROR REPORTING
;	P3=ADDR OF UNIT DATA BLOCK IN ERROR
;RETURN	CPOPJ, P1-P3 INTACT; P4,T1-4 BLOWN

IFN UNITN,<
GDVERR:	PUSHJ	P,ERRINI	;(0-2) HEADER, SETUP P4, CLEAR BUFER
	MOVE	T2,XDVEL	;LIST OF ITEMS TO DUMP
	PUSHJ	P,UNIDMP	;(3-17) DUMP THEM
	MOVEI	T1,UNIBRC(P3)	;BUFFERED READ COUNT
	PUSHJ	P,PEKSPY
	MOVE	T2,T1
	MOVEI	T1,UNIDRC(P3)	;DUMP-MODE READ COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIMRC(P3)	;MONITOR READ COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1		;GET THEM ALL TOGETHER
	PUSH	P4,T2		;(20) TOTAL READS ON THIS UNIT
	MOVEI	T1,UNIBWC(P3)	;BUFFERED WRITE COUNT
	PUSHJ	P,PEKSPY
	MOVE	T2,T1
	MOVEI	T1,UNIDWC(P3)	;DUMP MODE WRITES
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIMWC(P3)	;MONITOR WRITES
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	PUSH	P4,T2		;(21) TOTAL WRITES ON THIS UNIT
	MOVEI	T1,UNIMSC(P3)	;MONITOR SEEK COUNT
	PUSHJ	P,PEKSPY
	MOVE	T2,T1
	MOVEI	T1,UNIUSC(P3)	;USER SEEK COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	PUSH	P4,T2		;(22) TOTAL SEEKS ON THIS UNIT
	MOVEI	T1,UNINAM(P3)
	PUSHJ	P,PEKSPY	;RE-GET UNIT NAME
	MOVEI	T2,T1		;SET POINTER TO IT
	DSKCHR	T2,		;GET UNIT CHARACTERISTICS
	  SETZ	T2,		;LOSE
	PUSH	P4,T2		;(23) DSKCHR INFO FOR THIS UNIT
	MOVEI	T1,UNILOG(P3)	;(24) LOGICAL NAME OF UNIT
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE  UNILOG
;START [463]
	MOVE	T1,UNICCT
	ADDI	T1,0(P3)	;OFFSET
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;# BAT SLOTS LEFT
	MOVEI	T3,2		;# OF WORDS TO GET FROM DDB
	MOVE	T2,LDDBSH	;LENGTH OF SHORT DDB=OFFSET OF DEVFIL IN DSK DDB
GDVER1:	MOVEI	T1,(P2)		;GET DDB ADDR INTO T1
	ADDI	T1,(T2)		;ADD IN OFFSET OF  WORD WE WANT
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;AND SAVE IT AWAY IN ERABUF
	AOS	T2		;STEP TO NEXT WORD
	SOJG	T3,GDVER1	;DONE?
	HLLZS	0(P4)		;SAVE ONLY LH OF EXTENSION WORD
	MOVE	T1,P2		;GET DDB ADDRESS INTO T1
	PUSHJ	P,DDBJOB	;GET JOB # OWNING THIS DDB
	MOVE	T2,T1		;REMEMBER JOB NUMBER IN T2 FOR 2ND GETTAB
	MOVSI	T1,(T2)		;SET UP T1 TO GETTAB USERS PPN
	HRRI	T1,.GTPPN	; FOR THIS JOB
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1		;STASH IT
	MOVSI	T1,(T2)		;AND SET UP T1 TO GETTAB PROGRAM
	HRRI	T1,.GTPRG	; NAME FOR THIS JOB
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;CAN'T GET IT, STORE 0
	PUSH	P4,T1		;STORE IT IN ERABUF
;	END [463]
	PJRST	ERRFIN		;FALL INTO CLOSE AND RETURN

;STILL IN UNITN COND
;STILL IN FTERR COND
;SUBROUTINE TO RECORD A MASSBUS DEVICE ERROR (CODE 11) IN ERROR.SYS
;ARGS	T1=CODE FOR ENTRY IN ERROR.SYS
;	T2=NUMBER OF DRIVE REGISTRS SAVED ON THIS UNIT
;	P1=AOBJN WORD FOR ALL UNITS IN SYS
;	P2=ADDR OF DDB WITH ERROR, IFF WE DO NEW ERROR REPORTING, AND
;	    WE STOPPED THE JOB, UNDEFINED IF WE DO OLD ERROR REPORTING
;	P3=ADDR OF UNIT DATA BLOCK IN ERROR
;RETURN CPOPJ, P1-P3 INTACT; T1-T4,P4 BLOWN
	ND	(%LDCDA,(XWD 105,16))	;[551]

GMDVER:	PUSH	P,P2		;SAVE P2
	PUSH	P,T2		;SAVE T2 FOR LATER
	PUSHJ	P,ERRINI	;WRITE HEADER (0-2)
	MOVE	T1,[%LDCDA]	;[551]
	PUSHJ	P,GTBSPY	;[551] GET OFFSET OF UNICDA
	 MOVEI	T1,UNICDA	;[551] GETTAB FAILED?
	ADD	T1,P3	;[551] NOW GET ADDR OF DDB
	PUSHJ	P,PEKSPY
	SKIPN	NERRPT		;DON'T USE THE ONE IN THE UDB
	MOVE	P2,T1		;GET IT IN P2
	MOVE	T2,XMDVEL	;GET AOBJN WORD FOR TABLE
	PUSHJ	P,UNIDMP	;AND DUMP THE TABLE'S ITEMS
	MOVEI	T3,2		;# OF WORDS TO GET FROM DDB
	MOVE	T2,LDDBSH	;LENGTH OF SHORT DDB=OFFSET OF DEVFIL IN DSK DDB
GMDVR1:	MOVEI	T1,(P2)		;GET DDB ADDR INTO T1
	ADDI	T1,(T2)		;ADD IN OFFSET OF  WORD WE WANT
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;AND SAVE IT AWAY IN ERABUF
	AOS	T2		;STEP TO NEXT WORD
	SOJG	T3,GMDVR1	;DONE?
	HLLZS	0(P4)		;SAVE ONLY LH OF EXTENSION WORD
	MOVE	T1,P2		;GET DDB ADDRESS INTO T1
	PUSHJ	P,DDBJOB	;GET JOB # OWNING THIS DDB
	MOVE	T2,T1		;REMEMBER JOB NUMBER IN T2 FOR 2ND GETTAB
	MOVSI	T1,(T2)		;SET UP T1 TO GETTAB USERS PPN
	HRRI	T1,.GTPPN	; FOR THIS JOB
	PUSHJ	P,GTBSPY
	  SETZ	T1,
	PUSH	P4,T1		;STASH IT
	MOVSI	T1,(T2)		;AND SET UP T1 TO GETTAB PROGRAM
	HRRI	T1,.GTPRG	; NAME FOR THIS JOB
	PUSHJ	P,GTBSPY
	  SETZ	T1,		;CAN'T GET IT, STORE 0
	PUSH	P4,T1		;STORE IT IN ERABUF
	MOVSI	T1,(1B0)	;CHECK IF NO CONTROLLER REGS
	TDNN	T1,UNISCR	;ARE THERE ANY
	JRST	GMDVR2		;YES
	PUSH	P4,[0]		;SYSERR EXPECT SOME DATAI'S HERE,
	PUSH	P4,[0]		; THE MONITOR DOESN'T SAVE THEM
	PUSH	P4,[0]		; SO WRITE ZEROES FOR NOW
	PUSH	P4,[0]
GMDVR2:	MOVNI	T3,MAXREG	;GET TOTAL NUMBER OF REGS TO WRITE
	POP	P,T2		;AND NUMBER SAVED BY MONITOR
	ADD	T3,T2		;T3=-NUMBER LEFT OVER
	SKIPL	T3		;IF T3 NOT LT 0, 
	SETZ	T3,		;DEVICE MUS BE NEW-JUST SAVE KONREG REGISTERS
	MOVNS	T2		;T2=-NUMBER TO SAVE
	HRLZS	T2		;T2=AOBJN WORD FOR REGS TO SAVE
	HRR	T2,UNISCR	;MUST POINT INTO KDB
	TDNN	T1,UNISCR	;DID GETTAB SAY NO UNISCR?
	SUB	T2,[4,,0]	;NO, ACCOUNT FOR CONTROLLER REGS
	ADDI	T2,(P3)		;INTO THIS KDB
MBDRLP:	MOVEI	T1,(T2)		;GET POINTER TO NEXT REG
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE THIS REGISTER
	AOBJN	T2,MBDRLP	;AND LOOP TO NEXT REGISTER
	JUMPE	T3,MBDVDN	;NO MORE REGS, MONITOR SAVED ALL?
	SETZ	T1,		;SAVE SOME ZEROES FOR
	PUSH	P4,T1		; SYSERR
	AOJL	T3,.-1		;T3 HAS NUMBER TO SAVE
MBDVDN:	MOVEI	T1,(T2)		;GET ADDRESS OF ISSUED DRCR
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;PUT IT IN ERABUF
	MOVE	T1,UNICCT	;[463]
	ADDI	T1,0(P3)	;OFFSET
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;[463] # OF BAT SLOTS 
	POP	P,P2		;RESTORE P2
	MOVEI	T1,(P3)		;ADDRESS OF UDB
	PUSHJ	P,PEKSPY	;GET UNIT NAME
	MOVE	T3,T1		;SAVE FOR DIAG.
	MOVE	T1,[2,,T2]	;SET UP CALL
	MOVEI	T2,7		;GET CONTROLLER UNIT
	DIAG.	T1,		;DO IT
	  SETZ	T1,		;BEFORE 603 ASSUME RH10
	CAMGE	T1,[540,,0]	;RH10?
	SKIPA	T1,[RH10CD]	;YES
	MOVEI	T1,RH20CD	;NO
	DPB	T1,[POINT 3,ERABUF+10,14]	;AND SAVE IT IN RETRIES WORD
;	PJRST	ERRFIN		;FALL INTO CLOSE AND RETURN

>;END UNITN COND
;STILL IN FTERR COND
;SUBROUTINE TO APPEND TO ERROR.SYS
;ARGS	P4=LAST ADDR STORED IN ERRBUF
;BLOWS T1-3
;ALWAYS RETURNS CPOPJ

ERRFIN:	SKIPE	IOERR		;[62]CAN WE WRITE IN ERROR.SYS
	POPJ	P,		;[62]NO, RETURN NOW
	INIT	FCT,17		;[62]OPEN A CHANNEL FOR THE PURPOSE
	ERRDEV			;OPEN DESIRED DEVICE
	0
	  JRST	E.IEF		;CAN'T INIT ERROR FILE
	MOVEI	T1,RBSIZE-RBCNTE	;LENGTH OF DESIRED EXTENDED LOOKUP
	MOVEM	T1,RBCNTE
IFE ERRPPN,<
	SETZM	RBPPNE		;NO DIRECTORY>
IFN ERRPPN,<
	MOVE	T1,[ERRPPN]
	MOVEM	T1,RBPPNE	;STORE DIRECTORY>
	MOVE	T1,[SIXBIT/ERROR/]
	MOVEM	T1,RBNAME	;STORE FILNAM
	HRLZ	T1,ERREXT	;[62]GET CURRENT ERROR EXTENSION
	MOVEM	T1,RBEXTE	;STORE EXT
	MOVSI	T1,(155B8)	;IF NOT FOUND, MAKE IT READ-ONLY
	MOVEM	T1,RBPRVE
	SETZM	RBSIZE		;IF LOOKUP FAILS, LEN IS ZERO
	MOVEI	T1,ERRBUF-1	;PREPARE IOWD
	HRRM	T1,ILIST	; FOR INPUT
	HRRM	T1,OLIST	; AND FOR OUTPUT
	MOVEI	T1,-200		;PUT WORD COUNT INTO OUTPUT
	HRLM	T1,OLIST	; IOWD FOR FULL BLOCK
	MOVEI	T1,-1		;MASK IN RIGHT HALF FOR ERROR CODE
	LOOKUP	FCT,EBLOCK	;DO EXTENDED LOOKUP
	  TDZN	T1,RBEXTE	;IF FILE NOT FOUND, MAKE ONE. ELSE BOMB
	ENTER	FCT,EBLOCK	;DO UPDATE
	  JRST	E.EEF		;WHAT?
	MOVE	T1,RBSIZE	;GET SIZE IN WORDS
	SOJL	T1,ERFIL0	;DECR FOR LAST WORD
	ROT	T1,-WRDSPB	;COMPUTE LAST BLOCK
	MOVEI	T2,1(T1)	;START AT BLOCK 1
	USETI	FCT,(T2)	;READ LAST BLOCK
	ROT	T1,WRDSPB	;RESTORE WORD COUNT
	ANDI	T1,<1_WRDSPB>-1	;RELATIVE LAST WORD IN BLOCK
	INPUT	FCT,ILIST	;READ THE LAST BLOCK
	STATZ	FCT,740000	;OK?
	  JRST	E.INEF		;OOPS

;STILL IN FTERR CONDITIONAL
;HERE TO CHECK FOR MESS-UPS IN ERROR.SYS

ERCHK:	MOVS	T3,ERRBUF(T1)	;PICK UP LAST WORD
	JUMPE	T3,ERBAK	;IF 0, BACK UP TO FIND GOOD ENTRY
	CAIN	T3,.ESEOF_9	;IS IT EOF?
	JRST	ERFILL		;YES, INSERT NEW ENTRY OVER IT
ERPHIA:	MOVSI	T3,.ESHIA_9	;MARK HIATUS
	MOVEM	T3,ERRBUF(T1)	;IN THE BUFFER
	USETO	FCT,(T2)	;WHEN WE MARK HAITUS,
	OUTPUT	FCT,OLIST	;WE USE NEW BLOCK
	STATZ	FCT,740000	;OK
	  JRST	E.OUEF		;NOPE!
;**;[534] DELETE	MOVE	T1,[.ESOFF_9,,1]	;PUT POINTER TO FIRST ENTRY
;**;[534] DELETE	MOVEM	T1,ERRBUF	;INTO FIRST WORD OF NEXT BLOCK
	AOJA	T2,ERFIL3	;[534] AND GO PUT THIS ENTRY INTO NEXT BLOCK

ERBAK:	JUMPE	T1,ERPHIA	;STOP BACKING AT BEGINNING OF BUFFER
	SOJ	T1,		;ELSE BACK UP
	MOVS	T3,ERRBUF(T1)
	JUMPE	T3,ERBAK	;BACK UP AGAIN IF STILL 0
	CAIE	T3,.ESEOF_9	;IS THIS EOF ENTRY?
	AOJA	T1,ERPHIA	;NO, DO NOT OVERWRITE IT
	JRST	ERFILL		;YES, THIS IS OKAY;STORE ENTRY OVER IT

ERFIL0:	MOVEI	T2,1		;[534] SO USETO WILL WRITE FIRST BLOCK
ERFIL3:	SETZM	ERRBUF		;[534] CLEAR FIRST WORD
	MOVE	T1,[ERRBUF,,ERRBUF+1]	;[534] SET UP TO CLEAR ANY JUNK
	BLT	T1,ERRBUF+177	;[534] BLITTTT!
	MOVE	T1,[.ESOFF_9,,1];[534] PUT POINTER TO FIRST ENTRY IN BLOCK
	MOVEM	T1,ERRBUF	;[534] INTO FIRST WORD OF BLOCK
ERFILL:	SUBI	P4,ERABUF+EL.HED-1	;CALCULATE WORDS STORED
	DPB	P4,[POINT 9,ERABUF,35]	;STORE LENGTH
	ADDI	P4,EL.HED(T1)		;TOTAL WORDS TO WRITE
	MOVEI	T1,ERRBUF(T1)	;TO LOCATION
	HRLI	T1,ERABUF	;FROM
	MOVEI	T3,ERRBUF-1(P4)		;GET LOCATION LAST WORD WILL GO INTO
	SUBI	T3,ERABUF-1		;SUBTRACT END OF BUFFER 
	JUMPGE	T3,ESPLIT	;IF T3 .GE. THEN ENTRY IS SPLIT ACROSS BLOCKS
ERFIL1:	BLT	T1,ERRBUF-1(P4)	;COPY INTO BUFFER
ERFIL2:	MOVSI	T1,.ESEOF_9	;MARK END OF FILE
	MOVEM	T1,ERRBUF(P4)	;AT LAST LOC
	USETO	FCT,(T2)	;SET TO WRITE LAST BLOCK
	OUTPUT	FCT,OLIST
	STATZ	FCT,740000	;OK?
	  JRST	E.OUEF		;BAD EGGS
	MOVEI	T1,^D10		;[62]REINITIALIZE NUMBER
	MOVEM	T1,IERCNT	;[62]OF ERROR RETRIES
	MOVEM	T1,NEWEXT	;[62]AND COUNT ON NEW EXTENSIONS IN ROW
ERRXIT:	MOVEI	T1,FCT		;[535] SET UP TO GIVE UP FCT CHANNEL
	PJRST	RELDSK		;[535] GO DO IT


ESPLIT:	SUBI	P4,(T1)		;CONVERT P4 BACK TO JUST LENGTH
	ADDI	P4,ERRBUF	;...
ESPLI1:	BLT	T1,ERABUF-1	;BLT AS MUCH AS WILL FIT CURRENT BLOCK
	USETO	FCT,(T2)	;SET THE BLOCK
	OUTPUT	FCT,OLIST	;AND OUTPUT IT
	STATZ	FCT,740000	;OK
	  JRST	E.OUEF		;NOPE!
	AOS	T2		;STEP TO NEXT BLOCK
	SETZM	ERRBUF		;CLEAR OUT ERRBUF
	MOVE	T1,[ERRBUF,,ERRBUF+1]
	BLT	T1,ERABUF-1
	MOVEI	T1,1(T3)	;T3 IS NUMBER OF WORDS THAT DIDN'T FIT
	CAIL	T1,<1_WRDSPB>	;ARE THERE STILL MORE THAN A BLOCKS WORTH
				; OF WORDS TO OUTPUT?
	MOVEI	T1,<1_WRDSPB>	;POINT AT START OF NEXT BLOCK FOR SYSERR
	HRLI	T1,.ESOFF_9	;PUT CODE FOR FIRST WORD IN LH
	MOVEM	T1,ERRBUF	;SO +1 IS LOC OF NEXT ENTRY
	HRRZI	T1,ERABUF(P4)	;GET VERY LAST WORD TO TRANSFER
	SUBI	T1,(T3)		;AND SUBTRACT # WORDS NOT TRANSFERED
	HRLS	T1		;PUT IN LH OF AC FOR BLT
	HRRI	T1,ERRBUF+1	;AND GET LAST LOC TO TRANSFER TO
	JUMPN	T3,ESPLI2	;IF NON-ZERO, MORE TO DO
	HRRZI	P4,1(T3)	;AND SET UP P4 TO STOP BLT
	JRST	ERFIL2		;JUST WRITE LAST WORD
ESPLI2:	SUBI	T3,<1_WRDSPB>-1	;SUBTRACT OUT WORDS FOR NEXT BLOCK
	JUMPGE	T3,ESPLI1	;IF T3 STILL GE ZERO, SPLIT AGAIN
	HRRZI	P4,200(T3)	;AND SET UP P4 TO STOP BLT
	JRST	ERFIL1		;AND GO OUTPUT REST OF ENTRY
;SUBROUTINE TO INITIALIZE FOR WRITING IN ERROR.SYS
;ARGS	T1=FIRST (TYPE) WORD OF ENTRY
;VALUES	P4=IOWD ERRSIZ,ERABUF	SUITABLE FOR PUSH-ING
;	HEADER WORD SETUP (EXCEPT LENGTH)
;	DATE & TIME IN WORD 1
;	UPTIME IN WORD 2
;RETURN	CPOPJ, T1-4 BLOWN

ERRINI:	TLO	F,L.ANY		;NOTE SOMETHING DONE
	SETZM	ERABUF		;CLEAR BUFFER
	MOVE	T2,[XWD ERABUF,ERABUF+1]
	BLT	T2,ERABUF+ERRSIZ-1	;CLEAR TO END
	HRRI	T1,<EL.VER>B23+<EL.HED>B26	;[464]FORMAT VERS & HEADER LEN
	TLNE	F,FL.DSK	;[551]ENTRY COMING FROM A CRASH FILE?
	 TLO	T1,EL.CRS	;[551]YES-SAY SO
	MOVEM	T1,ERABUF	;(0) HEADER TYPE IDENTIFIER
	PUSHJ	P,NBSDAT	;GET DATE AND TIME
	MOVEM	T1,ERABUF+1	;(1) DATE (LH) AND TIME (RH)
	MOVE	T1,[%NSUPT]
	PUSHJ	P,GTBSPY	;GET UPTIME
	  SETZ	T1,		;SNH...
	SETZ	T2,
	ASHC	T1,-^D17	;JIFFIES*2**18 IN T2[7(55)]
	DIV	T1,JIFDAY	;DAYS IN LH, FRACTION IN RH
	MOVEM	T1,ERABUF+2	;(2) UPTIME IN STD FORMAT
	MOVE	T1,[%CNSER]	;[464]
	PUSHJ	P,GTBSPY	;GET CPU0 SER #
	 SETZ	T1,		;OPPS
	MOVEM	T1,ERABUF+3	;(3) CPU S/N [464]
	MOVE	P4,[IOWD ERRSIZ-EL.HED,ERABUF+EL.HED] ;SETUP FOR PUSHING
	POPJ	P,		;SO FAR SO GOOD
;[62]NEW ROUTINES TO PROCESS I/O ERRORS ON ERROR.SYS

;[62]HERE IF INIT FAILS
E.IEF:	SETOM	IOERR		;[62]SET FLAG SO WE STOP TRYING
;**;[535] CHANGE AT E.IEF+1
;**;[535] DELETE	RELEAS	FCT,		;[62]RELEASE CHANNEL
;**;[535] DELETE	POPJ	P,		;[62]AND RETURN TO CALLER OF ERRFIN
	MOVEI	T1,FCT		;[535] SET UP CHANNEL TO RELEASE
	PJRST	RELDSK		;[535] GO DO IT

;[62]HERE IF LOOKUP/ENTER ERROR
E.EEF:	CAIN	T1,-1		;[62]LOOKUP HAS CODE IN T1
	TDZ	T1,RBEXTE	;[62]ENTER HAD -1 IN T1, THIS GETS CODE
	XORI	T1,-1		;[62]CODE WAS IN ONE'S COMPLEMENT
	CAIN	T1,ERTRN%	;[62]BAD RIB OR UFD?
	JRST	NEREXT		;[62]YES, TRY NEW FILE NOW
	CAIE	T1,ERFBM%	;[62]FILE BEING MODIFIED?
	CAIN	T1,ERNRM%	;[62]OR DISK FULL?
	JRST	ERRCLK		;[62]YES, DO SOME RETRIES
	CAIE	T1,ERNET%	;[62]NO MONITOR FREE CORE?
	CAIN	T1,ERSLE%	;[62]OR EMPTY SEARCH LIST
	JRST ERRCLK		;[62]YES, DO SOME RETRIES
	PJRST	E.IEF		;[62]ALL OTHERS FATAL, TREAT LIKE INIT ERROR

;[62]HERE ON INPUT/OUTPUT ERROR
E.INEF:
E.OUEF:	GETSTS	FCT,T1		;[62]GET STATUS IN T1
	TRNE	T1,IO.BKT	;[62]DISK FULL
	PJRST	ERRCLK		;[62]YES,DO SOME RETRIES

;[62]ROUTINE TO TRY NEW EXTENSIONS.INPUT/OUTPUT ERRORS FALL THROUGH
;[62]EXCEPT IO.BKT
NEREXT:	SOSG	NEWEXT		;[62]HERE TOO MANY TIMES IN A ROW?
	PJRST	E.IEF		;[62]YES, GIVE UP
	HRRZ	T1,ERREXT	;[62]TRY NEW FILE. FIRST GET CURRENT EXT
	CAIN	T1,'SYS'	;[62]IS IT SYS?
	MOVEI	T1,'X00'	;[62]YES, SET UP X00
	ADDI	T1,1		;[62]INCREMENT TO GET NEW EXTENSION
	TRNN	T1,7		;[62]SHOULD WE CARRY TO SECOND DIGIT?
	ADDI	T1,100-10	;[62]YES,CAUSE THE SIXBIT TO CARRY
	CAILE	T1,'X77'	;[62]HAS THE EXTENSION OVERFLOWED?
	PJRST	E.IEF		;[62]YES, FATAL
	HRRZM	T1,ERREXT	;[62]GOOD NEW EXT., STORE IT
;**;[535] CHANGE AT NEREXT+11
;**;[535] DELETE	RELEAS	FCT,		;[62]RELEASE THE CHANNEL
	MOVEI	T1,FCT		;[535] SET UP CHANNEL
	PUSHJ	P,RELDSK	;[535] RELEASE IT
	PJRST	ERRFIN		;[62]AND TRY THE NEW FILE

;[62]ROUTINE FOR RETRIES ON SAME FILE. USES INTERNAL CLOCK REQUEST TO
;[62]WAIT BETWEEN RETRIES. AFTER 10 RETRIES WITH NO LUCK,IT TRIES A NEW FILE
ERRCLK:	SOSG	IERCNT		;[62]DECREMENT COUNT OF RETRIES LEFT
	PJRST	NEREXT		;[62]TOO MANY RETRIES, TRY NEW FILE
	SETOM	IOERR		;[62]NO IO TO ERROR FILE UNTIL CLOCK EXPIRES
;**;[535] CHANGE AT ERRCLK+3
;**;[535] DELETE	RELEAS	FCT,		;[62]RELEASE THE CHANNEL
	MOVEI	T1,FCT		;[535] SET UP CHANNEL
	PUSHJ	P,RELDSK	;[535] RELEASE IT
	PUSH	P,J		;[62]SAVE J
	MOVEI	J,IOERQ		;[62]SET UP Q # FOR INTERNAL CLOCK REQUEST
	MOVEI	T1,ERRTIM	;[62]SET UP TIME FOR CLOCK REQUEST
	PUSHJ	P,CLKREQ	;[62]DO THE CLOCK REQUEST
	POP	P,J		;[62]RESTORE J
	POPJ	P,		;[62]RETURN

;SUBROUTINE TO INITIALIZE EXTENSION FOR ERROR FILE
;NO ARGS
;CHANGES ERREXT TO THE EXTENSION OF THE LAST ERROR FILE
; FOUND ON ERRDEV
;RETURNS CPOPJ, DESTROYS T1
ERRSTR:		INIT	FCT,17			;INIT A CHANNEL FOR LOOKUPS
	ERRDEV				;DESIRED DEVICE
	0
	  JRST	E.IEF			;CAN'T INIT ERRDEV
	MOVEI	T1,RBEXTE-RBCNTE	;LENGTH FOR EXTENDED LOOKUP
	MOVEM	T1,RBCNTE		;SAVE IN LOOKUP BLOCK
IFE ERRPPN,<
	SETZM	RBPPNE			;SET UP DIRECTORY>
IFN ERRPPN,<
	MOVE	T1,[ERRPPN]		;SET UP DIRECTORY
	MOVEM	T1,RBPPNE		; FOR LOOKUP>
	MOVE	T1,[SIXBIT/ERROR/]	;AND SET UP NAME
	MOVEM	T1,RBNAME		; FOR LOOKUP
	MOVEI	T1,'X01'		;START AT X01
ENAMLP:	HRLZM	T1,RBEXTE		;SAVE EXT FOR LOOKUP
	LOOKUP	FCT,EBLOCK		;LOOK UP THIS ONE
	  POPJ	P,			;ALL DONE WHEN A LOOKUP FAILS
	ADDI	T1,1			;INCREMENT EXTENSION
	TRNN	T1,7			;SHOULD WE CARRY TO SECOND DIGIT?
	ADDI	T1,100-10		;YES, CAUSE THE SIXBIT TO CARRY
	CAILE	T1,'X77'		;HAS THE EXTENSION OVERFLOWED?
	PJRST	E.IEF			;YES, GIVE UP
	JRST	ENAMLP			;NO, LOOK UP THIS ONE
;SUBROUTINE TO RETURN DATE AND TIME IN NBS FORMAT,
; DAYS SINCE NOV 17, 1858 IN LH, FRACTION OF DAY IN RH
;USES T1-4
	RADIX	10
DATOFS==38395	;DAYS FROM NOV 17, 1858 TO JAN 1, 1964

NBSDAT:	MOVE	T1,[%CNDTM]	;[562]  WAS %CNDAT
	PUSHJ	P,GTBSPY	;GET DATE IN INTERNAL (12-BIT) FORMAT
	  SETZ	T1,		;[562] ???
	POPJ	P,		;[562] RETURN
REPEAT 0,<			;[562] DELETE THIS OBSOLETE CODE.
	IDIVI	T1,12*31	;T1 = YEAR - 1964
	IDIVI	T2,31		;T2 = MONTH - JAN, T3 = DAY OF MON -1
	ADD	T3,MONTAB(T2)	;T3 = DAY OF YEAR -1
	PUSH	P,ZERO		;ASSUME NOT LEAP YEAR
	CAIL	T2,2		;JAN OR FEB?
	AOS	0(P)		;NO, ENABLE ADDING ONE FOR L.Y.
	MOVEI	T4,(T1)		;HOLD  YEAR
	ADDI	T1,3		;OFFSET
	IDIVI	T1,4		;CHECK FOR THIS BEING LEAP YEAR
	CAIE	T2,3		;IS IT?
	SETZM	0(P)		;NO, NO INCREMENT
	ADDI	T3,DATOFS(T1)	;ADD DAYS FROM NOV 17, 1858 TO JAN 1, 1964
				; PLUS LEAP YEARS ALREADY PASSED SINCE 64
	MOVEI	T1,(T4)		;RESTORE YEAR SINCE 64
	IMULI	T1,365		;DAYS SINCE 64 (NOT COUNTING LY'S)
	ADDI	T3,(T1)		;T3 = DAYS SINCE 11/17/1858
				;IGNORING CENTURY GLITCH
	HRREI	T1,1964-2001(T4);CHECK FOR CENTURY CHANGE
	POP	P,T4		;T4 = 1 IF ADD 1 FOR THIS YEAR
	JUMPLE	T1,NOCENT	;JUMP IF NOT YET 2001
	IDIVI	T1,100		;GET CENTURIES SINCE 2001
	SUB	T3,T1		;DECR FOR "LOST" LEAP YEARS
	CAIE	T2,99		;IS THIS A LOST LY?
NOCENT:	ADDI	T3,(T4)		;NO, ADD 1 IF LY AND AFTER FEB
	MSTIME	T1,		;GET TIME OF DAY
	SETZ	T2,
	ASHC	T1,-17		;READY TO MAKE FRACTION OF A DAY
	DIV	T1,[24*60*60*1000]
	HRLI	T1,(T3)		;INSERT DATE WITH IT
	POPJ	P,		;RETURN

ZERO:
MONTAB:	EXP	0,31,59,90,120,151,181,212,243,273,304,334
>				;[562] END DELETION OF OBSOLETE CODE.
	RADIX	8
>;END FTERR CONDITIONAL
SUBTTL	ROUTINE TO WRITE CHKPNT INFO INTO FACT FILE

IFN FTCHKPNT,<
CHECK:
IFE FTDET,<
	TLNE	F,L.CHK		;SUPPRESS BIT ON?
	POPJ	P,		;YES, DO NOT CHECKPOINT
>;END FTDET
	JSP	T4,SAVE4	;SAVE THE ACS
	MOVE	P4,FACTSZ	;CURRENT SIZE OF BUFFER CONTENTS
	MOVN	J,HJOB		;HIGHEST JOB # IN SYS
	HRLZS	J
	HRRI	J,1		;START WITH JOB 1 (0 IS NULL)
CHKLUP:	HRROI	T1,.GTSTS	;JOB'S STATUS
	PUSHJ	P,GTBSPY
	  JRST	CHKEND		;NO MORE JOBS
	TLNN	T1,JLOG		;IS THIS JOB LOGGED IN?
	JRST	CHKNXT		;NO, LOOK AT NEXT
	PUSHJ	P,BUFAGE	;ENABLE BUFFER DUMP WHEN IT GETS TOO OLD
IFE FT1975,<			;[7(57)]
	MOVE	T1,[200000,,10]	;FIRST WORD
>
IFN FT1975,<			;[7(57)]
	MOVE	T1,[201000,,10] ;FIRST WORD, NEW TYPE[7(57)]
>
	MOVEM	T1,FACTBF(P4)	;(0) CONTROL WORD WITH LENGTH
	DPB	J,[POINT 9,FACTBF(P4),17] ;(0) JOB NUMBER
	PUSHJ	P,GETTTY	;GET JOB'S TTY NUMBER
	  MOVNI	T1,2		;DETACHED-MARK SO
	DPB	T1,[POINT 12,FACTBF(P4),29]	;(0) LINE NUMBER

;STILL IN FTCHKPNT CONDITIONAL
;HERE TO FILL IN REST OF ENTRY

	HRROI	T1,.GTPPN	; JBTPPN
	PUSHJ	P,GTBSPY	;GET THE DATA
	  JRST	CHKEND		;END OF TABLE
	MOVEM	T1,FACTBF+1(P4)	;(1) PPN
	PUSHJ	P,FACTIM	;GET TIME AND DATE
	MOVEM	T1,FACTBF+2(P4)	;(2) DATE AND TIME
	HRROI	T1,.GTTIM	;RUNTIME
	PUSHJ	P,GTBSPY	;GO GET IT
	  SETZ	T1,		;MAYBE THERE'S NO SUCH TABLE
	IMULI	T1,^D1000	;AVOID MILJIF FOR PRECISION
	IDIV	T1,JIFSEC	;CONVERT TO MILLISECONDS
	MOVEM	T1,FACTBF+3(P4)	;(3) RUN TIME
	HRROI	T1,.GTKCT	;KILLO-CORE-TICKS
	PUSHJ	P,GTBSPY	;GO READ THEM
	  SETZ	T1,		;NO TABLE, MAYBE?
IFN FT1975,<			;IN NEW FORMAT, JIFSEC IS ILLEGAL[7(57)]
	IMULI	T1,^D100		;CONVERT JIFFIES TO 1/100THS[7(57)]
	IDIV	T1,JIFSEC	;[7(57)]
>
	MOVEM	T1,FACTBF+4(P4)	;(4) KCT
	HRROI	T1,.GTRCT	;READ COUNT
	PUSHJ	P,GTBSPY	;GET OUT OF MONITOR
	  SETZ	T1,
	TLZ	T1,777700	;CLEAR OUT JUNK BITS
	MOVEM	T1,FACTBF+5(P4)	;(5) DISK READS
	HRROI	T1,.GTWCT	;WRITE COUNT
	PUSHJ	P,GTBSPY	;GET FROM MONITOR
	  SETZ	T1,
	TLZ	T1,777700	;CLEAR INCR. BITS
	MOVEM	T1,FACTBF+6(P4)	;(6) DISK WRITES
	HRROI	T1,.GTPRG	;NAME TABLE
	PUSHJ	P,GTBSPY	;GET BY SPYING
	  SETZ	T1,
	MOVEM	T1,FACTBF+7(P4)	;(7) PROGRAM NAME
	ADDI	P4,10		;UPDATE SIZE TO NOTE 10 WORDS STORED
	CAIGE	P4,MAXFCT	;HAVE WE FILLED THE BUFFER?
	JRST	CHKNXT		;NO, LOOK FOR NEXT JOB
	HRLZI	P1,(P4)		;YES, GET LEN IN P1 LEFT
	HRRI	P1,FACTBF	;AND ADDRESS IN P1 RIGHT
	PUSHJ	P,APPEND	;UPDATE FILE
	SETZ	P4,		;NOTE BUFFER EMPTY
CHKNXT:	AOBJN	J,CHKLUP	;LOOP FOR MORE JOBS
CHKEND:	MOVEM	P4,FACTSZ	;RESTORE SIZE OF FACT THINGS
	MOVE	T1,CCTIM	;SETUP TIME FOR NEXT CHECKPOINT
	MOVEI	J,CHKRQ		;DUMMY JOB NO FOR CHKPNT
	PJRST	CLKREQ		;MAKE THE CLOCK REQUEST AND QUIT

>;END FTCHKPNT CONDITIONAL
SUBTTL FACT FILE UPDATE ROUTINE

IFN CHKFCT,<
;LOCAL ACS
A==T1		;SCRATCH ACS
B==T2
C==T3
D==T4
;SUBROUTINE TO APPEND AN ENTRY TO A FILE IN THE ACCOUNTING SYSTEM.
; THIS ROUTINE FIRST ATTEMPTS TO APPEND TO THE FILE NAMED FACT.SYS, BUT IF THIS FILE
; IS UNAVAILABLE, THEN FILES NAMED FACT.X01, FACT.X02,..., FACT.X77 WILL BE ATTEMPTED
;
;CALLING SEQUENCE:
;		MOVE P1,[XWD SIZE,ADDRESS] ;POINTER TO ENTRY TO BE APPENDED.
;		PUSHJ P,APPEND
;		RETURNS HERE IN ANY EVENT. BLOWING P1 AND P2, T1-4
;		GUARANTEE 200 WORDS FREE ABOVE ENTRY
;
APPEND:	HLRZ	P2,P1		;CONVERT P1 TO
	MOVNI	P2,(P2)		; AN AOBJN POINTER
	HRL	P1,P2		; ..
	PUSH	P,P1		;SAVE P1
	MOVEI	B,(SIXBIT /SYS/)	;TRY FACT.SYS FIRST.
APPLUP:	PUSH	P,B		;SAVE LAST EXTENSION TRIED.
APPLP1:	MOVSS	B		;SET UP ACCUMULATORS FOR THE APPNDF
	MOVE	P1,-1(P)	; SUBROUTINE (WHICH DOES THE ACTUAL APPEND).
	PUSHJ	P,APPNDF	;TRY TO APPEND ENTRY TO TRANSACTION FILE.
	  JRST	APPERR		;ERROR ON THAT TRANSACTION FILE--TRY NEXT.
	 JRST	APPBZY		;TRANSACTION FILE BUSY--TRY ANOTHER.
	POP	P,B		;NORMAL EXIT--FILE SUCCESSFULLY UPDATED.
APPXIT:	POP	P,P1		;RESTORE STACK AND P1

FCTINI:	SETZM	FACTSZ
	POPJ	P,		;*** SUBROUTINE EXIT. ***

APPERR:	POP	P,B		;NON-RECOVERABLE ERROR--TRY NEXT FILE.
	CAIN	B,(SIXBIT /SYS/)	;WAS .SYS THE LAST EXTENSION ATTEMPTED?
	MOVEI	B,(SIXBIT /X00/)	;YES, TRY .X01 NEXT.
APPERB:	CAIN	B,(SIXBIT /X77/)	;NO, TRIED ALL 64 POSSIBLE FILES ?
	JRST	APPXIT		;YES, GIVE UP.
	ADDI	B,1		;NO, TRY NEXT FILE IN SEQUENCE.
	TRNN	B,7		;CARRY INTO SECOND DIGIT ?
	ADDI	B,100-10	;YES, CAUSE SIXBIT CARRY.
	JRST	APPLUP		;TRY AGAIN.

APPBZY:	POP	P,B		;SPECIFIED FILE WAS BUSY--GET ITS EXTENSION.
	CAIE	B,(SIXBIT /SYS/)	;WAS IT .SYS ?
	JRST	APPERB		;NO, GO TRY NEXT FILE IN SEQUENCE.
	PUSH	P,[SIXBIT /   X00/]	;TRY .SYS TWICE JUST TO BE SURE.
	JRST	APPLP1

;STILL IN CHKFCT CONDITIONAL (EITHER FTFACT OR FTCHKPNT)
;SUBROUTINE TO APPEND A TRANSACTION ENTRY TO THE END OF THE ACCOUNTING FILE
; (NORMALLY, THIS IS THE FILE NAMED FACT.SYS, BUT THE EXTENSION IS A PARAMETER
; SUPPLIED TO THIS SUBROUTINE SO THAT IF FACT.SYS BECOMES FOULED UP, AN ENTRY
; MAY BE APPENDED TO AN ALTERNATE FACT.XXX FILE.)

;CALLING SEQUENCE:
;	MOVSI B,(SIXBIT /EXT/)   ;DESIRED EXTENSION FOR FACT FILE (NORMALLY .SYS)
;	MOVE P1,[XWD  -SIZE,ADDRESS]	;POINTER TO ENTRY TO BE APPENDED
;	PUSHJ P,APPNDF
;	NON-RECOVERABLE ERROR RETURN -- CAN'T APPEND TO FILE.
;	BUSY ERROR RETURN -- FILE HAS BEEN BUSY EVERY SECOND FOR TEN SECONDS.
;	NORMAL RETURN -- ENTRY HAS BEEN SUCCESSFULLY APPENDED TO THE FILE.

APPNDF:	MOVE	A,[XWD APPBLK,EBLOCK]
	BLT	A,RBNAME	;MOVE COUNT,PPN, & NAME INTO EBLOCK
	MOVEM	B,RBEXTE	;SAVE REQUESTED EXTENSION FOR FILENAME FACT
	MOVSI	A,(177B8)	;SETUP PROTECTION
	MOVEM	A,RBPRVE	;[7(56)]
	SETZM	RBSIZE		;AND FILE SIZE
	MOVEI	P2,^D10
	MOVEM	P2,TRYCTR	;SET NUMBER OF TIMES TO TRY IF BUSY.
	INIT	FCT,17		;OPEN SOFTWARE I/O CHANNEL FOR FACT FILE
	FCTDEV			; IN DUMP MODE
	0
	  JSP	P2,APPNDR	;IMMEDIATE ERROR RETURN IF CAN'T GET DEVICE SYS.

APPNDL:	LOOKUP	FCT,EBLOCK	;ATTEMPT TO OPEN FACT FILE FOR READING.
	  JRST	APPNDN		;LOOK-UP FAILED--PERHAPS FILE DOESN'T EXIST.
	PUSHJ	P,APPNDE	;ATTEMPT TO GRAB THE FACT FILE.
	SKIPN	P2,RBSIZE	;FILE SIZE IN WORDS
	JRST	APPNDM		;IF ZERO LEN, NO INPUT
	SOJ	P2,		;POINT TO LAST WORD
	MOVEI	C,200(P2)
	LSH	C,-7		;COMPUTE LAST BLOCK OF FILE
	ANDI	P2,177		;P2 NOW HAS RELATIVE DEPTH (0-127) OF
	USETI	FCT,(C)		; LAST WORD IN LAST BLOCK.
	MOVEI	D,-201(P1)	;ADDR OF AVAILABLE CORE-1
	HRRM	D,ILIST		;SAVE IN IOWDS
	HRRM	D,OLIST
	AOJ	D,		;BUMP FOR BUFFER POINTER
	HRLI	D,P2		;MAKE INDEXABLE
	INPUT	FCT,ILIST	;READ LAST BLOCK OF FACT FILE INTO DUMP BUFFER.
	STATZ	FCT,740000
	  JSP	P2,APPNDR	;ERROR OR EOF WILL YIELD ERROR RETURN.

;STILL IN CHKFCT CONDITIONAL (EITHER FTFACT OR FTCHKPNT)
APPNDA:	MOVS	A,@D		;GET LAST WORD OF CURRENT FACT FILE.
	CAIN	A,777000	;END-OF-FILE ENTRY ?
	JRST	APPNDB		;YES, THINGS ARE LOOKING GOOD.
	SKIPN	A		;NO, FACT FILE SCREWED UP!  IS LAST WORD NON-ZERO ?
	TRNN	P2,-1		;OR IS THIS THE FIRST WORD OF A 200-WORD BLOCK ?
	JSP	P2,APPNDR	;YES TO EITHER QUESTION. TAKE ERROR EXIT.
	SUB	P2,[XWD 1,1]	;TRY BACKING UP OVER ZERO WORDS ATTEMPTING TO FIND
	JRST	APPNDA		; THE END-OF-FILE ENTRY.

APPNDB:	TLNN	P2,-1		;WAS END-OF-FILE ENTRY WHERE IT WAS SUPPOSED TO BE ?
	JRST	APPNDC		;YES, PROCEED.
	MOVE	A,[XWD 377000,1]	;NO, FILL WITH DUMMY ONE-WORD ENTRIES TO
	MOVEM	A,@D		; SHOW WHERE DATA LOSS MAY HAVE OCCURED.
	AOBJN	P2,.-1

APPNDC:	MOVE	A,0(P1)		;PICK UP ENTRY AS SPECIFIED IN CALLING SEQUENCE.
	MOVEM	A,@D		;STORE IN FACT FILE OUTPUT BUFFER.
	AOJ	P2,		;NEXT
	AOBJN	P1,APPNDC
	MOVSI	A,777000	;LAY DOWN END-OF-FILE ENTRY AGAIN.
	MOVEM	A,@D	
	SETCA	P2,0		;(IN PLACE OF AOS P2 FOLLOWED BY MOVNS P2)
	HRLM	P2,OLIST	;STORE CORRECT NUMBER OF WORDS TO BE WRITTEN.
	USETO	FCT,(C)
	OUTPUT	FCT,OLIST	;OUTPUT UPDATED FACT FILE.
	STATZ	FCT,740000
	  JSP	P2,APPNDR	;ERROR OR EOF WILL YIELD ERROR EXIT.
	AOSA	0(P)		;DOUBLE SKIP EXIT
FCTBSY:	AOS	BSYFCT		;COUNT BUSY ERRORS
	AOS	0(P)		;SINGLE SKIP EXIT
APPNER:;**;[535] DELETE	RELEASE	FCT,0		;RELEASE FACT FILE'S CHANNEL.
;**;[535] DELETE	POPJ	P,		;*** SUBROUTINE EXIT .***
	MOVEI	T1,FCT		;[535] SET UPCHANNEL
	PJRST	RELDSK		;[535] GIVE IT UP

APPNDR:	AOS	FCTGUF		;COUNT ERRORS IN FACT FILE
	HRLM	P2,FCTGUF	;AND SAVE ADDRESS WHERE DETECTED
	JRST	APPNER		;THEN EXIT

;STILL IN CHKFCT CONDITIONAL (EITHER FTFACT OR FTCHKPNT)
APPNDE:	ENTER	FCT,EBLOCK
	  JRST	.+2
	POPJ	P,		;**GOOD EXIT. THE FACT FILE IS OPEN FOR WRITING.**
	POP	P,(P)		;CORRECT THE STACK, SINCE WE WON'T POPJ
	HRRZ	P2,RBEXTE
	CAIE	P2,ERFBM%	;ERROR CODE=3 FROM DSKSER MEANS FILE BEING MODIFIED
	JSP	P2,APPNDR	; BY SOMEONE ELSE. ANY OTHER ERROR CODE LOSES.
	SOSG	TRYCTR		;TRIED OFTEN ENOUGH?
	JRST	FCTBSY		;YES, GIVE UP AFTER 10 TRIES
	MOVEI	P2,1		;WAIT A SECOND
	SLEEP	P2,
	JRST	APPNDL		;NO, TRY AGAIN BEGINNING WITH LOOK-UP. (FILE COULD
	 			; HAVE COME INTO EXISTENCE OR DIED IN THE INTERIM.)

APPNDN:	HRRZ	P2,RBEXTE	;ONLY ERROR CODE 0 IS REASONABLE ON LOOKUP FAILURE.
	JUMPN	P2,APPNDR	;ERROR EXIT ON ANY OTHER LOOKUP FAILURE.
	PUSHJ	P,APPNDE	;FACT FILE DIDN'T EXIST.  TRY TO CREATE IT.
APPNDM:	MOVEI	C,1		;POINT TO BEGIN OF FILE
	MOVEI	D,-201(P1)	;ADDR OF AVAILABLE CORE-1
	HRRM	D,OLIST
	AOJ	D,		;BUMP TO BEGINNING OF BUFFER
	HRLI	D,P2		;INDEX FOR INDIRECT ADDRESSING
	JRST	APPNDC		;GO MOVE TRANSACTION ENTRY INTO FILE AND EXIT.

;SUBROUTINE TO RETURN DATE AND TIME IN FACT-FILE (12/24 BIT) FORMAT
;VALUE	T1=BYTE (12)DATE(24)TIME
;	USES T2

IFE FT1975,<			;CAN'T USE THIS FORMAT AFTER '74[7(57)]
FACTIM=ODATIM		;[63]IF ONLY OLD FORMAT, ALWAYS USE OLD ROUTINE
>			;[63]NEED THIS ROUTINE ALWAYS!
ODATIM:	MOVE	T1,[%CNTIM]	;[63]SET UP FOR GETTAB OR SPY
	PUSHJ	P,GTBSPY	;GET TIME OF DAY IN JIFFIES
	  SETZ	T1,
	MOVE	T2,T1		;HOLD THAT
	MOVE	T1,[%CNDAT]
	PUSHJ	P,GTBSPY	;GET THE DATE IN 12-BIT FORMAT
	  SETZ	T1,
	ROT	T1,-14		;ROTATE
	IOR	T1,T2		;MUSH TOGETHER
	POPJ	P,		;DONE
IFN FT1975,<		;USE NEW FORMAT TIME
FACTIM=NBSDAT		;FOR WHICH ROUTINE EXISTS[7(57)]
>

;STILL IN CHKFCT COND
TRYCTR:	BLOCK	1	;#OF TIMES TO TRY IF FACT FILE IS BUSY
APPBLK:	EXP	<RBSIZE-RBCNTE>	;LEN OF EXT LOOKUP,ENTER
	EXP	FCTPPN		;PPN FOR FACTFILE
	SIXBIT	/FACT/		;NAME
>;END CHKFCT CONDITIONAL
SUBTTL ROUTINES TO READ CRASH.EXE

IFL FTSAVE,<
CRSCHK:	POPJ	P,0
>
IFGE FTSAVE,<

;[551]GENERAL PROCEDURE IS TO GET EACH STR IN THE SYSTEM SEARCH LIST
;[551]LOOK UP "CRASH.EXE", IF PRESENT, READ THE FIRST REAL DATA BLOCK AND
;[551]CHECK TO SEE IF THIS FILE HAS BEEN PROCESSED. WORD 36(CRSWRD) WILL BE NON-
;[551]ZERO IF THIS FILE HASN'T BEEN PROCESSED.  IF TRUE, EXTRACT ANY PENDING ENTRIES
;[551]FROM THE CRASH VIA GETTAB AND PEKSPY SIMULATION,
;THEN CREATE A SEPARATE ENTRY  CONTAINING INTERESTING INFORMATION FROM THIS 
;[551]CRASH SUCH AS UPTIME, DISK STATISTICS, PERFORMANCE STATS, DEVICE STATUS
;[551]ETC.  ALL ITEMS MUST BE EITER DIRECTLY GETTAB'D OR THE STARTING
;[551]ADDRESS MUST BE GETTABABLE.  INFO ADDED TO THE LIST
;[551]VIA FIELD EDITS WILL BE PRESERVED BUT ONLY LISTED IN
;OCTAL BY SYSERR.  OTERS WILL B DECENTLY FORMATED INCLUDING ITEM NAME,ETC.
;ROUTINE TO LOOK FOR AND PROCESS UN-CHECKED CRASH.EXE FILES.
;CALL  PUSHJ, RETURNS POPJ AND USES ALL AC'S

CRSCHK:	TLO	F,FL.DSK		;PEEK/SPY ARE SIMULATED TO DSK
	SETZM	INDEV
	SETZM	INFILE
	SETZM	INEXT
	SETZM	INPPN
	MOVE	P1,[-1]			;1ST STR NAME TO GET
CRSNXT:	PUSHJ	P,GOBUUO		;GET A STR IN SYS SEARCH LIST
	SKIPN	P1			;IF 0, END OF LIST
	 JRST	CRSEND			;CLEAN UP AND RETURN
	MOVEM	P1,INDEV		;STORE STR NAME
	PUSHJ	P,SETDS3		;DO A LOOKUP ON THIS STR
	SKIPA				;SKIP OVER ERROR RETURN
	 JRST	CRSNX1		;***LOOKUP FAILED
	USETI	DSKX,CRSBLK		;SET TO READ 1ST 200 WDS
	IN	DSKX,DSKIOW	;GET THAT NLOCK
	SKIPA			;SKIP OVER ERROR
	 JRST	CRSNX1		;***READ FAILED
	SKIPE	DSKBUF+CRSWRD	;IF 0,FILE AS BEEN PROCESSED
	 PUSHJ	P,READCR	;GO PROCESS THIS FILE
	USETI	DSKX,0		;GET THE RIB
	IN	DSKX,DSKIOW	;READ IT
	SKIPA
	 JRST	CRSNX1		;***IN FAILED
	MOVE	T1,DSKBUF+177	;GET RIB'S SELF BLOCK #
	ADDI	T1,CRSBLK	;POINT AT CORRECT BLOCK
	PUSH	P,T1			;SAVE IT
	MOVEI	T1,DSKX		;GET [564] GET CHANNEL
	MOVEM	T1,DSKBUF+.DCNAM	;[564] FOR DSKCHR
	MOVE	T1,[XWD .DCUPN+1,DSKBUF]
	DSKCHR	T1,
	  JRST	CRSNX2
	MOVEI	T1,.FOCLS	;CLOSE FUNCTION CODE
	HRRM	T1,FLP+.FOFNC
	MOVE	T1,[XWD 6,FLP]
	FILOP.	T1,		;CLOSE THE FILE
	  JRST	CRSNX2		;***CLOSE FAILED (OR FILOP. NOT IMPLEMENTED)
	MOVE	T1,DSKBUF+.DCUPN;GET ACTUAL PACK NAME[564]
	MOVEM	T1,FLP+.FODEV
	OPEN	DSKX,FLP+.FOIOS	;[564] REOPEN FOR SUSET
	  JRST CRSNXT		;   TO GET RIGHT WORD
	MOVE	T1,0(P)
	HRLI	T1,DSKX_5
	SUSET.	T1,		;SUPER IO
	 USETI	DSKX,(P)
	IN	DSKX,DSKIOW	;READ THE BLOCK
	SKIPA
	 JRST	CRSNX2
	SETZM	DSKBUF+CRSWRD	;CLEAR THAT WORD
	MOVE	T1,0(P)
	HRLI	T1,<4000+DSKX>_5
	SUSET.	T1,
	 USETO	DSKX,(P)
	POP	P,T1
	OUT	DSKX,DSKIOW	;REWRITE IT
	SKIPA
	 JFCL		;***WRITE FAILED
CRSNX1:	MOVE	P1,INDEV		;STR WE JUST USED
	JRST	CRSNXT		;GET NEXT

CRSEND:	TLZ	F,FL.DSK	;USE REAL PEEK/SPY NOW
	POPJ	P,0		;WER'E DONE


CRSNX2:	POP	P,T1
	JRST	CRSNX1
;ROUTINES TO CECK FOR AND EXTRACT ENTRIES OR DATA FROM A CRASH.EXD
;FILE.  CALL PUSHJ WITH FILE OPEN AND 1ST 200 WORDS  OF CORE DUMP
;ALREADY IN DSKBUF.  RETURNS POPJ WEN DONE
	ND	(%LDERT,(XWD 101,16))	;STARTING ADDR OF TABLE
	ND	(%LDPT1,(XWD 102,16))	;PNTR TO EXTRACT ENTRIES
	ND	(%LDPT2,(XWD 103,16))	;PNTR TO INSERT ENTRIES
	ND	(%LDLTH,(XWD 104,16))	;MAX LENGTH OF TABLE



READCR:	MOVE	T1,[%LDPT1]	;GETTAB FOR PNTR TO EXTRACT ENTRIES
	PUSHJ	P,GETZ		;GET IT
	 SKIPN	T1		;IF NOT ZERO
	PJRST	CRSINF		;LEAVE HERE
	PUSHJ	P,PEKSPY	;NOW GET CONTENTS OF THE PNTR
	MOVEM	T1,EPKIDX	;SAVE IT
	SKIPN	T1		;IF INITIAL IS ZERO
	 MOVEI	T1,2		;0TH ENTRY IS BLANK
	MOVEM	T1,EPKID1	;...AND SET UP GET POINTER
	MOVE	T1,[%LDLTH]	;NOW GET MAX TABLE LENGTH
	PUSHJ	P,GETZ
	MOVEM	T1,ERPTMX	;SAVE IT TOO
	MOVE	T1,[%LDERT]	;GETTAB ADDR FOR ST OF DAEMON Q TABLE
	PUSHJ	P,GETZ		;GO GET IT

	SKIPN	T1		;IF 0,NOT IMPLEMENTED
	 PJRST	CRSINF		;JUST RECORD CRASH ENTRY
	MOVEM	T1,ESVIDX	;SAVE AS START ADDR OF TABLE
	MOVE	T1,EPKID1	;GET CURRENT OFFSET
READC1:	CAML	T1,ERPTMX	;OFF END?
	 SETZM	EPKID1		;YES,RESET TO TOP
	MOVE	T1,ESVIDX	;GET START OF TABLE
	ADD	T1,EPKID1	;ADD OFFSET
	MOVE	P1,T1		;STARTING ADDR
	PUSHJ	P,PEKSPY	;GO GET CONTENTS
	SKIPN	T1		;IF 0 NO MORE
	 PJRST CRSINF
	MOVEM	T1,ERPTBK	;SAVE FOR DSPERR
	MOVE	T1,P1		;CURRENT ADDR
	ADDI	T1,1		;BUMP TO 2ND VALUE
	PUSHJ	P,PEKSPY	;GO GET IT
	MOVEM	T1,ERPTBK+1	;SAVE IT TOO
	MOVEI	T1,ERPTBK	;FINISH SETUP FOR DSPERR
	PUSH	P,P1		;SAVE CURRENT ADDR TO QUEUE TABLE
	PUSHJ	P,DSPERR	;GO PROCESS THIS ENTRY
	POP	P,P1		;GET QUEUE ADDR BACK
	MOVE	T1,EPKID1	;GET CURRENT OFFSET
	ADDI	T1,2		;BUMP TO NEXT PAIR
	CAMN	T1,EPKIDX	;COMPARE WITH INITIAL VALUE
	 PJRST	CRSINF		;DONE, EXIT
	MOVEM	T1,EPKID1	;MORE TO GO, SAVE NEW PTR
	JRST	READC1		;AND GET NEXT PAIR

;HERE TO CREATE AN ENTRY OF EXTRACTED INFO FROM THE CRASH
;SUCH AS UPTIME, DISK STATS,ETC

ND	(%LDDES,(XWD 106,16))
ND	(.ESCIN,5)	;VALUE OF THIS ENTRY TYPE
CRSINF:	MOVSI	T1,.ESCIN_9	;CODE FOR THIS ENTRY
	PUSHJ	P,ERRINI	;CREATE HEADER AND PUSH LIST
	MOVE	T1,INDEV	;STR NAME FOR THIS CRASH
	PUSH	P4,T1		;(1)
	MOVE	T1,[%SYERR]	;SYS WIDE ERROR COUNT
	PUSHJ	P,GTBSPY	;GET IT
	 MOVE	T1,PATTERN	;LOOSER?
	PUSH	P4,T1		;(2)
	MOVE	P1,CRSGTB	;START OF GETTAB TABLE
	MOVE	T1,P1	
	HRRI	T1,1		;PNTR FOR SYSERR
	PUSH	P4,T1		;(3)
;NEXT SEVERAL COME FROM CRSGTB TABLE

CRSIN1:	MOVE	T1,0(P1)	;GET AN ITEM
	PUSH	P,P1		;SAVE P1 SINCE GETSPY DESTROYS IT
	TLNE	T1,-1		;IF LH=0,THIS IS A SUBTABLE
	 MOVE	P3,T1		;SAVE FOR NEXT ITEM MAYBE
	TLNN	T1,-1		;IF LH=0,THIS IS A SUBTABLE ITEM
	 JRST	CRSINX		;GO HANDLE SUBTABLE ITEM
	PUSHJ	P,GTBSPY	;GO GET GETTAB ITEM VALUE
	 MOVE	T1,PATTERN	;IF FAIL,USE 252525252525
	PUSH	P4,T1		;INTO ENTRY
	POP	P,P1		;GET P1 RESTORED
	AOBJN	P1,CRSIN1	;GET NEXT ITEM
;HERE TO PROCESS INFO RE DISKS 
CRSIN2:	POP	P4,T2		;GET BACK THE ADDR OF 1ST UDB
	SETZ	P2,		;COUNTER FOR # UNITS
	PUSH	P,P4		;SAVE CURRENT FILE ADDR
	PUSH	P4,P2		;A 0 FOR NOW
	MOVE	P1,T1		;SETUP THE ADDR OF 1ST UDB
CRSIN3:	HLRZ	P1,P1	;CORRECT THE ADDR FORMAT
	MOVEI	T1,UNINAM(P1)	;GET UNIT NAME
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE IT
	MOVE	T1,[%LDDES]
	PUSHJ	P,GETZ	;GET OFFSET TO UNIDES
	 MOVEI	T1,UNIDES	;GETTAB FAILED?
	ADD	T1,P1	;NOW GET DSKCHR WORD TO DETERMINE TYPE
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE IT
	SETZ	T2,		;CLEAR THE ADDER
	MOVEI	T1,UNIBRC(P1)	;BUFFERED READS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIDRC(P1)	;DUMP READ COUNT
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIMRC(P1)	;MONITOR READS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	PUSH	P4,T2		;TOTAL # READS THIS UNIT
	SETZ	T2,		;CLEAR THE ADDER FOR WRITES
	MOVEI	T1,UNIBWC(P1)	;BUFFERED WRITES
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIDWC(P1)	;DUMP WRITES
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIMWC(P1)	;MONITOR WRITES
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	PUSH	P4,T2		;TOTAL # WRITES THIS UNIT
	SETZ	T2,		;NOW FOR SEEKS
	MOVEI	T1,UNIMSC(P1)	;MONITOR SEEKS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	MOVEI	T1,UNIUSC(P1)	;USER SEEKS
	PUSHJ	P,PEKSPY
	ADD	T2,T1
	PUSH	P4,T2		;TOTAL # SEEKS THIS UNIT
	MOVEI	T1,UNISCT(P1)	;SOFT ERRORS
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE IT
	MOVEI	T1,UNIHCT(P1)	;HARD ERRORS
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE IT
	MOVEI	T1,UNIMCT(P1)	;MONITOR DETECTED ERRORS (RIB,ETC)
	PUSHJ	P,PEKSPY
	PUSH	P4,T1		;SAVE IT
	AOS	P2		;BUMP COUNT OF UNITS DONE
	MOVEI	T1,UNISYS(P1)	;ADDR OF NEXT UDB
	PUSHJ	P,PEKSPY	;GET IT
	HLLZ	T1,T1		;JUST THE LEFT HALF PLEASE
	SKIPE	P1,T1		;IF NON-0
	 JRST	CRSIN3		;WORK ON NEXT UNIT
	POP	P,T1		;WHERE TO PUT COUNT OF UNITS
	MOVEM	P2,1(T1)	;NOW SET THAT VALUE
;NOW CHECK FOR CUSTOMER DEFINED ITEMS TO DUMP
	MOVE	P1,CRSGT1	;PNTR OF ITEMS
	TLNN	P1,-1		;NULL LIST?
	 JRST	CRSIN5		;YES,CLOSE THIS ENTRY
CRSIN4:	MOVE	T1,0(P1)	;GET AN ITEM
	TLNE	T1,-1		;THIS CODE IS A COPY OF THAT AROUND CRSIN1
	 MOVE	P3,T1
	TLNN	T1,-1
	 JRST	CRSIN6
	PUSHJ	P,GTBSPY
	 MOVE	T1,PATTERN
	PUSH	P4,T1
	AOBJN	P1,CRSIN4
CRSIN5:	PUSHJ	P,ERRFIN	;CLOSE THE ENTRY AND WRITE IT
	POPJ	P,0		;
CRSIN6:	MOVE	T3,P3
	MOVE	T2,T1
	HRLI	T2,.GTC0V	;CPU0 ONLY FOR NOW??
	PUSHJ	P,GSUBTB
	 MOVE	T1,PATTERN
	PUSH	P4,T1
	AOBJN	P1,CRSIN4
	JRST	CRSIN5

;HERE TO HANDLE SUBTABLE ITEMS
;T1 HOLDS THE SUBITEM, P3 HOLDS THE LAST GETTAB ARGUEMENT
CRSINX:	MOVE	T3,P3		;GET MAIN GETTAB ARG
	MOVE	T2,T1		;AND THE SUB ARG
	HRLI	T2,.GTC0V	;CPU0 ONLY FOR NOW??
	PUSHJ	P,GSUBTB	;GO AFTER VALUE
	 MOVE	T1,PATTERN	;IF FAILURE USE 252525252525
	PUSH	P4,T1		;INTO THE ERROR FILE BUFFER
	POP	P,P1		;RESTORE P1
	AOBJN	P1,CRSIN1	;GET NEXT ITEM,OR
	JRST	CRSIN2		;INFO RE DISKS



;THIS IS THE TABLE OF GETTAB ITEMS TO BE EXTRACTED FROM A CRASH.
;ADDITIONAL ITEMS SHOULD NOT BE ADDED HERE BY A SITE BECAUSE IT WILL
;CONFUSE SYSERR VERY BADLY. USE THE TABLE CRSGT1 INSTEAD.
;  ";***" INDICATES A SUBTABLE ITEM

CRSGTB:	XWD	.-CRSGTE,.+1	;PNTR FOR TABLE LENGTH
	%CNTIM		;TIME OF DAY
	%CNSIZ		;SYSTEM MEMORY SIZE
	%CNPOK		;LAST ADDR POKED
	%CNLNM		;# JOBS LOGGED IN
	%CNTIC		;#TICKS PER SECOND
	%CNVER		;MONITOR VERSION
	%CNDBG		;DEBUG STATUS WORD
	%CNHSO		;START OF MONITO HIGH SEG
	%CNNWC		;#OF WORDS OF CORE
	%NSUPT		;UPTIME IN TICKS
	%NSMMS		;MEMORY SIZE
	%NSTPE		;TOTLAL MEM PAR ERRORS
	%NSSPE		;TOTAL SPURIOUS PARITY ERRORS
	%NSMPC		;MULTIPLE PARITY ERRORS
	%NSMPA		;LAST PARITY ADDR
	%NSMPW		;LAST PARITY WORD
	%NSMPP		;LASTPARITY PC
	%NSEPO		;# UNREC EXEC PDL OV
	%NSEPR		;# RECOVERED EXEC PDL OV
	%SWERC		;SWAP ERROR COUNT
	%SYDEL		;DISABLED HARDWARE ERROR COUNT
	%SYSPC		;LAST STOPCD
	%SYNDS		;# DEBUG STOPCDS
	%SYNJS		;# JOB STOPCDS
	%SYSJN		;LAST STOPCD-JOB NUMBER
	%SYSPN		;LAST STOPCD-PROGRAM NAME
	%SYSUU		;LAST STOPCD-UUO
	%SYSPP		;LAST STOPCD-P,PN
	%CCPAR		;PARITY SUBTABLE
	%CVPLA		;**HIGHEST ADDR OF PARITY ERROR
	%CVPMR		;**ADDRES IN SEGMENT OF PAR ERR
	%CVPTS		;**PAR ERRORS THIS SWEEP
	%CVPSC		;**#SWEEPS
	%CVPUE		;**USER ENABLED
	%CVPAA		;**LOGICAL AND  OF ADDR
	%CVPAC		;**LOGICAL AND OF WORDS
	%CVPOA		;**LOG OR OF ADDR
	%CVPOC		;**LOG OR OF DATA
	%CVPCS		;**COUNT OF SPUR CHANNEL ERROS
	%CCRSP		;ADDR OF RESPONSE SUBTABLE
	%CVRSO		;**SUM TTY OUT UUO RES
	%CVRNO		;**NUM TTY OUT UUO
	%CVRHO		;**HI-SUM SQ TTY OUT UUO
	%CVRLO		;**LO-SUM	"    "
	%CVRSI		;**SUM TTY INP UUO
	%CVRNI		;**NUMBER TTY INP UUO
	%CVRHI		;**HI-SUM SQ TTY INP UUO
	%CVRLI		;**LO-SUMSQ TTY INP UUO
	%CVRSR		;**SUM QUANTUM REQ RES
	%CVRNR		;**NUMBER QUANTUM REQ RES
	%CVRHR		;**HI-SUM SQ QUANTUM RES
	%CVRLR		;**LO-SUM SQ QUANTUM REQ RES
	%CVRSX		;**SUM ONE OF ABOVE
	%CVRNX		;**NUMBER ONE OF ABOVE
	%CVRHX		;** HI-SUM SQ ONE OF ABOVE
	%CVRLX		;**LO-SUM SQ ONE OF ABOVE
	%CVRSC		;**SUM CPU RES
	%CVRNC		;**NUMBER CPU RES
	%CVRHC		;**HI-SUM CPU RES
	%CVRLC		;**LO-SUM CPU RES
	%CVUPT		;UPTIME
	%CVLST		;LOST TIME
	%CVNUL		;NULTIME
	%CVOHT		;OVERHEAD TIME IN JIFFIES
	%CVTUC		;TOTAL UUO COUNT
	%CVTJC		;TOTAL JOB CONTEXT SWITCH COUNT
	%CVTNE		;TOTAL NXM
	%CVSNE		;TOTAL SPUR NXM
	%CVNJA		;# JOBS AFFECTED LAST NXM
	%CVMNA		;FIRST ADDR LAST NXM
	%LDUNI		;PNTR TO 1ST UNIT DATA BLOCK
	CRSGTE==.-1		;END OF TABLE
;%LDUNI SOULD BE LAST ITEM IN ABOVE TABLE TO SETUP FOR DISK UNIT STATS

CRSGT1:	XWD .-CRSGT2, .+1	;PNTR FOR TABLE TO BE DEFINED BY CUSTOMER
			;SYSERR WILL LIST TESE ITEMS IN OCTAL ONLY, IFF PRESENT

	CRSGT2==.-1

SETDS3:	PUSHJ	P,GETFIL
	JRST	CPOPJ1			;***(CAN'T GET AT THAT FILE)
	SETOM	DSKBLF		;CLEAR INITIAL DISK BLOCK
	MOVEI	T1,0		;LETS CHECK HEADER WORD
;	PUSHJ	P,DSKA		;GET FIRST WORD
;CAN'T USE DSKA BECAUSE WE WANT TO READ DIRECTORY
	USETI	DSKX,1	;GET BLOCK1
	IN	DSKX,DSKIOW	;GET IT
	SKIPA			;OVER FAIL RETURN
	 JRST	CPOPJ1	;**READ FAILED?
	MOVE	T1,DSKBUF	;GET THE FIRST WORD
	HLRZS	T1		;GET HEADER CODE
	CAIE	T1,1776		;CORRECT?
	JRST	CPOPJ1			;***NO
	MOVEI	T1,ABSTB1	;GET POINTER TO GETTABS
DSKJN1:	MOVEM	T1,MAXGTB	;BORROW THIS CELL TO REMEMBER WHICH ABSTAB TRYING
	PUSHJ	P,DSKA		;READ IT
	TLNE	T1,-1		;MAKE SURE ZERO LH
	JRST	DSKJNK		;NO. NOT ABSTAB
	CAMLE	T1,MAXGTB	;MAKE SURE IT MAKES SOME SENSE
	CAML	T1,DSKFLG	; ..
	JRST	DSKJNK		;NO--GIVE UP
	HRRZ	T2,T1		;SAVE FOR TEST LATER
	ADDI	T1,.GTSLF	;ADD OFFSET FOR GETTAB IMMEDIATE
	PUSHJ	P,DSKA		;READ THAT PLACE
	CAIE	T2,(T1)		;SEE IF IT MATCHES
	JRST	DSKJNK		;NO--MUST BE JUNK
	HRRZM	T1,OFSGTB	;YES--REMEMBER OFFSET
	LSH	T1,-^D9		;GET NUMBER OF TABLES
	HLRZM	T1,MAXGTB	;SAVE IT
	MOVE	T1,[ %CNPDB]	;SET UP PDB POINTER FOR CRASH FILE
	PUSHJ	P,GETZ		;SEE IIF IT IS THERE
	MOVEM	T1,PDBPTR	;STORE ZERO OR VALUE
	MOVE	T1,[%CNVER]	; GET CRASHED MONITORS
	PUSHJ	P,GETZ		; VERSION INTO A
	HRRZS	T1		; STRIP OFF NOISE BITS
	MOVEM	T1,MONVER	; AND STORE IT AWAY
	CAIGE	T1,60122		; OLD STYLE IF LESS
	CAIGE	T1,60000		; AN OLD MONITOR
	CAIGE	T1,50722		; IF NOT VERSION 6 OR LATER
	SETZM	NPJOBN		; OLD STYLE SO CLEAR NEW JOB PTR.
	SKIPE	NPJOBN		; IS IT OLD STYLE ?
	POPJ	P,		; NO--RETURN
	MOVE	T1,[%CNLSD]	; GET LENGTH OF SHORT DDB
	PUSHJ	P,GETZ		; GET ZERO OR VALUE
	JUMPE	T1,CPOPJ		; IF ZERO, RETURN
	HRRM	T1,.DVFIL	; UPDATE FILE POINTER
	ADDI	T1,1		; EXTENSION POINTER
	HRRM	T1,.DVEXT	; . .
	ADDI	T1,1		; UPDATE
	HRRM	T1,.DVPPN	; PPN POINTER
	ADDI	T1,DV.UNI-DV.PPN	; POINT TO UNIT ENTRY IN DISK DDB
	HRRM	T1,.DVUNI	; UPDATE UNIT POINTER
	POPJ	P,		; RETURN

DSKJNK:	MOVEI	T1,ABSTB2	;TRY SECOND ONE
	CAME	T1,MAXGTB	;OR DID WE ALREADY?
	JRST	DSKJN1		;NO, TRY IT.
	JRST	CPOPJ1			;*** CANT FIND GETTABS


;ROUTINE TO GET NEXT STR IN SYS SEARCH LIST P1 HOLDS PREVIOUS STR  NAME

GOBUUO:	MOVE	T1,[XWD 5,GOBBLK]
	SETZM	GOBBLK		;JOB  =SYS SEARC LIST
	MOVEM 	P1,GOBBLK+2		;LAST NAME WE USED
	SETZ	P1,
	GOBSTR	T1,		;DO THE UUO
	 JRST	CPOPJ1		;***FAILED, CODE IN T1
	MOVE	P1,GOBBLK+2	;NAME RETURNED
	POPJ	P,0		;AND WE RETURN
GOBBLK:	BLOCK	6

GETFIL:	MOVSI	T1,DSKX		; GET CHANNEL #
	MOVEM	T1,FLP+.FOFNC	; AND STORE IT IN FILOP. BLOCK
	MOVEI	T1,.FORED	; SET FUNCTION CODE FOR READ
	HRRM	T1,FLP+.FOFNC	;  TO READ FILE
	MOVEI	T1,17		; SET I/O MODE
	MOVEM	T1,FLP+.FOIOS	;  . .
	SKIPN	T1,INDEV		; DID USER SPECIFY A DEVICE ?
	MOVSI	T1,'DSK'		; NO--ASSUME DSK
	MOVEM	T1,FLP+.FODEV	; AND STORE IT
	DEVCHR	T1,		; GET DEVICE CHARACTERISTICS
	TLNN	T1,(DV.DIR)	; IS IT A DISK ?
	POPJ	P,			;***NOT DISK??
	SETZM	FLP+.FOBRH	; NO BUFFERS
	SETZM	FLP+.FONBF	;  . .
	MOVEI	T1,LKB		; ADDR. OF LOOKUP BLOCK
	MOVEM	T1,FLP+.FOLEB	;  . .
	SKIPN	T1,INFILE	; FILE SPECIFIED ?
	MOVE	T1,CRASH
	MOVEM	T1,LKB+.RBNAM	; STORE IT IN LOOKUP BLOCK
	SKIPN	T1,INEXT	; EXTENSION SPECIFIED ?
	MOVSI	T1,'EXE'	;ASSUME EXE
	MOVEM	T1,LKB+.RBEXT	; STORE IT
	SKIPN	T1,INPPN		; PPN SPECIFIED ?
	MOVE	T1,CRSPPN	; NO--USE CRASH PPN DEFAULT
	MOVEM	T1,LKB+.RBPPN	; STORE IT
	MOVEI	T1,10		; GET EXTENDED LOOKUP BLOCK SIZE
	MOVEM	T1,LKB		; STORE IT IN LOOKUP BLOCK
FLPAGN:	MOVE	T1,[XWD 6,FLP]	; POINT TO FILOP. BLOCK
	FILOP.	T1,		; OPEN CRASH FILE
	  JRST	FLPERR		; GO PROCESS FILOP. ERROR
FILOPN:	MOVE	T1,LKB+.RBSIZ	;GET FILE SIZE
	MOVEM	T1,DSKFLG	; AND SAVE IT AWAY FOR LATER
	JRST	CPOPJ1		; GIVE GOOD RETURN

FLPERR:	CAME	T1,[XWD 6,FLP]	; IS FILOP. IMPLEMENTED ?
	POPJ	P,		;YES, DONT KNOW WHAT WENT WRONG, ERR
	OPEN	DSKX,FLP+.FOIOS	; NO--DO MANUAL OPEN
	  POPJ	P,		; CAN'T ACCESS FILE
	LOOKUP	DSKX,LKB		; LOOKUP FILE
	POPJ	P,		;LOOKUP FAILURE, CANT GET IT
	JRST	FILOPN		;PROCEED


DSKBP1:	CAMN	BP,LASBPA	;SEE IF SAME AS LAST ONE
	JRST	[MOVE BP,LASBP1	;YES--GET SAME ANSWER
		 JRST CPOPJ1]	;GIVE SKIP RETURN
	MOVEM	BP,LASBPA	;NO--SAVE ADDRESS
	PUSH	P,T1		;SAVE T1
	MOVE	T1,BP		;GET ARGUMENT
	PUSHJ	P,DSKA		;GET WORD
	MOVE	BP,T1		;GIVE ANSWER
	POP	P,T1		;RESORE T1
	MOVEM	BP,LASBP1	;SAVE ANSWER
	JRST	CPOPJ1		;SKIP RETURN

DSKC:	PUSH	P,T1		;SAVE T1
	MOVE	T1,T3		;GET ARGUMENT
	PUSHJ	P,DSKA		;GET WORD
	MOVE	T3,T1		;GIVE ANSWER
	POP	P,T1		;RESTORE T1
	POPJ	P,		;RETURN
DSKA1:	AOS	(P)		;SKIP RETURN
DSKA:	PUSH	P,T2		;SAVE T2
	TLZ	T1,-1		;CLEAR JUNK
	CAML	T1,DSKFLG	;COMPARE TO AMOUNT IN FILE
	JRST	DSKA2			;ADDR OUT OF RANGE, WOULD BE ILL REF
	ADDI	T1,EXESIZ	;IGNORE DIRECTORY
	IDIVI	T1,LN.BUF	;SPLIT INTO BLOCK AND WORD
	CAMN	T1,DSKBLF	;SEE IF BLOCK IN CORE
	JRST	DSKARD		;YES--JUST GET WORD
	MOVEM	T1,DSKBLF	;AND REMEMBER BLOCK
	IFN  LN.BUF-200,<PUSH P,T2
			 IDIVI T1,LN.BUF/200
			 POP  P,T2>
	IFN	LN.BUF-<LN.BUF/200>*200,<PRINTX LN.BUF MUST BE MULT OF 200>
	USETI	DSKX,1(T1)	;NO--POSITION FILE
	IN	DSKX,DSKIOW
	JRST	DSKARD		;READ OK
DSKA2:	SETZ	T1,			;***READ FAILED
	POP	P,T2		;RETURN 0 VALUE
	POPJ	P,0


DSKARD:	MOVE	T1,DSKBUF(T2)
	POP	P,T2
	POPJ	P,
	SUBTTL	SUBROUTINES FOR READING CRASH.EXE
;GETTAB OPTIONAL TABLE--RETURN 0 IF ABSENT (RESULT IN T1)
GETZ:	PUSH	P,P1		;SAVE P1
	PUSHJ	P,FGETTB	;GO DO GETTAB
	  SETZ	T1,
	POP	P,P1		;RESTORE P1
	POPJ	P,

;GETTAB OPTIONAL TABLE--ERROR RETURN IF ABSENT (RESULT IN T2)
GETTB:	PUSH	P,T1		;SAVE T1
	PUSH	P,P1		;P1 TOO
	MOVE	T1,T2		;SETUP FOR GETTAB
	PUSHJ	P,FGETTB	;DO GETTAB
	  JRST	[POP	P,P1
		POP	P,T1
		 POPJ	P,]
	MOVE	T2,T1		;GET ANSWER
	POP	P,P1		;RESTORE T1
	POP	P,T1
>;END OF IFGE FTSAVE

CPOPJ1:	AOS	(P)
	POPJ	P,

IFGE	FTSAVE,<


;GETTAB SIMULATOR FOR DAEMON TO USE

GETSIM:	PUSH	P,P1
	PUSHJ	P,FGETTB
	JRST	[ SETZ T1,
		POP	P,P1
		  POPJ	P,0]
			;GIVES NON-SKIP RETURN
	POP	P,P1
	JRST	CPOPJ1	;GIVE GOOD RETURN

;ROUTINE TO FUDGE GETTABS VIA SPY IF POSSIBLE
;NOTE--DOES NOT HANDLE -2 IN LH, IF FAIL, CHANGES T1

FGETTB:	SKIPE	P1,MAXGTB	;SEE IF GETTAB SPYING POSSIBLE
	JRST	GETTB1		;YES--GO DO IT
FGETT1:	SKIPN	DSKFLG		;DONT GETTAB IF IN /X
	GETTAB	T1,		;NO--USE MONITOR
	  POPJ	P,		;ERROR RETURN
	JRST	CPOPJ1		;WIN RETURN
GETTB1:	HRRZ	BP,T1		;GET TABLE INDEX
	CAMLE	BP,P1		;SEE IF IN RANGE
	POPJ	P,		;NO--ERROR RETURN
	ADD	BP,OFSGTB	;YES--GET CORE ADDRESS
	TLNE	F,FL.DSK	;SEE IF DISK MODE
	PUSHJ	P,DSKBP1	;YES--READ FROM IT AND SKIP
	MOVE	BP,400000(BP)	;GET NUMTAB POINTER
	PUSHJ	P,SETSPY		;SET UP SPY DATA
	SKIPE	PDBPTR		;YES. HAVE WE THE POINTER TO JBTPDB?
	SKIPA			;OK
	JRST	FGETT1		;NO. GO USE A GETTAB
	HLRZ	T1,T1		;GET REQUESTED INDEX IN TABLE
	TRNE	T1,1B18		;SEE IF JOB FLAG
	MOVE	T1,MYJOB		;YES--GET JOB NUMBER
	CAMLE	T1,P1		;SEE IF IN RANGE
	POPJ	P,		;NO--ERROR RETURN
	TLNN	BP,(17B17)	;SEE IF INDEXING
	MOVEI	T1,0		;NO--CLEAR REQUEST
	TLNN	BP,(GT.PRC)	;PDB DATUM?
	JRST	FGETT2		;NO
	TLNE	F,FL.DSK	;DISK MODE?
	JRST	FGETP2		;YES, HANDLE IT
	ADD	BP,@PDBPTR	;GET ADDRESS IN JOBS PDB
	MOVEI	T1,0		;HAVE ADDED IN A ALREADY
FGETT2:	ADDI	T1,(BP)		;ADD TABLE LOCATION TO OFFSET
	TLNE	F,FL.DSK	;SEE IF DISK MODE
	PJRST	DSKA1		;YES--GET WORD FROM DISK
	MOVE	T1,400000(T1)	;GET WORD
	JRST	CPOPJ1		;GIVE WIN RETURN

FGETP2:	ADD	T1,PDBPTR	;GET JOBS PDB POINTER FROM DISK
	PUSHJ	P,DSKA
	ADDB	BP,T1		;POINT TO RELATIVE WORD
	PJRST	DSKA1		;GET THE PDB WORD

SETSPY:	LDB	P1,[POINT 9,BP,8];GET TABLE LENGTH
	PUSH	P,P1		;AND SAVE IT
	SKIPN	NEWSPY		;THE NEW STYLE OF SPYING
	JRST	SETSP0		;NO LEAVEIT AS IT IS
	LDB	P1,[POINT 3,BP,11];GET ENTRY TYPE
	TLZ	BP,777760	;ZAP ALL BUT INDEX FIELD
	CAIN	P1,GT.PDB	;SKIP IF NOT PDB DATA
	TLO	BP,(GT.PRC)	;COMPATIBLE
SETSP0:	POP	P,P1		;GET LENGTH OF TABLE BACK
	TLNN	BP,(GT.PRC)	;PDB DATA??
	AOS	(P)		;SET SKIP RETURN
	POPJ	P,0
;PEEK INTO T3
PEEKC:	TLNE	F,FL.DSK	;SEE IF DISK MODE
	PJRST	DSKC		;YES--PEEK AT THE DISK
	SKIPE	SPYFLG		;SEE IF SPYING
	SKIPA	T3,400000(T3)	;YES--GET FROM CORE
	PEEK	T3,		;NO--GET FROM MONITOR
	POPJ	P,

;PEEK INTO T1
PEEKA:	TLNE	F,FL.DSK	;SEE IF DISK MODE
	PJRST	DSKA		;YES--PEEK AT THE DISK
	SKIPE	SPYFLG		;SEE IF SPYING
	SKIPA	T1,400000(T1)	;YES--GET FROM CORE
	PEEK	T1,		;NO--GET FROM MONITOR
	POPJ	P,

GETBTH:	ANDI	T1,-1		;MASK TO SIZE
	SKIPE	T1		;ERROR IF 0
	CAML	T1,DSKFLG	;SEE IF IT FITS
	POPJ	P,		;NO--GIVE ERROR
	MOVEI	T3,-1(T1)		;GET ADDR-1
	PUSHJ	P,PEEKA		;GET CONT(ADDR)
	PUSHJ	P,PEEKC		;GET CONT(ADDR-1)
	JRST	CPOPJ1		;SKIP RETURN

DSKBLF:	0
DSKIOW:	IOWD	LN.BUF,DSKBUF	;
	0


DSKBUF:	BLOCK LN.BUF
LASBP1:	BLOCK	1		;VAL OF LAST DSKBP1 CALL
LASBPA:	BLOCK	1		;ARG OF LAST DSKBP1 CALL
SPYFLG:	BLOCK	1		;-1 IF SPYING
NEWSPY:	Z
MYJOB:	BLOCK	1		;WHY THIS
INDEV:	0
INFILE:	0
INEXT:	0
INPPN:	0
CRASH:	SIXBIT /CRASH/
CRSEXT:	SIXBIT /XPN/
CRSPPN:	XWD	1,4
DSKFLG:	BLOCK	1		;FLAG (AND MAX SIZE) OF DSK INPUT FILE
OFSGTB:	BLOCK	1		;START OF GETTAB TABLE POINTERS
NPJOBN:	Z
EPKIDX:	Z		;POINTER TO EXTRACT ENTRIES (INITIAL)
ERPTMX:	Z			;LENGTH OF TABLE
EPKID1:	Z			;CURRENT GETTER POINTER
ESVIDX:	Z			;PHYSICAL ADDR OF ERROR TABLE
.DVFIL:	T4,,DV.FIL			;TO GET FILE NAMES
.DVEXT:	T4,,DV.EXT		;TO GET FILE EXTNS
.DVPPN:	T4,,DV.PPN		;TO GET PPN
.DVUNI:	T4,,DV.UNI		;TO GET UDB ADDR

FLP:	BLOCK 6		;FILOP. ARG BLOCK
LKB:	BLOCK 20		;EXTENDED LOOKUP BLOCK

>;END OF IFGE FTSAVE




SUBTTL	DATA AND STORAGE, BUFFERS, ETC.

ILIST:	XWD	-200,0		;DUMP MODE INPUT COMMAND LIST 
	0
OLIST:	XWD	-P2,0		;DUMP MODE OUTPUT COMMAND LIST (WORD COUNT WILL
	0 			; BE FILLED IN.)

DLIST:
BPSTRT:	IOWD	200,DAEBUF
	0
UPDLST:	IOWD	200,SECBUF
	0
PDL:	IOWD	PDLEN,PDLIST
PATTERN:	XWD	252525,252525

JBYSUN:	POINT	3,SEGSWP,5	;PRE 601 SWAP UNIT POINTER
				; OVERWRITTEN IF 601 OR LATER MONITOR
JBYLKS:	POINT	12,SEGSWP,17	;PRE 601 SWAP BLOCK POINTER
				; OVERWRITTEN IF 601 OR LATER MONITOR

QUECOD:	POINT	5,T1,14

IFLE	FTSAVE,<
COMLST:	SIXBIT	.DCORE.
	SIXBIT	.DUMP.
	SIXBIT	.SAVE.
	SIXBIT	.SSAVE.
	SIXBIT	.E.
	SIXBIT	.D.
	SIXBIT	.VERSIO.
	SIXBIT	.OSAVE.
	SIXBIT	.OSSAVE.
COMLEN==.-COMLST

COMDSP:	DCORE
	DUMP
	SAVE
	SAVE
	ECOM
	DCOM
	VERCOM
	SAVE
	SAVE
>	;END IFLE FTSAVE

JBTCLK:	Z	0(J)
QIKNAM:	ASCIZ	\@SYS:QUIKDM.CCL\
IFN PURESW,<RELOC>

;[62]THIS CODE MUST GO HERE TO AVOID BLT OF ZEROES.
IOERR:	BLOCK	1	;[62]FLAG TO STOP IO TO ERROR FILE
IERCNT:	EXP	^D10	;[62]COUNTER FOR TIMED RETRIES
NEWEXT:	EXP	^D10	;[62]COUNT TO PREVENT TOO MANY NEW EXTS. IN ROW
ERREXT:	'SYS'	;[62]ERROR FILE EXTENSION
RELINS:	RELEAS	0,		;[535] CHANNEL # INSERTED BEFORE XCT
RESTART:	Z		;ZERO MEANS NOT RERUN BY RUN UUO
				;-1 MEANS RERUN

ZER:!
CCLFIL:	BLOCK	1	;SIXBIT JOB NUMBER IN LH FOR CCL FILES
CTYLIN:	BLOCK	1	;LINE NUMBER FOR CTY
CURBLK:	BLOCK	1
CURWRD:	BLOCK	1
C.BH:	BLOCK	3
DAQNAM:	BLOCK	1
D.DEV:	BLOCK	1
D.NAM:	BLOCK	1
	BLOCK	1
D.EXT:	BLOCK	1
D.DIR:	BLOCK	1
	BLOCK	1
D.PROT:	BLOCK	1
D.DPTH:	BLOCK	DPTHLN+1	;LAST WORD SURE TO BE ZERO

EBLOCK:				;BLOCK FOR EXTENDED LOOKUPS AND ENTERS
RBCNTE:	BLOCK	1
RBPPNE:	BLOCK	1
RBNAME:	BLOCK	1
RBEXTE:	BLOCK	1
RBPRVE:	BLOCK	1
RBSIZE:	BLOCK	1

GTBST:	BLOCK	1	;BEGINNING OF TABLE OF GETTAB PTRS
HGHOFF:	BLOCK	1	;BEGINNING OF HIGH SEGMENT
HGHREL:	BLOCK	1	;LENGTH OF HIGH SEGMENT
HJOB:	BLOCK	1	;HIGHEST JOB NO IN RH
LINE==HJOB			;LH LINE NO OF DUMP/DCORE COMMAND
INTADR:	BLOCK	1	;ADDR TO RESTART FOR ERROR INTERCEPT
INTBLK:	BLOCK	4	;ERROR INTERCEPT BLOCK
MAXGTB:	BLOCK	1	;HIGHEST LEGAL GETTAB TABLE
MFDPPN:	BLOCK	1
PDLIST:	BLOCK	PDLEN
PTRADR:	BLOCK	1
REMBLK:	BLOCK	1
REMWRD:	BLOCK	1
STRADR:	BLOCK	1	;SAVE .JBSA HERE DURING SAVE
SAVXWD:	BLOCK	1	;SAVE UUO XWD (FROM EXEC AC T2)
SECBUF:	BLOCK	200
SEGREL:	BLOCK	1
SEGSWP:	BLOCK	1
SWPADR:	BLOCK	1
BLKPAG:	BLOCK	1	;SHIFT COUNT TO CONVERT CHUNKS OF SWAPPING SPACE
			;(PAGES OR K'S) TO NUMBER OF BLOCKS
PKLSH:	BLOCK	1	;LSH T1,1 IF KA; JFCL IF KI
EXECT1:	BLOCK	1	;WORD FOR ADDRESS OF EXEC AC T1 IN USER'S JOBDAT
ERPTBK:	BLOCK	2	;2 WORD BLOCK FOR ERRPT. UUO
NERRPT:	BLOCK	1	;-1 IF NEW ERROR REPORTING IN MONITOR
VMMON:	BLOCK	1	;-1 IF MONITOR HAS VM , 0 OTHERWISE
.UPJOB:	BLOCK	1	;OFFSET OF JOB NUMBER IN UPMP
LDDBSH:	BLOCK 	1	;LENGTH OF SHORT DDB
LDDBLN:	BLOCK	1	;LENGTH OF LONG DDB
LDDBDS:	BLOCK	1	;LENGTH OF DISK DDB
KONREG:	BLOCK	1	;OFFSET OF # OF DRIVE REGS IN KDB
UNISCR:	BLOCK	1	;OFFSET OF DRIVE REGISTERS IN UNIT DATA BLOCK
UNICCT:	BLOCK 1	;OFFSET TO # BAT SLOTS LEFT IN UDB [463]
CHNTCW:	BLOCK 1	;OFFSET TO EXP. TERM WD IN CDB [463]
		; (I.E. THE VALUE OF .CHTCW)
MONVER:	BLOCK	1	;[545] MONITOR VERSION
IFN FTSVSL,<
PSRCH:	BLOCK	1	;LEN,,ADDR OF OUR SEARCH LIST
SRCLST:	BLOCK	3*^D9+4	;SPACE FOR OUR SEARCH LIST>
USRLST:	BLOCK	3*^D9+4	;SPACE FOR USER SEARCH LIST
THSJOB:	BLOCK	1	;OUR JOB NUMBER
THSLIN:	BLOCK	1	;OUR LINE NUMBER
THSOFF:	BLOCK	1
THSSEG:	BLOCK	1
UPDFLG:	BLOCK	1	;-1 IF MUST DO USETO FOR NORMAL WRITE, 0 IF NOT
USRADR:	BLOCK	1
USRCOR:	BLOCK	MAXUCR+<1_WRDSPB>
USRUPM:	BLOCK	MAXUPM
USRPPN::BLOCK	1
WRDCNT:	BLOCK	1	;WORDS FROM LAST PATTERN
.SWPUN:	BLOCK	MAXSWP
.UNSLB:	BLOCK	MAXSWP
IFN FTERR,<
$CPPAR:	BLOCK	CPUN	;TOTAL PARITY ERRORS EACH CPU
$UNIER:	BLOCK	UNITN	;TOTAL I/O ERRORS EACH UNIT
$MTAER:	BLOCK	MTAN	;TOTAL I/O ERRORS FOR EACH MTA
$MTAUN:	BLOCK	MTAN	;TOTAL UNLOADS FOR EACH MTA
$CHERR:	BLOCK	CHNN	;TOTAL ERRORS EACH CHANNEL
>;END COND ON FTERR
PDBPTR:	BLOCK	1		;ADDRESS OF JBTPDB IN MONITOR FOR SPY
NEXTUP:	BLOCK	1		;NEXT TIME TO CAUSE A WAKE
NEXTJB:	BLOCK	1		;JOB TO WAKE
CCTIM:	BLOCK	1		;CURRENT CHKPNT INTERVAL
CUTIM:	BLOCK	1		;CURRENT UNIT SCAN INTERVAL
QPNTR:	BLOCK	1		;POINTER TO QUEUE
OPRPPN:	BLOCK	1		;PPN OF THE OPERATOR
JIFSEC:	BLOCK	1	;JIFFIES PER SECOND
JIFDAY:	BLOCK	1	;JIFFIES PER DAY
MILJIF:	BLOCK	1	;MILLISECONDS PER JIFFY
SERCNT:	BLOCK	1	;LAST NOTICED COUNT OF SYSTEM HARDWARE ERRORS
DERCNT:	BLOCK	1	;NUMBER OF TIMES DAEMON HAS LOGGED ERRORS
JDPCNT:	BLOCK	1	;NUMBER OF JOBS SEEN STOPPED FOR HDW ERRORS
PDLGUF:	BLOCK	1	;DEBUG - CONTAINS ERRONEOUS P CONTENTS
GTBGUF:	BLOCK	1	;DEBUG - COUNTS MISTAKES IN GTBSPY
ATTGUF:	BLOCK	1	;DEBUG - COUNTS ATTACH FAILURES
FRCGUF:	BLOCK	1	;DEBUG - COUNTS FRCUUO FAILURES
FINGUF:	BLOCK	1	;DEBUG - COUNTS DAEFIN ERROR RETURNS
STRGUF:	BLOCK	1	;DEBUG - COUNTS STRUUO ERROR RETURNS
WAKGUF:	BLOCK	1	;DEBUG - COUNTS ERROR RETURNS FROM WAKE UUO
CLKGUF:	BLOCK	1	;DEBUG - COUNTS CLOCK REQUESTS ON UNASSIGNED CHANNELS
INTGUF:	BLOCK	1	;DEBUG - COUNTS INTERCEPTS
;**;[537] DELETE	INTRPC:	BLOCK	1	;DEBUG - PC OF INTERCEPT
OUTGUF:	BLOCK	1	;COUNTS TIMES WE WANTED TO OUTSTR BUT WERE DETACHED
SWRGUF:	BLOCK	1	;COUNTS SWAP READ ERRORS
SWWGUF:	BLOCK	1	;COUNTS SWAP WRITE ERORS
WRTGUF:	BLOCK	1	;COUNTS FAILURES IN MARKSPT
FCTGUF:	BLOCK	1	;COUNTS FACT FILE ERRORS
BSYFCT:	BLOCK	1	;COUNTS TIMES FACT FILE BEING MODIFIED TOO LONG
CURJOB:	BLOCK	1	;DEBUG - LAST JOB SERVICED
WTUERR:	BLOCK	1	;FLAG TO PREVENT RECURSIVE CALLS OF WTUCOR WHEN
			;IT GETS IO ERRORS ON THE SWAPPING DEVICE WHILE
			;ATTEMPTING TO WRITE THE EXIT VALUES FOR A UUO.
IFN FTDEBG,<		;DON'T WASTE SPACE
PATT:	BLOCK	100	;SPACE FOR PATCHES>
FACTSZ:	BLOCK	1		;NUMBER OF WORDS IN FACT BUFFER
IFN FTERR,<
NXMLEN:	BLOCK	1		;LENGTH OF NXMTAB
NXMTAB:	BLOCK	1		;POINTER TO FIRST COPY OF NXMTAB
RP4MON:	BLOCK	1	 	;WORD TO REMEMBER IF WE HAVE RP04
				; SUPPORT IN THIS MONITOR
ERRBUF:	BLOCK	<1_WRDSPB>+ERRSIZ+2	;LAST BLOCK OF ERROR.SYS READ HERE
ERABUF=ERRBUF+<1_WRDSPB>	;WHERE TO PUT THE NEW STUFF
>;END COND ON FTERR
GOBBUF:
DAEBUF:	BLOCK	<1_WRDSPB>	;BUFFER FOR DUMP IO
IFN CHKFCT,<
FACTBF:	BLOCK	MAXFCT+TRNSIZ+1	;FACT FILE BUFFER
>;END COND ON CHKFCT
IFG	FTSAVE,<
SAVWAT:	Z			;POINTER TO TABLE OF JOBS WOKEN FOR SAVER
>;END IFG FTSAVE
EZER==.-1
DAEEND::	PRGEND	DAEMON
	TITLE	SCANER		COMMAND SCANNER FOR DEMON
	SUBTTL	DEFINITIONS

	IFNDEF	LINSIZ,<LINSIZ==^D135>	;MAX CHARS/LINE
	IFNDEF	.FXLNF,<.FXLNF==6>	;MAX DIRECTORY NESTING

;AC DEFINITIONS

	SF=0	;SCANNER FLAGS
	T1=1	;TEMP
	T2=2
	T3=3
	T4=4
	P1=5	;PERM
	P2=6
	SN=14
	SC=16	;CHAR
	P=17	;PDL PTR

;FLAGS IN SF

	F%BRK==1B0		;SIGN BIT -- ON IF BREAK SEEN
	F%SOM==1B1		;ON IF SOME INPUT SEEN IN FILE SPEC COLLECTOR
	F%EXT==1B2		;EXTENSION SPECIFIED
	F%OCT==1B3		;VALID INPUT FROM OCTIN

;USEFUL OPDEF'S

	OPDEF	PJRST	[JRST]

;IMPORTANT NON-PRINTING CHARACTERS

	.CHNUL==0	;NULL
	.CHBEL==7	;BELL
	.CHTAB==11	;TAB
	.CHLFD==12	;LINE FEED
	.CHVTB==13	;VERTICAL TAB
	.CHFFD==14	;FORM FEED
	.CHCRT==15	;CARRIAGE RETURN
	.CHCNR==22	;CONTROL R
	.CHCNU==25	;CONTROL U
	.CHCNZ==32	;CONTROL Z
	.CHESC==33	;ESCAPE
	.CHDEL==177	;RUBOUT
	SUBTTL	INITIALIZE COMMAND SCANNER

;ISCAN - INITIALIZE, RESCAN, AND INPUT MONITOR COMMAND
;TSCAN - CALLED AFTER ISCAN TO INPUT A COMMAND OR KEYWORD
;CALL WITH C(T1)=IOWD TO LIST OF MONITOR COMMANDS
;RETURNS WITH C(T1)=INDEX INTO MONITOR COMMAND LIST OR -1

.ISCAN::TLO	SF,(F%BRK)	;MARK END OF LINE SO NEW COMMAND
				; WILL BE SCANNED
	RESCAN	1		;COMMAND?
	SKPINL			;?
	  JRST	RETNEG		;NO COMMAND, RETURN -1

.TSCAN:	PUSH	P,T1		;SAVE IOWD
	PUSHJ	P,SIXIN		;READ SIXBIT COMMAND
	POP	P,T4		;RESTORE PTR TO COMMAND TABLE
	PUSHJ	P,NAME		;FIND NAME IN TABLE
RETNEG:	  SKIPA	T1,[EXP -1]	;RETURN -1 FOR NOT FOUND
	HRRZ	T1,T2		;INDEX INTO T1
	POPJ	P,		;AND RETURN
	SUBTTL	SUBROUTINES

;MAKPJN	SUBROUTINE TO MAKE CCL JOB NUMBER
;ARGS	T2=JOB NUMBER
;VALUES	T4=CCL JOB NUMBER

MAKPJN::PUSH	P,P1		;SAVE P1
	MOVEI	P1,3		;3 DIGITS
MAKPJ1:	IDIVI	T2,^D10		;DIVIDE BY DECIMAL 10
	ADDI	T3,'0'		;MAKE SIXBIT REMAINDER
	LSHC	T3,-6		;SHIFT INTO T4
	SOJG	P1,MAKPJ1	;LOOP
	POP	P,P1		;RESTORE P1
	POPJ	P,		;RETURN

;TSIXN - TYPE C(T2) AS SIXBIT, NO TRAILING BLANKS

TSIX:	SETZ	T1,		;MAKE ROOM
	LSHC	T1,6		;GET CHAR IN T1
	MOVEI	SC,40(T1)	;MAKE ASCII IN SC
	OUTCHR	SC		;TYPE IT
TSIXN::	JUMPN	T2,TSIX		;LOOP IF MORE
	POPJ	P,		;DONE

;TOCT - TYPE OCTAL VALUE GIVEN IN T1

TOCT::	IDIVI	T1,^D8		;DIVIDE OUT
	JUMPE	T1,TOCT1	;EXIT IF NO MORE
	HRLM	T2,(P)		;SAVE REMAINDER
	PUSHJ	P,TOCT		;LOOP
	HLRZ	T2,(P)		;RESTORE DIGIT
TOCT1:	MOVEI	SC,"0"(T2)	;MAKE ASCII
	OUTCHR	SC		;TYPE
	POPJ	P,		;RETURN

;TPPN - SUBROUTINE TO TYPE A PPN
;CALL	MOVE	T2,PPN
;	PUSHJ	P,TPPN
;USES T1,T2,T3,SC

TPPN::	OUTCHR	["["]		;OPEN BRACKET
	HRLM	T2,(P)		;SAVE PROGRAMMER NO.
	HLRZ	T1,T2		;SET UP PROJECT NO.
	PUSHJ	P,TOCT		;TYPE IT
	OUTCHR	[","]		;COMMA
	HLRZ	T1,(P)		;RESTORE PROGRAMMER NO.
	PUSHJ	P,TOCT		;TYPE IT
	OUTCHR	["]"]		;CLOSE BRACKET
	POPJ	P,		;RETURN
	SUBTTL	GATHER FILE SPECIFICATION

;FILSPC - INPUT A FILE SPECIFICATION OF THE FORM
;DEV:FILE.EXT[P,PN,SFD1,SFD2,...]

FILIN::	SETZM	F.ZER		;GET SET
	MOVE	T1,[F.ZER,,F.ZER+1]	;TO CLEAR DATA
	BLT	T1,F.EZER	;BLITTTTT!
	TLZA	SF,(F%SOM!F%EXT);NOTHING YET
FILSP0:	JUMPL	SF,CPOPJ1	;RETURN AT END OF LINE
	PUSHJ	P,SIXINX	;READ A SIXBIT WORD
	JUMPN	T1,FILSP5	;IF NON-NULL WORD SEEN, GO PROCESS IT
	JUMPL	SF,CPOPJ1	;RETURN IF AT END OF LINE

FILSP5:	TLO	SF,(F%SOM)	;SOME INPUT HAS BEEN SEEN
	CAIE	SC,":"		;COLON?
	  JRST	FILSP1		;NO
	SKIPE	F.DEV		;YES, DEVICE ALREADY SEEN?
	  PJRST	MULDEV		;YES, ERROR
	JUMPE	T1,NULDEV	;NULL DEVICE ILLEGAL
	MOVEM	T1,F.DEV	;STORE DEVICE NAME
	JRST	FILSP0		;GO BACK FOR MORE INPUT

FILSP1:	JUMPE	T1,FILSP2	;GO IF NO FILE NAME SEEN
	SKIPE	F.NAM		;ALREADY SEEN A FILE NAME?
	  PJRST	MULNAM		;YES, ERROR
	MOVEM	T1,F.NAM	;STORE NAME

FILSP2:	JUMPL	SF,CPOPJ1	;RETURN IF EOL
	CAIE	SC,"["		;LEFT SQUARE BRACKET?
	  JRST	FILSP3		;NO
	SKIPE	F.DIR		;DIRECTORY ALREADY SEEN?
	  PJRST	MULDIR		;YES, ERROR
	PUSHJ	P,FDIRIN	;READ A DIRECTORY SPECIFICATION
	  POPJ	P,		;ILLEGAL DIRECTORY
	JRST	FILSP0		;GOT IT.  GO BACK FOR MORE

FILSP3:	CAIE	SC,"."		;WAS TERMINATOR A PERIOD?
	  JRST	SYNERR		;NO
	TLOE	SF,(F%EXT)	;YES, EXTENSION ALREADY SEEN?
	  PJRST	MULEXT		;YES, MULTIPLE EXTENSION ILLEGAL
	PUSHJ	P,SIXINX	;READ EXTENSION
	HLLZM	T1,F.EXT	;STORE EXTENSION
	SETZ	T1,		;CLEAR NAME
	JRST	FILSP5		;AND LOOP
;FDIRIN - RETURN C(F.DIR)=DIRECTORY
;INCLUDING SFD'S (UP TO .FXLNF ALTOGETHER)
;NON-SKIP RETURN IF ERROR

FDIRIN:	MOVEI	T1,F.DIRP	;GET POINTER TO PATH BLOCK
	MOVEM	T1,F.DIR	;SAVE IN DIRECTORY POINTER
	PUSHJ	P,OCTIN		;GET PROJECT NUMBER
	CAIE	SC,","		;TERMINATED BY COMMA?
	  PJRST	ILLDIR		;NO, ERROR
	TLNN	SF,(F%OCT)	;ANYTHING?
	  HLRZ	T2,USRPPN##	;NO, GRAB DEFAULT
	TLNN	T2,-1		;OVERFLOW TO LH?
	TRNN	T2,-1		;OR PROJECT 0?
	  PJRST	ILLDIR		;YES, BOUNCE THIS JERK!
	HRLM	T2,F.PTH	;SAVE VALUE
	PUSHJ	P,OCTIN		;GET PROGRAMMER
	TLNN	SF,(F%OCT)	;IF NOTHING
	  HRRZ	T2,USRPPN##	;GRAB DEFAULT
	TLNN	T2,-1		;CHECK AGAIN
	TRNN	T2,-1		; ..
	  PJRST	ILLDIR		;SOME PEOPLE NEVER GIVE UP
	HRRM	T2,F.PTH	;SAVE
	CAIE	SC,","		;SFD'S COMING?
	  JRST	FDIRI0		;NO, NO SFD'S
	PUSHJ	P,SAVE1		;SAVE AN AC

	MOVSI	P1,-<.FXLNF-1>	;MAX NUMBER OF SFD'S
FDIRI1:	PUSHJ	P,SIXINX	;GET SFD NAME
	MOVEM	T1,F.PTH+1(P1)	;STORE SFD NAME
	CAIE	SC,","		;MORE COMING?
	  JRST	FDIRI0		;NO, WE ARE DONE
	AOBJN	P1,FDIRI1	;GO GET NEXT
	OUTSTR	[ASCIZ/? Too many SFD's in file spec
/]
	POPJ	P,		;THAT'S TELLING HIM

FDIRI0:	CAIN	SC,"]"		;TERMINATED BY BRACKET?
	  JRST	CPOPJ1		;YES, RETURN NOW
	JUMPL	SF,CPOPJ1	;ALSO RETURN IF EOL

ILLDIR:	OUTSTR	[ASCIZ/? Illegal directory spec
/]
	POPJ	P,		;RETURN
;SUB TO GET NEXT CHAR FROM TTY INPUT BUFFER
;LOADS SC, USES NO AC'S
;IF BREAK, F%BRK (SIGN BIT) OF SF IS SET AND SC IS SET TO -1

TYIA::	JUMPGE	SF,GETB3	;JUMP IF MORE CHAR'S LEFT
	PUSHJ	P,SAVE2		;NO -- READ IN LINE
	TLZ	SF,(F%BRK)	;NO BREAK YET

FILBUF:	MOVE	P2,TTIBP	;LOAD PTR TO BEG OF BUF
	MOVEM	P2,TTIPTR	;STORE FOR LATER USE

	MOVEI	P1,LINSIZ	;LOAD SIZE IN BYTES
FILL1:	INCHSL	SC		;OK, GET NEXT CHAR
	  MOVEI	SC,.CHLFD	;NONE, RETURN LINE FEED
	PUSHJ	P,ISBRK		;PLACE IN BUFFER, SEE IF BREAK
	  JRST	GETB3		;WELL, THAT'S A BREAK
	SOJG	P1,FILL1	;LOOP
	CLRBFI			;LINE TOO LONG -- BUFFER FULL
	OUTSTR	[ASCIZ/% Input line too long
/]
	MOVEI	SC,.CHNUL	;SET UP NULL BYTE
	DPB	SC,P2		;AND CONCLUDE WITH EOL
;	JRST	GETB3		;PROCEED

GETB3:	ILDB	SC,TTIPTR	;GET FROM BUFFER
	JUMPN	SC,CPOPJ	;IF NOT NULL, GOOD CHAR
	TLO	SF,(F%BRK)	;ELSE FLAG BREAK
	SOJA	SC,CPOPJ	;SET ALL BITS OF SC AND RETURN
BRKTAB:	EXP .CHBEL,.CHLFD,.CHVTB,.CHFFD,.CHCNR,.CHCNU
	EXP .CHCNZ,.CHESC,.CHDEL
BRKLEN==.-BRKTAB

;ISBRK - SKIP RETURN IF NOT A BREAK CHARACTER

ISBRK:	CAIN	SC,.CHCRT	;IGNORE CARRIAGE RETURN
	  AOJA	P1,CPOPJ1	;INCREMENT CHAR COUNT FOR IGNORE
	PUSHJ	P,SAVE1		;SAVE AN AC
	MOVSI	P1,-BRKLEN	;GET LENGTH OF TABLE
	CAMN	SC,BRKTAB(P1)	;MATCH?
	  TDZA	SC,SC		;YES, REPLACE WITH NULL
	AOBJN	P1,.-2		;NO, TRY NEXT
	CAIN	SC,.CHTAB	;CONVERT TABS
	  MOVEI	SC," "		;TO SPACES
	CAIG	SC,"Z"+40	;CONVERT LC
	CAIGE	SC,"A"+40	; ..
	  JRST	.+2
	MOVEI	SC,-40(SC)	;TO UC
	IDPB	SC,P2		;SAVE CHAR AWAY
	CAIE	SC,";"		;CHECK FOR COMMENT COMING
	  JUMPN	SC,CPOPJ1	;ELSE RETURN IF NOT BREAK
	JUMPE	SC,CPOPJ	;NON-SKIP IF BREAK
	MOVEI	SC,.CHNUL	;COMMENT -- INSERT TERMINATOR
	DPB	SC,P2		;INSERT
CPOPJ1::AOS	(P)		;AND SKIP RETURN
CPOPJ:	POPJ	P,		;OR JUST RETURN

;ROUTINE TO IGNORE SPACES AND SCAN FOR GOOD CHAR
STYIA:	PUSHJ	P,TYIA		;GET CHAR
	CAIN	SC," "		;IGNORE SPACES
	  JRST	STYIA		;LOOP
	POPJ	P,		;GOOD CHAR, RETURN
;NAME - SCAN TABLE FOR COMMAND OR UNIQUE ABBREVIATION
;CALL WITH C(1)=SIXBIT COMMAND, C(T4)=IOWD TABLE LENGTH,TABLE ADR
;RETURNS C(T2)=INDEX INTO TABLE, ALWAYS PRESERVES T1
;CPOPJ1 IF MATCH FOUND, USES T2-T4

NAME:	PUSHJ	P,SAVE2		;SAVE P1 AND P2
	SETZB	P1,T3		;CLEAR
	SKIPN	T2,T1		;COPY COMMAND INTO T2
	  SOJA	T3,NAME2	;SET UP MASK, GO IF NULL COMMAND
	SOJA	T3,NAME1	;SET UP INITIAL MASK (-1) AND GO

NAME0:	LSH	T2,-6		;SHIFT 1 CHAR TO THE RIGHT
	LSH	T3,6		;AND ONE TO THE LEFT
NAME1:	TRNN	T2,77		;A CHAR IN RIGHTMOST POSITION?
	  JRST	NAME0		;NO, TRY SOME MORE

NAME2:	HRLI	P2,1(T4)	;REMEMBER START OF COMMAND TABLE
NAMELP:	CAMN	T1,1(T4)	;EXACT MATCH?
	  JRST	NAMEFN		;YES
	MOVE	T2,1(T4)	;CANDIDATE INTO T2
	AND	T2,T3		;MASKED TO CORRECT # OF CHARACTERS
	CAME	T1,T2		;GOT A MATCH?
	AOBJN	T4,NAMELP	;NO, TRY NEXT ONE
	JUMPGE	T4,NAMTST	;YES, YOUR FACE AND ...
	TROE	P1,1		;MARK THAT ONE WAS FOUND
	  TRO	P1,2		;TWO WERE FOUND
	HRRI	P2,1(T4)	;REMEMBER WHERE
	AOBJN	T4,NAMELP	;LOOK FOR MORE MATCHES

NAMTST:	CAIE	P1,1		;ONE MATCH FOUND?
	  POPJ	P,		;NO, COMMAND UNKNOWN OR NOT UNIQUE
	JRST	NAMDSP		;GOOD RESULT

NAMEFN:	HRRI	P2,1(T4)	;EXACT MATCH, RH(P2)=INDEX OF COMMAND
NAMDSP:	HLRZ	T4,P2		;BASE OF TABLE
	SUBI	P2,(T4)		;OFFSET INTO TABLE
	HRRZ	T2,P2		;RETURN RESULT IN T2
	JRST	CPOPJ1		;SKIP RETURN
;SIXINX - LIKE SIXIN, EXCEPT ADVANCES TTY INPUT SO NEXT CHARACTER
;WILL BE RELEVANT

SIXINX:	PUSHJ	P,SIXIN		;READ
	CAIN	SC," "		;SPACE?
	  PJRST	STYIA		;YES, READ NULLS
	POPJ	P,		;NO, RETURN

;SIXIN - RETURNS C(T1)=UP TO SIX CHARACTERS OF SIXBIT
;USES T2,SC

SIXIN:	PUSHJ	P,STYIA		;GET A CHAR
	SETZ	T1,		;CLEAR COLLECTOR
	MOVE	T2,[POINT 6,T1]	;SET UP BYTE POINTER
SIXIN1:	CAIL	SC,"0"		;SEE IF ALPHANUMERIC
	CAILE	SC,"Z"		; ..
	  POPJ	P,		;NO
	CAIGE	SC,"A"		; ..
	CAIG	SC,"9"		; ..
	  JRST	.+2		;OK
	  POPJ	P,		;BAD
	SUBI	SC,40		;MAKE SIXBIT
	TLNE	T2,770000	;SIX CHARACTERS YET?
	IDPB	SC,T2		;NO, LOAD IT IN
	PUSHJ	P,TYIA		;GET NEXT
	JRST	SIXIN1		;LOOP
	SUBTTL	NUMERIC INPUT

;OCTINW - READ OCTAL NUMBER FROM COMAND STREAM INTO SN

OCTINW::PUSHJ	P,OCTIN		;GET OCTAL NUMBER IN T2
	MOVE	SN,T2		;MOVE
	POPJ	P,		;RETURN

;OCTIN - READ OCTAL NUMBER INTO T2

OCTIN:	PUSHJ	P,STYIA		;SKIP SPACES
	SETZB	T2,T3		;CLEAR COUNT
	TLZ	SF,(F%OCT)	;NOTHING IN YET
	CAIN	SC,"#"		;FORCING OCTAL (WHICH IS DEFAULT)?
	  PUSHJ	P,TYIA		;YES, IGNORE AND GET NEXT CHAR
OCTIN0:	CAIG	SC,"9"		;RANGE CHECK
	CAIGE	SC,"0"		; ..
	  JRST	OCTIN1		;NO, EXIT LOOP
	TLO	SF,(F%OCT)	;FLAG SOMETHING IN
	LSH	T2,3		;SHIFT OVER RESULT
	ADDI	T2,-"0"(SC)	;AND ADD OCTAL
	IMULI	T3,^D10		;AND KEEP UP DECIMAL COUNT ALSO
	ADDI	T3,-"0"(SC)	; ..
	PUSHJ	P,TYIA		;NEXT
	JRST	OCTIN0		;LOOP

OCTIN1:	CAIE	SC,"."		;FORCING DECIMAL?
	  POPJ	P,		;NO, RETURN NOW
	MOVE	T2,T3		;YES, USE DECIMAL COUNT
	PJRST	TYIA		;GET NEXT CHAR AND RETURN
	SUBTTL	ACCUMULATOR SAVERS

;SAVE2 - SAVES P1 AND P2
;CALL IS	PUSHJ P,SAVE2

SAVE2::	EXCH	P1,(P)		;GET RETURN, SAVE P1
	PUSH	P,P2		;SAVE P2
	MOVEM	P1,1(P)		;SAVE RETURN
	MOVE	P1,-1(P)	;RESTORE P1
	PUSHJ	P,@1(P)		;CALL CALLER
	  JRST	.+2		;NON-SKIP
	AOS	-2(P)		;SKIP RET
	POP	P,P2		;RESTORE P2
	POP	P,P1		;RESTORE P1
	POPJ	P,		;RESTORE PC

;SAVE1 - SAVES ONLY P1, SAME AS ABOVE

SAVE1::	EXCH	P1,(P)		;COMMENTS SAME
	MOVEM	P1,1(P)
	MOVE	P1,(P)
	PUSHJ	P,@1(P)
	  JRST	.+2
	AOS	-1(P)
	POP	P,P1
	POPJ	P,
	SUBTTL	ERROR MESSAGES

MULDEV:	OUTSTR	[ASCIZ/? Multiple device specs illegal
/]
	POPJ	P,

MULDIR:	OUTSTR	[ASCIZ/? Multiple directory specs illegal
/]
	POPJ	P,

MULEXT:	OUTSTR	[ASCIZ/? Multiple file extension illegal
/]
	POPJ	P,

MULNAM:	OUTSTR	[ASCIZ/? Multiple file name illegal
/]
	POPJ	P,

NULDEV:	OUTSTR	[ASCIZ/? Null device illegal
/]
	POPJ	P,

SYNERR:	OUTSTR	[ASCIZ/? Syntax error
/]
	POPJ	P,
	SUBTTL	STORAGE

;CONSTANTS

TTIBP:	POINT	7,TTIBUF

;VARIABLES

TTIPTR:	BLOCK	1
TTIBUF:	BLOCK	<LINSIZ+4>/5

;FILE SPECIFICATION AREA

F.ZER:!
F.DEV::	BLOCK	1
F.NAM::	BLOCK	1
F.EXT::	BLOCK	1
F.DIR::	BLOCK	1	;PTR TO DIRECTORY
F.DIRP::BLOCK	2
F.PTH::	BLOCK	.FXLNF	;ROOM FOR DIRECTORY
F.EZER==.-1

	END