Google
 

Trailing-Edge - PDP-10 Archives - BB-H241B-BM - decnet/ncu.mac
There are 3 other files named ncu.mac in the archive. Click here to see a list.
;<JENNESS.NETCON>NCU.MAC.2, 31-Jan-80 13:28:12, Edit by JENNESS
; Update copyright date
;<JENNESS>NCU.MAC.15, 14-Nov-79 13:46:04, Edit by JENNESS
; Fix RQLERR to not use the ASUBR macro.  This messed up register 15 which
; was pointing to the stack framed needed to load RQLREC properly.
;<JENNESS>NCU.MAC.14, 14-Nov-79 11:21:33, Edit by JENNESS, PLATUKIS
; Change RQLERR to properly release the record block.  Fix accidental call
; to FATAL.ERROR if none existed.  Same fix to RQLINT also.
;<JENNESS>NCU.MAC.10, 30-Oct-79 17:06:12, Edit by JENNESS
; Change REQLOG to NOT return a success code across the link. The NICE
; protocol has NEVER needed this.
;<JENNESS>NCU.MAC.9, 30-Oct-79 10:42:41, Edit by JENNESS, PLATUKIS
; Add TOPFRE routine to release a topology table.
;<JENNESS>NCU.MAC.7, 23-Oct-79 10:56:23, Edit by PLATUKIS
; Fix ADVTOP to give proper error return, instead of trying to release
; memory it doesn't have.
;<JENNESS>NCU.MAC.6, 23-Oct-79 10:53:58, Edit by PLATUKIS
; Fix TSTL05 to properly loop over multiple DN20 front ends.
;<JENNESS>NCU.MAC.6, 23-Oct-79 10:52:01, Edit by PLATUKIS
; Fix to STODMC to put a -1 byte pointer as first word.  Needed since
; SYSERR treats DMCs the same a KMCs, and DMCs don't have sub-device data.
;<JENNESS>NCU.MAC.6, 23-Oct-79 10:48:17, Edit by PLATUKIS
; Fix hardware event message processing to properly release chunks allocated 
; for device and register blocks.
;<JENNESS>NCU.MAC.3,  4-Oct-79 08:18:35, Edit by JENNESS
; Add SPRIW calls to set NCU fork priority higher to make loading/dumping
; run faster on loaded systems.  This will get a DN20 back up faster.
;<JENNESS>NCU.MAC.3,  4-Oct-79 08:18:30, Edit by JENNESS
; Change ASCLIN to suppress station number if 0 (no multi-drop).
;<JENNESS>NCU.MAC.2,  1-Oct-79 13:52:47, Edit by JENNESS
; Change LSTBLD so that host name byte string count is correctly calculated
;  for strings of exact match of 6 characters.
;<SROBINSON.NETCON>NCU.MAC.6, 26-Sep-79 15:28:56, Edit by JENNESS
; TCO 4.2489  Change PRTINF so that it returns real NICE line status
; codes instead of the garbage it was returning.
;<4.UTILITIES>NCU.MAC.245, 23-Aug-79 13:37:46, Edit by JENNESS
; Change ASGREC to assign a huge buffer to stop memory management
; overruns.
;<4.UTILITIES>NCU.MAC.244, 8-Aug-79 11:20:45, Edit by JENNESS
; Change all failures of RELFRE to FATAL.ERRORs
;<4.UTILITIES>NCU.MAC.243, 10-Jul-79 10:37:40, Edit by SROBINSON
;TCO 4.2320 Correct "Invalid Line ID" when it isn't invalid
;<4.UTILITIES>NCU.MAC.242, 20-Jun-79 16:08:01, EDIT BY KIRSCHEN
;ADD EVENT LOGGING COMMANDS
;<4.UTILITIES>NCU.MAC.241,  7-May-79 11:19:14, EDIT BY KIRSCHEN
;FIX TYPO'S IN DEFRQD
;<4.UTILITIES>NCU.MAC.240, 27-Apr-79 15:43:07, EDIT BY KIRSCHEN
;COMPUTE OFFSET TO LOG DATA FOR CHK11 ENTRIES CORRECTLY
;<4.UTILITIES>NCU.MAC.239, 20-Apr-79 14:27:20, EDIT BY KIRSCHEN
;USER CORRECT ENTRY TYPE FOR CHK11 ENTRIES; COMPUTE CORRECT POINTER
; TO LOG DATA
;<4.UTILITIES>NCU.MAC.238, 17-Mar-79 14:56:25, EDIT BY KIRSCHEN
;FIX EVENT LOGGING BUGS
;<4.UTILITIES>NCU.MAC.237, 10-Mar-79 14:32:32, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>NCU.MAC.236,  4-Feb-79 22:06:06, EDIT BY KIRSCHEN
;FIX SPURIOUS "?INTERNAL NETCON ERROR" MESSAGE
;<4.UTILITIES>NCU.MAC.235,  2-Feb-79 14:46:07, EDIT BY KIRSCHEN
;CORRECT EXTRACTION OF LINE ID FROM EVENT LOG MESSAGES TO CONFORM TO SPEC
;<4.UTILITIES>NCU.MAC.234,  1-Feb-79 10:22:24, EDIT BY KIRSCHEN
;ADD ROUTINE TO STORE KDZ EVENT LOG DATA
;<4.UTILITIES>NCU.MAC.233, 30-Jan-79 09:17:14, EDIT BY ENGEL
;FIX AUTO DUMP/LOAD BUG BY SETTING NDDIP/NDLIP AFTER NIB LOCKED
;<4.UTILITIES>NCU.MAC.232, 30-Jan-79 09:09:49, EDIT BY KIRSCHEN
;ADD CODE TO STORE KDP REGISTERS ON EVENT LOG MESSAGE
;<4.UTILITIES>NCU.MAC.230, 14-Jan-79 20:46:50, EDIT BY KIRSCHEN
;UPDATE NODE JSYS SYMBOLS
;<4.UTILITIES>NCU.MAC.229,  8-Jan-79 22:02:44, EDIT BY KIRSCHEN
;automate topology reporting
;<4.UTILITIES>NCU.MAC.228,  4-Jan-79 13:08:23, EDIT BY KIRSCHEN
;PASS NODE NAME AND HOST PARAMETERS ON LOAD
;<4.UTILITIES>NCU.MAC.227,  2-Jan-79 15:27:14, EDIT BY ENGEL
;FIX SHOW STATE LINE KDP_0_0 PROBLEM
;<4.UTILITIES>NCU.MAC.201, 26-Dec-78 11:03:44, EDIT BY ENGEL
;<4.UTILITIES>NCU.MAC.200, 26-Dec-78 10:55:47, EDIT BY ENGEL
;ADD TRANSFER ADDRESS CHECK. (DO NOT SEND "TRANSFER" LINE SERV. FOR ODD ADDR.
;<4.UTILITIES>NCU.MAC.189, 22-Dec-78 10:30:35, EDIT BY ENGEL
;ADD AUTO DUMP/LOAD CODE
;<4.UTILITIES>NCU.MAC.171, 15-Dec-78 09:09:33, EDIT BY KIRSCHEN
;BREAK NETCON INTO TWO MODULES NCP AND NCU; ADD RELEASE 4 FEATURES.
TITLE		NCU - TOPS20 Network Information and Control Exchange (NICE) Process
SUBTTL	D. KIRSCHEN/P. HURLEY	FEBRAURY, 1977


	SEARCH NETPAR
	SEARCH MONSYM,MACSYM,ORNMAC,GLXMAC,MACTEN
	.REQUIRE SYS:MACREL
	SALL


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.



; THE FOLLOWING SYMBOLS ARE ALL DEFINED IN MODULE NCP.MAC

EXTERN	GETFRE, RELFRE, ASGPAG, RELPGA, CPYASC, SAVPQ
EXTERN	LIDPRT, WRNING, ELOCK, DLOCK, LOKNOD, ULKNOD
EXTERN	MONINI, TOPCHK, FRELST, FNDDSP
EXTERN	OPRMES, SAVQ, SAVT, ERROR, NETCON

EXTERN	NIBTAB, SYSNAM
EXTERN	.ERR21, .ERR29
SUBTTL	Initialization

; NICE PROCESS IS INITIALLY STARTED HERE - READ PARAMETERS AND DO INITIALIZATION

NCU::	MOVE T1,[.PRARD,,.FHSLF] ;GET "READ PARAMETERS" FUNCTION CODE
	MOVEI T2,T3		;GET ADDRESS OF ARGUMENT BLOCK
	MOVEI T3,2		;ARGUMENT BLOCK CONTAINS TWO ITEMS
	PRARG			;READ STARTUP PARAMETERS
	 ERJMP [HALTF]		;FAILED, NO RECOURSE.

; THE PRARG ARGUMENT BLOCK CONTAINS TWO WORDS:
;
;	1.	JFN OF LOGICAL LINK FROM REQUESTING TASK TO NCU
;	2.	LENGTH,,ADDRESS OF PER-NCU STORAGE AREA

; SET UP STACK IN BEGINNING OF OUR STORAGE AREA

	HRRI P,-1(T4)		;SET UP AN IOWD FOR THE
	HRLI P,-PDLEN		; PUSHDOWN STACK

; SET UP ADDRESS OF GENERAL STORAGE AREA FOR VARIABLES

	MOVEI P5,PDLEN(T4)	;GET STARTING ADDRESS OF DATA AREA
	MOVEI T1,VARLEN(P5)	;GET STARTING ADDRESS OF STRING STORAGE AREA
	HRLI T1,(POINT 7,)	;FORM POINTER TO STRING AREA
	MOVEM T1,STRPTR		;SAVE STRING POINTER
	HLRZ T1,T4		;GET LENGTH OF DATA AREA
	ADDI T1,-1(T4)		;COMPUTE LAST ADDRESS IN DATA AREA
	MOVEM T1,STREND		;SAVE AS FINAL LOCATION IN STRING AREA
	HLRZ T1,T4		;GET ORIGINAL LENGTH OF STORAGE AREA
	SUBI T1,PDLEN+VARLEN	;COMPUTE NUMBER OF WORDS IN STRING STORAGE AREA
	MOVEM T1,STRSIZ		;SAVE SIZE OF STRING STORAGE AREA
	MOVEM T3,REQLNK		;SAVE LOGICAL LINK FROM REQUESTOR
	; ..
	; ..

; THE FOLLOWING LOOP IS PERFORMED FOR EACH OPERATION INITIATED BY
; THE REQUESTING TASK (THE SAME LOGICAL LINK MAY BE USED TO REQUEST
; SEVERAL SEQUENTIAL OPERATIONS).


; INPUT THE NICE MESSAGE FROM THE REQUESTOR AND CALL DISPATCHING ROUTINE

NCU010:	CALL CLRMSG		;GO CLEAR THE MESSAGE AREA
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN)
	MOVEI T2,MSGBLK		;GET ADDRESS OF MESSAGE BLOCK
	HRLI T2,(POINT 8,)	;FORM POINTER TO MESSAGE BLOCK
	MOVNI T3,MSGSIZ*BPWRD	;GET MAX COUNT
	SINR			;INPUT THE MESSAGE
	 ERJMP [MOVX T2,.NRCME	;ON FAILURE, GET "COMMUNICATIONS ERROR" CODE
		BOUT		;RETURN RESPONSE TO REQUESTING TASK
		 ERJMP [HALTF]	;NOTHING ELSE LEFT TO DO
		HALTF ]		;DONE, NOTHING ELSE LEFT TO DO
	MOVEI T2,MSGSIZ*BPWRD(T3) ;GET NUMBER OF BYTES IN THE MESSAGE
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	LDB T3,[POINT 8,MSGBLK,7] ;GET NICE FUNCTION CODE
	CALL NCUDSP		;GO DISPATCH ACCORDING TO FUNCTION REQUESTED
	 SKIPA T4,T1		;FAILED, RETURN CODE ALREADY IN T1
	JRST NCU010		;SUCCESS, GO PROCESS NEXT FUNCTION

; HERE TO RETURN AN ERROR RETURN CODE WHEN THE OPERATION FAILED

	MOVE T1,REQLNK		;GET LOGICAL LINK TO REQUESTING TASK
	MOVE T2,[POINT 8,T4,27]	;GET POINTER TO SINGLE BYTE RETURN CODE
	MOVNI T3,1		;RETURN CODE IS JUST ONE SINGLE BYTE
	SOUTR			;SEND THE RETURN CODE TO REQUESTING TASK
	 ERJMP [HALTF]		;IF FAILED, JUST QUIT, SINCE NOTHING ELSE TO
				; DO IF CANNOT REPORT FAILURE TO REQUESTOR
	JRST NCU010		;DONE WITH THIS REQUEST, LOOP BACK FOR NEXT MSG
;NCUDSP - ROUTINE TO DISPATCH TO NSP MESSAGE HANDLING ROUTINE
;
;ACCEPTS IN T1/	NICE FUNCTION CODE FROM MESSAGE
;	    T2/	POINTER TO START OF NICE MESSAGE
;	    T3/	NUMBER OF BYTES IN NICE MESSAGE
;		CALL NCUDSP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, OPERATION COMPLETED.

NCUDSP:	ASUBR <DSPPTR,DSPCNT,DSPFCN>

	MOVE T4,[-NCTSIZ,,NICTAB] ;SET UP TO SEARCH NICE FUNCTION CODE TABLE
NSPD10:	HLRZ T1,(T4)		;GET A KNOWN NICE FUNCTION CODE
	CAMN T1,DSPFCN		;FOUND FUNCTION CODE IN THIS NICE MESSAGE ?
	JRST NSPD40		;YES, GO DISPATCH TO PROCESSING ROUTINE
	AOBJN T4,NSPD10		;LOOP OVER ALL KNOWN NICE FUNCTION CODES
	RETBAD (.NRFNC)		;NOT FOUND, RETURN "INVALID FUNCTION"


; HERE TO DISPATCH TO THE PROPER PROCESSING ROUTINE FOR THE NICE MESSAGE

NSPD40:	MOVE T1,DSPPTR		;GET POINTER TO NICE MESSAGE
	MOVE T2,DSPCNT		;GET COUNT OF BYTES IN MESSAGE
	HRRZ T4,(T4)		;GET ADDRESS OF PROCESSING ROUTINE
	CALLRET (T4)		;GO HANDLE THE NSP MESSAGE



; NICE FUNCTION TABLE

NICTAB:	.NCRQL,,REQDLL		;REQUEST DOWN-LINE LOAD
	.NCRQD,,REQDMP		;REQUEST UP LINE DUMP
	.NCRED,,REQRED		;REQUEST TO READ INFORMATION
	.NCZRO,,REQZRO		;REQUEST TO ZERO COUNTERS
	.NCLSV,,REQLSV		;REQUEST FOR LINE SERVICE
	.NCSET,,REQSET		;REQUEST TO SET PARAMETER
	.NCLOG,,REQLOG		;REQUEST TO LOG DATA

	NCTSIZ==.-NICTAB
SUBTTL	NICE Process -- Down-Line Load

;REQDLL - ROUTINE TO PROCESS REQUESTS FOR A DOWN-LINE LOAD OPERATION
;
;ACCEPTS IN T1/	POINTER TO START OF NICE DOWN-LINE LOAD REQUEST MESSAGE
;	    T2/	NUMBER OF BYTES IN MESSAGE
;		CALL REQDLL
;RETURNS: +1	 FAILED, T1/ NICE RETURN CODE
;	  +2	SUCCESS

REQDLL:	ASUBR <RQLPTR,RQLCNT,RQLLNK,RQLREC>

; EXTRACT THE FIELDS PRESENT IN THE NICE DOWN-LINE LOAD REQUEST MESSAGE

	SETZM RQLLNK		;INITIALIZE LOGICAL LINK CELL
	SETZM RQLREC		;INITIALIZE ADDRESS OF RECORD BLOCK
	MOVE T1,RQLPTR		;GET POINTER TO START OF NICE MESSAGE
	MOVE T2,RQLCNT		;GET NUMBER OF BYTES IN THE MESSAGE
	CALL GETRQL		;GO DECODE THE FIELDS IN THE REQUEST LOAD MSG
	 RETBAD (.NRIMF)	;FAILED, RETURN "INVALID MESSAGE FORMAT"

; IF LOADING ALL KNOWN NODES, LOOP OVER EACH NODE IN THE CONFIGURATION DATABASE

RQL010:	CALL DEFRQL		;GO FILL IN DEFAULTS FROM CONFIGURATION DATABASE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER

; LOCK THE TARGET NODE

	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET NIB ADDRESS FOR NODE BEING LOADED
	 RETBAD (.NRICF)	;FAILED, RETURN ERROR
	MOVEM T1,RQLLNK		;SAVE THE NIB ADDRESS
	MOVX T2,RM%PRI		;USE PRIMARY RESOURCE
	CALL LOKNOD		;LOCK THE TARGET NODE
	MOVE T1,RQLLNK		;GET THE NIB ADDRESS
	SETONE NDLIP,(T1)	;SHOW LOAD IN PROGRESS
	SETZM RQLLNK		;ZERO HOLDING CELL

; GET A LINK TO THE NICE PROCESS ON THE SERVER NODE

	MOVE T1,RQLSRV		;GET POINTER TO ASCIZ NAME OF SERVER NODE
	CALL GETLNK		;GO GET A LOGICAL LINK TO ANOTHER NICE PROCESS
	 RETBAD (.NRPNA)	;FAILED, RETURN "PROCESS NOT AVAILABLE"
	MOVEM T1,RQLLNK		;SAVE LOGICAL LINK NUMBER

; IF NECESSARY, TRIGGER THE BOOTSTRAP ROM AT THE TARGET NODE

	MOVE T4,RQLOPT		;GET OPTIONS FROM DOWN-LINE LOAD REQUEST
	LOAD T3,LO%ROM,T4	;GET ROM FIELD
	CAIE T3,.LOTBD		;TRIGGER BOOT, DEFAULT PROGRAM DATA ?
	CAIN T3,.LOTBP		; OR TRIGGER BOOT & GET PROGRAM DATA RETURNED ?
	JRST [	MOVE T1,RQLLNK	;YES, GET LOGICAL LINK NUMBER
		CALL TRGGER	;TRIGGER THE BOOTSTRAP ROM AT THE TARGET NODE
		 LODERR ()	;FAILED, RETURN ERROR TO CALLER
		JRST .+1 ]	;DONE, BOOTSTRAP ROM HAS BEEN TRIGGERED

	MOVEI T1,.FHSLF		;Point to this process
	MOVEI T2,0102		;Only want to run in Q 1 (very high)
	SPRIW			;Set the fork scheduling priority
	; ..
	; ..

; AT THIS POINT, THE ACTUAL LOADING OPERATION BEGINS.  THE SEQUENCE OF
; EVENTS IS AS FOLLOWS:
;
;	1.	A NICE "INITIATE-LOAD-DIALOG" MESSAGE IS SENT TO THE SERVER NCU
;	2.	THE FILE TO BE LOADED IS OPENED.
;	3.	FOR EACH "BLOCK" IN THE .BIN FILE, 
;
;	   3.1		THE LOAD ADDRESS IS SENT USING A NICE LINE SERVICE
;			MESSAGE (SET BASE ADDRESS OPTION).
;	   3.2.		THE DATA IN THE "BLOCK" IS SENT TO THE SERVER NODE NCU
;			USING A NICE LINE SERVICE MESSAGE (MEMORY IMAGE OPTION).
;	   3.3		WHEN ALL  DATA "BLOCKS" IN THE .BIN FILE HAVE BEEN
;			LOADED IN THIS MANNER, THE TRANSFER ADDRESS IS 
;			OBTAINED FROM THE LAST BLOCK. A NICE LINE SERVICE
;			MESSAGE IS THEN USED TO SEND THIS ADDRESS AND ANY
;			PARAMETERS FOR THE NODE JUST LOADED TO THE SERVER
;			NODE NCU (SET PARAMETERS AND TRANSFER OPTION).
;
;	4.	THE SERVER NODE NCU REPLIES WITH AN END-OF-DIALOG NICE
;		LINE SERVICE MESSAGE.  THIS MAY CONTAIN A REQUEST FOR
;		ANOTHER PROGRAM TO BE LOADED, AND THE PROCESS REPEATS FROM
;		STEP NUMBER 1 FOR THIS NEXT PROGRAM.


; ASSEMBLE AND SEND A NICE "LINE SERVICE" MESSAGE TO INITIATE A LOAD DIALOG

RQL020:	CALL MAKLOD		;GO ASSEMBLE A NICE LINE SERVICE MESSAGE
	 LODERR ()		;FAILED, RETURN ERROR TO CALLER
	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;COPY POINTER TO START OF DATA MESSAGE
	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN)
	SOUTR			;SEND LINE SERVICE MESSAGE TO SERVER NODE NCU
	 ERJMP [LODERR (.NRCME)] ;ON FAILURE, RETURN "COMMUNICATIONS ERROR"

; NOW RECEIVE AND CHECK THE RETURN CODE FROM THE SERVER NODE NCU

	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN)
	BIN			;WAIT FOR A REPLY FROM THE SERVER NODE NCU
	 ERJMP [LODERR (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	MOVE T1,T2		;COPY THE RETURN CODE
	CAIE T1,.NRSUC		;SUCCESS ?
	LODERR ()		;NO, USE NICE RETURN CODE FROM SERVER NODE
	; ..
	; ..
; TOP OF LOOP OVER EACH FILE TO BE LOADED

; OPEN THE INPUT FILE TO BE LOADED AND DO INITIAL SET UP

	MOVX T1,OF%RD		;NOTE THAT FILE IS TO BE READ
	CALL ASGREC		;GO ASSIGN A RECORD BLOCK FOR THIS I/O OPERATION
	 LODERR (.NRRES)	;FAILED, RESOURCE ERROR
	MOVEM T1,RQLREC		;SAVE ADDRESS OF RECORD BLOCK
	CALL SETPGM		;GO GET POINTER TO FILESPEC TO BE LOADED
	 LODERR (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	CALL OPNIFL		;GO OPEN THE INPUT FILE
	 LODERR (.NRIFL)	;FAILED, RETURN "INVALID FILE"
	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	STOR T1,RBJFN,(T4)	;STORE THE JFN OF THE FILE TO BE LOADED
	STOR T2,RBTYP,(T4)	;STORE FILE FORMAT TYPE
	SETONE RBCAD,(T4)	;SET CURRENT ADDRESS TO TOP OF MEMORY
				; TO FORCE NEW BASE ADDRESS REQUIRED
	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN) TO SERVER NCU
	CALL INTSET		;SET UP INTERRUPT SYSTEM
	 RETBAD ()		;FAILED, RETURN ERROR

; TOP OF LOOP OVER ALL BLOCKS IN THE FILE.  INPUT THE NEXT BLOCK

RQL030:	MOVE T1,RQLREC		;GET ADDRESS OF RECORD BLOCK
	HRLI T4,(POINT 8,)	;FORM POINTER TO START OF DATA
	HRRI T4,.RBDAT(T1)	; AREA IN RECORD BLOCK
	STOR T4,RBPTR,(T1)	;STORE INITIAL POINTER
	LOAD T2,RBTYP,(T1)	;GET FILE FORMAT TYPE
	CALL @[	R		; 0 - ILLEGAL
		Z INPLDA	;LDA FORMAT
		Z INPTSK	;TASK IMAGE FORMAT
		Z INPDMP	;NETCON DUMP FILE FORMAT
		](T2)		;READ A BLOCK FROM THE FILE ACCORDING TO FORMAT
	 LODERR (.NRIOE)	;FAILED, RETURN "FILE I/O ERROR"
	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	JE RBCNT,(T4),RQL070	;IF END OF DATA, GO SEND "TRANSFER" MESSAGE
; SEE IF WE NEED TO SET A NEW BASE ADDRESS

	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T1,RBNAD,(T4)	;GET MEMORY ADDRESS AT WHICH TO LOAD THIS BLOCK
	LOAD T2,RBCAD,(T4)	;GET CURRENT ADDRESS
	CAMN T2,T1		;DO WE HAVE TO SET A NEW BASE ADDRESS?
	 JRST RQL035		;NO-- JUST UPDATE CURRENT ADDRESS

; ASSEMBLE AND SEND A "SET BASE ADDRESS" DIALOG MESSAGE TO SERVER NODE

	CALL MAKBAS		;GO ASSEMBLE A "SET BASE ADR" LINE SERVICE MSG
	MOVN T3,T2		;GET -NUMBER OF BYTES IN THE MESSAGE
	MOVE T2,T1		;COPY POINTER TO THE MESSAGE
	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN)
	SOUTR			;SEND THE MESSAGE TO THE SERVER NODE NCU
	 ERJMP [LODERR (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	; ..
	; ..

; UPDATE CURRENT ADDRESS IN "RBCAD" TO REFLECT NEW ADDRESS FROM
;  "RBNAD" PLUS COUNT OF THIS RECORD IN "RBCNT"

RQL035:	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T1,RBNAD,(T4)	;GET NEW ADDRESS
	LOAD T2,RBCNT,(T4)	;GET CURRENT ITEM COUNT
	ADD T1,T2		;COMPUTE NEW BASE ADDRESS AFTER THIS RECORD
	STOR T1,RBCAD,(T4)	;UPDATE CURRENT ADDRESS

; NOW SEND THE MEMORY IMAGE DATA IN "MEMORY IMAGE" LINE SERVICE MESSAGES

RQL040:	MOVE T1,RQLREC		;GET ADDRESS OF RECORD BLOCK
	MOVE T2,RQLCPU		;GET CPU TYPE OF TARGET NODE
	CALL MAKIMG		;GO MAKE A LINE SERVICE "MEMORY IMAGE" MESSAGE
	 LODERR ()		;FAILED, RETURN ERROR
	MOVN T3,T2		;GET - COUNT
	MOVE T2,T1		;GET POINTER TO MESSAGE
	MOVE T1,RQLLNK		;GET LOGICAL LINK TO SERVER NODE NCU
	SOUTR			;SEND THE "MEMORY IMAGE" MESSAGE
	 ERJMP [LODERR (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; HERE TO SEE IF THERE IS MORE DATA TO BE SENT IN THIS BLOCK

	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	JN RBCNT,(T4),RQL040	;LOOP BACK IF MORE DATA TO SEND
	JRST RQL030		;GO INPUT THE NEXT DATA BLOCK IN THE FILE
; HERE AT END OF DATA - SEND "SYSTEM PARAMETERS AND TRANSFER ADR" MESSAGE

RQL070:	MOVX T1,.FHSLF		;GET OUR FORK HANDLE
	MOVX T2,1B<RQLCHN>	;GET DOWN LINE LOAD CHANNEL
	DIC			;DISABLE DOWN LINE LOAD CHANNEL
	MOVE T1,RQLREC		;GET ADDRESS OF RECORD BLOCK
	LOAD t4,RBXAD,(t4)	;GET TRANSFER ADDRESS FROM FILE
	TRNE t4,1		;IS THE ADDRESS ODD?
	JRST [ 	MOVE T2,[POINT 8,[BYTE (8).LMEND,.NRSUC]] ;YES - END-OF-DIALOGUE
		MOVNI T3,2	;WE ARE SENDING 2 BYTES
		MOVE T1,RQLLNK	;GET LOGICAL LINK JFN
		SOUTR		;OUTPUT THE "END-OF"DIALOGUE" MSG
		 ERJMP [LODERR (.NRCME)]	;RETURN COMMUNICATION ERROR
		JRST RQL071]	;WAIT FOR RESPONSE
	CALL MAKXFR		;NO - GO MAKE A "TRANSFER" LINE SERVICE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;COPY POINTER TO START OF MESSAGE
	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN)
	SOUTR			;OUTPUT THE MESSAGE, FORCE ALL DATA OUT
	 ERJMP [LODERR (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; PROGRAM LOAD COMPLETE - WAIT FOR END OF DIALOG MESSAGE FROM SERVER NCU

RQL071:	CALL CLRMSG		;CLEAR THE MESSAGE AREA
	MOVE T1,RQLLNK		;GET LOGICAL LINK (JFN)
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO WHERE MESSAGE SHOULD GO
	MOVNI T3,MAXNIC		;GET -MAX COUNT
	SINR			;INPUT THE REPLY FROM THE SERVER NODE NCU
	 ERJMP [LODERR (.NRCME)] ;IF FAILED, RETURN "COMMUNICATIONS ERROR"

; VERIFY THAT RESPONSE WAS "END OF DIALOG" AND SEE IF ANOTHER LOAD WAS REQUESTED

	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF REPLY MESSAGE
	MOVEI T2,MAXNIC(T3)	;COMPUTE NUMBER OF BYTES RETURNED
	SUBI T2,2		;DECREMENT COUNT FOR TYPE CODE AND RETURN CODE
	JUMPL T2,[RETBAD (.NRPRO)] ;RETURN "PROTOCOL ERROR" IF NOT ENOUGH BYTES
	ILDB T4,T1		;YES, GET DIALOG MESSAGE TYPE CODE (.LSXXX)
	CAIE T4,.LMEND		;END OF DIALOG REPLY ?
	LODERR (.NRPRO)		;NO, NICE PROTOCOL ERROR
	ILDB T4,T1		;GET RETURN CODE
	CAIE T4,.NRSUC		;SUCCESS ?
	JRST [	MOVE T1,T4	;NO, GET RETURN CODE FROM SERVER NCU
		LODERR () ]	;RETURN THE CODE TO CALLER
	; ..
	; ..

; DETERMINE IF ANOTHER PROGRAM IS TO BE LOADED

	MOVEM T1,RQLPTR		;SAVE POINTER TO ANY REMAINING MESSAGE DATA
	MOVEM T2,RQLCNT		;SAVE COUNT OF BYTES LEFT IN MESSAGE
	MOVE T4,RQLREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T1,RBJFN,(T4)	;GET JFN OF FILE JUST LOADED
	CLOSF			;CLOSE THE FILE
	 JFCL			;FAILED, IGNORE FAILURE
	SETZRO RBJFN,(T4)	;NOTE THAT WE'RE NO LONGER USING THE JFN
	MOVE T1,RQLREC		;GET ADDRESS OF RECORD BLOCK FOR THIS LOAD
	CALL RELFRE		;RELEASE THE FREE SPACE
	 FATAL.ERROR		; Die on release failure
	SETZM RQLREC		;NOTE THAT WE NO LONGER HAVE A RECORD BLOCK
	MOVE T2,[POINT 8,[BYTE (8).LMEND,.NRSUC]] ;CONFIRM "END-OF-DIALOGUE"
	MOVNI T3,2		;WE ARE SENDING 2 BYTES
	MOVE T1,RQLLNK		;GET LOGICAL LINK JFN
	SOUTR			;OUTPUT THE "END-OF"DIALOGUE" MSG
	 ERJMP [LODERR (.NRCME)]	;RETURN COMMUNICATION ERROR
	SKIPG RQLCNT		;MORE BYTES IN REPLY MESSAGE ?
	JRST RQL080		;NO, GO CLEAN UP AND RETURN TO CALLER
	MOVE T1,RQLPTR		;YES, RESTORE POINTER
	MOVE T2,RQLCNT		;RESTORE COUNT
	CALL GETPDT		;GO EXTRACT THE PROGRAM DATA FROM MESSAGE
	 LODERR ()		;FAILED, RETURN ERROR CODE TO CALLER
	JRST RQL020		;LOOP BACK TO LOAD NEXT FILE



; HERE TO CLEAN UP AND RETURN TO DISPATCHING CODE

RQL080:	MOVE T1,RQLLNK		;YES, GET LOGICAL LINK (JFN) TO SERVER NCU
	CLOSF			;DISCONNECT THE LOGICAL LINK
	 JFCL			;IGNORE FAILURE, LINK NO LONGER NEEDED
	SETZM RQLLNK		;NOTE THAT WE NO LONGER HAVE A LINK TO SERVER
	MOVX T1,.NRSUC		;GET NICE PROTOCOL SUCCESS RETURN CODE
	CALL SYRLOD		;MAKE A SYSERR ENTRY FOR THIS LOAD

; UNLOCK THE TARGET NODE NIB

	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GO GET THE ADDRESS OF THE TARGET NODE NIB
	 JRST RQL085		;FAILED, JUST PROCEED.
	MOVX T2,RM%PRI		;USE PRIMARY RESOURCE
	SETZRO NDLIP,(T1)	;AUTO LOAD DONE
	CALL ULKNOD		;UNLOCK THE NODE

; SEND BACK A NICE "SUCCESS" RETURN CODE TO REQUESTING TASK

RQL085:	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET POINTER TO SUCCESS CODE
	MOVNI T3,1		;RETURN CODE IS A SINGLE BYTE
	SOUTR			;SEND BACK THE RETURN CODE
	 ERJMP RSKP		;IF FAILED, NOTHING ELSE TO DO
	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL TOPCHK		;INITIATE MONITORING OF TOPOLOGY ?
	 JRST RQL090		;NO, FINISH LOADING PROCESS
	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL MONINI		;INITIATE MONITORING OF TOPOLOGY
	 JFCL			;FAILED
RQL090:	SETOM LOGFLG		;NOTE THAT LOGGING SHOULD NOW BE DONE
	RETSKP			;LOAD IS FINISHED. RETURN SUCCESS.
; HERE ON INTERRUPT INDICATING UNEXPECTED RESPONSE FROM SERVER NCU


RQLINT:	MOVEI T1,RQINT1		;GET DEBRK ADDRESS
	MOVEM T1,RETPC1		;SAVE NEW DEBRK ADDRESS
	DEBRK			;DISMISS INTERRUPT

RQINT1:	CALL CLRMSG		;GO CLEAR THE MESSAGE AREA
	MOVE T1,RQLLNK		;GET LOGICAL LINK TO SERVER NCU
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO WHERE MESSAGE GOES
	MOVNI T3,MAXNIC		;GET MAX COUNT
	SINR			;READ THE DATA
	 ERJMP [ MOVX T1,.NRCME	;FAILED, GET "COMMUNCIATIONS ERROR"
		 JRST RQINT2 ]	;RETURN ERROR TO ORIGINATOR OF REQUEST
	MOVEI T2,MAXNIC(T3)	;GET NUMBER OF BYTES RECEIVED
	CAIE T2,2		;TWO BYTES EXPECTED
	JRST [	MOVX T1,.NRPRO	;FAILED, GET "PROTOCOL ERROR"
		JRST RQINT2 ]	;RETURN ERROR TO ORIGINATOR OF REQUEST
	MOVE T4,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	ILDB T1,T4		;GET TYPE CODE
	CAIE T1,.LMEND		;END OF DIALOG ?
	JRST [	MOVX T1,.NRPRO	;NO, GET "PROTOCOL ERROR"
		JRST RQINT2 ]	;RETURN ERROR TO ORIGINATOR OF REQUEST

; RETURN AN ERROR RETURN CODE

RQINT2:	MOVE T1,REQLNK		;GET LOGICAL LINK TO REQUESTING TASK
	MOVE T2,T4		;GET POINTER TO RETURN CODE
	MOVNI T3,1		;RETURN CODE IS JUST ONE SINGLE BYTE
	SOUTR			;SEND THE RETURN CODE TO REQUESTING TASK
	 JFCL
	SKIPE T1,RQLLNK		;DISCONNECT LOGICAL LINK TO THE
	CLOSF			; SERVER NCU
	 JFCL			;IGNORE ERRORS
	SKIPE T1,RQLREC		;CLOSE ANY OPEN INPUT FILE JFN'S
	CALL [	LOAD T1,RBJFN,(T1)
		SKIPE T1
		CLOSF
		 JFCL
		MOVE T1,RQLREC	;RELEASE ANY SPACE ASSIGNED FOR
		CALL RELFRE	; A RECORD BLOCK
		 FATAL.ERROR	; Die on release failure
		RET ]
	MOVE T1,RQLTGT		;GET ADDRESS OF TARGET NODE NIB
	CALL GETNIB
	 JFCL			;IGNORE FAILURE
	SETZRO NDLIP,(T1)	;SET LOAD NO LONGER IN PROGRESS
	ACUNLOCK (T1)		;UNLCOK TARGET NODE NIB
	HALTF			;DONE, OPERATION COMPLETE
;RQLERR - HERE ON ERROR DURING A DOWN-LINE LOAD
;
;ACCEPTS IN T1/	NICE RETURN CODE
;		CALL RQLERR
;RETURNS: +1 ALWAYS, HAVING CLEANED UP FROM THE DOWN-LINE LOAD

RQLERR:	PUSH P,T1		;Save the error code
	CALL SYRLOD		;MAKE A SYSERR ENTRY FOR THIS LOAD
	SKIPE T1,RQLLNK		;ANY LOGICAL LINK TO A SERVER NCU ?
	CLOSF			;YES, DISCONNECT THE LINK
	 JFCL			;IGNORE ERRORS IN CLEANUP ROUTINE
	SKIPE T1,RQLREC		;ANY RECORD BLOCK ASSIGNED ?
	CALL [	LOAD T1,RBJFN,(T1) ; Yes, any input file
		SKIPE T1	; JFN assigned ?
		CLOSF		; Yes, close the input file, release JFN
		 JFCL		; Ignore errors here
		MOVE T1,RQLREC	; Get address of record block again
		CALL RELFRE	; Release it
		 FATAL.ERROR	;  Die on release failure
		RET ]		; Back to mainline code
	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET ADDRESS OF TARGET NODE NIB
	 JRST RQLE.1		; Go restore the error code and return
	SETZRO NDLIP,(T1)	;SET LOAD NO LONGER IN PROGRESS
	ACUNLOCK (T1)		;UNLOCK THE TARGET NODE NIB

RQLE.1:	POP P,T1		; Get the error code back
	RET			; Give non-skip return always. (error)
;TRGGER - ROUTINE TO TRIGGER THE BOOTSTRAP ROM AT A REMOTE NODE
;
;ACCEPTS IN T1/	LOGICAL LINK TO NICE PROCESS IN SERVER NODE
;	    T2/	OPTIONS AS FOR DOWN-LINE LOAD REQUEST MESSAGE
;		CALL TRGGER
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS.  IF THE OPTIONS REQUESTED RETURN OF PROGRAM DATA,
;			  THEN THE FOLLOWING WILL BE SET UP:
;
;			RQLLDV/	BOOT LINE DEVICE TYPE AT TARGET NODE
;			RQLCPU/	CPU TYPE OF TARGET SYSTEM (.CPXXX)
;			RQLPGM/	PROGRAM TYPE BEING REQUESTED (.PTXXX)
;			RQLSID/	SOFTWARE ID

TRGGER:	ASUBR <TBTLNK,TBTOPT,TBTFLG>

; DETERMINE IF PROGRAM DATA IS TO BE RETURNED

	MOVE T4,TBTOPT		;GET OPTION BITS
	LOAD T3,LO%ROM		;GET ROM FIELD
	CAIE T3,.LOTBP		;TRIGGER ROM AND RETURN PROGRAM DATA ?
	SETOM TBTFLG		;YES, NOTE PROGRAM DATA IS TO BE RETURNED

; ASSEMBLE A NICE LINE SERVICE MESSAGE TO TRIGGER THE BOOTSTRAP

	CALL CLRMSG		;GO CLEAR THE MESSAGE AREA
	HRLI T1,(POINT 8,)	;FORM POINTER TO THE START OF THE
	HRRI T1,MSGBLK		; NICE MESSAGE BEING BUILT
	MOVX T4,.NCLSV		;GET "LINE SERVICE" NICE FUNCTION CODE
	IDPB T4,T1		;PUT FUNCTION CODE INTO NICE MESSAGE
	MOVX T4,.LSTBT		;ASSUME TRIGGER BOOT, NO PROGRAM DATA WANTED
	SKIPE TBTFLG		;PROGRAM DATA REQUESTED ?
	MOVX T4,.LSTBP		;YES, TRIGGER BOOT & RETURN PROGRAM DATA OPTION
	IDPB T4,T1		;STORE OPTION FIELD IN MESSAGE
	DMOVE T3,RQLLIN		;GET SERVER LINE ID
	CALL MAKLIN		;GO ADD STANDARD LINE ID TO MESSAGE
	DMOVE T3,RQLPSW		;GET BOOT PASSWORD
	MOVEI T2,MBPWSZ		;GET MAX # OF BYTES IN BOOT PASSWORDS
	CALL MAKIMB		;GO MAKE AN IMAGE BINARY FIELD

; SEND THE MESSAGE TO THE NICE PROCESS AT THE SERVER NODE

	MOVNI T3,<MBPWSZ+1>+<7>	;MESSAGE SIZE: <PASSWORD>+<FUNCTION+OPTION+LINE>
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	MOVE T1,TBTLNK		;GET LOGICAL LINK NUMBER (JFN)
	SOUTR			;SEND THE MESSAGE
	 ERJMP [RETBAD (.NRCME)] ;RETURN "COMMUNICATIONS FAILURE" ON ERROR
	; ..
	; ..

; WAIT FOR A RESPONSE MESSAGE

	MOVE T1,TBTLNK		;GET LOGICAL LINK (JFN) TO SERVER NCU
	BIN			;INPUT THE ONE-BYTE RETURN CODE (.NRXXX)
	 ERJMP [RETBAD (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	MOVE T1,T2		;COPY RETURN CODE
	TXNE T1,NEGBIT		;RETURN CODE INDICATES SUCCESS ?
	RETBAD ()		;NO, PASS RETURN CODE BACK TO CALLER

; IF PROGRAM DATA WAS REQUESTED, INPUT THE PROGRAM DATA

	SKIPN TBTFLG		;PROGRAM DATA WANTED ?
	RETSKP			;NO, DONE. RETURN SUCCESS
	CALL CLRMSG		;YES, CLEAR THE MESSAGE AREA TO RECEIVE THE DATA
	MOVE T1,TBTLNK		;GET JFN (LOGICAL LINK)
	SIBE			;DETERMINE THE NUMBER OF BYTES LEFT TO READ
	 ERJMP TBT020		;T2 NOW HAS # OF BYTES LEFT TO BE INPUT
	RETBAD (.NRNPE)		;FAILED, PROGRAM DATA WAS NOT RETURNED
TBT020:	MOVE T4,T2		;COPY NUMBER OF BYTES LEFT TO READ
	MOVN T3,T2		;GET -# OF BYTES TO READ
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO WHERE DATA SHOULD GO
	MOVE T1,TBTLNK		;GET LOGICAL LINK (JFN)
	SINR			;INPUT THE PROGRAM DATA FROM THE NETWORK
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"

; EXTRACT THE PROGRAM DATA FROM THE RESPONSE JUST RECEIVED

	ADD T4,T3		;COMPUTE # OF CHARACTERS READ
	MOVE T2,T4		;COPY NUMBER OF BYTES READ
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO PROGRAM REQUEST DATA
	CALL GETPDT		;GO GET PROGRAM DATA
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, RETURN SUCCESS
;INTSET - ROUTINE TO SET UP THE NCU INTERRUPT SYSTEM FOR DOWN LINE LOADS
;
;ACCEPTS IN T1/	LOGICAL LINK TO SERVER NCU
;		CALL INTSET
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, INTERRUPT SYSTEM SET UP AND ENABLED

INTSET:	ASUBR <INTLNK>

	MOVEI T1,RETPC1		;GET ADDRESS FOR RETURN PC FOR LEVEL 1
	MOVEM T1,NCULEV		;STORE ADDRESS FOR MONITOR
	MOVE T1,[1,,RQLINT]	;GET LEVEL,,INTERRUPT ROUTINE ADDRESS
	MOVEM T1,RQLCHN+NCUCHN	;STORE DISPATCH ADDRESS FOR INTERRUPT
	CIS			;CLEAR INTERRUPT SYSTEM
	MOVX T1,.FHSLF		;GET OUR PROCESS HANDLE
	HRLI T2,NCULEV		;GET ADDRESS OF LEVEL TABLE
	HRRI T2,NCUCHN		;GET ADDRESS OF CHANNEL TABLE
	SIR			;SET INTERRUPT TABLE ADDRESSES
	MOVX T2,1B<RQLCHN>	;GET DOWN-LINE LOAD CHANNEL NUMBER
	AIC			;ACTIVATE DOWN LINE LOAD CHANNEL
	MOVE T1,INTLNK		;GET LOGICAL LINE TO SERVER NCU
	MOVX T2,.MOACN		;GET "ASSIGN INTERRUPT CHANNEL" FUNCTION CODE
	SETZM T3		;INITIALIZE WORD WITH FIELDS TO CHANGE
	MOVX T4,.MONCI		;GET "NO CHANGE" VALUE
	STOR T4,MO%CDN,T3	;DO NOT ENABLE FOR CONNECT INTERRUPTS
	MOVX T4,RQLCHN		;GET CHANNEL TO USE FOR DOWN LINE LOADS
	STOR T4,MO%INA,T3	;INTERRUPT ON BOT INTERRUPT MESSAGES
	STOR T4,MO%DAV,T3	; AND ON DATA AVAILABLE
	MTOPR			;ENABLE INTERRUPT CHANNEL
	 ERJMP [RETBAD (.NRNPE)] ;FAILED, RETURN "NICE PROGRAM PROCESS ERROR"
	MOVX T1,.FHSLF		;GET OUR FORK HANDLE
	EIR			;ENABLE INTERRUPT SYSTEM
	RETSKP			;DONE, RETURN TO CALLER
SUBTTL	NICE Process -- Up Line Dump

;REQDMP - ROUTINE TO PROCESS A REQUEST TO PERFORM AN UPLINE DUMP
;
;ACCEPTS IN T1/	POINTER TO START OF NICE REQUEST UP LINE DUMP MESSAGE
;	    T2/	NUMBER OF BYTES IN THE NICE MESSAGE
;		CALL REQDMP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, NODE DUMPED

REQDMP:	ASUBR <RQDPTR,RQDCNT,RQDLNK,RQDREC>

; EXTRACT THE FIELD FROM THE NICE DUMP REQUEST MSG AND DEFAULT OTHER INFO

	CALL GETRQD		;GO GET THE FIELDS INCLUDED IN THE REQUEST MSG
	 RETBAD (.NRIMF)	;FAILED, INVALID MESSAGE FORMAT
	CALL DEFRQD		;GO DEFAULT REMAINING INFO NEEDED FOR DUMP
	 RETBAD (.NRICF)	;FAILED, INVALID CONFIGURATION FILE

; LOCK THE TARGET NODE

	MOVE T1,RQDTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET NIB ADDRESS FOR NODE BEING LOADED
	 RETBAD (.NRICF)	;FAILED, RETURN ERROR
	MOVX T2,RM%PRI		;USE PRIMARY RESOURCE
	MOVEM T1,RQDLNK		;SAVE NIB ADDRESS
	CALL LOKNOD		;LOCK THE TARGET NODE
	MOVE T1,RQDLNK		;GET THE NIB ADDRESS
	SETONE NDDIP,(T1)	;SHOW DUMP IN PROGRESS
	SETZM RQDLNK		;ZERO HOLDING CELL

; SEND A NICE LINE SERVICE MSG TO SERVER NODE NCU TO INTIATE DUMP DIALOG

	MOVE T1,RQDSRV		;GET POINTER TO ASCIZ SERVER NODE NAME
	CALL GETLNK		;GO GET A LOGICAL LINK TO THE SERVER NODE NCU
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T1,RQDLNK		;SAVE LOGICAL LINK (JFN) TO SERVER NODE NCU

; Set the fork scheduling priority higher so that dump goes fast

	MOVEI T1,.FHSLF		; Point to this process
	MOVEI T2,0102		; Only run in Q1
	SPRIW

; INITIATE A DUMP DIALOG

	CALL MAKDMP		;GO ASSEMBLE A NICE LINE SERVICE MSG
	 RETBAD ()		;FAILED, RETURN ERROR
	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;COPY POINTER TO START OF MESSAGE
	MOVE T1,RQDLNK		;GET LOGICAL LINK TO SERVER NCU
	SOUTR			;OUTPUT LINE SERVICE MSG TO INITIATE DUMP DIALOG
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"

; WAIT FOR A REPLY FROM THE SERVER NODE NCU

	MOVE T1,RQDLNK		;GET LOGICAL LINK (JFN) TO SERVER NODE NCU
	BIN			;WAIT FOR THE ONE-BYTE RETURN CODE
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	MOVE T1,T2		;COPY RETURN CODE
	TXNE T1,NEGBIT		;SUCCESSFUL DIALOG INITIATION ?
	RETBAD ()		;NO, RETURN ERROR CODE TO CALLER IN T1
	CAIE T1,.NRSUC		;RECEIVED EXPECTED SUCCESS CODE ?
	RETBAD (.NRPRO)		;NO, RETURN "PROTOCOL ERROR"

; ASSIGN A RECORD BLOCK AND OPEN THE OUTPUT FILE

	MOVX T1,OF%WR		;NOTE THAT OUTPUT IS TO BE DONE
	CALL ASGREC		;GO ASSIGN A RECORD BLOCK FOR THIS I/O
	 RETBAD ()		;FAILED, RETURN ERROR
	MOVEM T1,RQDREC		;SAVE ADDRESS OF RECORD BLOCK
	MOVE T1,RQDFIL		;GET POINTER TO OUTPUT FILESPEC
	CALL OPNOFL		;GO OPEN THE OUTPUT FILE
	 RETBAD ()		;FAILED, RETURN ERROR
	MOVE T4,RQDREC		;GET ADDRESS OF RECORD BLOCK
	STOR T1,RBJFN,(T4)	;STORE JFN OF DUMP FILE
	; ..
	; ..

; INPUT A DIALOG MESSAGE FROM THE SERVER NCU AND DISPATCH

RQD010:	MOVE T1,RQDLNK		;GET LOGICAL LING (JFN) TO SERVER NCU
	HRLI T2,(POINT 8,)	;FORM A BYTE POINTER TO THE
	HRRI T2,MSGBLK		; NICE MESSAGE AREA
	MOVNI T3,MAXNIC		;GET -MAX COUNT
	SINR			;INPUT FROM SERVER NCU
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	MOVEI T2,MAXNIC(T3)	;GET NUMBER OF BYTES RECEIVED
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	ILDB T4,T1		;GET DIALOG MESSAGE TYPE CODE
	CAIL T4,0		;RANGE CHECK THE DIALOG
	CAILE T4,DMPMAX		; MESSAGE TYPE CODE
	JRST [	TXNN T1,NEGBIT	;NEGATIVE IMPLIES A NICE PROTOCOL RETURN CODE
		RETBAD (.NRPRO)	;INVALID TYPE CODE; RETURN "PROTOCOL ERROR"
		RETBAD () ]	;RETURN NICE PROTOCOL RETURN CODE PROVIDED
	MOVE T3,RQDREC		;GET ADDRESS OF RECORD BLOCK
	CALL @DMPTAB(T4)	;DISPATCH TO PROCESSING ROUTINE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	SKIPL T1		;STILL IN DUMP DIALOG ?
	JRST RQD010		;YES, GO GET NEXT MESSAGE FROM SERVER NCU

; DONE - CLEAN UP AND UNLOCK THE TARGET NODE NIB

	MOVX T1,.NRSUC		;GET GENERAL SUCCESS RETURN CODE
	CALL SYRDMP		;GO MAKE A SYSERR ENTRY FOR THIS DUMP
	MOVE T1,RQDTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GO GET THE ADDRESS OF THE TARGET NODE NIB
	 JRST RQL085		;FAILED, JUST PROCEED.
	SETZRO NDDIP,(T1)	;SET DUMP DONE 
	MOVX T2,RM%PRI		;USE PRIMARY RESOURCE
	CALL ULKNOD		;UNLOCK THE TARGET NODE
	MOVE T1,RQDREC		;GET ADDRESS OF RECORD BLOCK AGAIN
	CALL RELFRE		;RELEASE THE RECORD BLOCK
	 FATAL.ERROR		; Die on release failure
	MOVE T1,RQDLNK		;GET LOGICAL LINK TO SERVER NCU
	CLOSF			;DISCONNECT THE LINK
	 JFCL			;IGNORE ERRORS HERE
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) FROM REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET SUCCESS RETURN CODE
	MOVEI T3,1		;ONE BYTE RESPONSE MESSAGE
	SOUTR			;SEND REPLY MESSAGE TO ORIGINATOR OF DUMP REQ
	 ERJMP RSKP		;IGNORE FAILURE
	RETSKP			;DONE, RETURN SUCCESS

; TABLE OF DUMP DIALOG MESSAGE TYPES

DMPTAB:	DMPEND			; 0 END OF DIALOG
	DMPSET			; 1 SET BASE ADDRESS
	DMPMEM			; 2 MEMORY IMAGE DATA
	[RETBAD (.NRPRO)]	; 3 SYSTEM PARAMETERS AND TRANSFER [ERROR!]

	DMPMAX==.-DMPTAB
;DMPEND - ROUTINE TO PROCESS AN END-OF-DIALOG MESSAGE
;
;ACCEPTS IN T3/	ADDRESS OF RECORD BLOCK
;		CALL DMPEND
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ -1 INDICATING DIALOG IS COMPLETE

DMPEND:	MOVE T1,T3		;COPY ADDRESS OF RECORD BLOCK
	MOVE T4,RQDREC		;GET ADDRESS OF RECORD BLOCK FOR THIS OPERATION
	CALL CLSOFL		;GO CLOSE THE OUTPUT FILE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	SETOM T1		;NOTE THAT DIALOG IS COMPLETED
	RETSKP			;DONE, RETURN SUCCESS


;DMPMEM - ROUTINE TO PROCESS A MEMORY IMAGE DUMP MESSAGE
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA (MEMORY IMAGE DATA)
;	    T2/	NUMBER OF BYTES REMAINING IN MEMORY IMAGE DATA
;	    T3/	ADDRESS OF RECORD TABLE
;		CALL DMPMEM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, DATA DUMPED TO FILE

DMPMEM:	SOSGE T2		;DECREMENT COUNT FOR CPU TYPE CODE
	RETBAD (.NRIMF)		;FAILED, RETURN ERROR
	IBP T1			;SKIP OVER CPU TYPE CODE
	CALL WRTDMP		;WRITE THE DATA TO THE FILE
	 RETBAD (.NRIOE)	;FAILED, RETURN FILE I/O ERROR
	SETZM T1		;NOTE THAT WE ARE STILL IN THE DIALOG
	RETSKP			;DONE, RETURN


;DMPSET - ROUTINE TO PROCESS "SET BASE ADDRESS" MESSAGES DURING A DUMP
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA IN MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;	    T3/	ADDRESS OF RECORD BLOCK
;		CALL DMPSET
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS

DMPSET:	SETZM T1		;NOTE THAT WE ARE STILL IN THE DIALOG
	RETSKP			;SET BASE MESSAGES NOT PROCESSED FOR IMAGE FILES
SUBTTL	NICE Process -- Read Information

REQRED:	ASUBR <RQRPTR,RQRCNT>

; DISPATCH ON OPTION REQUESTED

	CALL GETFCN		;GET NICE PROTOCOL FUNCTION CODE
	 RETBAD (.NRIMF)	;FAILED, INVALID MESSAGE FORMAT
	CALL GETOPT		;GET NICE PROTOCOL OPTION CODE
	 RETBAD (.NRIMF)	;FAILED, INVALID MESSAGE FORMAT
	CAIL T4,RQRSIZ		;WITHIN RANGE ?
	RETBAD (.NRFNC)		;NO, INVALID OPTION
	CALLRET @RQRTAB(T4)	;DISPATCH BASED ON ITEM REQUESTED

; DISPATCH TABLE FOR READ INFORMATION FUNCTION

RQRTAB:	RETBAD (.NRFNC)		;LOCAL NODE COUNTERS
	RQRLNS			;LOCAL NODE STATUS
	RETBAD (.NRFNC)		;REMOTE NODE COUNTERS
	RETBAD (.NRFNC)		;REMOTE NODE STATUS
	RQRLCT			;LINE COUNTERS
	RQRLST			;LINE STATUS
	RETBAD (.NRFNC)		;ROUTING PATHS

RQRSIZ==.-RQRTAB
SUBTTL	NICE Process -- Read Information -- Local Node Status


RQRLNS:	STKVAR <<LNSMSG,50>,LNSCNT,<COMBLK,3>,<COMVER,3>,<ROUVER,3>>
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE(8).NRSUC,1,0]]
	MOVNI T3,3		;NUMBER OF BYTES IN MESSAGE
	SOUTR			;SEND RESPONSE
	 ERJMP RSKP		;IF FAILED NOTHING ELSE TO DO
	HRRI T1,LNSMSG		;GET ADDRESS OF NICE MESSAGE TO BE SENT BACK
	HRLI T1,(POINT 8,)	;FORM POINTER TO MESSAGE
	MOVX T4,.RDLNS		;GET TYPE CODE FOR LOCAL NODE STATUS
	IDPB T4,T1		;ADD BYTE TO MESSAGE
	MOVEI T2,1		;ONE BYTES IN MESSAGE YET
	MOVE T3,[POINT 7,OURNAM] ;GET POINTER TO OUR NODE NAME
	CALL MAKNOD		;ASSEMBLE OUR NODE NAME IN MESSAGE
	 RET			;FAILED
	ADDI T2,^D11		;INCREMENT COUNT OF BYTES IN MESSAGE
	MOVEM T2,LNSCNT		; INCLUDING STATE AND VERSION BYTES
	MOVE T3,OURNUM		;GET OUR NODE NUMBER
	IDPB T3,T1		;ADD NODE NUMBER TO MESSAGE
	MOVX T3,.NSON		;GET "ON" STATE
	IDPB T3,T1		;ADD STATE TO MESSAGE
	MOVX T3,0		;GET UNUSED BYTE OF FILLER (LOGGING STATES)
	IDPB T3,T1		;ADD LOGGING STATES TO
	IDPB T3,T1		;  THE MESSAGE
	IDPB T3,T1		;NO DEFAULT HOST NODE

; ADD VERSIONS TO MESSAGE

	MOVE T4,T1		;SAVE THE BYTE POINTER
	MOVEI T1,.NDGVR		;GET VERSION NUMBERS FROM MONITOR
	MOVEI T2,COMBLK		;POINT TO JSYS BLOCK
	MOVEI T3,COMVER		;WHERE VERSION NUMBER IS TO GO
	MOVEM T3,.NDCVR(T2)	;STUFF IN REQUEST BLOCK
	MOVEI T3,ROUVER		;WHERE VERSION NUMBER IS TO GO
	MOVEM T3,.NDRVR(T2)	;STUFF IN REQUEST BLOCK
	NODE			;GET THE INFORMATION
	 ERJMP [RET]		;ERROR - RETURN FAILURE

; HAVE VERSION NUMBERS - NOW PUT IN MESSAGE

	MOVE T1,T4		;RESTORE MESSAGE POINTER
	MOVEI T3,ROUVER		;NOW GET ROUTING INFO INTO MSG
	MOVE T4,.NDVER(T3)	;GET VERSION NUMBER
	IDPB T4,T1		; INTO MSG
	MOVE T4,.NDECO(T3)	;ROUTING NUMBER
	IDPB T4,T1
	MOVE T4,.NDCST(T3)	;GET CUSTOMER CHANGE NUMBER
	IDPB T4,T1		;PUT INTO MSG
	MOVEI T3,COMVER		;NOW GET COMMUNICATION INFO INTO MSG
	MOVE T4,.NDVER(T3)	;GET VERSION NUMBER
	IDPB T4,T1		; INTO MSG
	MOVE T4,.NDECO(T3)	;ROUTING NUMBER
	IDPB T4,T1
	MOVE T4,.NDCST(T3)	;GET CUSTOMER CHANGE NUMBER
	IDPB T4,T1		;PUT INTO MSG
	MOVX T2,^D32		;MAX SIZE OF SYSTEM NAME
	MOVE T3,[POINT 7,SYSNAM] ;GET POINTER TO OUR SYSTEM NAME
	CALL MAKIMA		;ADD IMAGE FIELD TO MESSAGE
	 RET			;FAILED
	ADD T2,LNSCNT		;COMPUTE TOTAL BYTES IN MESSAGE
	MOVN T3,T2		;GET -COUNT
	HRRI T2,LNSMSG		;GET ADDRESS OF NICE MESSAGE TO BE SENT BACK
	HRLI T2,(POINT 8,)	;FORM POINTER TO MESSAGE
	MOVE T1,REQLNK		;GET LINK TO REQUESTING TASK
	SOUTR			;OUTPUT REPLY
	 ERJMP R		;FAILED
	RETSKP			;DONE, RETURN SUCCESS
SUBTTL	NICE Process -- Read Information -- Line Counters

RQRLCT:	CALL GETLIN		;GET LINE-ID FROM MESSAGE
	 RETBAD ()		;FAILED
	JUMPL T3,NRILN		;IN CASE WANTS ALL
	STKVAR <<LINLID,2>,<LINCNT,100>,<LINMSG,100>>
	DMOVEM T3,LINLID	;SAVE LINE-ID FOR RESPONSE
	DMOVE T1,T3		;PUT LINE-ID IN RIGHT REGISTER
	CALL LIDPRT		;CONVERT LID TO PORT
NRILN:	 RETBAD (.NRILN)	;"INVALID LINE ID"
	MOVEM T1,.BTPRT+LINCNT	;PUT PORT IN ARGUMENT BLOCK
	MOVEI T1,20		;MAXIMUM NUMBER OF COUNTERS
	MOVEI T2,20+LINCNT	;WHERE TO PUT FIRST COUNTERS
	HRLI T2,444400		;MAKE INTO POINTER
	DMOVEM T1,.BTSCC+LINCNT	;STATUS COUNTERS
	ADDI T2,20		;ADR OF NEXT COUNTERS
	DMOVEM T1,.BTRCC+LINCNT	;RECEIVE COUNTERS
	ADDI T2,20		;ADR OF NEXT COUNTERS
	DMOVEM T1,.BTTCC+LINCNT	;TRANSMIT COUNTERS
	MOVEI T1,.BTRLC		;WANT LINE COUNTERS
	MOVEI T2,LINCNT		;ADDRESS OF ARGUMENT BLOCK
	BOOT
	ERJMP [RETBAD (.NRIST)] ;RETURN "Insufficient Status"
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE(8).NRSUC,1,0]]
	MOVNI T3,3		;NUMBER OF BYTES IN MESSAGE
	SOUTR			;SEND RESPONSE
	 ERJMP RSKP		;IF FAILED NOTHING ELSE TO DO
	MOVEI T1,LINMSG		;ADR OF RESPONSE MESSAGE
	HRLI T1,441000		;MAKE IT A POINTER TO MESSAGE
	MOVEI T2,.RDLCT		;CODE SAYES THIS IS LINE COUNTS
	IDPB T2,T1		;PUT CODE INTO MESSAGE
	MOVEI T2,1		;NUMBER OF BYTES IN MESSAGE SO FAR
	DMOVE T3,LINLID		;LINE-ID
	CALL MAKLIN		;PUT LINE-ID INTO MESSAGE
	MOVEI T3,0		;SECOND SINCE LAST ZEROED
	MOVE T4,.BTZTM+LINCNT	;TIME SINCE ZEROED
	CALL MAKLCT
	MOVEI T3,1		;TYPE = BLOCKS RECEIVED
	MOVE T4,40+LINCNT	;GET NUMBER OF BLOCKS RECEIVED
	CALL MAKLCT
	MOVEI T3,4		;RECEIVED LINE ERRORS
	MOVE T4,42+LINCNT	;HEADER BCC ERRORS
	ADD T4,43+LINCNT	;DATA BCC ERRORS
	CALL MAKLCT
	MOVEI T3,2		;TYPE = BLOCKS TRANSMITTED
	MOVE T4,60+LINCNT	;GET NUMBER OF BLOCKS TRANSMITTED
	CALL MAKLCT
	MOVEI T3,3		;RETRANSMISSIONS, LINE ERRORS
	MOVE T4,62+LINCNT	;HEADER BCC ERROR
	ADD T4,63+LINCNT	;DATA BCC ERROR
	CALL MAKLCT
	; ..
	; ..
	MOVEI T3,5		;RETRANSMISSION, NOT PARITY
	MOVE T4,61+LINCNT	;MISC NAKS RECEIVED
	ADD T4,64+LINCNT	;REP RESPONSE
	ADD T4,65+LINCNT	;BTU
	CALL MAKLCT
	MOVEI T3,^D8		;RESOURCE ERRORS
	MOVE T4,45+LINCNT	;NAKS SEND FOR BTU
	ADD T4,65+LINCNT	;RECEIVED
	CALL MAKLCT
	MOVNI T3,(T2)		;NUMBER OF BYTES IN MESSAGE
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	HRRI T2,LINMSG		;POINT TO MESSAGE
	HRLI T2,441000		;MAKE BYTE POINTER
	SOUTR			;SEND RESPONSE
	 ERJMP RSKP		;IF FAILED NOTHING ELSE TO DO
	RETSKP

MAKLCT:	IDPB T3,T1		;PUT TYPE(EX-2) IN MESSAGE
	IDPB T4,T1		;PUT COUNT(B2) INTO MESSAGE
	LSH T4,-8		;POSITION HIGH ORDER BITS
	IDPB T4,T1		;PUT HIGH ORDER BITS IN ALSO
	ADDI T2,3		;ADDED TWO BYTES TO MESSAGE
	RET
SUBTTL	NICE PROCESS -- Read Information -- Line Status
;HERE TO DO A "SHOW LINE STATUS" REQUEST

RQRLST:	SAVEQ
	STKVAR <<RQRHLD,2>,RQRBUF,<RLSMSG,10>>
	CALL GETLIN		;GET LINE-ID OUT OF MESSAGE
	 RETBAD			;BAD LINE-ID - RETURN
	DMOVEM T3,RQRHLD	;SAVE INTERNAL LINE ID
	CALL ASGPAG		;GET PAGE FOR NODE JSYS STUFF
	 RETBAD (.NRRES)	;NO STORAGE - FAIL
	MOVEM T2,RQRBUF		;SAVE "NICE" MESSAGE POINTER
	MOVEI T3,1000		;SIZE OF BUFFER WE'RE PROVIDING
	HRRZM T3,.NDNLN(T2)	;INTO ARGUMENT BLOCK
	MOVEI T1,.NDGLI	
	NODE
	 ERJMP [RETBAD (.NRNPE)]	;JSYS ERROR - FAIL
	HLRZ T1,.NDNLN(T2)	;ANY KNOWN LINES?
	SKIPN T1		;SKIP IF LINE COUNT .NE. 0
	RETBAD (.NRILN)		;FAIL - NO KNOWN LINES
	SKIPG RQRHLD		;IS THIS AN "ALL LINES" REQUEST
	JRST RQRLAL		;YES - THEN HANDLE

;HERE FOR A SINGLE LINE REQUEST

	DMOVE T1,RQRHLD		;GET THE INTERNAL LINE ID
	CALL LIDPRT		;CONVERT IT TO PORT NUMBER
	 RETBAD(.NRILN)		;ERROR - FAIL
	MOVEM T1,RQRHLD		;SAVE PORT NUMBER
	MOVE T1,[POINT 8,T4]	;BUILD THE INITIAL "NICE" ACKNOWLEDGMENT
	MOVEI T3,.NRSUC		;SHOW THAT WE LIKED THE REQUEST
	IDPB T3,T1		;PLACE INTO MESSAGE BLOCK
	MOVEI T2,1		;COUNT OF RESPONSES WE WILL SEND
	CALL MAKTWO		;PLACE COUNT OF # RESPONSE MSG'S WE WILL SEND
	MOVE T2,[POINT 8,T4]	;SEND INITIAL ACKNOWLEDMENT TO  REQUESTOR
	MOVNI T3,3		;TWO BYTE MESSAGE
	MOVE T1,REQLNK		;REQUESTOR LINK JFN
	SOUTR			;SEND IT
	 ERJMP [RETBAD(.NRNPE)]	;ERROR - FAIL
	MOVE T1,RQRHLD		;SAVE PORT NUMBER
	MOVE T2,RQRBUF		;POINT TO NODE JSYS INFO
	CALL PRTINF		;GET T1-T4 FILLED WITH INFO TO SEND
	 RETBAD			;ERROR - FAIL
	MOVEI Q1,RLSMSG		;BUILD POINTER TO MESSAGE AREA
	HRLI Q1,(POINT 8,)
	CALL LSTBLD		;BUILD THE "NICE" MESSAGE
	 RETBAD 		;ERROR - FAIL
	MOVN T3,T2		;LENGTH OF MESSAGE
	MOVE T1,REQLNK		;SEND RESPONSE TO REQUESTOR
	MOVEI T2,RLSMSG		;BUILD POINTER TO MESSAGE AREA
	HRLI T2,(POINT 8,)
	SOUTR			;SEND THE LINE STATUS INFORMATION
	 ERJMP [RETBAD(.NRNPE)]	;ERROR - FAIL
	JRST RQLOUT		;DONE - EXIT

	;...
	;...

;HERE FOR A "LINE STATUS ALL" REQUEST

RQRLAL:	MOVE T1,[POINT 8,T4]	;BUILD THE INITIAL "NICE" ACKNOWLEDGMENT
	MOVEI T3,.NRSUC		;SHOW THAT WE LIKED THE REQUEST
	IDPB T3,T1		;PLACE INTO MESSAGE BLOCK
	MOVE T2,RQRBUF		;POINTER TO NODE JSYS INFO
	HLRZ T2,.NDNLN(T2)	;GET PORT COUNT
	CALL MAKTWO		;PLACE COUNT OF # RESPONSE MSG'S WE WILL SEND
	MOVE T2,[POINT 8,T4]	;SEND INITIAL ACKNOWLEDMENT TO  REQUESTOR
	MOVNI T3,3		;TWO BYTE MESSAGE
	MOVE T1,REQLNK		;REQUESTOR LINK JFN
	SOUTR			;SEND IT
	 ERJMP [RETBAD(.NRNPE)]	;ERROR - FAIL
	MOVE Q2,RQRBUF		;POINT TO NODE INFORMATION
	HLRZ T1,.NDNLN(Q2)	;GET COUNT OF AVAILABLE LINE ENTRIES
	AOS T1			;BUMP COUNT FOR AOBJP
	MOVN T1,T1		;CREATE AN AOBJP POINTER
	HRL Q2,T1		;...
RQRLOP:	AOBJP Q2,RQLOUT		;END OF LOOP?
	MOVE T1,0(Q2)		;NO - POINT TO LINE BLOCK
	MOVE T1,.NDLNM(T1)	;GET PORT NUMBER
	MOVE T2,RQRBUF		;GET PORT INFORMATION
	CALL PRTINF		;GET ALL THE INFO OUT OF NODE JSYS BLOCK
	 RETBAD 		;COULDN'T FIND PORT NUMBER (SHOULD NEVER HAPPEN)
	MOVEI Q1,RLSMSG		;BUILD POINTER TO MESSAGE AREA
	HRLI Q1,(POINT 8,)
	CALL LSTBLD		;GO BUILD "NICE MESSAGE"
	 RETBAD 		;ERROR IN BUILDING MESSAGE
	MOVN T3,T2		;MAKE BYTE COUNT NEGATIVE
	MOVE T1,REQLNK		;SEND "NICE" MESSAGE TO REQUESTOR
	MOVEI T2,RLSMSG		;BUILD POINTER TO MESSAGE AREA
	HRLI T2,(POINT 8,)
	SOUTR			;SEND RESPONSE
	 ERJMP [RETBAD (.NRNPE)]
	JRST RQRLOP		;GO SEE IF MORE RESPONSES  NEEDED
RQLOUT:	MOVE T1,RQRBUF		;FREE BUFFER PAGE
	CALL RELPGA		;GO FREE IT
	 RETBAD			;ERROR - FAIL
	RETSKP			;SUCCESS RETURN
;PRTINF - GET PORT INFORMATION FROM NODE JSYS DATA

;ACCEPTS:	T1/PORT NUMBER
;		T2/ADDRESS OF NODE JSYS BUFFER

;RETURNS:	+1,ERROR, WITH "NICE" ERROR CODE IN T1
;		+2,OTHERWISE
;		T1/	STATUS
;		T2/	ASCIZ POINTER TO NODE NAME
;		T3-4/	LINE-ID

PRTINF:	ACVAR <Q1>		;GET A WORK REGISTER
	STKVAR <<PRTBUF,20>>
	MOVE Q1,T2		;MOVE ADDRESS OF DATA AREA
	HLRZ T4,.NDLNM(Q1)	;GET COUNT OF KNOWN LINES
	JUMPE T4,R		;ERROR OF NO KNOWN LINES
	MOVEI Q1,.NDLNM(Q1)	;POINT TO PORT NUMBER BLOCK
PRTLOP:	SOSGE T4		;SKIP IF MORE ITEMS TO SEARCH
	RETBAD (.NRILN)		;UNKNOWN PORT - ERROR
	AOS Q1			;POINT  TO NEXT ITEM
	MOVE T3,(Q1)		;GET THE PORT BLOCK NUMBER
	CAME T1,.NDLNM(T3)	;OUR PORT?
	JRST PRTLOP		;NO - KEEP LOOKING
	MOVEI T2,PRTBUF		;WE WANT TO GET A DEVICE STRING
	MOVEM T1,.BTPRT(T2)	;PUT PORT NUMBER IN DATA BLOCK
	HRROI T1,.BTLID+1(T2)	;WHERE WE WANT MESSAGE BUILT
	MOVEM T1,.BTLID(T2)	;INTO ARGUMENT BLOCK
	MOVEI T1,.BTCPN		;TELL BOOT WE WANT CONVERSION
	BOOT
	 ERJMP [RETBAD (.NRNPE)]
	HRRI T1,.BTLID+1(T2)	;GET POINTER TO DEVICE STRING
	HRLI T1,(POINT 7,)
	CALL ASCPRS		;CONVERT TO INTERNAL LINE-ID FORMAT
	 RETBAD
	MOVE Q1,(Q1)		;POINT TO PORT BLOCK
	MOVE T2,.NDLST(Q1)	;GET STATUS AND CONVERT TO "NICE" CODE
	SETO	T1,		;Initialize to absurdly large value
	CAIN	T2,.NDLON	;Check for LINE ON
	 MOVEI	T1,.LSTON	; Set NICE LINE ON code
	CAIN	T2,.NDLOF	;Check for LINE OFF
	 MOVEI	T1,.LSTOF	; Set NICE LINE OFF
	CAIN	T2,.NDLCN	;Check for CONTROLLER LOOPBACK
	 MOVEI	T1,.LSTCN	; Set NICE CONTROLLER LOOPBACK
	CAIN	T2,.NDLCB	;Check for CABLE LOOPBACK
	 MOVEI	T1,.LSTCB	; Set NICE CABLE LOOPBACK
	MOVE T2,.NDLND(Q1)	;GET ASCIZ NODE NAME
	RETSKP			;SUCCESS RETURN
;LSTBLD - BUILD A LINES STATUS "NICE" RESPONSE

;ACCEPTS:	T1/	STATUS
;		T2/	POINTER TO NODE NAME
;		T3-4/	LINE-ID
;		Q1/	ADDRESS OF WHERE TO BUILD MESSAGE

;RETURNS:	+1,ERROR, WITH "NICE" ERROR CODE IN T1
;		+2,OTHERWISE
;			T1/UPDATED BYTE POINTER (FROM Q1)
;			T2/COUNT OF BYTES IN MESSAGE

LSTBLD:	SAVEQ
	STKVAR <<LSTLID,2>,<LSTHLD,2>>
	SETZM Q2		;ZERO BYTE COUNT WORD
	DMOVEM T1,LSTHLD	;SAVE THE PTR AND STATUS
	MOVEI T1,.RDLST		;FUNCTION CODE FOR MESSAGE
	IDPB T1,Q1		;PLACE INTO MESSAGE
	AOS Q2			;BUMP BYTE COUNTER

;	HERE TO ADD INTERNAL LINE-ID TO "NICE" MESSAGE

	DMOVE T1,Q1		;WHERE TO PUT THE "NICE" MESSAGE & COUNT
	CALL MAKLIN		;PUT LINE ID INTO "NICE" MESSAGE
	DMOVE Q1,T1		;RESTORE MESSAGE POINTER AND COUNT
	DMOVE T3,LSTHLD		;GET STATUS AND NAME BYTE POINTER
	IDPB T3,Q1		;PUT STATUS INTO BYTE
	AOS Q2			;BUMP BYTE COUNT
	SETZ T3,		;PROTOCOL REQUIRES TWO ZERO BYTES HERE
	IDPB T3,Q1		;PUT IT INTO BYTE
	AOS Q2			;BUMP BYTE COUNT
	IDPB T3,Q1		;PUT IT INTO BYTE
	AOS Q2			;BUMP BYTE COUNT
	MOVE  T1,Q1		;NOW PUT NAME INTO MESSAGE
	MOVE T2,T4		;SEE IF THIS LINE HAS A NAME
	ILDB T3,T2		;GET FIRST CHARACTER
	JUMPE T3,[ IDPB T3,T1	;ZERO=NULL=NO NAME - PUT 0 COUNT IN MSG
		   MOVEI T2,T1	;SHOW COUNT ADDED
		   JRST LSTOUT]	;JOIN COMMON EXIT
	IBP T1			;POINT PAST IMAGE COUNT FOR NAME
	MOVE T2,T4		;POINT TO WHERE NODE NAME LIVES
	MOVEI T3,6		;MAXIMUM LENGTH OF MESSAGE
	SETZ T4,		;IT'S AN ASCIZ STRING
	SOUT			;MOVE THE STRING
	 ERJMP [RETBAD (.NRNPE)]		;ERROR - FAIL
	LDB T2,T2		;Get last character transfered
	CAIN T2,0		;Check for a zero byte
	AOS T3			;We don't want to count null
	MOVEI T2,6		;Compute bytes put into message
	SUB T2,T3
	IDPB T2,Q1		;Place in message
	AOS T2			;Account for length field
LSTOUT:	ADD T2,Q2		;FINAL COUNT OF BYTES IN MESSAGE
	RETSKP
;ASCPRS - ROUTINE TO PARSE AN ASCIZ LINE ID
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NAME
;		CALL ASCPRS

;RETURNS:	+1,ERROR, WITH "NICE" ERROR CODE IN T1
;		+2	SUCCESS, WITH T3-T4/ LINE ID

;**N.B.   ASCIZ STRING GETS DESTROYED


ASCPRS:	STKVAR <PRSLDV,PRSCTL,PRSUNT,PRSSTN>

	SETZM PRSCTL		;CONTROLLERE NUMBER WILL GO HERE
	SETZM PRSUNT		;;UNIT NUMBER HERE
	SETZM PRSLDV		;DEVICE NUMBER HERE
	SETZM PRSSTN		;STATION NUMBER HERE

; PARSE DEVICE TYPE

	MOVE T4,T1		;SAVE THE STRING POINTER
	MOVNI T3,^D15		;SAFETY CHECK - AT MOST 15 CHARS
	HRLZ T3,T3		;MAKE AOBJN POINTER
FNDUDR:	ILDB T2,T1		;GET THE CHARACTER
	CAIN T2,"_"		;IS IT AN UNDERSCORE
	JRST PRSFND		;YES - HANDLE
	AOBJN T3,FNDUDR		;KEEP LOOKING
	RETBAD (.NRNPE)		;NOT FOUND - ERROR
PRSFND:	SETZ T2,		;ZERO BYTE FOR TBLUK
	DPB T2,T1
	MOVE T2,T4		;SET UP STRING POINTER FOR TBLUK
	MOVEM T1,T4		;SAVE POINTER
	MOVEI T1,LINNAM		;POINT TO TABLE OF NAMES
	TBLUK			;FIND NAME
	 ERJMP [RETBAD (.NRNPE)]	;ERROR - RETURN
	TXNN T2,TL%EXM+TL%ABR	;MATCH?
	RETBAD (.NRNPE)		;NO
	HRRZ T2,0(T1)		;YES - GET THE FUNCTION CODE
	MOVEM T2,PRSLDV		;AND SAVE
	MOVE T1,T4		;GET STRING POINTING TO CONTROLLER NUMBER
	CALL CVTNUM		;CONVERT CONTROLLER NUMBER
	 RETBAD			;ERROR
	MOVEM T2,PRSCTL		;SAVE
	CALL PRSEND		;ANY MORE?
	 JRST PRSBLD		;NO - BUILD MESSAGE
	CALL CVTNUM		;CONVERT UNIT NUMBER
	 RETBAD			;ERROR
	MOVEM T2,PRSUNT		;SAVE
	CALL PRSEND		;ANY MORE?
	 JRST PRSBLD		;NO - BUILD MESSAGE
	CALL CVTNUM		;CONVERT STATION NUMBER
	 RETBAD			;ERROR
	MOVEM T2,PRSSTN		;SAVE
	CALL PRSEND		;ANY MORE?
	 JRST PRSBLD		;NO - BUILD MESSAGE
	RETBAD			;ERROR - RETURN
PRSBLD:	HRL T3,PRSLDV		;GET DEVICE IDENTIFIER
	HRR T3,PRSCTL		;CONTROLLER NUMBER
	HRL T4,PRSUNT		;UNIT NUMBER
	HRR T4,PRSSTN		;STATION NUMBER
	RETSKP
;CVTNUM - MAKE AN ASCII CHARACTER INTO A NUMBER

;ACCEPTS:	T1/POINTER TO THE STRING

;RETURNS:	+1,ERROR - NOT NUMERIC
;		+2,SUCCESS - T2/NUMBER

CVTNUM:	ILDB T2,T1		;GET THE CHARACTER
	SUBI T2,60		;STRIP THE ASCII  BITS
	CAIG T2,10		;CHECK RANGE
	SKIPGE T2
	RET			;NOT A LEGAL NUMBER
	RETSKP			;A NUMBER

;PRSEND - LOAD BYTE AND CHECK FOR IT BEING ZERO

;ACCEPTS:	T1/BYTE POINTER

;RETURNS:	+1,BYTE WAS ZERO - T1/UPDATED
;		+2,BYTE NOT ZERO - T1/UPDATED

PRSEND:	ILDB T2,T1		;GET THE BYTE
	SKIPN T2			;SKIP IF ZERO
	RET			;ZERO
	RETSKP			;NOT ZERO


; DISPATCH ON OPTION REQUESTED

REQSET:	CALL GETFCN		;GET NICE PROTOCOL FUNCTION CODE
	 RETBAD (.NRIMF)	;FAILED, INVALID MESSAGE FORMAT
	CALL GETOPT		;GET NICE PROTOCOL OPTION CODE
	 RETBAD (.NRIMF)	;FAILED, INVALID MESSAGE FORMAT
	CAIL T4,RSTLEN		;WITHIN RANGE ?
	RETBAD (.NRFNC)		;NO, INVALID OPTION
	CALLRET @RSTTAB(T4)	;DISPATCH BASED ON ITEM REQUESTED

; DISPATCH TABLE FOR SET PARAMETER FUNCTION

RSTTAB:	[RETBAD (.NRFNC)]	;DEFAULT HOST
	[RETBAD (.NRFNC)]	;RECEIVE ACCESS PASSWORD
	[RETBAD (.NRFNC)]	;TRANSMIT ACCESS PASSWORD
	[RETBAD (.NRFNC)]	;LOCAL LOOPBACK
	[RETBAD (.NRFNC)]	;NODE STATE
	[RETBAD (.NRFNC)]	;NODE OPERATOR LOGGING STATE
	[RETBAD (.NRFNC)]	;NODE MAINTENANCE LOGGING STATE
	[RETBAD (.NRFNC)]	;ILLEGAL ????
	LINSTA			;LINE STATE
	[RETBAD (.NRFNC)]	;LINE OPERATOR LOGGING STATE
	[RETBAD (.NRFNC)]	;LINE MAINTENANCE LOGGING STATE
	[RETBAD (.NRFNC)]	;DEFAULT RECEIVE ACCESS PASSWORD
	[RETBAD (.NRFNC)]	;DEFAULT TRANSMIT ACCESS PASSWORD

RSTLEN==.-RSTTAB
SUBTTL	NICE Process -- Set Parameter -- Line State

LINSTA:	STKVAR <<LSTLIN,2>,LSTPRT>
	CALL GETLIN		;GET LINE IDENTIFICATION
	 RETBAD ()		;FAILED, INVALID LINE ID
	DMOVEM T3,LSTLIN	;SAVE LINE ID
	SOSGE T2		;STILL ONE MORE BYTE LEFT ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T1,T1		;GET ANOTHER BYTE
	MOVX T2,LSTTAB		;GET ADDRESS OF DISPATCH TABLE
	MOVX T3,LSTLEN		;GET LENGTH OF DISPATCH TABLE
	CALL FNDDSP		;FIND ENTRY IN DISPATCH TABLE
	 RETBAD (.NRILS)	;FAILED, INVALID LINE STATE
	JRST (T1)		;DISPATCH TO PROCESSING ROUTINE


LSTTAB:	.LSTON,,LSTON
	.LSTOF,,LSTOFF
	.LSTMN,,LSTMNT
	.LSTCN,,LSTCTL
	.LSTCB,,LSTCBL

LSTLEN==.-LSTTAB
; ROUTINES TO SET A LINE STATE

LSTON:	CALL CLRBOT		;CLEAR BOOT JSYS ARG BLOCK
	DMOVE T1,LSTLIN		;GET LINE ID
	CALL LIDPRT		;CONVERT LINE ID TO PORT NUMBER
	 RETBAD ()		;FAILED
	MOVEM T1,LSTPRT		;SAVE PORT NUMBER
	SETOM T4		;SET FLAG NOTING VALID DEVICE NOT YET FOUND
	HLRZ T1,LSTLIN		;GET DEVICE TYPE FOR THIS LINE
	CAIN T1,.DTDTE		;IS IT A DTE20 ?
	MOVX T4,.VNMCB		;YES, USE NSP
	CAIN T1,.DTKDP		;IS IT A KMC/DUP ?
	MOVX T4,.VNDDC		;YES, USE DDCMP
	JUMPL T4,R		;FAIL IF NO VALID DEVICE TYPE FOUND
	MOVE T1,LSTPRT		;GET PORT NUMBER
	MOVE T2,T4		;GET PROTOCOL VERSION NUMBER
	CALL SETLIN		;GO SET LINE STATE
	 RETBAD ()		;FAILED
	RETSKP			;DONE, RETURN SUCCESS

LSTOFF:	CALL CLRBOT		;CLEAR BOOT JSYS ARG BLOCK
	DMOVE T1,LSTLIN		;GET LINE ID
	CALL LIDPRT		;CONVERT LINE ID TO PORT NUMBER
	 RETBAD ()		;FAILED
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK
	MOVEM T1,.BTDTE(T2)	;SAVE PORT NUMBER
	MOVX T1,.BTTPR		;GET "TERMINATE PROTOCOL" FUNCTION
	BOOT			;TURN THE LINE OFF
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET POINTER TO SUCCESS CODE
	MOVNI T3,1		;RETURN CODE IS A SINGLE BYTE
	SOUTR			;SEND BACK THE RETURN CODE
	 ERJMP RSKP		;IF FAILED, NOTHING ELSE TO DO
	RETSKP			;DONE

LSTMNT:	RETBAD (.NRFNC)

LSTCTL:	CALL CLRBOT		;CLEAR BOOT JSYS ARG BLOCK
	DMOVE T1,LSTLIN		;GET LINE ID
	CALL LIDPRT		;CONVERT LINE ID TO PORT NUMBER
	 RETBAD ()		;FAILED
	MOVX T2,.VNCNL		;GET PROTOCOL VERSION FOR CONTROLLER LOOPBACK
	CALLRET SETLIN		;GO SET LINE STATE

LSTCBL:	CALL CLRBOT		;CLEAR BOOT JSYS ARG BLOCK
	DMOVE T1,LSTLIN		;GET LINE ID
	CALL LIDPRT		;CONVERT LINE ID TO PORT NUMBER
	 RETBAD ()		;FAILED
	MOVX T2,.VNCBL		;GET PROTOCOL VERSION FOR CABLE LOOPBACK
	CALLRET SETLIN		;GO SET LINE STATE


; SETLIN - ROUTINE TO SET A LINE ON OR IN LOOPBACK
;
;ACCEPTS IN T1/	PORT NUMBER
;	    T2/	PROTOCOL VERSION NUMBER
;		CALL SETLIN
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, LINE STATE SET

SETLIN:	MOVEI T4,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK
	MOVEM T1,.BTDTE(T4)	;SAVE PORT NUMBER
	MOVEM T2,.BTPRV(T4)	;SAVE PROTOCOL VERSION NUMBER
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK AGAIN
	MOVX T1,.BTIPR		;GET "INITIATE PROTOCOL" FUNCTION
	BOOT			;TURN THE LINE ON
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET POINTER TO SUCCESS CODE
	MOVNI T3,1		;RETURN CODE IS A SINGLE BYTE
	SOUTR			;SEND BACK THE RETURN CODE
	 ERJMP RSKP		;IF FAILED, NOTHING ELSE TO DO
	RETSKP			;DONE
SUBTTL	NICE Process -- Zero Line Counters

REQZRO:	CALL GETFCN		;GET FUNCTION CODE
	 RETBAD (.NRIMF)	;"INVALID MESSAGE FORMAT"
	CALL GETEXB		;GET OPTION FIELD
	 RETBAD ()		;FAILED
	CAIE T4,.NCZLN		;ASKING FOR LINE COUNTS
	 RETBAD (.NRFNC)	;"INVALID FUNCTION"
	CALL GETLIN		;GET LINE-ID FROM MESSAGE
	 RETBAD ()		;FAILED
	JUMPL T3,NRILN		;IN CASE WANTS ALL
	STKVAR <<ZROLID,2>,<ZROBLK,40>>
	DMOVEM T3,ZROLID	;SAVE LINE ID
	DMOVE T1,T3		;COPY LINE-ID TO RIGHT REGISTER
	CALL LIDPRT		;CONVERT LINE-ID TO PORT
	JRST NRILN		;LOSE
	HRLI T1,(BT%ZRO)	;FLAG TO ZERO COUNTERS
	MOVEM T1,.BTPRT+ZROBLK	;PUT PORT IN ARGUMENT BLOCK
	MOVEI T1,20		;MAXIMUM NUMBER OF COUNTERS
	MOVEI T2,20+ZROBLK	;WHERE TO PUT FIRST COUNTERS
	HRLI T2,444400		;MAKE INTO POINTER
	DMOVEM T1,.BTSCC+ZROBLK	;STATUS COUNTERS
	DMOVEM T1,.BTRCC+ZROBLK	;RECEIVE COUNTERS
	DMOVEM T1,.BTTCC+ZROBLK	;TRANSMIT COUNTERS
	MOVEI T1,.BTRLC		;WANT LINE COUNTERS
	MOVEI T2,ZROBLK		;ADDRESS OF ARGUMENT BLOCK
	BOOT
	ERJMP NRILN		;WHY ?
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE(8).NRSUC]]
	MOVNI T3,1		;NUMBER OF BYTES IN MESSAGE
	SOUTR			;SEND RESPONSE
	 ERJMP RSKP		;IF FAILED NOTHING ELSE TO DO
	RETSKP			;WON
SUBTTL	NICE Process -- Line Service Handler

;LINSRV - ROUTINE TO PROCESS REQUESTS FOR LINE SERVICE
;
;ACCEPTS IN T1/	POINTER TO NICE LINE SERVICE REQUEST MESSAGE
;	    T2/	NUMBER OF BYTES IN THE NICE MESSAGE
;		CALL LINSRV
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, FUNCTION PERFORMED

REQLSV:	ASUBR <LSVPTR,LSVCNT>
	STKVAR <LSVOPT,LSVDTE,LSVLTB,LSVCOD>
	SUBI T2,2		;ACCOUNT FOR FUNCTION AND OPTION BITS
	JUMPL T2,[RETBAD (.NRIMF)] ;MAKE SURE ENOUGH BYTES LEFT IN MESSAGE
	IBP T1			;SKIP OVER THE NICE FUNCTION CODE
	ILDB T4,T1		;GET OPTION BYTE FROM THE MESSAGE
	MOVEM T4,LSVOPT		;SAVE OPTION BYTE

; GET THE LINE ID FROM THE MESSAGE AND SET UP LINE TABLE

	CALL GETLIN		;GO GET THE LINE ID
	 RETBAD ()		;FAILED, RETURN ERROR CODE TO CALLER
	MOVEM T1,LSVPTR		;SAVE POINTER TO NEXT FIELD IN MESSAGE
	MOVEM T2,LSVCNT		;SAVE # OF BYTES REMAINING IN THE MESSAGE
	CALL CHKLIN		;GO CHECK LINE ID AND GET DTE20 NUMBER
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T1,LSVDTE		;SAVE DTE20 NUMBER
	IMULI T1,LTBSIZ		;COMPUTE STARTING ADDRESS OF LINE
	MOVEI T1,LINTAB(T1)	; TABLE FOR THIS LINE
	MOVEM T1,LSVLTB		;SAVE LINE TABLE ADDRESS
	MOVE T2,LSVDTE		;GET DTE20 NUMBER
	STOR T2,LNDTE,(T1)	;STORE DTE20 IN LINE TABLE
	CALL ASGPAG		;GET A PAGE TO USE FOR DATA
	 RETBAD (.NRRES)	;RETURN "RESOURCE ERROR" RETURN CODE
	MOVE T4,LSVLTB		;GET LINE TABLE ADDRESS
	HRLI T2,(POINT 8,)	;FORM POINTER TO MESSAGE AREA
	STOR T2,LNMSG,(T4)	;SAVE POINTER TO MESSAGE AREA IN LINE TABLE
	ACLOCK (T4)		;LOCK THIS LINE TABLE (ADDRESS IN T4)
	; ..
	; ..

; LOOP OVER LINE SERVICE TABLE LOOKING FOR THE REQUESTED OPTION

	MOVE T3,[-LSVSIZ,,LSVTAB] ;SET UP TOO LOOP THROUGH LINE SERVICE TABLE
	MOVE T4,LSVOPT		;RESTORE OPTION REQUESTED
LSV010:	HLRZ T1,(T3)		;GET OPTION FROM TABLE
	CAMN T1,T4		;FOUND DESIRED OPTION ?
	JRST LSV020		;YES, GO DISPATCH TO SERVICE ROUTINE
	AOBJN T3,LSV010		;LOOP OVER LINE SERVICE TABLE
	MOVX T1,.NRFNC		;FAILED, GET "INVALID OPTION" NICE RETURN CODE
	JRST LSVERR		;GO RELEASE FREE SPACE AND RETURN

; HERE TO DISPATCH TO SERVICE ROUTINE

LSV020:	MOVEI T1,.FHSLF		; Before dispatch point to this process
	MOVEI T2,0102		;  and put it into scheduler Q1
	SPRIW

	SETZM LSVCOD		;INITIALIZE ERROR FLAG
	HRRZ T4,(T3)		;GET SERVICE ROUTINE ADDRESS
	MOVE T3,LSVLTB		;GET ADDRESS OF LINE TABLE
	MOVE T2,LSVCNT		;GET NUMBER OF BYTES LEFT IN MESSAGE
	MOVE T1,LSVPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	CALL (T4)		;GO HANDLE REQUESTED FUNCTION
LSVERR:	 MOVEM T1,LSVCOD	;SAVE ERROR CODE
	MOVE T4,LSVLTB		;GET LINE TABLE ADDRESS
	ACUNLOCK (T4)		;UNLOCK THE LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET ADDRESS OF MESSAGE AREA
	HRRZ T1,T1		;KEEP JUST THE ADDRESS
	CALL RELPGA		;RELEASE FREE PAGE
	 RETBAD (.NRRES)	;RETURN "RESOURCE ERROR" RETURN CODE
	SKIPN T1,LSVCOD		;ANY ERROR ?
	RETSKP			;NO, SUCCESS, DONE.
	RETBAD ()		;YES, RETURN ERROR CODE



LSVTAB:	.LSLOD,,LSLOD		;INITIATE A LOAD DIALOG
	.LSDMP,,LSDMP		;INITIATE A DUMP DIALOG
	.LSTBT,,LSTBT		;TRIGGER BOOTSTRAP, NO PROGRAM DATA
	.LSTBP,,LSTBP		;TRIGGER BOOTSTRAP, RETURN PROGRAM DATA

	LSVSIZ==.-LSVTAB	;SIZE OF LINE SERVICE DISPATCH TABLE
;LSLOD - LINE SERVICE ROUTINE TO INITIATE A DOWN-LINE LOAD DIALOG
;
;ACCEPTS IN T1/	POINTER TO PARAMETERS IN NICE LINE SERVICE MESSAGE
;	    T2/	NUMBER OF BYTES LEFT IN MESSAGE
;	    T3/	ADDRESS OF LINE TABLE FOR THIS OPERATION
;		CALL LSLOD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, DIALOG INITIATED

LSLOD:	ASUBR <LSLPTR,LSLCNT,LSLLIN,LSLPGM>

; GET AND CHECK THE PROGRAM TYPE BEING LOADED

	SOJN T2,[RETBAD (.NRIMF)] ;FAIL IF NOT EXACTLY ONE BYTE LEFT IN MESSAGE
	ILDB T3,T1		;GET THE PROGRAM TYPE FROM THE MESSAGE
	MOVEM T3,LSLPGM		;SAVE PROGRAM TYPE
	CAIL T3,.PTSLD		;A VALID PROGRAM TYPE
	CAILE T3,.PTOPS		; BEING LOADED ?
	RETBAD (.NRIPV)		;NO, RETURN "INVALID PARAMETER VALUE"
	MOVE T4,LSLLIN		;GET ADDRESS OF LINE TABLE
	STOR T3,LNPGM,(T4)	;SAVE TYPE OF PROGRAM BEING LOADED
	SETZRO LNLDN,(T4)	;INITIALIZE FIRST LOAD NUMBER TO USE
	MOVE T1,REQLNK		;YES, GET LOGICAL LINK TO REQUESTOR
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET POINTER TO SUCCESS RETURN CODE
	MOVNI T3,1		;RESPONSE MESSAGE IS ONE BYTE RETURN CODE
	SOUTR			;OUTPUT THE RETURN CODE
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	; ..
	; ..

; DIALOG MESSAGE LOOP.  THE BASIC SEQUENCE OF OPERATIONS IS TO RECEIVE
; A NICE LINE SERVICE DIALOG MESSAGE FROM THE REQUESTING TASK, AND THEN
; TO PERFORM THE SPECIFIED OPERATION.  THIS IS REPEATED UNTIL THE DIALOG
; MESSAGE RECEIVED IS "END-OF-DIALOG", AT WHICH TIME THE LINE SERVICE
; OPERATION IS COMPLETE AND CONTROL RETURNS TO THE NICE DISPATCHER.


; WAIT FOR A DIALOG MESSAGE FROM THE REQUESTOR

LSLOD1:	CALL CLRMSG		;GO CLEAR THE MESSAGE AREA
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN)
	MOVEI T2,MSGBLK		;GET ADDRESS OF MESSAGE BLOCK
	HRLI T2,(POINT 8,)	;FORM POINTER TO WHERE MESSAGE IS TO GO
	MOVNI T3,MSGSIZ*BPWRD	;GET MAX NUMBER OF BYTES
	SINR			;WAIT FOR A DIALOG MESSAGE FROM REQUESTOR
	 ERJMP [RETBAD (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; DISPATCH BASED ON TYPE OF DIALOG MESSAGE RECEIVED

	MOVEI T2,MSGSIZ*BPWRD(T3) ;GET NUMBER OF BYTES IN THE MESSAGE
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	SOSGE T2		;AT LEAST ONE BYTE IN THE DIALOG MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T4,T1		;GET TYPE CODE FROM MESSAGE
	CAIL T4,.LMEND		;IS THIS A VALID DIALOG
	CAILE T4,.LMXFR		; MESSAGE TYPE CODE ?
	RETBAD (.NRFNC)		;NO, RETURN "INVALID FUNCTION" ERROR
	MOVE T3,LSLLIN		;GET ADDRESS OF LINE TABLE
	CALL @DLGTAB(T4)	;YES, DISPATCH TO PROCESSING ROUTINE
	 JRST [	CALL SNDEND	;FAILED, GO SEND END-OF-DIALOG MESSAGE
		RETSKP ]	;DONE, RETURN
	SKIPE T1		;ARE WE STILL IN THE LOAD DIALOG ?
	RETSKP			;NO, LOAD COMPLETE, RETURN SUCCESS
	JRST LSLOD1		;SUCCESS, WAIT FOR NEXT DIALOG MESSAGE

; TABLE OF DIALOG MESSAGE SERVICE ROUTINES

DLGTAB:	RSKP			; 0 END OF DIALOG
	DIABAS			; 1 SET BASE ADDRESS
	DIAMEM			; 2 MEMORY IMAGE DATA
	DIAXFR			; 3 PARAMETERS AND TRANSFER ADDRESS
;DIABAS - SET BASE ADDRESS DIALOG MESSAGE RECEIVED
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA (BASE ADDRESS)
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL DIABAS
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, BASE ADDRESS FOR NEXT LOAD IMAGE SET

DIABAS:	STKVAR <BASLIN>
	MOVEM T3,BASLIN		;SAVE LINE TABLE ADDRESS
	CALL GETMEM		;GO EXTRACT LOAD ADDRESS FROM MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR CODE TO CALLER
	MOVE T4,BASLIN		;GET ADDRESS OF LINE TABLE
	STOR T3,LNADR,(T4)	;STORE BASE ADDRESS IN LINE TABLE
	SETZM T1		;NOTE THAT WE ARE STILL IN LOAD DIALOG
	RETSKP			;DONE, RETURN SUCCESS


;DIAMEM - ROUTINE TO PROCESS A MEMORY IMAGE DIALOG MESSAGE
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA IN LINE SERVICE MESSAGE
;	    T2/	NUMBER OF BYTES LEFT IN MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL DIAMEM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, DATA LOADED OR ADDED TO LOAD IMAGE

DIAMEM:	ASUBR <MEMPTR,MEMCNT,MEMLIN>

	SOSGE MEMCNT		;AT LEAST ONE BYTE IN THE MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT"
	ILDB T4,MEMPTR		;YES, GET CPU TYPE CODE (.CPXXX)
	CAIE T4,.CP11		;PDP-11 ?
	RETBAD (.NRIPV)		;NO, RETURN "INVALID PARAMETER VALUE" ERROR

; DETERMINE IF A SECONDARY LOADER IS BEING LOADED - IF SO, ADD THE MEMORY
; DATA TO THE CORE IMAGE BEING BUILT IN MEMORY. ELSE, SEND THE MEMORY IMAGE
; ACROSS THE DTE-20 TO THE LOADER IN THE TARGET NODE.

	MOVE T4,MEMLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNPGM,(T4)	;GET PROGRAM TYPE BEING LOADED (.PTXXX)
	CAIE T1,.PTSLD		;SECONDARY LOADER ?
	JRST MEM010		;NO, GO SEND DATA ACROSS DTE20 TO TARGET NODE
	MOVE T1,MEMPTR		;YES, GET POINTER TO MEMORY IMAGE DATA
	MOVE T2,MEMCNT		;GET NUMBER OF BYTES OF DATA
	MOVE T3,MEMLIN		;GET ADDRESS OF LINE TABLE
	CALL MOPLDR		;GO ADD DATA TO IMAGE BEING BUILT
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	SETZM T1		;NOTE THAT WE ARE STILL IN LOAD DIALOG
	RETSKP			;DONE, MEMORY IMAGE DATA HANDLED
; HERE TO SEND LOAD IMAGE DATA ACROSS THE DTE20 AND RECEIVE THE REPLY
; FIRST, BUILD THE MOP "LOAD IMAGE" MESSAGE

MEM010:	MOVE T1,MEMPTR		;GET POINTER TO MEMORY IMAGE DATA IN NICE MSG
	MOVE T2,MEMCNT		;GET NUMBER OF MEMORY IMAGE DATA BYTES
	MOVE T3,MEMLIN		;GET ADDRESS OF LINE TABLE
	CALL MAKMPL		;GO ASSEMBLE A MOP "LOAD-WITHOUT-TRANSFER" MSG
	 RETBAD (.NRNPE)	;FAILED, NICE PROCESS PROGRAM ERROR

; SEND THE MOP MESSAGE ACROSS THE DTE20 AND RECEIVE THE REPLY MOP MESSAGE

	MOVE T1,MEMLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESND		;GO SEND THE DATA ACROSS THE DTE20
	 RETBAD (.NRCME)	;FAILED, RETURN "COMMUNICATIONS ERROR"
	MOVE T1,MEMLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;RECEIVE THE REPLY MOP MESSAGE FROM THE LOADER
	 RETBAD (.NRCME)	;FAILED, RETURN "COMMUNICATIONS ERROR"

; CHECK THE MOP MESSAGE RECEIVED. SHOULD BE "REQUEST NEXT LOAD"

	MOVE T3,MEMLIN		;GET ADDRESS OF LINE TABLE
	CALL CHKMOP		;GO CHECK MOP MESSAGE AND UPDATE LOAD NUMBER
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	SETZM T1		;NOTE THAT WE ARE STILL IN LOAD DIALOG
	RETSKP			;DONE, RETURN SUCCESS.
;DIAXFR - ROUTINE TO PROCESS A "TRANSFER" DIALOG MESSAGE
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA (PARAMETERS AND TRANSFER ADDRESS)
;	    T2/	NUMBER OF BYTES LEFT IN DIALOG MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL DIAXFR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, PROGRAM IN TARGET NODE STARTED AND PARAMETERS SENT

DIAXFR:	ASUBR <XFRPTR,XFRCNT,XFRLIN,XFRADR>

; EXTRACT THE SYSTEM PARAMETERS AND TRANSFER ADDRESS FROM THE MESSAGE

	CALL GETPAR		;GET PARAMETERS FROM THE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	CALL GETMEM		;GO GET THE TRANSFER ADDRESS FROM THE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,XFRADR		;SAVE TRANSFER ADDRESS

; IF LOADING A SECONDARY LOADER, SEND THE LOADER ACROSS THE DTE20

	MOVE T4,XFRLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNPGM,(T4)	;GET PROGRAM TYPE BEING LOADED (.PTXXX)
	CAIE T1,.PTSLD		;LOADING A SECONDARY LOADER ?
	JRST XFR010		;NO, GO SEND A MOP "TRANSFER" MESSAGE

; LOAD THE SECONDARY BOOTSTRAP AND WAIT FOR A PROGRAM REQUEST

	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESLD		;GO LOAD THE SECONDARY BOOTSTRAP
	 RETBAD (.NRCME)	;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;GO RECEIVE A MOP MESSAGE FROM THE TARGET NODE
	 RETBAD (.NRCME)	;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; CHECK MOP MESSAGE AND RETURN PROGRAM REQUEST TO THE TASK THAT INITIATED
; THE LOAD DIALOG.

	MOVE T3,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL MAKEND		;GO CHECK MOP MESSAGE AND ASSEMBLE AN
				; END-OF-DIALOG NICE LINE SERVICE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	JRST XFR030		;SEND THE "END-OF-DIALOG" AND WAIT FOR ESPONSE
	;...
	;...

; HERE TO ASSEMBLE AND SEND A MOP "PARAMETERS AND TRANSFER" MESSAGE

XFR010:	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	MOVE T2,XFRADR		;GET TRANSFER ADDRESS
	CALL MAKMLP		;GO MAKE A MOP LOAD-PARAMETERS AND TRANSFER MSG
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVE T4,XFRLIN		;GET ADDRESS OF LINE TABLE
	STOR T1,LNMSG,(T4)	;STORE POINTER TO MOP MESSAGE
	STOR T2,LNCNT,(T4)	;STORE SIZE OF MOP MESSAGE
	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESND		;GO SEND THE MESSAGE ACROSS THE DTE20
	 RETBAD (.NRCME)	;FAILED, RETURN "COMMUNICATIONS ERROR"

; RECEIVE THE REPLY MESSAGE FROM THE LOADER IN THE TARGET NODE

	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;GO RECEIVE A MOP MESSAGE FROM THE TARGET NODE
	 RETBAD (.NRCME)	;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; VERIFY THE RESPONSE FROM THE TARGET NODE

	MOVE T3,XFRLIN		;GET ADDRESS OF LINE TABLE
	LOAD T4,LNPGM,(T3)	;GET TYPE OF PROGRAM BEING LOADED
	CAIE T4,.PTOPS		;LOADING AN OPERATING SYSTEM ?
	JRST [	CALL MOPVER	;NO, GO CHECK THAT REPLY IS A PROGRAM REQ MSG
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		JRST XFR030 ]	;GO SEND END-OF-DIALOG MESSAGE TO REQUESTOR

; HERE IF LOADING AN OPERATING SYSTEM - CHECK FINAL MOP LOAD REQUEST MESSAGE

	CALL CHKMOP		;GO CHECK THE MOP "REQUEST LOAD" MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVE T1,XFRLIN		;GET ADDRESS OF LINE TABLE
	CALL INIPRO		;GO INITIATE PROTOCOL ON THIS LINE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T4,[POINT 8,MSGBLK] ;GET POINTER TO MOP MESSAGE
	MOVX T1,.LMEND		;GET "END-OF-DIALOG" TYPE CODE
	IDPB T1,T4		;PUT TYPE CODE INTO REPLY MESSAGE
	MOVX T1,.NRSUC		;GET GENERAL SUCCESS CODE
	IDPB T1,T4		;ADD RETURN CODE TO END-OF-DIALOG MESSAGE
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO NICE MESSAGE
	MOVX T2,2		;MESSAGE CONTAINS ONLY TWO BYTES

; HERE TO SEND "END-OF-DIALOG" MESSAGE BACK TO REQUESTING TASK

XFR030:	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;COPY POINTER TO MESSAGE
	MOVE T1,REQLNK		;GET LINK TO REQUESTING TASK
	SOUTR			;SEND MESSAGE TO REQUESTING TASK
	 ERJMP [RETBAD (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	;...
	;...

; PROGRAM LOAD COMPLETE - WAIT FOR END OF DIALOG MESSAGE FROM SERVER NCU

	CALL CLRMSG		;CLEAR THE MESSAGE AREA
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN)
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO WHERE MESSAGE SHOULD GO
	MOVNI T3,MAXNIC		;GET -MAX COUNT
	SINR			;INPUT THE REPLY FROM THE SERVER NODE NCU
	 ERJMP [LODERR (.NRCME)] ;IF FAILED, RETURN "COMMUNICATIONS ERROR"

; VERIFY THAT RESPONSE WAS "END OF DIALOG"

	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF REPLY MESSAGE
	MOVEI T2,MAXNIC(T3)	;COMPUTE NUMBER OF BYTES RETURNED
	SUBI T2,2		;DECREMENT COUNT FOR TYPE CODE AND RETURN CODE
	JUMPL T2,[RETBAD (.NRPRO)] ;RETURN "PROTOCOL ERROR" IF NOT ENOUGH BYTES
	ILDB T4,T1		;YES, GET DIALOG MESSAGE TYPE CODE (.LSXXX)
	CAIE T4,.LMEND		;END OF DIALOG REPLY ?
	LODERR (.NRPRO)		;NO, NICE PROTOCOL ERROR
	ILDB T4,T1		;GET RETURN CODE
	CAIE T4,.NRSUC		;SUCCESS ?
	JRST [	MOVE T1,T4	;NO, GET RETURN CODE FROM SERVER NCU
		LODERR () ]	;RETURN THE CODE TO CALLER
	SETOM T1		;NOTE THAT WE ARE NO LONGER IN LOAD DIALOG
	RETSKP			;DONE, RETURN.
;MOPVER - ROUTINE TO VERIFY MOP REPLY MESSAGE AFTER TRANSFER MSG SENT
;
;ACCEPTS IN T1/	POINTER TO START OF MOP REPLY MESSAGE
;	    T2/	COUNT OF BYTES IN THE MOP MESSAGE
;	    T3/ ADDRESS OF LINE TABLE
;		CALL MOPVER
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF NICE REPLY MSG
;			      T2/ COUNT OF BYETS IN NICE MESSAGE

MOPVER:	ASUBR <MPVPTR,MPVCNT,MPVLIN,MPVMSG>
	STKVAR <MPVLNK,MPVLEN>

; DETERMINE IF THE MOP PROGRAM REQUEST MSG IS PRECEDED BY DIAGNOSTIC DATA

	MOVE T2,MPVCNT		;GET COUNT OF BYTES IN MOP MESSAGE
	SOSGE T2		;AT LEAST FUNCTION CODE PRESENT ?
	RETBAD (.NRIMF)		;NO, ILLEGAL MESSAGE FORMAT
	MOVE T1,MPVPTR		;GET POINTER TO START OF MOP MESSAGE
	ILDB T4,T1		;GET MOP FUNCTION CODE
	CAIN T4,.MPRQP		;PROGRAM REQUEST ?
	JRST MPV030		;YES, GO PROCESS IT
	CAIE T4,.MPDIA		;DIAGNOSTIC DATA ?
	RETBAD (.NRLPE)		;NO, LINE PROTOCOL ERROR

; HERE IF THERE IS ASCII DIAGNOSTIC DATA TO RETURN TO THE HOST FROM CHK11

	CALL ASGPAG		;GET A PAGE FOR THE ASCII DATA
	 RETBAD ()		;FAILED
	MOVEM T2,MPVMSG		;SAVE MESSAGE ADDRESS
	HRLI T2,(POINT 8,)	;FORM POINTER TO MESSAGE DESTINATION
	MOVE T1,T2		;COPY POINTER TO MESSAGE DESTINATION
	MOVX T2,.EVASC		;GET CODE FOR ASCII DATA
	CALL MAKEVT		;ASSEMBLE AN EVENT LOGGING MESSAGE HEADER
	 JRST MPVERR		;FAILED, RELEASE LINK AND RETURN ERROR
	MOVEM T2,MPVLEN		;SAVE INITIAL LENGTH OF NICE MESSAGE
	CALL REPLNK		;GET LINK TO NICE PROCESS ON HOST SYSTEM
	 JRST MPVERR		;FAILED
	MOVEM T1,MPVLNK		;SAVE LOGICAL LINK ID
	MOVE T2,MPVMSG		;GET ADDRESS OF NICE MESSAGE
	HRLI T2,(POINT 8,)	;FORM POINTER TO NICE MESSAGE
	MOVN T3,MPVLEN		;GET -COUNT
	SOUT			;SEND FIRST PART OF NICE MESSAGE TO HOST NCU
	 ERJMP [MOVE T1,MPVLNK	;FAILED, GET LOGICAL LINK
		TXO T1,CZ%ABT	;CLOSE THE LOGICAL LINK
		CLOSF		;CLOSE THE LOGICAL LINK
		 NON.FATAL.ERROR
		MOVX T1,.NRNCE	;GET ERROR CODE
		JRST MPVERR ]	;GO RELEASE ASSIGNED PAGE

; SEND ALL THE DIAGNOSTIC DATA BACK TO THE HOST

	MOVE T1,MPVPTR		;GET POINTER TO MOP MESSAGE
	MOVE T2,MPVCNT		;GET COUNT OF BYTES IN MOP MESSAGE
	MOVE T3,MPVLIN		;GET ADDRESS OF LINE TABLE
	MOVE T4,MPVLNK		;GET LOGICAL LINK TO LOGGING NICE PROCESS
	CALL SNDTXT		;GO SEND BACK THE TEXT TO THE HOST
	 JRST [	MOVE T1,STXLNK	;FAILED, GET LOGICAL LINK
		TXO T1,CZ%ABT	;FLUSH ANYTHING IN PIPE
		CLOSF		;CLOSE THE LOGICAL LINK
		 NON.FATAL.ERROR
		MOVX T1,.NRNCE	;GET ERROR CODE
		JRST MPVERR ]	;GO RELEASE ASSIGNED PAGE
	MOVEM T1,MPVPTR		;SAVE POINTER TO MOP MESSAGE
	MOVEM T2,MPVCNT		;SAVE COUNT OF BYTES IN MOP MESSAGE

; HERE WHEN ALL DIAGNOSTIC DATA HAS BEEN RETURNED TO THE HOST

MPV020:	MOVE T1,MPVLNK		;GET LOGICAL LINK
	CLOSF			;CLOSE THE LINK WHEN ALL DATA AWAY OK
	 NON.FATAL.ERROR	;FAILED, ISSUE MESSAGE
	MOVE T1,MPVMSG		;GET ADDRESS OF ASSIGNED PAGE
	CALL RELPGA		;RELEASE THE PAGE
	 NON.FATAL.ERROR	;FAILED

MPV030:	MOVE T1,MPVPTR		;GET POINTER TO MOP MESSAGE
	MOVE T2,MPVCNT		;GET NUMBER OF BYTES IN MOP MESSAGE
	MOVE T3,MPVLIN		;GET ADDRESS OF LINE TABLE
	CALL MAKEND		;CHECK MOP PROGRAM REQ MSG AND MAKE NICE MSG
	 RETBAD ()		;FAILED
	RETSKP			;DONE, RETURN SUCCESS

; HERE ON AN ERROR WITH A PAGE ASSIGNED

MPVERR:	EXCH T1,MPVMSG		;GET ADDRESS OF MESSAGE PAGE
	CALL RELPGA		;RELEASE THE PAGE
	 NON.FATAL.ERROR	;FAILED
	MOVE T1,MPVMSG		;RESTORE ERROR CODE
	RETBAD ()		;FAIL
;SNDTXT - ROUTINE TO RETURN CHK11 DIAGNOSTIC TEXT TO THE HOST NICE PROCESS
;
;ACCEPTS IN T1/	POINTER TO MOP MESSAGE
;	    T2/	NUMBER OF BYTES LEFT IN MOP MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;	    T4/	LOGICAL LINK TO HOST NICE PROCESS
;		CALL SNDTXT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO MOP MESSAGE
;			      T2/ COUNT OF BYTES IN MOP MESSAGE

SNDTXT:	ASUBR <STXPTR,STXCNT,STXLIN,STXLNK>

; LOOP TO SEND ASCII DATA BACK TO THE NICE PROCESS FOR LOGGING

STX010:	MOVE T1,STXLNK		;GET LOGICAL LINK TO HOST NICE LOGGER
	MOVX T2,.EDTXT		;GET ASCII DATA TYPE CODE
	BOUT			;SEND ASCII DATA TYPE CODE
	 ERJMP [RETBAD (.NRNCE)] ;FAILED, NETWORK COMMUNICATIONS ERROR
	MOVE T2,STXCNT		;GET COUNT OF BYTES IN MOP MESSAGE
	SUBI T2,1		;ALLOW FOR MOP FUNCTION CODE
	CAILE T2,^D255		;GREATER THAN MAX IMAGE ASCII FIELD SIZE ?
	RETBAD (.NRIMF)		;YES, FAIL, INVALID MESSAGE FORMAT
	BOUT			;SEND BACK COUNT BYTE FOR IMAGE ASCII FIELD
	 ERJMP [RETBAD (.NRNCE)] ;FAILED, NETWORK COMMUNICATIONS ERROR
	MOVN T3,T2		;GET -COUNT
	MOVE T2,STXPTR		;GET POINTER TO START OF MOP MESSAGE
	ILDB T4,T2		;SKIP FUNCTION CODE, POINT TO START OF DATA
	SOUTR			;SEND THE DATA BACK TO THE LOGGER
	 ERJMP [RETBAD (.NRNCE)] ;FAILED, NETWORK COMMUNICATIONS ERROR

; READ ANOTHER MOP MESSAGE

	MOVE T1,STXLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;GO RECEIVE A MOP MESSAGE FROM THE TARGET NODE
	 RETBAD (.NRCME)	;RETURN "COMMUNICATIONS ERROR" ON FAILURE
	MOVEM T1,STXPTR		;SAVE POINTER TO MOP MESSAGE
	MOVEM T2,STXCNT		;SAVE COUNT OF BYTES IN MOP MESSAGE

; SEE IF THERE IS MORE DIAGNOSTIC DATA

	MOVE T2,STXCNT		;GET COUNT OF BYTES IN MOP MESSAGE
	SOSGE T2		;AT LEAST FUNCTION CODE PRESENT ?
	RETBAD (.NRIMF)		;NO, ILLEGAL MESSAGE FORMAT
	MOVE T1,STXPTR		;GET POINTER TO START OF MOP MESSAGE
	ILDB T4,T1		;GET MOP FUNCTION CODE
	CAIN T4,.MPRQP		;PROGRAM REQUEST ?
	JRST [	MOVE T1,STXPTR	;GET POINTER TO MOP MESSAGE
		MOVE T2,STXCNT	;GET NUMBER OF BYTES IN MESSAGE
		RETSKP ]	;RETURN SUCCESS
	CAIE T4,.MPDIA		;DIAGNOSTIC DATA ?
	RETBAD (.NRLPE)		;NO, LINE PROTOCOL ERROR
	JRST STX010		;YES, GO SEND THE DATA BACK TO THE HOST
;REPLNK - ROUTINE TO GET A LOGICAL LINK TO A PROCESS ON THE SAME NODE
;	    THAT ORIGINATED A NICE REQUEST.
;
;CALL:		CALL REPLNK
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ JFN FOR LOGICAL LINK

REPLNK:	STKVAR <RPLHST,RPLLNK>

; GET HOST NAME OF TASK ORIGINALLY REQUESTING SERVICE FROM US

	HRROI T3,RPLHST		;GET POINTER TO DESTINATION FOR STRING
	MOVX T2,.MORHN		;GET "READ HOST NAME" FUNCTION
	MOVE T1,REQLNK		;GET LOGICAL LINK TO REQUESTING TASK
	MTOPR			;ADD HOST NAME TO STRING
	 ERJMP [RETBAD (.NRNPE)] ;FAILED, RETURN ERROR

; GET A LOGICAL LINK TO THE NCU ON THE REQUESTING HOST

	HRRI T1,RPLHST		;GET ADDRESS OF HOST NAME
	HRLI T1,(POINT 7,)	;FORM POINTER TO HOST NAME
	CALLRET GETLNK		;GO GET A LOGICAL LINK TO THE NCU
;LSTBT - ROUTINE TO PROCESS A NICE LINE SERVICE MESSAGE TO TRIGGER THE
;	  BOOTSTRAP ROM IN AN ADJACENT TARGET NODE.
;
;ACCEPTS IN T1/	POINTER TO PARAMETERS IN NICE LINE SERVICE MSG (BOOT PASSWORD)
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL LSTBT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, BOOTSTRAP ROM TRIGGERED

LSTBT:	TDZA T4,T4		;NOTE THAT NO PROGRAM DATA WAS REQUESTED
LSTBP:	SETOM T4		;PROGRAM DATA IS WANTED
	STKVAR <LSTLIN,LSTFLG,<LSTBPW,2>>
	MOVEM T3,LSTLIN		;SAVE LINE TABLE ADDRESS
	MOVEM T4,LSTFLG		;SAVE FLAG INDICATING WHICH TYPE OF CALL
	CALL GETBPW		;GO EXTRACT THE BOOT PASSWORD FROM THE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	DMOVEM T3,LSTBPW	;SAVE BOOT PASSWORD

; CHECK THE BOOT PASSWORD FOR THIS TARGET NODE

; ACTIVATE (TRIGGER) THE ROM IN THE TARGET NODE

	MOVE T1,LSTLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESTP		;TERMINATE ANY PROTOCL RUNNING ON THE TARGET
	 RETBAD (.NRLPE)	;FAILED, RETURN "LINE PROTOCOL ERROR"
	MOVE T1,LSTLIN		;GET ADDRESS OF LINE TABLE
	CALL DTEINI		;GO TRIGGER THE ROM
	 RETBAD (.NRLPE)	;FAILED, RETURN 'LINE PROTOCOL ERROR'

; SEND BACK A "SUCCESS" RETURN CODE TO THE REQUESTING TASK

	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET POINTER TO RETURN CODE
	MOVNI T3,1		;ONE BYTE MESSAGE
	SOUTR			;RETURN THE SUCCESS CODE
	 ERJMP [RETBAD (.NRCME)] ;RETURN "COMMUNICATIONS ERROR" ON FAILURE

; IF NO PROGRAM DATA WANTED, RETURN, ELSE SEND BACK THE PROGRAM DATA

	SKIPN LSTFLG		;PROGRAM DATA WANTED ?
	RETSKP			;DONE, RETURN SUCCESS
	MOVE T1,REQLNK		;YES, GET LOGICAL LINK TO REQUESTING TASK
	MOVE T2,[POINT 8,[ BYTE (8) .DTDTE, .CP11, .PTSLD, 0 ]]
	MOVNI T3,4		;NUMBER OF BYTES OF PROGRAM DATA
	SOUTR			;SEND BACK THE PROGRAM DATA
	 ERJMP [RETBAD (.NRCME)] ;RETURN "'COMMUNICATIONS ERROR' ON FAILURE
	RETSKP			;DONE, RETURN
;MOPLDR - ROUTINE TO ADD BYTES TO A LOAD IMAGE BEING CONSTRUCTED
;	    FOR A SECONDARY LOADER
;
;ACCEPTS IN T1/	POINTER TO MEMORY IMAGE DATA TO BE LOADED
;	    T2/	NUMBER OF BYTES OF MEMORY IMAGE DATA
;	    T3/	ADDRESS OF LINE TABLE
;		CALL MOPLDR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, DATA ADDED TO LOAD IMAGE

MOPLDR:	ASUBR <MLDPTR,MLDCNT,MLDLIN>
	STKVAR <MLDCTR,MLDPTB>

; SET UP WORD CONTAINING ADDRESS OF BYTE POINTER TABLE TO USE

	MOVE T1,MLDLIN		;GET ADDRESS OF LINE TABLE ENTRY
	LOAD T1,LNPGM,(T1)	;GET PROGRAM TYPE BEING LOADED
	MOVSI T4,-PTRSIZ	;SET UP TO FIND CORRECT BYTE POINTER TABLE
LODM10:	HLRZ T2,PTRTAB(T4)	;GET A PROGRAM TYPE FROM THE TABLE
	CAMN T2,T1		;FOUND TYPE OF PROGRAM BEING LOADED ?
	JRST LODM20		;YES, GO GET ADDRESS OF BYTE POINTER TABLE
	AOBJN T4,LODM10		;NO, LOOP OVER ALL PROGRAM TYPES
	RETBAD (.NRIPV)		;FAILED, RETURN ERROR TO CALLER

; GET THE ADDRESS OF THE BYTE POINTER TABLE

LODM20:	HRRZ T1,PTRTAB(T4)	;GET ADDRESS OF BYTE POINTER TABLE TO USE
	MOVEM T1,MLDPTB		;SAVE POINTER TABLE ADDRESS

; SET UP AN INDEX INTO BYTE POINTER TABLE AND OFFSET INTO LOAD IMAGE

	MOVE T4,MLDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNADR,(T4)	;GET LOAD ADDRESS FOR THIS DATA
	IDIVI T1,BPWRD		;COMPUTE OFFSET INTO LOAD IMAGE
	MOVE T4,MLDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T4,LNMSG,(T4)	;GET POINTER TO MOP MESSAGE BLOCK FOR THIS LINE
	ADD T1,T4		;COMPUTE ADDRESS TO START LOADING AT
	MOVEM T1,T3		;SAVE LOADING ADDRESS
	MOVEM T2,MLDCTR		;SAVE INDEX INTO BYTE POINTER TABLE
	; ..
	; ..

; DEPOSIT THE DATA BYTES INTO THE LOAD IMAGE RECORD
; (T3 HAS THE DESTINATION ADDRESS & THE BYTE POINTERS ARE INDEXED BY T3)

	HRRZ T4,MLDCNT		;GET NUMBER OF DATA BYTES TO DEPOSIT
	JUMPE T4,RSKP		;DONE IF NO DATA TO BE LOADED
LODM30:	ILDB T1,MLDPTR		;GET A DATA BYTE FROM THE DIALOG MESSAGE
	LDB T2,[POINT 2,MLDCTR,35] ;GET INDEX INTO BYTE POINTER TABLE
	ADD T2,MLDPTB		;FORM ADDRESS OF A BYTE POINTER
	DPB T1,(T2)		;DEPOSIT THE BYTE
	AOS T2,MLDCTR		;INCREMENT THE INDEX COUNTER
	TXNN T2,3		;INCREMENTED TO FIRST BYTE OF NEXT WORD ?
	ADDI T3,1		;YES, INCREMENT DESTINATION ADDRESS
	SOJG T4,LODM30		;LOOP OVER ALL DATA BYTES IN MESSAGE

; UPDATE THE NEXT LOAD ADDRESS TO USE

	MOVE T4,MLDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNADR,(T4)	;GET ADDRESS USED TO LOAD THIS DATA
	ADD T1,MLDCNT		;FORM NEXT ADDRESS TO USE
	STOR T1,LNADR,(T4)	;STORE NEXT BASE ADDRESS
	RETSKP			;DONE, RETURN SUCCESS
;CHKMOP - ROUTINE TO CHECK A MOP "REQUEST LOAD" MESSAGE AND UPDATE THE
;	    NEXT LOAD NUMBER EXPECTED.
;
;ACCEPTS IN T1/	POINTER TO START OF MOP MESSAGE
;	    T2/	NUMBER OF BYTES IN THE MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL CHKMOP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, MESSAGE IS OK AND NEXT LOAD # IS UPDATED

CHKMOP:	ASUBR <CKMPTR,CKMCNT,CKMLIN>

	SUBI T2,2		;AT LEAST FUNCTION AND LOAD # PRESENT ?
	JUMPL T2,[RETBAD (.NRCME)] ;IF NOT, RETURN "COMMUNICATIONS ERROR"
	ILDB T4,CKMPTR		;GET MOP FUNCTION CODE
	CAIE T4,.MPRQL		;REQUEST MEMORY LOAD FUNCTION ?
	RETBAD (.NRCME)		;NO, RETURN "COMMUNICATIONS ERROR"
	ILDB T4,CKMPTR		;YES, GET NEXT LOAD NUMBER REQUESTED
	INCR LNLDN,(T3)		;INCREMENT LOAD NUMBER
	LOAD T1,LNLDN,(T3)	;GET NEXT LOAD NUMBER
	CAME T1,T4		;CORRECT LOAD NUMBER REQUESTED ?
	RETBAD (.NRCME)		;NO, RETURN "COMMUNICATIONS ERROR"
	STOR T1,LNLDN,(T3)	;YES, STORE UPDATED LOAD NUMBER IN LINE TABLE
	SOSGE T2		;ANOTHER BYTE IN MOP MESSAGE ?
	RETSKP			;NO, NO STATUS CODE IS PRESENT, ASSUME SUCCESS
	ILDB T4,CKMPTR		;YES, GET THE STATUS CODE FROM THE LOADER
	CAIE T4,.MPACK		;SUCCESS ON PREVIOUS LOAD ?
	RETBAD (.NRCME)		;NO, RETURN "COMMUNICATIONS ERROR"
	RETSKP			;YES, DONE. RETURN SUCCESS.
;SNDEND - ROUTINE TO SEND BACK AN END-OF-DIALOG MESSAGE WHEN A LINE SERVICE
;	  DIALOG OPERATION HAS FAILED.
;
;ACCEPTS IN T1/	NICE RETURN CODE
;		CALL SNDEND
;RETURNS: +1 ALWAYS, WITH MESSAGE SENT IF POSSIBLE


SNDEND:	ASUBR <SEMCOD>

	CALL CLRMSG		;GO CLEAR NICE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO MESSAGE AREA
	MOVX T4,.LMEND		;GET END-OF-DIALOG MESSAGE TYPE CODE
	IDPB T4,T1		;ADD TYPE CODE TO MESSAGE
	MOVE T4,SEMCOD		;GET RETURN CODE (.NRXXX)
	IDPB T4,T1		;ADD RETURN CODE TO MESSAGE

; SEND THE MESSAGE BACK TO ORIGINATOR OR THIS REQUEST

	MOVNI T3,2		;GET NUMBER OF BYTES IN THE MESSAGE
	HRLI T2,(POINT 8,)	;FORM BYTE POINTER TO START
	HRRI T2,MSGBLK		; OF THE END-OF-DIALOG MESSAGE
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO REQUESTING TASK
	SOUTR			;SEND THE MESSAGE
	 ERJMP .+1		;FAILED, IGNORE FAILURE
	RET			;DONE, RETURN
;INIPRO - ROUTINE TO INITIATE PROTOCOL ON A LINE
;
;ACCPETS IN T1/	ADDRESS OF LINE TABLE
;		CALL INIPRO
;RETURNS: +1	 FAILED, COULD NOT INITIATE PROTOCOL
;	  +2	SUCCESS, PROTOCOL INITIATED IF ANY PROTOCOL TYPE HAD BEEN
;			 SPECIFIED FOR THE TARGET NODE.

INIPRO:	ASUBR <IPRLIN,IPRPRO,IPRCNT,IPRADJ>

	HRROI T1,OURNAM		;GET POINTER TO NAME OF OUR NODE
	CALL GETNIB		;GET THE NIB ADDRESS FOR OUR NODE
	 RETBAD (.NRICF)	;FAILED, "INVALID CONFIGURATION FILE"
	LOAD T1,NDLIN,(T1)	;GET ADDRESS OF LINE ADJACENCY TABLE
	MOVEM T1,IPRADJ		;SAVE TABLE ADDRESS
	MOVE T4,IPRLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER
	CALL CVTDEV		;CONVERT TO STANDARD NICE LINE ID
	 RETBAD (.NRNPE)	;FAILED, NICE PROGRAM ERROR
	MOVE T1,IPRADJ		;RESTORE ADJACENCY TABLE ADDRESS
	CALL FNDTGT		;GET ADDRESS OF NIB FOR TARGET NODE
	 RETBAD (.NRICF)	;FAILED, RETURN "CONFIGURATION FILE ERROR"
	JE NDPST,(T1),RSKP	;IF NO PROTOCOL TYPE HAS BEEN SET, WE ARE DONE
	LOAD T2,NDPRO,(T1)	;GET PROTOCOL TYPE TO INITIATE ON THIS LINE
	MOVEM T2,IPRPRO		;SAVE PROTOCOL TYPE


; LOOP FOR 3 MINUTES TRYING TO INITIATE PROTOCOL, THEN GIVE ERROR IF FAILED

	SETZM IPRCNT		;INITIALIZE COUNT OF TRIALS
INIP10:	MOVE T2,IPRPRO		;GET PROTOCOL TYPE
	MOVE T1,IPRLIN		;GET ADDRESS OF LINE TABLE
	CALL DTEGO		;INITIATE PROTOCOL
	 JRST [	AOS T1,IPRCNT	;INCREMENT LOOP COUNTER
		CAIL T1,^D6	;BEEN TRYING FOR 1 MINUTE YET ?
		RETBAD (.NRCME)	;YES, RETURN "LINE COMMUNICATIONS ERROR"
		MOVX T1,^D1000*^D10 ;WAIT TIME IS 10 SECONDS
		DISMS		;WAIT FOR TARGET NODE TO BECOME READY
		JRST INIP10 ]	;TRY TO INIT AGAIN
	RETSKP			;DONE, RETURN SUCCESS
;LSDMP - ROUTINE TO INITIATE AN UP-LINE DUMP DIALOG
;
;ACCEPTS IN T1/	POINTER TO DIALOG DATA IN LINE SERVICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL LSDMP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS

LSDMP:	ASUBR <LSDPTR,LSDCNT,LSDLIN,LSDNUM>

	CALL GETMEM		;GO GET INITIAL ADDRESS AT WHICH TO START DUMP
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	JUMPN T3,[RETBAD (.NRNPE)] ;FAIL IF NOT STARTING AT 0
	MOVE T4,LSDLIN		;GET ADDRESS OF LINE TABLE
	STOR T3,LNADR,(T4)	;STORE STARTING ADDRESS FOR DUMP
	CALL GETMEM		;EXTRACT NUMBER OF LOCATIONS TO DUMP FROM MSG
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,LSDNUM		;SAVE NUMBER OF BYTES TO BE DUMPED
	MOVX T3,INIDMP		;INITIAL COUNT IS SIZE OF DUMP BOOTSTRAP+BUFFER
	MOVE T4,LSDLIN		;GET ADDRESS OF LINE TABLE
	STOR T3,LNDCT,(T4)	;STORE NUMBER OF BYTES LEFT TO DUMP

; SEND BACK A SUCCESS RETURN CODE TO ORIGINATOR OF THE DIALOG

	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO ORIGINATING TASK
	MOVE T2,[POINT 8,[BYTE (8) .NRSUC]] ;GET SUCCESS CODE
	MOVNI T3,1		;MESSAGE CONTAINS ONE BYTE
	SOUTR			;SEND BACK THE MESSAGE
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"

; TRIGGER THE ROM BEFORE STARTING THE DUMP

	MOVE T1,LSDLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESTP		;FIRST TERMINATE ANY PROTOCOL OVER THIS DTE
	 RETBAD (.NRCME)	;FAILED, RETURN "LINE COMMUNICATIONS ERROR"
	MOVE T1,LSDLIN		;GET ADDRESS OF LINE TABLE
	CALL DTEINI		;TRIGGER THE ROM
	 RETBAD (.NRCME)	;FAILED

; DUMP THE FIRST "INIDMP" WORDS OF PDP-11 MEMORY

	MOVE T1,LSDLIN		;GET ADDRESS OF LINE TABLE
	CALL ROMDMP		;DO A ROM DUMP OF FIRST "INIDMP" WORDS
	 RETBAD ()		;FAILED


; FIRST "INIDMP" WORDS HAVE BEEN DUMPED.  NOW LOAD A DUMP BOOTSTRAP PROGRAM

	MOVE T1,LSDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T4,LNMSG,(T1)	;GET ADDRESS OF WHERE -11 PROGRAM GOES
	HRLI T4,DBOOT		;GET ADDRESS OF DUMP BOOTSTRAP
	HRRZ T3,T4		;COPY DESTINATION ADDRESS
	BLT T4,200(T3)		;COPY 256 WORD (-11 WORDS) DUMP PROGRAM
	CALL DTESLD		;LOAD THE DUMP BOOTSTRAP
	 RETBAD (.NRCME)	;FAILED

; FIRST 256 WORDS HAVE BEEN DUMPED.  NOW LOAD A DUMP BOOTSTRAP PROGRAM
;
;	MOVE T1,LSDLIN		;GET ADDRESS OF LINE TABLE
;	CALL LODDMP		;GO LOAD A DUMP PROGRAM
;	 RETBAD (.NRCME)	;FAILED

; NOW DUMP THE REMAINING MEMORY USING THE DUMP BOOTSTRAP

	MOVE T1,LSDNUM		;GET NUMBER OF BYTES TO DUMP
	MOVE T2,LSDLIN		;GET ADDRESS OF LINE TABLE
	CALL MOPDMP		;GO DO A MOP DUMP
	 RETBAD ()		;FAILED

; RETURN AN END-OF-DIALOG MESSAGE TO THE HOST NCU

	MOVX T1,.NRSUC		;GET SUCCESS RETURN CODE
	CALL SNDEND		;GO SEND AN END-OF-DIALOG MESSAGE TO HOST NCU
	RETSKP			;DONE, RETURN SUCCESS
; DUMP BOOTSTRAP CODE

DBOOT:

001200010040
000700007000
427446000060
153444100000
007754256140
003470256000
700000256040
376030204760
751400204760
751410204760
751420204760
751470120760
751600256760
037003647040
053574174000
751670256760
000007773640
053400400000
053574002340
000020454540
713574000200
751610136200
057427647040
031424146120
031424146120
042421056100
177774146120
031424010140
113133456000
004000136200
040024120100
040030256040
001060244540
101134016440
417760002200
043431456140
002420210040
351137777440
213413777700
027424030020
025010404560
000020020100
025410257560
700000010040
041334010000
053400011020
023734004000
153444100000
007764256000
002264256040
000044204060
023734004340
513734000160
001614020100
513734000100
001564030020
004260356000
001550200760
003511456760
000024016440
073414006200
073410006140
441574016520
473574005720
003532204760
003536356760
001324016600
355137777640
041577647100
073414005100
213417776000
313415000000
053410016620
451511760040
213707000000
777620256000
003510117560
000060003560
777010015200
042307777100
302400201420
777720256220
240000257420
000004000040
053444050000
153446400000
007766007360
001034211420
777621412000
040307777540
301002060200
006034201140
700010120000
023734000100
053010204000
053444002020
701014030060
013551256040
400000130040
213411200000
007520205420
777712656220
001010037720
401470136000
004015457420
200003777100
041410004160
020000140000
002120000000
000000000040
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000070000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000004540
000000001300
000000000000
000000000000
000000000000
; LODDMP - ROUTINE TO LOAD A DUMP PROGRAM INTO AN ADJACENT PDP-11
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL LODDMP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, PROGRAM LOADED AND STARTED

LODDMP:	ASUBR <LDPLIN,<LDPNOD,2>,LDPLNK>

; GET A LINK TO THE HOST INITIATING THIS DUMP OPERATION

	MOVE T1,REQLNK		;GET LINK TO REQUESTING TASK
	MOVX T2,.MORHN		;READ HOST NAME FUNCTION
	HRROI T3,LDPNOD		;GET POINTER TO WHERE NAME SHOULD GO
	MTOPR			;GET THE NODE NAME
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	HRROI T1,LDPNOD		;GET POINTER TO HOST NODE NAME
	CALL GETLNK		;GO GET A LOGICAL LINK TO THE HOST
	 RETBAD ()		;FAILED
	MOVEM T1,LDPLNK		;SAVE LOGICAL LINK

; GO ASSEMBLE A NICE "REQUEST DOWN-LINE LOAD" MESSAGE

	MOVE T1,LDPLIN		;GET ADDRESS OF LINE TABLE
	CALL MAKRQL		;GO ASSEMBLE THE NICE MESSAGE
; SEND A DOWN-LINE LOAD REQUEST TO THE HOST TO LOAD THE DUMP PROGRAM

;	MOVE T1,LDPLNK		;GET LOGICAL LINK
;	MOVE T2,[POINT 8,LODMSG] ;GET POINTER TO NICE LOAD REQUEST MESSAGE
;	MOVNI T3,LDMSIZ		;GET -COUNT
	SOUTR			;SEND THE MESSAGE TO THE HOST
	 ERJMP [RETBAD (.NRNCE)] ;FAILED
; MOPDMP - ROUTINE TO DUMP AN ADJACENT NODE'S MEMORY USING THE MOP PROTOCOL
;
;ACCEPTS IN T1/	NUMBER OF LOCATIONS TO DUMP
;	    T2/	ADDRESS OF LINE TABLE
;		CALL MOPDMP
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, DATA RETURNED TO HOST NICE PROCESS

MOPDMP:	ASUBR <MPDNUM,MPDLIN,MPDPTR,MPDCNT>

; RECEIVE "MOP MODE RUNNING" MESSAGE FROM DN20

	MOVE T1,MPDLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;RECEIVE A MOP MESSAGE FROM ADJACENT NODE
	 RETBAD ()		;FAILED
	CALL CHKMMR		;GO CHECK MOP MODE RUNNING MSG AND GET COUNT
	 RETBAD ()		;FAILED, RETURN ERROR
	CAMGE T1,MPDNUM		;MORE MEMORY THERE THAN WAS REQUESTED ?
	MOVEM T1,MPDNUM		;NO, USE ONLY WHAT IS THERE

; SAVE TOTAL NUMBER OF BYTES TO BE DUMPED AND INITIAL DUMP ADDRESS

	MOVE T1,MPDNUM		;GET NUMBER OF BYTES REQUESTED
	SUBI T1,INIDMP		;COMPUTE NUMBER STILL LEFT TO DUMP
	MOVE T4,MPDLIN		;GET ADDRESS OF LINE TABLE
	STOR T1,LNDCT,(T4)	;STORE NUMBER OF BYTES LEFT TO DUMP
	MOVX T1,INIDMP		;GET INITIAL ADDRESS FOR DUMP
	STOR T1,LNADR,(T4)	;STORE NEXT ADDRESS TO START AT
	;..
	;..
; SEND A MOP "REQUEST MEMORY DUMP" MESSAGE TO THE DUMP PROGRAM

MOPD10:	MOVE T4,MPDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T3,LNDCT,(T4)	;GET NUMBER OF BYTES LEFT TO DUMP
	JUMPLE T3,RSKP		;IF NO MORE DATA TO DUMP, THEN DONE
	LOAD T1,LNADR,(T4)	;GET NEXT BYTE TO BE DUMPED
	MOVX T2,RCVMAX-5	;GET AMOUNT OF MEMORY WE WANT
				; = MAX - NUMBER OF MOP OVERHEAD BYTES
	CAML T2,T3		;LESS THAN THAT STILL LEFT ?
	MOVE T2,T3		;YES, USE LESSER AMOUNT
	LOAD T3,LNMSG,(T4)	;SAVE POINTER TO MOP MESSAGE
	CALL MAKRQD		;GO MAKE A MOP DUMP REQUEST MESSAGE
	MOVE T4,MPDLIN		;GET ADDRESS OF LINE TABLE
	STOR T2,LNCNT,(T4)	;SAVE SIZE OF MOP MESSAGE
	MOVE T1,MPDLIN		;GET ADDRESS OF LINE TABLE
	CALL DTESND		;SEND THE "REQUEST DUMP" MOP MESSAGE
	 RETBAD ()		;FAILED

; RECEIVE A MOP "MEMORY DUMP DATA" MESSAGE

	MOVE T1,MPDLIN		;GET ADDRESS OF LINE TABLE
	CALL DTERCV		;RECEIVE A MOP MESSAGE FROM ADJACENT NODE
	 RETBAD ()		;FAILED
	MOVEM T2,MPDCNT		;SAVE NUMBER OF BYTES IN MSG RECEIVED

; CHECK THE MOP MESSAGE JUST READ

	CALL MOPCHK		;GO VERIFY MOP MESSAGE
	 RETBAD ()		;FAILED
	MOVE T4,MPDLIN		;GET ADDRESS OF LINE TABLE
	LOAD T3,LNADR,(T4)	;GET ADDRESS USED FOR THIS DUMP
	ADD T3,T2		;COMPUTE NEXT ADDRESS TO START AT
	STOR T3,LNADR,(T4)	;SAVE FOR NEXT PASS
	LOAD T3,LNDCT,(T4)	;GET TOTAL NUMBER OF BYTES LEFT TO DUMP
	SUB T3,T2		;COMPUTE TOTAL LEFT AFTER THIS PASS
	STOR T3,LNDCT,(T4)	;SAVE TOTAL NUMBER OF BYTES LEFT TO DUMP

; RETURN THE DUMP DATA TO THE HOST NICE PROCESS

	CALL SNDDAT		;GO SEND DUMP DATA BACK TO HOST NICE PROCESS
	 RETBAD ()		;FAILED
	JRST MOPD10		;LOOP BACK FOR MORE DATA
;SNDDAT - ROUTINE TO RETURN DUMP DATA TO HOST NICE PROCESS
;
;ACCEPTS IN T1/	POINTER TO DATA TO BE RETURNED
;	    T2/	NUMBER OF DATA BYTES TO RETURN
;		CALL SNDDAT
;RETURNS: +1	 FAILED
;	  +2	SUCCESS

SNDDAT:	ASUBR <SDTPTR,SDTCNT>

	MOVE T1,REQLNK		;GET LOGICAL LINK TO HOST NICE PROCESS
	MOVE T2,[POINT 8,[BYTE (8) .LMMEM, .CP11]]
	MOVNI T3,2		;MESSAGE BEGINS WITH TWO BYTES
	SOUT			;OUTPUT FIRST PART OF NICE MESSAGE
	 ERJMP [RETBAD (.NRNCE)] ;FAILED
	MOVN T3,SDTCNT		;GET -COUNT OF BYTES TO RETURN
	MOVE T2,SDTPTR		;COPY POINTER TO DATA BYTES
	SOUTR			;RETURN DATA TO HOST NICE PROCESS
	 ERJMP [RETBAD (.NRNPE)] ;RETURN ERROR ON FAILURE
	RETSKP			;DONE, RETURN SUCCESS
; ROMDMP - ROUTINE TO DUMP AN ADJACENT PDP-11 USING ITS ROM
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL ROMDMP
;RETURNS: +1	 FAILED
;	  +2	SUCCESS

; GET SOME MEMORY IMAGE DATA FROM THE ADJACENT NODE

ROMDMP:	ASUBR <RDMLIN>
RMDMP2:	MOVE T1,RDMLIN		;GET ADDRESS OF LINE TABLE
	CALL DTEDMP		;GO RECEIVE SOME DATA
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVE T4,RDMLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDCT,(T4)	;GET TOTAL NUMBER OF BYTES LEFT TO DUMP
	LOAD T2,LNCNT,(T4)	;GET NUMBER OF BYTES JUST DUMPED
	SUB T1,T2		;COMPUTE NUMBER OF BYTES REMAINING TO BE DUMPED
	STOR T1,LNDCT,(T4)	;STORE NUMBER OF BYTES STILL LEFT TO DUMP

; RETURN THE MEMORY IMAGE DATA TO REQUESTING HOST NCU

	MOVE T1,RDMLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNMSG,(T1)	;GET POINTER TO DUMP DATA
	MOVEI T1,@T1		;GET ADDRESS OF DUMP DATA
	CALL MAKIMD		;GO MAKE A DUMP DIALOG MEMORY IMAGE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR
	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;COPY POINTER TO MEMORY IMAGE DATA MESSAGE
	MOVE T1,REQLNK		;GET LOGICAL LINK (JFN) TO HOST NCU
	SOUTR			;SEND THE MEMORY IMAGE MESSAGE BACK TO THE HOST
	 ERJMP [RETBAD (.NRNCE)] ;FAILED, "NETWORK COMMUNICATIONS ERROR"

; IF THERE IS MORE DATA TO DUMP, LOOP BACK AND GET MORE DATA FROM DTE

	MOVE T4,RDMLIN		;GET ADDRESS OF LINE TABLE
	JN LNDCT,(T4),RMDMP2	;LOOP BACK IF THERE IS MORE DATA TO DUMP
	RETSKP			;DONE, RETURN
;CHKMMR - ROUTINE TO CHECK A "MOP MODE RUNNING" MESSAGE FROM ADJACENT DN20
;
;ACCEPTS IN T1/	POINTER TO MOP MESSAGE
;	    T2/ NUMBER OF BYTES IN MOP MESSAGE
;		CALL CHKMMR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ SIZE OF MEMORY TO BE DUMPED

CHKMMR:	ASUBR <CMRPTR,CMRCNT>

	CAIE T2,^D8		;CORRECT NUMBER OF BYTES IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,T1		;GET MOP FUNCTION CODE
	CAIE T4,.MPMMR		;MOP MODE RUNNING ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,T1		;GET DEVICE TYPE
	CAIE T4,.DTDTE		;DTE20 ?
	RETBAD (.NRILN)		;NO, FAIL
	ILDB T4,T1		;GET STATION ADDRESS
	CAIE T4,1		;PT - TO - PT ?
	RETBAD (.NRIMF)		;NO, FAIL
	CALL GETMEM		;GO GET MEMORY SIZE
	 RETBAD ()		;FAILED, BAD MESSAGE
	ILDB T4,T1		;GET FEATURES MASK
	TXNN T4,MP%DMP		;DUMP SUPPORTED ?
	RETBAD (.NRFNC)		;NO, FAIL
	MOVE T1,T3		;GET MEMORY SIZE
	RETSKP			;DONE, RETURN SUCCESS




; MOPCHK - ROUTINE TO CHECK MOP "MEMORY DUMP DATA" MESSAGE
;
;ACCEPTS IN T1/	POINTER TO START OF MOP "MEMORY DUMP DATA" MESSAGE
;	    T2/	NUMBER OF BYTES IN MOP MESSAGE
;		CALL MOPCHK
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF DATA IN MSG
;			      T2/ NUMBER OF DATA BYTES IN THE MSG

MOPCHK:	SOSGE T2		;AT LEAST ONE BYTE IN MESSAGE
	RETBAD (.NRIMF)		;NO, NOT EVEN A FUNCTION CODE THERE !
	ILDB T4,T1		;GET MOP FUNCTION CODE
	CAIE T4,.MPDMP		;MEMORY DUMP DATA ?
	RETBAD (.NRIMF)		;FAILED, INVALID MESSAGE FORMAT
	CALL GETMEM		;GO GET MEMORY ADDRESS FROM MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR
	RETSKP			;DONE, RETURN SUCCESS
SUBTTL	NICE Process --  Event Logger

REQLOG:	SAVEPQ
	STKVAR <<RLGSRC,2>,RLGSEQ,RLGOPT>

; EXTRACT FIELDS FROM THE INITIAL PART OF THE NICE MESSAGE

	CALL GETFCN		;EXTRACT FUNCTION CODE FROM MESSAGE
	 RETBAD ()		;FAILED
	CALL GETOPT		;GET THE OPTION FROM THE MESSAGE
	 RETBAD ()		;FAILED
	MOVEM T4,RLGOPT		;SAVE OPTION CODE
	HRRI T3,RLGSRC		;GET ADDRESS OF SOURCE NODE NAME STRING
	HRLI T3,(POINT 7,)	;FORM POINTER TO STRING DESTINATION
	CALL GETIMA		;GO EXTRACT SOURCE NODE NAME
	 RETBAD ()		;FAILED
	HRLI T3,440000		;USE POINTER WITH ZERO SIZE FIELD TO DISCARD
	CALL GETIMA		; IMAGE ASCII FIELD HOLDING SOURCE COMPONENT
	 RETBAD ()		;FAILED
	CALL GETSEQ		;GET SEQUENCE NUMBER FROM MESSAGE
	 RETBAD ()		;FAILED
	MOVEM T3,RLGSEQ		;SAVE SEQUENCE NUMBER

; EXTRACT EVENT TYPE CODE FROM MESSAGE AND DISPATCH TO PROCESSING ROUTINE

	CALL GETEVT		;GO GET EVENT CODE FROM NICE MESSAGE
	 RETBAD ()		;FAILED
	HRR T4,T3		;COPY EVENT CODE
	HRL T4,RLGSEQ		;GET SEQUENCE NUMBER
	HRRI T3,RLGSRC		;GET ADDRESS OF SOURCE NODE NAME
	HRLI T3,(POINT 7,)	;FORM POINTER TO NAME
	CALL DOLOG		;GO MAKE THE LOG ENTRY
	 RETBAD ()		;FAILED
	RETSKP			;DONE, RETURN SUCCESS
;DOLOG - ROUTINE TO LOG DATA FROM THE NETWORK
;
;ACCEPTS IN T1/	POINTER TO "LOG DATA" PORTION OF NICE REQUEST-LOG MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;	    T3/	POINTER TO SOURCE NODE NAME
;	    T4/	SEQUENCE NUMBER,,EVENT CODE (.EVXXX)

DOLOG:	SAVEPQ
	ASUBR <DLGPTR,DLGCNT,DLGSRC,DLGEVT>
	STKVAR <DLGSEQ>
	HLRZM T4,DLGSEQ		;STORE SEQUENCE NUMBER
	HRRZS DLGEVT		;KEEP JUST EVENT CODE

; VALIDATE EVENT CODE

	MOVE T4,DLGEVT		;GET EVENT CODE TYPE
	CAILE T4,EVTSIZ-1	;WITHIN VALID RANGE ?
	RETBAD (.NRIPV)		;NO, INVALID PARAMETER VALUE

; ASSIGN A PAGE FOR THE SYSERR ENTRY

	CALL ASGPAG		;ASSIGN A PAGE TO HOLD SYSERR ENTRY
 	 RETBAD ()		;FAILED
	MOVEI P1,(T2)		;SAVE BASE ADDRESS OF SYSERR ENTRY
	MOVEI P2,.SYDAT(P1)	;GET ADR OF NETWORK HEADER PART OF ENTRY

; SET UP NETWORK HEADER PART OF SYSERR ENTRY WITH COMMON INFO

	MOVE T1,P1		;GET BASE ADDRESS OF SYSERR ENTRY
	MOVE T2,DLGSRC		;GET POINTER TO SOURCE NODE
	MOVE T3,DLGSEQ		;GET SEQUENCE NUMBER
	CALL EVTSYR		;SET UP NETWORK HEADER
	 JRST DOLOGX		;FAILED, GO RELEASE PAGE

; DISPATCH TO PROPER PROCESSING ROUTINE FOR THIS EVENT TYPE

	MOVE T3,T1		;GET NEXT ADR TO USE IN SYSERR ENTRY
	MOVE T1,DLGPTR		;GET POINTER TO REMAINDER OF NICE MESSAGE
	MOVE T2,DLGCNT		;GET NUMBER OF BYTES LEFT IN MESSAGE
	MOVE T4,DLGEVT		;GET EVENT TYPE CODE
	CALL @EVTTAB(T4)	;YES, DISPATCH TO PROCESSING ROUTINE
	 JRST DOLOGX		;FAILED, RELEASE SYSERR PAGE
	STOR T2,SYLEN,(P1)	;STORE LENGTH OF ENTRY
	MOVE T1,P1		;GET BASE ADDRESS OF SYSERR ENTRY (LENGTH IN T2)
	SYERR			;RECORD THE SYSERR ENTRY
	 ERJMP [ NON.FATAL.ERROR (.ERR29) ;COULD NOT MAKE SYSERR ENTRY
		 JRST .+1 ]
	MOVE T1,P1		;GET ADDRESS OF SYSERR PAGE
	CALL RELPGA		;RELEASE THE PAGE
	 NON.FATAL.ERROR	;FAILED
	RETSKP			;DONE, RETURN SUCCESS
; HERE ON ERROR WITH SYSERR PAGE ASSIGNED

DOLOGX:	EXCH T1,P1		;SAVE ERROR CODE, GET ADDRESS OF SYSERR PAGE
	CALL RELPGA		;RELEASE THE PAGE
	 NON.FATAL.ERROR	;FAILED
	MOVE T1,P1		;RESTORE ERROR CODE
	RETBAD ()		;FAIL





; TABLE OF EVENT CODE PROCESSING ROUTINES

EVTTAB:	[RETBAD (.NRIPV)]	;  0 - ILLEGAL
	EVTASC			;  1 - ASCII INFORMATION
	EVTEXA			;  2 - EXTENDED ASCII INFORMATION
	EVTHDW			;  3 - HARDWARE ERROR
	EVTSFT			;  4 - SOFTWARE ERROR
	EVTTOP			;  5 - TOPOLOGY CHANGE

EVTSIZ==.-EVTTAB
EVTEXA:	SAVEPQ
	ASUBR <EVAPTR,EVACNT,EVALGD,EVAMSG>
	STKVAR <EVATMP,EVABLK>
	SETZM P4		;INITIALIZE "NOT DONE YET" FLAG

; SET UP TO ADD CHK11 TEXT TO SYSERR ENTRY

	HRLI T3,(POINT 7,)	;FORM POINTER TO WHERE TEXT WILL GO
	MOVEM T3,EVAMSG		;SAVE POINTER TO TEXT
	MOVE T1,EVAPTR		;GET POINTER TO NICE MESSAGE
	MOVE T2,EVACNT		;GET NUMBER OF BYTES LEFT IN NICE MESSAGE

; LOOP TO ADD EACH MESSAGE-FUL OF TEXT TO SYSERR ENTRY

EVTA05:	CALL GETFLD		;GO EXTRACT FIELD FROM EVENT LOGGING MESSAGE
	 RETBAD ()		;FAILED
	MOVEM T4,EVABLK		;SAVE EVENT BLOCK ADDRESS
	CAIE T3,.EDTXT		;ASCII DATA TYPE CODE ?
	JRST EVTA05		;NO, IGNORE IT - GO GET NEXT FIELD
	ILDB T1,T4		;GET FIRST CHARACTER IN STRING
	CAIN T1,0		;LAST MESSAGE ?
	SETOM P4		;YES, NOTE BY SETTING FLAG
	MOVE T1,EVAMSG		;GET DESTINATION POINTER FOR TEXT
	MOVEM T1,EVATMP		;SAVE POINTER TO FIRST DATA BYTE
	MOVE T2,EVABLK		;GET SOURCE TEXT POINTER
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ACCUMULATE TEXT
	MOVEM T1,EVAMSG		;SAVE UPDATED DESTINATION POINTER
	MOVE T1,EVABLK		;GET BLOCK ADDRESS AGAIN
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		; Die on release failure
	MOVE T1,EVATMP		;GET POINTER TO TEXT MESSAGE
	SKIPE P4		;GOT LAST MESSAGE YET ?
	JRST EVTA10		;YES, GO MAKE SYSERR ENTRY
	MOVE T1,REQLNK		;GET LOGICAL LINK FROM REQUESTING TASK
	HRRI T2,MSGBLK		;GET ADDRESS OF NICE MESSAGE AREA
	HRLI T2,(POINT 8,)	;FORM POINTER TO NICE MESSAGE DESTINATION
	MOVNI T3,MSGSIZ*BPWRD	;GET MAX COUNT
	SINR			;GET NEXT BLOCK OF TEXT
	 ERJMP [RETBAD (.NRNCE)] ;FAILED, "NETWORK COMMUNICATIONS ERROR"
	MOVEI T2,MSGSIZ*BPWRD(T3) ;GET NUMBER OF BYTES IN MESSAGE
	HRRI T1,MSGBLK		;GET ADDRESS OF NICE MESSAGE AREA
	HRLI T1,(POINT 8,)	;FORM POINTER TO NICE MESSAGE DESTINATION
	JRST EVTA05		;GO EXTRACT TEXT FROM NEXT MESSAGE

; HERE WHEN ALL ASCII DATA EXTRACTED

EVTA10:	MOVX T4,SY%CHK		;CHK11 ENTRY TYPE CODE
	STOR T4,SYCOD,(P1)	;STORE ENTRY TYPE CODE IN SYSERR ENTRY
	HRRZ T2,EVAMSG		;GET LAST ADDRESS USED IN SYSERR ENTRY
	SUB T2,EVALGD		;COMPUTE NUMBER OF WORDS IN LOG DATA SECTION
	MOVN T2,T2		;GET -NUMBER OF WORDS
	HRLZ T2,T2		;GET -COUNT,,0
	MOVE T3,EVALGD		;GET LOG DATA STARTING ADDRESS
	SUB T3,P2		;COMPUTE OFFSET TO LOG DATA
	HRRI T2,(T3)		;FORM SYSERR POINTER TO LOG DATA SECTION
	STOR T2,SYPTR,(P2)	;STORE POINTER TO LOG DATA SECTION
	HRRZ T2,EVAMSG		;GET LAST ADDRESS USED IN SYSERR ENTRY
	SUB T2,P1		;COMPUTE SIZE OF ENTIRE ENTRY
	STOR T2,SYLEN,(P1)	;STORE LENGTH OF ENTRY
	RETSKP			;DONE, RETURN
;EVTTOP - ROUTINE TO HANDLE TOPOLOGY CHANGE LOGGING MESSAGES

EVTTOP:	SAVEPQ
	STKVAR <ETPNOD,ETPLID,ETPDST,ETPERR,ETPRSN>
	MOVEM T3,ETPDST		;SAVE DESTINATION FOR NEXT ITEM IN SYSERR ENTRY

; INITIALIZE VARIABLES

	SETZM ETPNOD		;NODE ID
	SETZM ETPLID		;LINE ID
	SETZM ETPRSN		;REASON CODE

; LOOP OVER EACH FIELD IN THE MESSAGE

ETP010:	JUMPE T2,ETP020		;IF NO MORE FIELDS, GO MAKE SYSERR ENTRY
	CALL GETFLD		;GO EXTRACT NEXT FIELD FROM NICE LOG MESSAGE
	 JRST EVTTPX		;FAILED, RELEASE ANY ASSIGNED RESOURCES
	CAIL T3,ETPLEN		;DATA TYPE CODE WITHIN RANGE ?
	JRST [	MOVX T1,.NRIMF	;NO, BAD MESSAGE FORMAT
		JRST EVTTPX ]	;RETURN ERROR
	JRST @ETPTAB(T3)	;STORE ITEM FROM LOG MESSAGE
				; (EACH PROCESSING ROUTINE RETURNS TO ETP015)
ETP015:	JRST ETP010		;LOOP BACK FOR NEXT FIELD IN MESSAGE

; TABLE OF ROUTINES TO STORE DATA FOR TOPOLOGY CHANGE ENTRIES

ETPTAB:	EVTTPX			;  0 - ILLEGAL
	EVTTPX			;  1 - GENERAL DATA
	ETP015			;  2 - TIME OF DAY (NOT USED)
	ETP015			;  3 - DATE (NOT USED)
	EVTTPX			;  4 - UPTIME
	ESTLID			;  5 - LINE ID
	ESTRSN			;  6 - REASON CODE
	EVTTPX			;  7 - RECOVERY
	EVTTPX			;  8 - OPERATING SYSTEM ID
	ESTNOD			;  9 - NODE ID
	EVTTPX			; 10 - MICROCODE INFO
	EVTTPX			; 11 - LINE PROTOCOL
	EVTTPX			; 12 - TRANSMISSION PROTOCOL

ETPLEN==.-ETPTAB
; HERE WHEN ALL FIELDS EXTRACTED FROM MESSAGE

ETP020:

; ADD ADJACENT NODE NAME TO NETWORK HEADER

	MOVE T3,ETPDST		;COPY DESTINATION ADDRESS FOR STRING
	MOVE T2,ETPNOD		;GET POINTER TO NODE NAME
	MOVE T1,P1		;GET ADDRESS OF SYSERR ENTRY
	CALL SYRSTR		;ADD STRING TO ENTRY
	 JRST EVTTPX		;FAILED
	STOR T2,SYADJ,(P2)	;STORE POINTER TO ADJACENT NODE
	MOVEM T1,ETPDST		;UPDATE NEXT ADDRESS TO USE IN SYSERR ENTRY

; STORE REASON CODE AND LINE ID

	SKIPN T4,ETPRSN		;GET REASON CODE
	JRST ETP030		;NONE SUPPLIED
	STOR T4,SYRSN,(P2)	;STORE REASON IN NETWORK HEADER OF SYSERR ENTRY
ETP030:	SKIPN T4,ETPLID		;GET ADDRESS OF BLOCK HOLDING LINE ID
	JRST ETP040		;NO LINE ID SUPPLIED
	MOVE T3,1(T4)		;GET FIRST WORD OF LINE ID
	STOR T3,SYLID,(P2)	;STORE FIRST PART OF LINE ID
	MOVE T3,2(T4)		;GET SECOND WORD OF LINE ID
	STOR T3,SYLI1,(P2)	;STORE SECOND SECTION OF LINE ID

; HERE WHEN DONE, RELEASE RESOURCES AND RETURN

ETP040:	SKIPE T1,ETPNOD		;ANY NODE ID YET ?
	JRST [	CALL RELFRE	;YES, RELEASE NODE NAME
		 FATAL.ERROR	; Die on release failure
		JRST .+1 ]
	SKIPE T1,ETPLID		;ANY LINE ID YET ?
	JRST [	CALL RELFRE	;YES, RELEASE LINE ID
		 FATAL.ERROR	; Die on release failure
		JRST .+1 ]
	MOVE T2,ETPDST		;GET NEXT ADDRESS TO USE IN SYSERR ENTRY
	SUB T2,P1		;COMPUTE SIZE OF SYSERR ENTRY
	MOVX T1,SY%TOP		;GET TOPOLOGY CHANGE EVENT CODE
	RETSKP			;DONE, RETURN SUCCESS


; HERE ON AN ERROR TO RELEASE ANY ASSIGNED RESOURCES

EVTTPX:	MOVEM T1,ETPERR		;SAVE ERROR CODE
	SKIPE T1,ETPNOD		;ANY NODE ID YET ?
	JRST [	CALL RELFRE	;YES, RELEASE NODE NAME
		 FATAL.ERROR
		JRST .+1 ]
	SKIPE T1,ETPLID		;ANY LINE ID YET ?
	JRST [	CALL RELFRE	;YES, RELEASE LINE ID
		 FATAL.ERROR
		JRST .+1 ]
	MOVE T1,ETPERR		;RESTORE ERROR CODE
	RETBAD ()		;FAIL
; ROUTINES TO STORE INFO USED TO MAKE TOPOLOGY CHANGE SYSERR ENTRIES

ESTRSN:	MOVEM T4,ETPRSN		;STORE REASON CODE
	JRST ETP015		;DONE, RETURN


ESTNOD:	MOVEM T4,ETPNOD		;STORE POINTER TO NODE NAME
	JRST ETP015		;DONE, RETURN

ESTLID:	MOVEM T4,ETPLID		;STORE POINTER TO LINE ID
	JRST ETP015		;DONE, RETURN
;EVTHDW - ROUTINE TO PROCESS HARDWARE EVENT LOG ENTRIES

EVTHDW:	SAVEPQ
	STKVAR <HDWNOD,HDWDEV,HDWREG,HDWUPT,HDWDAT,HDWRSN,HDWRCV,HDWOPS,HDWERR,HDWMCD,HDWDST,HDWTHR,HDWLXX>

	MOVEM T3,HDWDST		;SAVE NEXT ADR TO USE IN SYSERR ENTRY

; INITIALIZE VARIABLES

	SETOM HDWTHR		;NO THRESHOLD VALUE YET
	SETZM HDWNOD		;NO NODE NAME YET
	SETZM HDWDEV		;NO DEVICE YET
	SETZM HDWREG		;NO REGISTER DATA YET
	SETZM HDWUPT		;NO UPTIME YET
	SETZM HDWDAT		;NO DATE YET
	SETZM HDWRSN		;NO REASON CODE YET
	SETOM HDWRCV		;NO RECOVERY CODE YET
	SETZM HDWOPS		;NO OPERATING SYSTEM ID YET
	SETZM HDWMCD		;NO MICROCODE ID YET

; LOOP OVER EACH FIELD IN THE MESSAGE

HDW010:	JUMPE T2,HDW020		;IF NO MORE FIELDS, GO MAKE SYSERR ENTRY
	CALL GETFLD		;GO EXTRACT NEXT FIELD FROM NICE LOG MESSAGE
	 JRST EVTHDX		;FAILED, RELEASE ANY ASSIGNED RESOURCES
	CAIL T3,HDWLEN		;DATA TYPE CODE WITHIN RANGE ?
	JRST [	MOVX T1,.NRIMF	;NO, BAD MESSAGE FORMAT
		JRST EVTHDX ]	;RETURN ERROR
	JRST @HDWTAB(T3)	;STORE ITEM FROM LOG MESSAGE
				; (EACH PROCESSING ROUTINE RETURNS TO HDW015)
HDW015:	JRST HDW010		;LOOP BACK FOR NEXT FIELD IN MESSAGE

; TABLE OF ROUTINES TO STORE DATA FOR HARDWARE ENTRIES

HDWTAB:	EVTHDX			;  0 - ILLEGAL
	HSTREG			;  1 - REGISTER DATA
	HDW015			;  2 - TIME OF DAY (NOT USED)
	HDW015			;  3 - DATE (NOT USED)
	HSTUPT			;  4 - UPTIME
	HSTDEV			;  5 - LINE ID
	HSTRSN			;  6 - REASON CODE
	HDW015			;  7 - RECOVERY (IGNORED)
	HSTOPS			;  8 - OPERATING SYSTEM ID
	HSTNOD			;  9 - NODE ID
	HSTMCD			; 10 - MICROCODE INFO
	EVTHDX			; 11 - LINE PROTOCOL
	EVTHDX			; 12 - TRANSMISSION PROTOCOL
	HSTTHR			; 13 - THRESHOLD VALUE

HDWLEN==.-HDWTAB

EVTHDX:	MOVEM T1,HDWERR		;SAVE ERROR CODE
	SKIPE T1,HDWDEV		;ANY DEVICE YET ?
	JRST [	CALL RELFRE	;YES, RELEASE SPACE
		 FATAL.ERROR
		JRST .+1 ]
	SKIPE T1,HDWREG		;ANY REGISTERS YET ?
	JRST [	CALL RELFRE	;YES, RELEASE FREE BLOCK
		 FATAL.ERROR
		JRST .+1]
	MOVE T1,HDWERR		;RESTORE ERROR CODE
	RETBAD ()		;RETURN FAILURE
; HERE WHEN ALL FIELDS EXTRACTED FROM NICE EVENT LOGGING MESSAGE

HDW020:	MOVE T1,HDWDEV		;GET ADDRESS OF DEVICE ID
	HLRZ T1,1(T1)		;GET DEVICE TYPE CODE
	CALL CVTHDW		;CONVERT NICE DEVICE CODE TO SYSERR CODE
	 JRST EVTHDX		;FAILED
	STOR T1,SYHDW,(P2)	;STORE HARDWARE DEVICE TYPE IN ENTRY

; STORE OPERATING SYSTEM AND REASON CODES, AND RECOVERY INFO

	MOVE T1,HDWOPS		;GET OPERATING SYSTEM ID CODE
	STOR T1,SYOPS,(P2)	;STORE IN SYSERR ENTRY
	MOVE T1,HDWRSN		;GET REASON CODE
	STOR T1,SYRSN,(P2)	;STORE IN SYSERR ENTRY
	MOVE T1,HDWTHR		;GET THRESHOLD VALUE PROVIDED IN MESSAGE
	STOR T1,SYTHR,(P2)	;STORE IN SYSERR ENTRY
	MOVE T1,HDWRCV		;GET RECOVERY ACTION CODE
	STOR T1,SYRCV,(P2)	;STORE IN SYSERR ENTRY

; STORE THE CONTROLLER AND UNIT NUMBER

	MOVE T1,HDWDEV		;GET ADR OF BLOCK HOLDING DEVICE ID
	CALL FNDCTL		;GO FIND CONTROLLER AND LINE NUMBERS
	 JRST EVTHDX		;FAILED
	STOR T1,SYLID,(P2)	;STORE CONTROLLER/LINE NUMBERS IN ENTRY
	STOR T2,SYLI1,(P2)	; AND STORE STATION NUMBER

; STORE THE REGISTER DATA IN THE SYSERR ENTRY

	MOVE T1,HDWDEV		;GET ADR OF BLOCK HOLDING DEVICE ID
	HRL T1,HDWDST		;GET NEXT ADR TO USE IN SYSERR ENTRY
	MOVE T2,HDWREG		;GET ADR OF BLOCK HOLDING REGISTER DATA
	MOVEI T3,.SYPTR(P2)	;GET ADDRESS TO USE IN SYSERR ENTRY
	MOVE T4,HDWMCD		;GET MICROCODE INFO IN CASE APPLICABLE
	CALL STOREG		;STORE REGISTER DATA IN SYSERR ENTRY
	 JRST EVTHDX		;FAILED
	MOVEM T1,T4		;SAVE NEXT SYSERR ADDRESS TO USE

; ADD LOG DATA POINTER AND EVENT CODE TO ENTRY, THEN RETURN

	HRRZ T2,HDWDST		;GET STARTING ADR FOR LOG DATA SECTION
	SUB T1,T2		;COMPUTE NUMBER OF WORDS IN LOG DATA SECTION
	MOVE T3,T1		;COPY COUNT OF WORDS IN LOG DATA SECTION
	IMULI T3,BPWRD		;COMPUTE BYTES IN LOG DATA SECTION
	STOR T3,SYNCT,(P2)	;STORE BYTE COUNT IN NETWORK HEADER
	MOVN T1,T1		;COMPUTE -COUNT
	HRL T1,T1		;GET -COUNT,,0
	SUB T2,P2		;COMPUTE OFFSET TO START OF LOG DATA
	HRR T1,T2		;FORM SYSERR POINTER TO LOG DATA
	STOR T1,SYPTR,(P2)	;STORE SYSERR POINTER TO LOG DATA
	MOVX T3,SY%MLG		;HARDWARE LOG ENTRY EVENT CODE
	STOR T3,SYCOD,(P1)	;STORE ENTRY TYPE CODE IN SYSERR ENTRY
	MOVE T2,T4		;COPY NEXT DESTINATION ADR IN SYSERR ENTRY
	SUBI T2,(P1)		;COMPUTE # OF BYTES IN SYSERR ENTRY
	MOVEM T2,HDWLXX		;Save length so chunks can be released
	SKIPE T1,HDWDEV		;ANY DEVICE YET ?
	JRST [	CALL RELFRE	;YES, RELEASE SPACE
		 FATAL.ERROR
		JRST .+1 ]
	SKIPE T1,HDWREG		;ANY REGISTERS YET ?
	JRST [	CALL RELFRE	;YES, RELEASE FREE BLOCK
		 FATAL.ERROR
		JRST .+1]
	MOVE T2,HDWLXX		;Restore length of SYSERR entry
	MOVX T1,SY%MLG		;GET SYSERR EVENT CODE TYPE
	RETSKP			;DONE, RETURN TO CALLER
;STOREG - ROUTINE TO STORE DEVICE REGISTER IN SYSERR ENTRY
;
;ACCEPTS IN T1/	NEXT ADR TO USE IN SYSERR ENTRY,,ADR OF DEVICE ID BLOCK
;	    T2/	ADDRESS OF BLOCK HOLDING REGISTERS
;	    T3/	NEXT ADDRESS TO STORE INTO IN SYSERR ENTRY
;	    T4/	MICROCODE INFO (NOT APPLICABLE TO ALL DEVICES)
;		CALL STOREG
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ NEXT ADR TO STORE INTO IN ENTRY

STOREG:	ASUBR <SRGDEV,SRGREG,SRGDST,SRGMCD>

	HLRZM T1,SRGDST		;SAVE NEXT ADR TO USE IN SYSERR ENTRY
	MOVEI T1,1(T1)		;POINT PAST BLOCK HEADER TO DEVICE ID
	HLRZ T1,(T1)		;GET DEVICE TYPE CODE
	MOVEI T2,REGTAB		;GET TABLE ADDRESS
	MOVEI T3,REGLEN		;GET TABLE LENGTH
	CALL FNDDSP		;GET PROCESSING ROUTINE ADDRESS
	 RETBAD ()		;FAILED
	MOVE T4,T1		;SAVE PROCESSING ROUTINE ADDRESS
	MOVE T1,SRGREG		;GET ADR OF BLOCK HOLDING REGISTERS
	MOVE T2,SRGDST		;GET NEXT DESTINATION TO USE IN ENTRY
	HRLI T2,(POINT 8,)	;FORM POINTER TO WHERE REGISTERS WILL GO
	MOVE T3,SRGMCD		;GET MICROCODE INFO
	CALL (T4)		;ADD REGISTERS TO SYSERR ENTRY
	 RETBAD ()		;FAIL
	RETSKP			;DONE, RETURN SUCCESS


; TABLE OF PROCESSING ROUTINES TO STORE REGISTER DATA IN SYSERR ENTRY

REGTAB:	.DTDTE,,STODTE
	.DTDUP,,STODUP
	.DTKDP,,STOKDP
	.DTKDZ,,STOKDZ
	.DTDMC,,STODMC
REGLEN==.-REGTAB
; ROUTINES TO STORE REGISTER DATA IN SYSERR ENTRY

STOKDZ:
STOKDP:	ASUBR <SKDREG,SKDDST,SKDMCD,SKDCNT>

	MOVE T1,SKDDST		;GET DESTINATION POINTER
	ADDI T1,1		;SKIP FIRST WORD (PTR TO SUB-DEVICE DATA)
	MOVE T2,SKDREG		;GET ADR OF BLOCK HOLDING REGISTERS
	ADDI T2,2		;GET ADDRESS OF REGISTER DATA
	HRLI T2,(POINT 8,)	;FORM POINTER TO REGISTER DATA
	MOVNI T3,NKMCRG		;GET NUMBER OF KMC11 REGISTER DATA BYTES
	SOUT			;ADD KMC REGISTER DATA TO ENTRY
	 ERJMP [RETBAD (.NRNPE)] ;FAILED

; STORE POINTER TO DUP11 REGISTER DATA ("SUB-DEVICE TABLE")

	MOVE T1,SKDDST		;GET POINTER TO ORIGINAL DESTINATION
	MOVE T4,SKDREG		;GET ADR OF BLOCK HOLDING REGISTER DATA
	MOVE T3,1(T4)		;GET NUMBER OF BYTES OF REGISTER DATA
	SUBI T3,NKMCRG		;COMPUTE NUMBER OF DUP11 REGISTER BYTES LEFT
	MOVN T3,T3		;GET -NUMBER OF DUP BYTES
	MOVEM T3,SKDCNT		;SAVE -NUMBER OF DUP REGISTER BYTES
	JUMPE T3,STKDP2		;SKIP STORING DUP DATA IF NONE
	MOVEI T3,6(T1)		;GET ADDRESS OF DUP REGISTER DATA
	SUB T3,P2		;COMPUTE OFFSET TO DUP DATA
	HRL T3,SKDCNT		;GET -NUMBER OF DUP BYTES,,OFFSET
	MOVEM T3,(T1)		;STORE POINTER TO "SUB-DEVICE TABLE"
STKDP2:	MOVE T4,SKDMCD		;GET MICROCODE INFO
	MOVEM T4,3(T1)		;STORE IN SYSERR ENTRY

; STORE DUP11 REGISTER DATA

	MOVEI T1,6(T1)		;GET DESTINATION ADR FOR REGISTER DATA
	HRLI T1,(POINT 8,)	;FORM DESTINATION POINTER
	MOVE T3,SKDCNT		;GET NUMBER OF DUP11 REGISTER BYTES
	JUMPE T3,STKDP4		;SKIP STORE IF NO BYTES
	SOUT			;ADD DUP REGISTERS TO SYSERR ENTRY
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
STKDP4:	IBP T1			;INCREMENT POINTER TO NEXT BYTE TO USE IN ENTRY
	HRRZ T1,T1		;KEEP JUST ADDRESS
	RETSKP			;DONE, RETURN SUCCESS
STODMC:	ASUBR <SDMREG,SDMDST>

	MOVE T2,SDMREG		;GET ADR OF BLOCK HOLDING REGISTERS
	MOVN T3,1(T2)		;GET NUMBER OF BYTES OF REGISTER DATA
	ADDI T2,2		;GET ADDRESS OF REGISTER DATA
	HRLI T2,(POINT 8,)	;FORM POINTER TO REGISTER DATA
	MOVE T1,SDMDST		;GET DESTINATION POINTER
	SETOM (T1)		;-1 instead of pointer to sub-device data
	AOS T1			;Move past dummy sub-device data pointer
	SOUT			;COPY THE REGISTERS INTO SYSERR ENTRY
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	IBP T1			;INCREMENT POINTER TO NEXT BYTE TO USE
	HRRZ T1,T1		;KEEP JUST ADDRESS
	RETSKP			;DONE, RETURN NEXT SYSERR ENTRY ADDRESS TO USE

STODTE:	ASUBR <DTSREG,DTSDST>

	MOVE T2,DTSREG		;GET ADR OF BLOCK HOLDING REGISTERS
	MOVN T3,1(T2)		;GET NUMBER OF BYTES OF REGISTER DATA
	ADDI T2,2		;GET ADDRESS OF REGISTER DATA
	HRLI T2,(POINT 8,)	;FORM POINTER TO REGISTER DATA
	MOVE T1,DTSDST		;GET DESTINATION POINTER
	SOUT			;COPY THE REGISTERS INTO SYSERR ENTRY
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	IBP T1			;INCREMENT POINTER TO NEXT BYTE TO USE
	RETSKP			;DONE, RETURN NEXT SYSERR ENTRY ADDRESS TO USE


STODUP:	ASUBR <DTUREG,DTUDST>

	MOVE T2,DTUREG		;GET ADR OF BLOCK HOLDING REGISTERS
	MOVN T3,1(T2)		;GET -NUMBER OF BYTES OF REGISTER DATA
	ADDI T2,2		;GET ADDRESS OF REGISTER DATA
	HRLI T2,(POINT 8,)	;FORM POINTER TO REGISTER DATA
	MOVE T1,DTUDST		;GET DESTINATION POINTER
	SOUT			;COPY THE REGISTERS INTO SYSERR ENTRY
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	IBP T1			;INCREMENT POINTER TO NEXT BYTE TO USE
	HRRZ T1,T1		;KEEP JUST ADDRESS
	RETSKP			;DONE, RETURN NEXT SYSERR ENTRY ADDRESS TO USE
;FNDCTL - ROUTINE TO FIND THE CONTROLLER AND LINE NUMBERS IN THE
;	  DEVICE ID SENT IN THE NICE EVENT LOGGING MESSAGE
;
;ACCEPTS IN T1/	ADDRESS OF BLOCK CONTAINING LINE ID
;		CALL FNDCTL
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ CONTROLLER #,,LINE #

FNDCTL:	MOVEI T4,1(T1)		;GET ADDRESS OF DEVICE ID
	HRL T1,(T4)		;GET CONTROLLER NUMBER
	HLR T1,1(T4)		;AND GET UNIT NUMBER
	HRR T2,1(T4)		;GET STATION ID
	HRLI T2,-1		;AND DO NOT USE RESERVED BITS
	RETSKP			;DONE
;CVTHDW - ROUTINE TO CONVERT NICE DEVICE CODE TO SYSERR DEVICE CODE
;
;ACCEPTS IN T1/	NICE DEVICE TYPE CODE (.DTXXX) FROM EVENT LOGGING MSG
;		CALL CVTHDW
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ SYSERR DEVICE CODE

CVTHDW:	MOVX T2,HTPTAB		;GET TABLE ADDRESS
	MOVX T3,HTPLEN		;GET TABLE LENGTH
	CALL FNDDSP		;FIND CORRESPONDING SYSERR CODE
	 RETBAD (.NRIPV)	;FAIL, INVALID PARAMETER VALUE
	RETSKP			;DONE, RETURN SUCCESS

; CONVERSION TABLE FOR NICE PROTOCOL TO SYSERR HARDWARE DEVICE TYPE CODES

HTPTAB:	.DTDMC,,.SYDMC
	.DTDTE,,.SYDTE
	.DTDUP,,.SYDUP
	.DTKDP,,.SYKDP
	.DTKDZ,,.SYKDZ

HTPLEN==.-HTPTAB
; ROUTINES TO STORE ITEMS FROM HARDWARE EVENT LOGGING MESSAGE


HSTDEV:	MOVEM T4,HDWDEV		;STORE ADDRESS OF LINE ID
	JRST HDW015		;DONE, RETURN


HSTREG:	MOVEM T4,HDWREG		;SAVE ADDRESS OF BLOCK HOLDING REG DATA
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTUPT:	MOVEM T4,HDWUPT		;SAVE UPTIME
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTRSN:	MOVEM T4,HDWRSN		;SAVE REASON CODE
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTRCV:	MOVEM T4,HDWRCV		;SAVE RECOVERY CODE
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTOPS:	MOVEM T4,HDWOPS		;SAVE OPERATING SYSTEM ID CODE
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTMCD:	MOVEM T4,HDWMCD		;SAVE MICROCODE ID
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTNOD:	MOVEM T4,HDWNOD		;SAVE ADR OF BLOCK HOLDING NODE NAME
	JRST HDW015		;RETURN TO MESSAGE PARSER


HSTTHR:	MOVEM T4,HDWTHR		;SAVE THRESHOLD VALUE
	JRST HDW015		;RETURN TO MESSAGE PARSER
;EVTSYR - ROUTINE TO MAKE A SYSERR HEADER FOR EVENT LOGGING ENTRIES
;
;ACCEPTS IN T1/	BASE ADDRESS OF SYSERR ENTRY
;	    T2/	ASCIZ SOURCE NODE NAME STRING
;	    T3/	SEQUENCE NUMBER
;		CALL EVTSYR
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ ADDRESS OF NEXT WORD TO USE IN SYSERR ENTRY

EVTSYR:	SAVEPQ			;SAVE SOME AC'S
	STKVAR <ESRSRC,ESRSEQ>
	MOVEM T2,ESRSRC		;SAVE POINTER TO SOURCE NODE
	MOVEM T3,ESRSEQ		;SAVE SEQUENCE NUMBER

; INITIALIZE HEADER TO ALL "UNKNOWN"

	MOVE P1,T1		;GET BASE ADDRESS OF SYSERR ENTRY
	MOVEI P2,.SYDAT(P1)	;GET ADDRESS OF START OF NETWORK DATA HEADER
	SETOM (P2)		;INITIALIZE FIRST WORD TO "UNKNOWN"
	HRLZ T1,P2		;START AT NETWORK DATA HEADER
	HRRI T1,1(P2)		;DESTINATION IS NEXT WORD
	BLT T1,.SYPTR-1(P2)	;INITIALIZE ENTIRE NETWORK DATA HEADER

; SET UP SEQUENCE NUMBER

	MOVE T1,ESRSEQ		;GET SEQUENCE NUMBER
	STOR T1,SYSEQ,(P2)	;STORE IN NETWORK HEADER OF SYSERR ENTRY

; ADD TRANSMITTING NODE NAME

	MOVE T1,P1		;GET BASE ADDRESS OF SYSERR ENTRY
	MOVE T2,ESRSRC		;GET POINTER TO SOURCE NODE NAME
	MOVEI T3,.SYPTR+1(P2)	;START AT FIRST ADDRESS AFTER NET DATA HEADER
	CALL SYRSTR		;ADD STRING TO SYSERR ENTRY
	 RETBAD ()		;FAILED
	STOR T2,SYNOD,(P2)	;STORE POINTER TO TRANSMITTING NODE NAME

; ADD DESTINATION NODE NAME

	MOVE T3,T1		;GET NEXT ADR TO USE IN SYSERR ENTRY
	MOVE T2,[POINT 7,OURNAM] ;GET PTR TO OUR NAME (WE ARE DESTINATION)
	MOVE T1,P1		;GET BASE ADDRESS OF SYSERR ENTRY
	CALL SYRSTR		;STORE STRING IN SYSERR ENTRY
	 RETBAD ()		;FAILED
	STOR T2,SYDST,(P2)	;STORE POINTER TO DESTINATION NODE NAME

; DONE. T1 STILL HAS NEXT WORD TO USE IN SYSERR ENTRY FROM SYRSTR CALL

	RETSKP			;RETURN SUCCESS
EVTASC:	RETBAD (.NRIPV)

EVTSFT:	RETBAD (.NRIPV)		;FAIL
SUBTTL	Routines to Default Information from the Configuration Database

;DEFRQL - ROUTINE TO FILL IN DEFAULTS IN DOWN LINE LOAD REQUESTS
;
;CALL:		CALL DEFRQL
;RETURNS: +1	 FAILED, COULD NOT SUPPLY ALL DEFAULTS
;	  +2	SUCCESS, VARIABLES DESCRIBED UNDER GETRQL ROUTINE ALL SET UP

DEFRQL:

; DEFAULT TARGET NODE TO LOAD IF NOT SPECIFIED IN MESSAGE

	MOVE T4,RQLOPT		;GET OPTION BITS
	LOAD T4,LO%TGT,T4	;GET JUST TARGET SPECIFICATION OPTION
	CAIE T4,.LOSRV		;TARGET TO BE DETERMINED BY SERVER AND LINE ?
	JRST DRQ010		;NO, TARGET NODE WAS INCLUDED IN MESSAGE
	MOVE T1,RQLSRV		;YES, GET POINTER TO NAME OF SERVER NODE
	CALL GETNIB		;GET ADDRESS OF NIB FOR SERVER NODE
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDLIN,(T1)	;GET ADDRESS OF SERVER NODE'S LINE TABLE
	DMOVE T2,RQLLIN		;GET SERVER NODE LINE ID
	CALL FNDTGT		;GO FIND THE TARGET NODE AT THE END OF THE LINE
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDNAM,(T1)	;GET POINTER TO NAME OF TARGET NODE
	MOVEM T1,RQLTGT		;SAVE POINTER TO ASCIZ TARGET NODE NAME

; DEFAULT THE BOOTSTRAP PASSWORD IF NEEDED AND NOT SPECIFIED IN MESSAGE

DRQ010:	MOVE T4,RQLOPT		;GET OPTIONS FROM MESSAGE
	LOAD T3,LO%ROM,T4	;GET BOOTSTRAP SPECIFICATION FIELD
	CAIN T3,.LOTBD		;TRIGGER BOOT AND DEFAULT BOOT PASSWORD ?
	JRST [	MOVE T1,RQLTGT	;GET POINTER TO ASCIZ NAME OF TARGET NODE
		CALL DEFBPW	;YES, GO FILL IN DEFAULT FROM DATABASE
		 RETBAD ()	;FAILED, BAD CONFIGURATION FILE
		DMOVEM T3,RQLPSW ;SAVE DEFAULT BOOT PASSWORD
		JRST .+1 ]	;CONTINUE IN MAINLINE CODE

; HERE TO DEFAULT THE INPUT (PRIMARY) LOAD FILE IF NOT SUPPLIED

	MOVE T1,RQLOPT		;GET OPTIONS FROM NICE MESSAGE
	TXNE T1,LO%OPS		;OPERATING SYSTEM FILE INCLUDED IN MESSAGE ?
	JRST DRQ020		;YES, GO CHECK SERVER NODE AND SERVER LINE
	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET ADR OF NODE INFORMATION BLOCK FOR TARGET
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDLOD,(T1)	;GET POINTER TO PRIMARY LOAD FILE
	JUMPE T1,[RETBAD (.NRICF)] ;IF NO FILE IN DATABASE, RETURN ERROR
	MOVEM T1,RQLOPS		;SAVE POINTER TO OPERATING SYSTEM FILE SPEC
	; ..
	; ..

; HERE TO DEFAULT SERVER NODE AND SERVER LINE IF NOT IN NICE MESSAGE

DRQ020:	MOVE T1,RQLOPT		;GET OPTIONS FROM NICE MESSAGE
	LOAD T4,LO%TGT,T4	;GET TARGET SPECIFICATION OPTION
	CAIE T4,.LOTGT		;TARGET SPECIFIED BY NAME & SERVER DEFAULTED ?
	JRST DRQ030		;NO, SERVER WAS INCLUDED IN MESSAGE
	MOVE T1,RQLTGT		;YES, GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET ADDRESS OF NODE INFORMATION BLOCK
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T2,NDSRV,(T1)	;GET POINTER TO DEFAULT SERVER FOR TARGET NODE
	JUMPE T2,[RETBAD (.NRICF)] ;IF NO SERVER KNOWN, RETURN ERROR
	MOVEM T2,RQLSRV		;SAVE POINTER TO ASCIZ SERVER NODE NAME
	LOAD T2,NDSL1,(T1)	;GET FIRST PART OF SERVER LINE ID
	LOAD T3,NDSL2,(T1)	;GET SECOND HALF OF SERVER LINE ID
	DMOVEM T2,RQLLIN	;SAVE SERVER LINE ID

; HERE TO DEFAULT THE PROGRAM REQUEST DATA IF NOT SPECIFIED IN MESSAGE

DRQ030:	MOVE T4,RQLOPT		;GET OPTIONS FROM MESSAGE
	LOAD T3,LO%ROM,T4	;GET ROM FIELD
	CAIE T3,.LODEF		;DEFAULT THE PROGRAM REQUEST ?
	JRST DRQ040		;NO, GO ON
	MOVE T1,RQLTGT		;YES, GET POINTER TO ASCIZ TARGET NODE NAME
	CALL DEFPGM		;GO FILL IN DEFAULT PROGRAM REQUEST DATA
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T4,RQLSID		;SAVE SOFTWARE ID
	MOVEM T3,RQLPGM		;SAVE PROGRAM TYPE REQUESTED
	MOVEM T2,RQLCPU		;SAVE CPU TYPE OF TARGET NODE
	MOVEM T1,RQLLDV		;SAVE LOAD DEVICE AT TARGET NODE

; DEFAULT THE SYSTEM PARAMETERS TO BE PASSED TO THE TARGET NODE IF NEEDED

DRQ040:	MOVE T4,RQLOPT		;GET OPTIONS FROM DOWN-LINE LOAD REQUEST MESSAGE
	TXNE T4,LO%PAR		;PARAMETERS SPECIFIED IN THE MESSAGE ?
	JRST DRQ050		;YES, GO ON...
	MOVE T1,RQLTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL DEFPAR		;GO DEFAULT THE SYSTEM PARAMETERS
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T2,RQLNAM		;SAVE NAME TARGET NODE IS TO USE
	MOVEM T3,RQLNUM		;SAVE NUMBER OF TARGET NODE
	MOVEM T4,RQLHST		;SAVE HOST FOR TASK LOADS

DRQ050:	RETSKP			;DONE, RETURN SUCCESS
;DEFRQD - ROUTINE TO DEFAULT DUMP INFORMATION FROM CONFIGURATION DATABASE
;
;CALL:		CALL DEFRQD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, VARIABLES DESCRIBED UNDER GETRQD ROUTINE ALL SET UP

; DEFAULT TARGET NODE TO BE DUMPED IF NOT INCLUDED IN DUMP REQUEST MESSAGE

DEFRQD:	MOVE T4,RQDOPT		;GET OPTIONS FOR DUMP OPERATION
	LOAD T4,DO%TGT,T4	;GET TARGET ID OPTION FIELD
	CAIE T4,.DOSRV		;TARGET TO BE DETERMINED FROM SERVER & LINE ?
	JRST DFD010		;NO, GO SEE IF SERVER NEEDS TO BE DEFAULTED
	MOVE T1,RQDSRV		;YES, GET POINTER TO ASCIZ NAME OF SERVER NODE
	CALL GETNIB		;GET NODE INFORMATION BLOCK FOR SERVER
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDLIN,(T1)	;GET ADDRESS OF LINE ADJACENCY TABLE
	DMOVE T2,RQDLIN		;GET SERVER LINE ID (2 WORDS)
	CALL FNDTGT		;GO DETERMINE TARGET NODE FOR THIS SERVER & LINE
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDNAM,(T1)	;GET POINTER TO NAME OF TARGET NODE
	MOVEM T1,RQDTGT		;SAVE POINTER TO ASCIZ TARGET NODE NAME

; DEFAULT SERVER NODE AND SERVER LINE IF NOT SPECIFIED IN DUMP REQUEST MESSAGE

DFD010:	MOVE T4,RQDOPT		;GET OPTIONS FROM NICE MESSAGE
	LOAD T4,DO%TGT,T4	;GET TARGET SPECIFICATION OPTION
	CAIE T4,.DOTGT		;TARGET SPECIFIED BY NAME & SERVER DEFAULTED ?
	JRST DFD020		;NO, SERVER WAS INCLUDED IN MESSAGE
	MOVE T1,RQDTGT		;YES, GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET ADDRESS OF NODE INFORMATION BLOCK
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T2,NDSRV,(T1)	;GET POINTER TO DEFAULT SERVER FOR TARGET NODE
	JUMPE T2,[RETBAD (.NRICF)] ;IF NO SERVER KNOWN, RETURN ERROR
	MOVEM T2,RQDSRV		;SAVE POINTER TO ASCIZ SERVER NODE NAME
	LOAD T2,NDSL1,(T1)	;GET FIRST PART OF SERVER LINE ID
	LOAD T3,NDSL2,(T1)	;GET SECOND HALF OF SERVER LINE ID
	DMOVEM T2,RQDLIN	;SAVE SERVER LINE ID

; HERE TO DEFAULT THE DUMP FILESPEC IF NOT SPECIFIED IN DUMP REQUEST MESSAGE

DFD020:	MOVE T1,RQDOPT		;GET OPTIONS FROM NICE MESSAGE
	TXNE T1,DO%FIL		;DUMP FILE INCLUDED IN MESSAGE ?
	JRST DFD030		;YES, GO CHECK ADDRESS AND COUNT
	MOVE T1,RQDTGT		;GET POINTER TO ASCIZ TARGET NODE NAME
	CALL GETNIB		;GET ADR OF NODE INFORMATION BLOCK FOR TARGET
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T1,NDDMP,(T1)	;GET POINTER TO PRIMARY DUMP FILE
	JUMPE T1,[RETBAD (.NRICF)] ;IF NO FILE IN DATABASE, RETURN ERROR
	MOVEM T1,RQDFIL		;SAVE POINTER TO DUMP FILE SPEC
	; ..
	; ..

; HERE TO DEFAULT ADDRESS AND COUNT IF NOT INCLUDED IN THE MESSAGE

DFD030:	MOVE T4,RQDOPT		;GET OPTIONS
	TXNE T4,DO%ADR		;ADDRESS AND COUNT INCLUDED IN MESSAGE ?
	JRST DFD040		;YES, DO NOT DEFAULT THEM

; ASSUME DUMPS BEGIN AT 0 AND 128K IS TO BE DUMPED

	MOVX T1,0		;GET STARTING ADDRESS FOR DUMP
	MOVEM T1,RQDADR		;SAVE STARTING ADDRESS
	MOVX T1,DEFCNT		;GET NUMBER OF LOCATIONS TO DUMP
	MOVEM T1,RQDCNT		;SAVE COUNT OF LOCATIONS TO DUMP

DFD040:	RETSKP			;RETURN TO CALLER
;DEFBPW - ROUTINE TO DEFAULT THE BOOT PASSWORD TO TRIGGER A ROM BOOTSTRAP
;
;ACCEPTS IN T1/	POINTER TO ASCIZ TARGET NODE NAME
;		CALL DEFBPW
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T3-T4/ BOOT PASSWORD

DEFBPW:	CALL GETNIB		;GET ADDRESS OF NODE INFORMATION BLOCK OF TARGET
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T3,NDBP1,(T1)	;LOAD FIRST PART OF BOOT PASSWORD
	LOAD T4,NDBP2,(T1)	;LOAD SECOND PART OF BOOT PASSWORD
	RETSKP			;DONE, RETURN SUCCESS


;DEFPGM - ROUTINE TO DEFAULT THE PROGRAM REQUEST DATA
;
;ACCEPTS IN T1/	POINTER TO ASCIZ TARGET NODE NAME
;		CALL DEFPGM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ BOOT LOAD DEVICE AT TARGET NODE (.DTXXX)
;			      T2/ CPU TYPE OF TARGET NODE (.CPXXX)
;			      T3/ PROGRAM TYPE REQUESTED (.PTXXX)
;			      T4/ POINTER TO SOFTWARE ID REQUESTED

DEFPGM:	CALL GETNIB		;GO GET NODE INFORMATION BLOCK ADDRESS OF TARGET
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	MOVE T4,[POINT 7,[.CHNUL]] ;SOFTWARE ID DEFAULTS TO NULL
	MOVX T3,.PTSLD		;DEFAULT PROGRAM TYE IS SECONDARY LOADER
	LOAD T2,NDCPU,(T1)	;GET CPU TYPE OF TARGET NODE
	LOAD T1,NDLDV,(T1)	;GET LOAD DEVICE TYPE AT TARGET NODE
	RETSKP			;DONE, RETURN


;DEFPAR - ROUTINE TO DEFAULT THE SYSTEM PARAMETERS FOR A DOWN-LINE LOAD
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NAME OF TARGET NODE
;		CALL DEFPAR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T2/ NAME TARGET NODE IS TO USE ON INIT
;			      T3/ NUMBER TARGET NODE IS TO USE
;			      T4/ HOST TARGET IS TO USE FOR TASK LOADS

DEFPAR:	CALL GETNIB		;GO GET THE NODE INFORMATION BLOCK FOR TARGET
	 RETBAD (.NRICF)	;FAILED, RETURN "INVALID CONFIGURATION FILE"
	LOAD T2,NDPNA,(T1)	;GET NAME TARGET NODE IS TO USE
	LOAD T3,NDPNU,(T1)	;GET NUMBER TARGET NODE IS TO USE
	LOAD T4,NDPHT,(T1)	;GET HOST TARGET IS TO USE FOR TASK LOADS
	RETSKP			;DONE, RETURN
SUBTTL	Routines to Extract Fields from NICE Messages

;GETRQL - ROUTINE TO EXTRACT THE FIELDS FROM A NICE REQUEST DOWN-LINE LOAD MSG
;
;ACCEPTS IN T1/	POINTER TO START OF NICE MESSAGE
;	    T2/	NUMBER OF BYTES IN THE MESSAGE
;		CALL GETRQL
;RETURNS: +1	 FAILED, INVALID MESSAGE FORMAT
;	  +2	SUCCESS, WITH THE FOLLOWING VARIABLES SET UP IF THE
;			 ASSOCIATED FIELD IS PRESENT IN THE MESSAGE:
;
;			RQLTGT/	POINTER TO ASCIZ NAME OF TARGET NODE
;			RQLSRV/	POINTER TO ASCIZ NAME OF SERVER NODE
;			RQLLIN/	SERVER LINE ID (2 WORDS)
;			RQLPSW/	BOOT PASSWORD TO TRIGGER TARGET'S BOOTSTRAP ROM
;			RQLLDV/	BOOT LINE DEVICE TYPE AT TARGET NODE
;			RQLCPU/	CPU TYPE OF TARGET SYSTEM (.CPXXX)
;			RQLPGM/	PROGRAM TYPE BEING REQUESTED (.PTXXX)
;			RQLSID/	SOFTWARE ID
;			RQLOPS/	POINTER TO ASCIZ OPERATING SYSTEM FILE SPEC
;			RQLNAM/	POINTER TO ASCIZ NAME TARGET NODE IS TO USE
;			RQLNUM/	NUMBER OF TARGET NODE
;			RQLHST/	POINTER TO ASCIZ NAME OF HOST FOR TASK LOADS

GETRQL:

; SKIP OVER NICE FUNCTION CODE AND GET OPTIONS FROM NICE MESSAGE

	CALL GETFCN		;GET FUNCTION CODE FROM NICE MESSAGE
	 RETBAD (.NRIMF)	;FAILED, RETURN "INVALID MESSAGE FORMAT"
	CALL GETEXB		;OPTION FIELD IS EXTENSIBLE BINARY
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T4,RQLOPT		;SAVE OPTIONS

; GET NAME OF TARGET NODE IF INCLUDED IN MESSAGE

	MOVE T3,RQLOPT		;GET OPTIONS
	LOAD T4,LO%TGT,T3	;GET TARGET SPECIFICATION OPTION
	CAIE T4,.LOTGT		;TARGET NODE SPECIFIED BY NAME ?
	CAIN T4,.LOPTH		; OR EVEN WITH A PATH SPECIFIED ?
	JRST [	CALL GETNOD	;YES, GO GET THE TARGET NODE FROM THE MESSAGE
		 RETBAD (.NRIMF) ;FAILED, RETURN "INVALID MESSAGE FORMAT"
		MOVEM T3,RQLTGT	;SAVE POINTER TO ASCIZ NAME OF TARGET NODE
		JRST .+1]	;RETURN TO MAINLINE CODE
	; ..
	; ..

; GET NAME OF SERVER NODE AND SERVER LINE ID IF SPECIFIED IN MESSAGE

	MOVE T3,RQLOPT		;GET OPTIONS
	LOAD T4,LO%TGT,T3	;GET TARGET SPECIFICATION OPTION
	CAIE T4,.LOPTH		;TARGET NODE SPECIFIED BY PATH ?
	CAIN T4,.LOSRV		; OR SERVER NODE SPECIFIED EXPLICITLY ?
	JRST [	CALL GETNOD	;YES, GO GET THE TARGET NODE FROM THE MESSAGE
		 RETBAD (.NRIMF) ;FAILED, RETURN "INVALID MESSAGE FORMAT"
		MOVEM T3,RQLSRV	;SAVE POINTER TO ASCIZ NAME OF SERVER NODE
		CALL GETLIN	;GET SERVER LINE IDENTIFICATION
		 RETBAD (.NRIMF) ;FAILED, RETURN "INVALID MESSAGE FORMAT"
		DMOVEM T3,RQLLIN ;SAVE SERVER LINE ID (2 WORDS)
		JRST .+1]	;RETURN TO MAINLINE CODE

; GET TARGET NODE BOOT PASSWORD IF INCLUDED IN NICE MESSAGE

	MOVE T3,RQLOPT		;GET OPTIONS
	LOAD T4,LO%ROM,T3	;GET BOOTSTRAP ROM OPTIONS
	CAIN T4,.LOTBP		;BOOT PASSWORD INCLUDED IN MESSAGE ?
	JRST [	CALL GETBPW	;YES, GO GET BOOT PASSWORD FROM NICE MESSAGE
		 RETBAD (.NRIMF) ;FAILED, RETURN "INVALID MESSAGE FORMAT"
		DMOVEM T3,RQLPSW ;SAVE BOOT PASSWORD
		JRST .+1 ]	;RETURN TO MAINLINE CODE

; GET PROGRAM DATA IF INCLUDED IN NICE MESSAGE

	MOVE T3,RQLOPT		;GET OPTIONS
	LOAD T4,LO%ROM,T3	;GET ROM BOOTSTRAP OPTION FIELD
	CAIN T4,.LOPGM		;PROGRAM DATA INCLUDED IN NICE MESSAGE ?
	JRST [	CALL GETPDT	;YES, GO EXTRACT PROGRAM DATA FROM NICE MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		JRST .+1 ]	;RETURN TO MAINLINE CODE
	
; GET OPERATING SYSTEM FILE SPECIFICATION IF INCLUDED IN MESSAGE

	MOVE T4,RQLOPT		;GET OPTIONS
	TXNE T4,LO%OPS		;IS OPERATING SYSTEM FILE SPEC IN MESSAGE ?
	JRST [	CALL GETOPS	;YES, GO GET OPERATING SYSTEM FILE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQLOPS	;SAVE POINTER TO ASCIZ FILE SPEC
		JRST .+1]	;RETURN TO MAINLINE CODE
	; ..
	; ..

; GET SYSTEM PARAMETERS IF INCLUDED IN MESSAGE

	MOVE T4,RQLOPT		;GET OPTIONS
	TXNE T4,LO%PAR		;ARE PARAMETERS INCLUDED IN MESSAGE ?
	JRST [	CALL GETPAR	;YES, GO EXTRACT PARAMETERS FROM MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		JRST .+1]	;RETURN TO MAINLINE CODE

; DONE - ALL FIELDS EXTRACTED FROM NICE DOWN-LINE LOAD REQUEST MESSAGE

	JUMPN T2,[RETBAD (.NRPRO)] ;ANY BYTES LEFT => NICE PROTOCOL ERROR
	RETSKP			;RETURN SUCCESS
;GETRQD - ROUTINE TO EXTRACT THE FIELDS FROM A NICE UP-LINE DUMP
;	  REQUEST MESSAGE.
;
;ACCEPTS IN T1/	POINTER TO START OF NICE UP-LINE DUMP REQUEST MESSAGE
;	    T2/	NUMBER OF BYTES IN THE MESSAGE
;		CALL GETRQD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH THE FOLLOWING FIELDS SET UP:
;
;			RQDTGT/	POINTER TO ASCIZ NAME OF TARGET NODE
;			RQDSRV/	POINTER TO ASCIZ NAME OF SERVER NODE
;			RQDLIN/	SERVER LINE ID (2 WORDS)
;			RQDFIL/	POINTER TO ASCIZ DUMP FILESPEC
;			RQDOPT/	OPTIONS FOR DUMP OPERATION
;			RQDADR/	STARTING ADDRESS FOR THE DUMP
;			RQDCNT/	NUMBER OF UNITS TO DUMP

GETRQD:	CALL GETFCN		;GET FUNCTION CODE FROM NICE MESSAGE
	 RETBAD (.NRIMF)	;FAILED, RETURN "INVALID MESSAGE FORMAT"
	CALL GETEXB		;GO GET OPTIONS FOR DUMP OPERATION
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T4,RQDOPT		;SAVE OPTIONS

; GET NAME OF TARGET NODE TO BE DUMPED

	MOVE T4,RQDOPT		;GET OPTION BITS
	LOAD T4,DO%TGT,T4	;GET TARGET SPECIFICATION FIELD
	CAIE T4,.DOTGT		;EITHER TARGET & PATH OR JUST THE
	CAIN T4,.DOPTH		; TARGET NODE SPECIFIED ?
	JRST [	CALL GETNOD	;YES, GO EXTRACT TARGET NODE NAME FROM MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQDTGT	;SAVE POINTER TO ASCIZ TARGET NODE NAME
		JRST .+1]	;RETURN TO MAINLINE CODE

; EXTRACT PATH TO TARGET IF INCLUDED IN THE MESSAGE

	MOVE T4,RQDOPT		;GET OPTION BITS
	LOAD T4,DO%TGT,T4	;GET TARGET SPECIFICATION OPTION
	CAIE T4,.DOPTH		;BOTH TARGET & PATH, OR JUST THE
	CAIN T4,.DOSRV		; PATH ALONE SPECIFIED ?
	JRST [	CALL GETNOD	;YES, GET NAME OF SERVER NODE FROM MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQDSRV	;SAVE POINTER TO ASCIZ SERVER NODE NAME
		CALL GETLIN	;GO GET SERVER LINE ID
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		DMOVEM T3,RQDLIN ;SAVE SERVER LINE ID
		JRST .+1]	;RETURN TO MAINLINE CODE
	; ..
	; ..

; DETERMINE OUTPUT FILE FOR DUMP

	MOVE T4,RQDOPT		;GET OPTIONS FOR DUMP OPERATION
	TXNE T4,DO%FIL		;OUTPUT FILE SPECIFIED ?
	JRST [	SETZM T3	;NO POINTER PROVIDED
		CALL GETIMA	;YES, GO EXTRACT FILE SPEC FROM MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQDFIL	;SAVE POINTER TO ASCIZ FILE SPEC
		JRST .+1]	;CONTINUE WITH MAINLINE CODE

; EXTRACT STARTING ADR AND COUNT IF PRESENT IN DUMP REQUEST MESSAGE

	MOVE T4,RQDOPT		;GET OPTION BITS
	TXNE T4,DO%ADR		;ADDRESS AND COUNT INCLUDED IN MESSAGE ?
	JRST [	CALL GETMEM	;YES, GO EXTRACT THE ADDRESS
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQDADR	;SAVE STARTING ADDRESS FOR THE DUMP
		CALL GETMEM	;GO EXTRACT THE COUNT FROM THE MESSAGE
		 RETBAD ()	;FAILED, RETURN ERROR TO CALLER
		MOVEM T3,RQDCNT	;SAVE NUMBER OF UNITS TO DUMP
		JRST .+1]	;CONTINUE WITH MAINLINE CODE

; DONE, RETURN TO CALLER

	JUMPN T2,[RETBAD (.NRIMF)] ;ALL FIELDS SHOULD NOW HAVE BEEN EXTRACTED
	RETSKP			;DONE, RETURN SUCCESS
;GETFCN - ROUTINE TO EXTRACT THE FUNCTION CODE FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO START OF NICE MESSAGE (I.E., TO THE FUNCTION CODE)
;	    T2/	NUMBER OF BYTES IN THE NICE MESSAGE
;		CALL GETFCN
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN NICE MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ FUNCTION CODE

GETFCN:	SOSGE T2		;AT LEAST ON BYTE (FUNCTION CODE) IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT"
	ILDB T3,T1		;YES, LOAD THE FUNCTION CODE
	RETSKP			;RETURN SUCCESS


;GETOPT - ROUTINE TO EXTRACT THE OPTION CODE FIELD (SUB-FUNCTION) FROM
;	  A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO OPTION FIELD
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GETOPT
;RETURNS: +1	 FAILED, NOT ENOUGH BYTES LEFT IN MESSAGE
;	  +2	SUCCESS, WITH OPTION CODE IN T4, PTR AND COUNT UPDATED


GETOPT:	CALLRET GETEXB		;GET EXTENSIBLE BINARY FIELD
;GETPDT - ROUTINE TO EXTRACT THE PROGRAM DATA FIELDS FROM A NICE
;	    DOWN-LINE LOAD REQUEST MESSAGE
;
;ACCEPTS IN T1/	POINTER TO START OF PROGRAM DATA FIELDS
;	    T2/	COUNT OF BYTES REMAINING IN MESSAGE
;		CALL GETPDT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH THE FOLLOWING VARIABLES SET UP:
;			RQLLDV/	BOOT LINE DEVICE TYPE AT TARGET NODE
;			RQLCPU/	CPU TYPE OF TARGET SYSTEM (.CPXXX)
;			RQLPGM/	PROGRAM TYPE BEING REQUESTED (.PTXXX)
;			RQLSID/	SOFTWARE ID

GETPDT:	ASUBR <GTPPTR,GTPCNT>

	CALL GETLDV		;GO GET BOOT LINE DEVICE TYPE AT TARGET NODE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLLDV		;SAVE BOOT LINE DEVICE TYPE (.DTXXX)
	CALL GETCPU		;GO GET CPU TYPE OF TARGET SYSTEM
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLCPU		;SAVE CPU TYPE OF TARGET (.CPXXX)
	CALL GETPGM		;GO GET PROGRAM TYPE REQUESTED
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLPGM		;SAVE PROGRAM TYPE (.PTXXX)
	CALL GETSID		;GO GET SOFTWARE ID OF SOFTWARE REQUESTED
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLSID		;SAVE FURTHER IDENTIFICATION OF SOFTWARE WANTED
	RETSKP			;DONE, RETURN TO CALLER
;GETLDV - ROUTINE TO EXTRACT THE BOOT LOAD DEVICE TYPE FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (DEVICE TYPE) IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETLDV
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN NICE MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ DEVICE TYPE CODE (.DTXXX)

GETLDV:	SOSGE T2		;AT LEAST ONE BYTE REMAINING IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T3,T1		;YES, GET DEVICE TYPE CODE (.DTXXX)
	RETSKP			;DONE, RETURN SUCCESS

;GETCPU - ROUTINE TO EXTRACT THE CPU TYPE FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (CPU TYPE) IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETCPU
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDQTED POINTER TO NEXT FIELD IN NICE MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ DEVICE TYPE CODE (.CPXXX)
GETCPU:	SOSGE T2		;AT LEAST ONE BYTE REMAINING IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T3,T1		;YES, GET CPU TYPE CODE (.CPXXX)
	RETSKP			;DONE, RETURN SUCCESS


;GETPGM - ROUTINE TO EXTRACT THE PROGRAM TYPE FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (PROGRAM TYPE) IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETPGM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN NICE MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ PROGRAM TYPE CODE (.PTXXX)

GETPGM:	SOSGE T2		;AT LEAST ONE BYTE REMAINING IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T3,T1		;YES, GET PROGRAM TYPE CODE (.PTXXX)
	RETSKP			;DONE, RETURN SUCCESS
;GETSID - ROUTINE TO GET A SOFTWARE ID FIELD FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (SOFTWARE ID) IN MESSAGE
;	    T2/	NUMBER OF BYTES LEFT IN MESSAGE
;		CALL GETSID
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ POINTER TO ASCIZ SOFTWARE ID STRING

GETSID:	MOVE T4,T1		;COPY POINTER TO # OF CHARACTERS IN STRING
	ILDB T3,T4		;GET NUMBER OF CHARACTERS IN SOFTWARE ID
	CAILE T3,MAXSID		;IS STRING LONGER THAN MAX ALLOWED ?
	RETBAD (.NRIMF)		;YES, RETURN "INVALID MESSAGE FORMAT" ERROR
	SETZM T3		;NO POINTER PROVIDED
	CALL GETIMA		;NO, GO GET AN ASCIZ STRING FROM AN IMAGE FIELD
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, RETURN WITH T3/ POINTER TO STRING


;GETBPW - ROUTINE TO EXTRACT THE BOOT PASSWORD FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (BOOT PASSWORD) IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETBPW
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN NICE MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T4-T3/ 64 BIT BOOT PASSWORD, RIGHT JUSTIFIED

GETBPW:	MOVE T4,T1		;COPY POINTER TO NUMBER OF BYTES IN PASSWORD
	ILDB T3,T4		;GET NUMBER OF BYTES IN BOOT PASSWORD
	CAILE T3,MBPWSZ		;PASSWORD FIELD TOO BIG ?
	RETBAD (.NRIMF)		;YES, RETURN "INVALID MESSAGE FORMAT" ERROR
	CALL GETIMB		;GO GET BINARY NUMBER FROM IMAGE FIELD
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, RETURN WITH T3-T4/ BINARY PASSWORD


;GETOPS - ROUTINE TO EXTRACT THE OPERATION SYSTEM FILE SPEC FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (FILE SPEC) IN MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GETOPS
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ POINTER TO ASCIZ OPERATING SYSTEM FILE SPEC

GETOPS:	SETZM T3		;NO POINTER PROVIDED
	CALL GETIMA		;GO GET AN ASCII STRING FROM AN IMAGE FIELD
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, T3 HAS POINTER TO FILE SPEC
;GETPAR - ROUTINE TO EXTRACT THE SYSTEM PARAMETERS FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (SYSTEM PARAMETERS) IN MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN THE MESSAGE
;		CALL GETPAR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;  PARAMETERS:
;			RQLNAM/	POINTER TO ASCIZ NAME TARGET NODE IS TO USE
;			RQLNUM/	NUMBER OF TARGET NODE
;			RQLHST/	POINTER TO ASCIZ NAME OF HOST FOR TASK LOADS

GETPAR:	ASUBR <GTPPTR,GTPCNT>

	SETOM RQLNAM		;INITIALIZE THE SYSTEM PARAMETERS TO KNOWN
	SETOM RQLNUM		; VALUES SO THAT IT CAN BE DETERMINED WHICH
	SETOM RQLHST		; PARAMETERS WERE EXTRACTED FROM THE MESSAGE
	SOSGE GTPCNT		;AT LEAST ONE BYTE LEFT IN THE MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T4,GTPPTR		;GET NUMBER OF BYTES IN PARAMETER FIELD
	CAMLE T4,T2		;AT LEAST THAT MANY BYTES LEFT IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	MOVE T1,GTPPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	MOVE T2,GTPCNT		;GET COUNT OF BYTES LEFT IN MESSAGE

; LOOP OVER EACH PARAMETER

GTP010:	SOSGE T2		;DECREMENT BYTE COUNT
	RETBAD (.NRIMF)		;NOT ENOUGH BYTES IN MESSAGE, RETURN ERROR
	ILDB T3,T1		;GET PARAMETER VALUE TYPE CODE (.PVXXX)
	CAIle T3,.PVHST		;PARAMETER VALUE WITHIN ACCEPTABLE RANGE ?
	RETBAD (.NRIPV)		;NO, RETURN "INVALID PARAMETER VALUE" ERROR
	CAIN T3,.PVEND		;END MARK ENCOUNTERED ?
	RETSKP			;YES, RETURN SUCCESS
	MOVE T3,PARTAB(T3)	;GET DISPATCH ADDRESS
	CALL (T3)		;GO HANDLE THIS TYPE OF PARAMETER
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	JRST GTP010		;GO GET NEXT PARAMETER


; TABLE OF DISPATCH ADDRESSES TO EXTRACT PARAMETERS FROM NICE MESSAGES

PARTAB:	RSKP			;END MARK, NO OP
	PARNAM			;NAME NODE IS TO USE FOR NODE INIT
	PARNUM			;NUMBER NODE IS TO USE
	PARHST			;HOST FOR TASK LOADS
;PARNAM - ROUTINE TO EXTRACT THE NODE NAME PARAMETER FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NODE NAME
;	    T2/ NUMBER OF BYTES LEFT IN MESSAGE
;		CALL PARNAM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      RQLNAM/ POINTER TO NODE NAME

PARNAM:	CALL GETNOD		;GO GET THE NODE NAME
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLNAM		;SAVE NAME PARAMETER
	RETSKP			;DONE, RETURN SUCCESS

;PARNUM - ROUTINE TO RETURN THE NUMBER TO BE USED BY THE TARGET NODE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (NUMBER) IN NICE MESSAGE
;	    T2/ NUMBER OF BYTES LEFT IN MESSAGE
;		CALL PARNUM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      RQLNUM/ NUMBER TO BE USED

PARNUM:	SOJL T2,[RETBAD (.NRIMF)] ;DECREMENT COUNT FOR COUNT-BYTE
	ILDB T4,T1		;GET COUNT BYTE
	CAIE T4,2		;A TWO BYTE NUMBER ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT"
	CALL GETTWO		;GO GET THE NEXT TWO BYTE FIELD FROM THE MESSAGE
	 JRST [RETBAD (.NRIMF)] ;FAIL IF INSUFFICIENT BYTES IN MESSAGE
	MOVEM T4,RQLNUM		;SAVE THE NUMBER
	RETSKP			;DONE, RETURN SUCCESS


;PARHST - ROUTINE TO EXTRACT THE TASK LOAD HOST NAME FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NODE NAME
;	    T2/ NUMBER OF BYTES LEFT IN MESSAGE
;		CALL PARHST
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      RQLHST/ POINTER TO NODE NAME

PARHST:	CALL GETNOD		;GO GET THE NODE NAME
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVEM T3,RQLHST		;SAVE POINTER TO NAME OF HOST FOR TASK LOADS
	RETSKP			;DONE, RETURN SUCCESS
;GETIMA - ROUTINE TO GET AN ASCII STRING FROM AN IMAGE FIELD IN A NICE MSG
;
;ACCEPTS IN T1/	POINTER TO START OF IMAGE FIELD
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;	    T3/	0 TO USE GENERAL STRING AREA, OR POINTER FOR ASCII STRING
;		CALL GETIMA
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ POINTER TO ASCIZ STRING IN STRING STORAGE AREA

GETIMA::ASUBR <GIAPTR,GIACNT,GIADST,GIALEN>

	SOSGE T3,GIACNT		;AT LEAST ONE BYTE REMAINING IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T4,GIAPTR		;YES, GET # OF CHARACTERS IN STRING
	CAMLE T4,GIACNT		;AT LEAST THAT MANY CHARACTERS LEFT IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	MOVEM T4,GIALEN		;SAVE # OF CHARACTERS IN FIELD
	SUB T3,T4		;COMPUTE # OF BYTES REMAINING AFTER THIS FIELD
	MOVEM T3,GIACNT		;SAVE UPDATED BYTE COUNT
	SKIPN T3,GIADST		;ANY POINTER PROVIDED AS INPUT ?
	MOVE T3,[POINT 7,TMPSTR] ;NO, SET UP POINTER TO TEMPORARY DESTINATION

; LOOP OVER EACH CHARACTER IN THE STRING

GIA010:	SOJL T4,GIA020		;DECREMENT COUNT OF CHARACTERS LEFT IN STRING
	ILDB T2,GIAPTR		;GET A CHARACTER FROM THE STRING
	SKIPE T2			;DISCARD NULLS
	IDPB T2,T3		;STORE CHARACTER INTO TEMPORARY DESTINATION
	JRST GIA010		;LOOP OVER ALL CHARACTERS IN THE STRING

; TERMINATE THE STRING WITH A NULL AND MOVE TO STRING STORAGE AREA

GIA020:	MOVEI T2,.CHNUL		;GET A NULL
	IDPB T2,T3		;TERMINATE THE STRING WITH A NULL
	SKIPE GIADST		;WAS A DESTINATION POINTER SUPPLIED ?
	JRST [	MOVE T1,T3	;COPY POINTER TO END OF STRING
		JRST GIA030 ]	;GET REMAINING ITEMS TO RETURN
	MOVEI T1,TMPSTR		;GET ADDRESS OF TEMPORARY STRING LOCATION
	CALL STOSTR		;STORE THE STRING IN THE PERMANENT STRING AREA
	 RETBAD (.NRRES)	;FAILED, RETURN "RESOURCE ERROR"
	MOVE T3,T1		;GET POINTER TO PERMANENT STRING LOCATION
GIA030:	MOVE T2,GIACNT		;GET # OF BYTES REMAINING IN MESSAGE
	MOVE T1,GIAPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	MOVE T4,GIALEN		;RETURN LENGTH OF FIELD
	RETSKP			;DONE, RETURN SUCCESS
;GETIMB - ROUTINE TO EXTRACT A BINARY NUMBER FROM AN IMAGE FIELD
;
;ACCEPTS IN T1/	POINTER TO START OF FIELD
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GETIMB
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3-T4/ BINARY NUMBER

GETIMB:	ASUBR <GIBPTR,GIBCNT,GIBSFT>

	SOSGE T3,GIBCNT		;AT LEAST ONE BYTE REMAINING IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	ILDB T1,GIBPTR		;YES, GET # OF CHARACTERS IN STRING
	CAMLE T1,GIBCNT		;AT LEAST THAT MANY CHARACTERS LEFT IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	SUB T3,T1		;COMPUTE COUNT REMAINING AFTER THIS FIELD
	MOVEM T3,GIBCNT		;SAVE UPDATED COUNT
	MOVEI T2,MAXIMB		;GET MAX NUMBER OF BYTES IN IMAGE BINARY FIELDS
	SUB T2,T1		;COMPUTE NUMBER OF EXTRA HIGH ORDER BYTES
	MOVEM T2,GIBSFT		;SAVE NUMBER OF EXTRA SHIFTS TO DO
	SETZB T3,T4		;CLEAR ACCUMULATORS TO RECEIVE RESULT

; LOOP OVER EACH BYTE IN THE FIELD

GIB010:	SOJL T1,GIB020		;IF ALL BYTES DEPOSITED, GO DO REMAINING SHIFTS
	LSHC T3,-8		;SHIFT ANY PREVIOUS BYTES RIGHT ONE BYTE
	ILDB T2,GIBPTR		;GET A BYTE FROM THE IMAGE FIELD
	DPB T2,[POINT 8,T3,7]	;DEPOSIT INTO HIGH ORDER END OF BINARY NUMBER
	JRST GIB010		;LOOP OVER ALL BYTES IN THE FIELD

; HERE TO SHIFT THE NUMBER UNTIL IT IS RIGHT-ADJUSTED IN THE TWO AC'S

GIB020:	SOSGE GIBSFT		;ANOTHER SHIFT REQUIRED ?
	JRST GIB030		;NO, GO RETURN TO CALLER
	LSHC T3,-8		;YES, MOVE THE NUMBER ONE BYTE TO THE RIGHT
	JRST GIB020		;LOOP OVER EACH EXTRA HIGH ORDER BYTE

; HERE TO RETURN TO CALLER

GIB030:	MOVE T1,GIBPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	MOVE T2,GIBCNT		;GET UPDATED COUNT OF BYTES LEFT IN MESSAGE
	RETSKP			;RETURN, T3 AND T4 CONTAIN THE BINARY NUMBER
;GETLIN - ROUTINE TO GET A LINE ID FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (LINE ID) IN NICE MESSAGE
;	    T2/	COUNT OF NUMBER OF BYTES LEFT IN NICE MESSAGE
;		CALL GETLIN
;RETURNS: +1	 FAILED, NICE RETURN CODE
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ LINE DEVICE TYPE (.DTXXX),,LINE CONTROLLER #
;			      T4/ LINE UNIT NUMBER,,LINE STATION ADDRESS
;
; NOTE:  IF "ALL LINES" IS SPECIFIED AS THE LINE ID, THEN ON A SUCCESS
;	 RETURN, T3/ -1 AND T4/ UNDEFINED

GETLIN::ASUBR <GTLPTR,GTLCNT>
	SOSGE GTLCNT		;AT LEAST ONE BYTE LEFT IN MESSAGE ?
	RETBAD (.NRILN)		;NO, RETURN "INVALID LINE ID" ERROR
	ILDB T4,GTLPTR		;GET LINE ID FORMAT BYTE
	CAIL T4,.LTALL		;IS THE LINE ID FORMAT WITHIN
	CAILE T4,.LTSTR		; LEGAL LIMITS ?
	RETBAD (.NRILN)		;NO, RETURN "INVALID LINE ID" ERROR
	MOVE T1,GTLPTR		;GET POINTER TO REMAINDER OF LINE ID
	MOVE T2,GTLCNT		;GET REMAINING COUNT OF BYTES IN MESSAGE
	CALLRET @GTLTAB(T4)	;YES, CALL LINE-FORMAT-SPECIFIC ROUTINE


; TABLE OF LINE-FORMAT-SPECIFIC ROUTINES TO EXTRACT LINE-ID'S FROM MESSAGES

GTLTAB:	GTLALL			;ALL LINES
	GTLSTD			;STANDARD NICE PROTOCOL LINE IDENTIFIER
	GTLSTR			;ASCII NAME STRING
;GTLALL - ROUTINE TO EXTRACT A FORMAT 0 LINE ID FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO BYTE AFTER LINE ID FORMAT
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GTLALL
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES IN MESSAGE
;			      T3/ -1, INDICATING "ALL LINES" WAS SPECIFIED

GTLALL:	SETOM T3		;NOTE THAT ALL LINES WAS SPECIFIED IN MESSAGE
	RETSKP			;DONE, RETURN

;GTLSTD - ROUTINE TO EXTRACT A STANDARD NICE LINE ID FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO BYTE AFTER LINE ID FORMAT BYTE
;	    T2/	COUNT OF BYTES REMAINING IN NICE MESSAGE
;		CALL GTLSTD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3/ LINE DEVICE TYPE (.DTXXX),,LINE CONTROLLER #
;			      T4/ LINE UNIT NUMBER,,LINE STATION ADDRESS

GTLSTD:	SUBI T2,4		;DECREMENT REMAINING BYTES BY LINE ID BYTES
	JUMPL T2,[RETBAD (.NRILN)] ;IF NOT ENOUGH BYTES LEFT, RETURN ERROR
	PUSH P,T2		;SAVE COUNT
	ILDB T2,T1		;GET LINE DEVICE TYPE (.DTXXX)
	ILDB T3,T1		;GET LINE CONTROLLER NUMBER
	HRL T3,T2		;PUT DEVICE TYPE IN LH
	ILDB T2,T1		;GET LINE UNIT NUMBER
	ILDB T4,T1		;GET LINE STATION NUMBER
	HRL T4,T2		;FORM UNIT,,STATION NUMBERS
	POP P,T2		;RESTORE COUNT
	RETSKP			;DONE, RETURN SUCCESS


;GTLSTR - ROUTINE TO EXTRACT A LINE IN FORMAT 2 (STRING) FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO BYTE AFTER LINE ID FORMAT BYTE
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GTLSTR
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3-T4/ LINE ID IN STANDARD FORMAT

GTLSTR:	RETBAD (.NRILN)		;FOR NOW, JUST FAIL- STRINGS NOT SUPPORTED
;GETMEM - ROUTINE TO GET A MEMORY ADDRESS FROM A NICE OR MOP MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (MEM ADDRESS) IN MESSAGE
;	    T2/	NUMBER OF BYTES LEFT IN THE MESSAGE
;		CALL GETMEM
;RETURNS: +1	 FAILED, BADLY FORMED MESSAGE
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ MEMORY ADDRESS (OR MEMORY SIZE)

GETMEM:	ASUBR <GTMPTR,GTMCNT>

	MOVE T2,GTMCNT		;GET # OF BYTES LEFT IN MESSAGE
	SUBI T2,4		;DECREMENT BY SIZE OF MEM ADDRESS
	JUMPL T2,R		;RETURN FAILURE IF NOT ENOUGH BYTES LEFT
	MOVEM T2,GTMCNT		;SAVE UPDATED BYTE COUNT
	MOVE T1,GTMPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	CALL GET4		;GET THE NEXT 4-BYTE FIELD FROM MESSAGE
	MOVE T3,T2		;GET MEMORY ADDRESS
	MOVE T2,GTMCNT		;GET UPDATED BYTE COUNT
	RETSKP			;DONE, RETURN



;GETTWO - ROUTINE TO GET A TWO BYTE NUMBER FROM A NICE MESSAGE
;
;ACCEPTS  T1/ POINTER TO NEXT FIELD IN NICE MESSAGE
;	  T2/ COUNT OF BYTES LEFT IN NICE MESSAGE
;		CALL GETTWO
;RETURNS: +1	FAILED
;	  +2 WITH T1/ UPDATED BYTE POINTER
;		  T2/ UPDATED BYTE COUNTER
;		  T3/ NUMBER FROM NICE MESSAGE

GETTWO::SOSG T2			;ANOTHER BYTE ?
	RET
	ILDB T3,T1		;GET NEXT BYTE FROM MESSAGE
	SOSGE T2		;ANOTHER BYTE ?
	RET
	ILDB T4,T1		;GET SECOND BYTE FROM MESSAGE
	DPB T4,[POINT 8,T3,27]	;ADD HIGH ORDER BYTE OF NUMBER
	RETSKP			;RETURN
;GETFLD - ROUTINE TO EXTRACT A FIELD FROM AN EVENT LOGGING NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MSG
;	    T2/	NUMBER OF BYTES LEFT IN MESSAGE
;		CALL GETFLD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ DATA TYPE CODE OF THIS FIELD
;			      T4/ DATA-TYPE-DEPENDENT INFO

GETFLD:	SOSGE T2		;AT LEAST ONE BYTE LEFT
	RETBAD (.NRIMF)		;FAILED, INVALID MESSAGE FORMAT
	ILDB T3,T1		;GET DATA TYPE ID BYTE
	CAIL T3,EVTLEN		;VALID DATA TYPE SPECIFIED ?
	RETBAD (.NRIMF)		;NO, FAIL WITH INVALID MESSAGE FORMAT
	CALLRET @EVTDSP(T3)	;EXTRACT SPECIFIC DATA

EVTDSP:	RETBAD (.NRIMF)		;  0 - ILLEGAL
	REGFLD			;  1 - DEVICE REGISTERS
	TIMFLD			;  2 - TIME OF DAY
	DATFLD			;  3 - DATE
	UPTFLD			;  4 - UPTIME
	DEVFLD			;  5 - DEVICE
	RSNFLD			;  6 - REASON CODE
	RCVFLD			;  7 - RECOVERY ACTION
	OPSFLD			;  8 - OPERATING SYSTEM
	NODFLD			;  9 - NODE ID
	MCDFLD			;  10 - MICROCODE DESCRIPTOR
	LPRFLD			; 11 - LINE PROTOCOL
	TPRFLD			; 12 - TRANSMISSION PROTOCOL
	THRFLD			; 13 - THRESHOLD VALUE
	TXTFLD			; 14 - ASCII TEXT
EVTLEN==.-EVTDSP
; ROUTINES TO EXTRACT SPECIFIC FIELDS FROM NICE EVENT LOGGING MESSAGES

; DATFLD - EXTRACT DATE FIELD FROM A NICE EVENT LOGGING MESSAGE

DATFLD:	STKVAR <DTFDAY,DTFMON,DTFYR,DTFPTR,DTFCNT>
	SUBI T2,2		;DECREMENT COUNT BY SIZE OF DAY AND MONTH
	JUMPLE T2,[RETBAD (.NRIMF)] ;FAIL IF NOT ENOUGH BYTES
	ILDB T3,T1		;GET THE DAY
	MOVEM T3,DTFDAY		;SAVE THE DAY
	ILDB T3,T1		;GET THE MONTH
	MOVEM T3,DTFMON		;SAVE MONTH
	CALL GETTWO		;GET THE YEAR
	 RETBAD ()		;FAILED, RETURN ERROR
	MOVEM T3,DTFYR		;SAVE YEAR
	MOVEM T2,DTFCNT		;SAVE CURRENT COUNT OF BYTES IN MESSAGE
	MOVEM T1,DTFPTR		;SAVE POINTER TO NEXT FIELD IN MESSAGE

; CONVERT DATE TO STANDARD TOPS20 FORMAT

	HRL T2,DTFYR		;GET THE YEAR
	HRR T2,DTFMON		;GET THE MONTH
	HRLZ T3,DTFDAY		;GET THE DAY
	MOVX T4,0		;NO FLAGS
	IDCNV			;CONVERT THE DATE
	 ERJMP [RETBAD (.NRNPE)] ;FAILED
	MOVE T4,T2		;GET DATE
	MOVX T3,.EDDAT		;GET EVENT DATA TYPE CODE
	MOVE T2,DTFCNT		;GET COUNT OF BYTES IN MESSAGE
	MOVE T1,DTFPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
; UPTFLD - ROUTINE TO EXTRACT NODE UPTIME FROM A NICE EVENT LOGGING MESSAGE

UPTFLD:	CALL GETEXB		;GET UPTIME
	 RETBAD ()		;FAILED
	MOVX T3,.EDUPT		;GET EVENT DATA TYPE CODE
	RETSKP			;DONE, RETURN SUCCESS


; DEVFLD - ROUTINE TO EXTRACT A DEVICE DESIGNATOR FROM A NICE LOGGING MESSAGE

DEVFLD:	STKVAR <DVFBLK,DVFPTR,DVFCNT,<DVFDEV,2>>

; EXTRACT THE DEVICE ID FROM THE MESSAGE

	SOSGE T2		;AT LEAST IMAGE FIELD BYTE COUNT PRESENT ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,T1		;YES, GET NUMBER OF BYTES IN DEVICE ID
	SUB T2,T4		;ENOUGH BYTES LEFT IN MESSAGE ?
	JUMPL T2,[RETBAD (.NRIMF)] ;NO, FAIL
	SUBI T4,3		;AT LEAST FORMAT CODE BYTE, DEVICE TYPE, AND
	JUMPL T4,[RETBAD (.NRILN)] ; CONTROLLER NUMBER MUST BE PRESENT
	ILDB T3,T1		;YES, GET FORMAT CODE BYTE
	CAIE T3,.LTSTD		;STANDARD LINE ID FORMAT ?
	RETBAD (.NRILN)		;NO, INVALID LINE ID
	ILDB T3,T1		;GET DEVICE TYPE CODE (.DTXXX)
	HRLM T3,DVFDEV		;SAVE DEVICE TYPE CODE
	ILDB T3,T1		;GET CONTROLLER NUMBER
	HRRM T3,DVFDEV		;SAVE CONTROLLER NUMBER
	SETOM 1+DVFDEV		;INITIALIZE UNIT AND STATION NUMBERS
	SOSGE T4		;IS UNIT NUMBER PRESENT ?
	JRST DVFLD2		;NO, GO SAVE DEVICE ID
	ILDB T3,T1		;YES, GET UNIT NUMBER
	HRLM T3,1+DVFDEV	;SAVE UNIT NUMBER
	SOSGE T4		;STATION ADDRESS PRESENT ?
	JRST DVFLD2		;NO, GO SAVE DEVICE ID
	ILDB T3,T1		;GET STATION ADDRESS
	HRRM T3,1+DVFDEV	;SAVE STATION ADDRESS

; ASSIGN FREE SPACE TO HOLD DEVICE

DVFLD2:	MOVEM T2,DVFCNT		;SAVE COUNT OF BYTES IN MESSAGE
	MOVEM T1,DVFPTR		;SAVE UPDATED POINTER
	MOVX T1,3		;DEVICE ID'S ARE 2 WORDS LONG
	CALL GETFRE		;GET SOME FREE SPACE
	 RETBAD ()		;FAILED
	MOVEM T1,DVFBLK		;SAVE BLOCK ADDRESS

; RETURN BLOCK WITH DEVICE

	DMOVE T2,DVFDEV		;GET DEVICE
	DMOVEM T2,1(T1)		;SAVE DEVICE
	MOVE T4,T1		;GET ADDRESS OF BLOCK HOLDING DEV
	MOVX T3,.EDDEV		;GET EVENT DATA TYPE FOR A DEVICE
	MOVE T2,DVFCNT		;GET COUNT OF BYTES LEFT IN MESSAGE
	MOVE T1,DVFPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	RETSKP			;DONE, RETURN SUCCESS


RSNFLD:	CALL GETEXB		;GET REASON
	 RETBAD ()		;FAILED
	MOVX T3,.EDRSN		;GET EVENT DATA TYPE CODE
	RETSKP			;DONE, RETURN SUCCESS
;NODFLD - EXTRACT NODE ID FROM NICE EVENT LOGGING MESSAGE

NODFLD:	STKVAR <NDFPTR,NDFCNT,NDFBLK>
	MOVEM T1,NDFPTR		;SAVE POINTER INTO NICE MESSAGE
	MOVEM T2,NDFCNT		;SAVE NUMBER OF BYTES LEFT IN MSG

; ASSIGN FREE SPACE FOR THE NODE NAME

	MOVX T1,3		;GET MAX NUMBER OF WORDS IN A NODE NAME
	CALL GETFRE		;ASSIGN FREE SPACE
	 RETBAD ()		;FAILED
	MOVEM T1,NDFBLK		;SAVE ADDRESS OF FREE BLOCK

; EXTRACT NODE NAME FROM THE MESSAGE

	MOVE T3,NDFBLK		;GET ADDRESS OF FREE BLOCK
	HRLI T3,(POINT 7,0,35)	;FORM POINTER TO DESTINATION FOR NAME
	MOVE T2,NDFCNT		;GET # OF BYTES LEFT IN NICE MESSAGE
	MOVE T1,NDFPTR		;GET POINTER TO NODE NAME FIELD
	CALL GETIMA		;EXTRACT NODE ID FROM MESSAGE
	 JRST NDFERR		;FAILED, FREE SPACE AND RETURN ERROR
	MOVX T3,.EDNOD		;GET NODE DATA TYPE CODE
	MOVE T4,NDFBLK		;GET ADDRESS OF BLOCK HOLDING NAME
	HRLI T4,(POINT 7,0,35)	;POINT TO NODE NAME
	RETSKP			;DONE, RETURN SUCCESS

; HERE ON AN ERROR TO RELEASE SPACE

NDFERR:	EXCH T1,NDFBLK		;GET BLOCK ADDRESS AND SAVE ERROR CODE
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		; Die on release failure
	MOVE T1,NDFBLK		;RESTORE ERROR CODE
	RETBAD ()		;FAIL
; MCDFLD - EXTRACT MICROCODE DESCRIPTOR FROM NICE EVENT LOGGING MESSAGE

MCDFLD:	SUBI T2,2		;MICROCODE ID IS TWO BYTES
	JUMPL T2,[RETBAD (.NRIMF)] ;FAIL IF NOT ENOUGH BYTES
	ILDB T3,T1		;GET MICROCODE TYPE
	ILDB T4,T1		;GET MICROCODE VERSION
	HRL T4,T3		;FORM TYPE,,VERSION
	MOVX T3,.EDMCD		;GET MICROCODE DATA TYPE CODE
	RETSKP			;RETURN MICROCODE ID


; ASCII DATA

TXTFLD:	ASUBR <AFDPTR,AFDCNT,AFDBLK,AFDSTR>
	MOVE T1,AFDCNT		;GET NUMBER OF BYTES TO EXTRACT
	IDIVI T1,5		;COMPUTE # OF WORDS
	SKIPE T2		;ROUND UP IF
	ADDI T1,1		; NECESSARY
	ADDI T1,1		;ACCOUNT FOR BLOCK HEADER
	CALL GETFRE		;GET FREE SPACE FOR THE TEXT
	 RETBAD ()		;FAILED
	HRLI T1,(POINT 7,0,35)	;FORM POINTER TO DESTINATION
	MOVEM T1,AFDSTR		;SAVE POINTER TO STRING
	MOVE T3,T1		;GET POINTER TO DESTINATION FOR TEXT
	MOVE T2,AFDCNT		;GET COUNT OF BYTES LEFT IN MESSAGE
	MOVE T1,AFDPTR		;GET POINTER TO MESSAGE
	CALL GETIMA		;EXTRACT IMAGE ASCII DATA
	 RETBAD ()		;FAILED
	MOVX T3,.EDTXT		;GET ASCII DATA TYPE CODE
	MOVE T4,AFDSTR		;GET POINTER TO ASCII STRING
	RETSKP			;DONE, RETURN SUCCESS
;REGFLD - ROUTINE TO EXTRACT REGISTER DATA FROM NICE EVENT LOGGING MESSAGE


REGFLD:	ASUBR <RGFPTR,RGFCNT,RGFNUM,RGFBLK>

; COMPUTE NUMBER OF BYTES IN REGISTER DATA

	SOSGE RGFCNT		;AT LEAST COUNT BYTE PRESENT ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T1,RGFPTR		;GET NUMBER OF BYTES IN REGISTER DATA
	MOVEM T1,RGFNUM		;SAVE NUMBER OF BYTES TO MOVE

; CHECK THAT ENOUGH BYTES ARE ACTUALLY PRESENT IN MESSAGE

	MOVE T2,RGFCNT		;GET NUMBER OF BYTES LEFT IN MESSAGE
	SUB T2,T1		;COMPUTE # LEFT AFTER REMOVING REGISTER DATA
	JUMPL T2,[RETBAD (.NRIMF)] ;NOT ENOUGH BYTES LEFT
	MOVEM T2,RGFCNT		;STORE UPDATED COUNT OF BYTES LEFT IN MESSAGE

; ASSIGN SPACE TO HOLD THE REGISTER DATA

	IDIVI T1,4		;COMPUTE # OF WORDS NEEDED FOR THAT MANY BYTES
	SKIPE T2		; AND ROUND UP
	ADDI T1,1		; IF NEEDED
	ADDI T1,2		;ACCOUNT FOR BLOCK HEADER AND WORD HOLDING COUNT
	CALL GETFRE		;ASSIGN SPACE FOR REGISTER DATA
	 RETBAD ()		;FAILED
	MOVEM T1,RGFBLK		;SAVE BLOCK ADDRESS

; SET UP TO EXTRACT THE REGISTER DATA

	MOVE T4,RGFNUM		;GET COUNT OF BYTES IN REGISTER DATA
	MOVEM T4,1(T1)		;STORE IN ASSIGNED BLOCK
	MOVEI T3,2(T1)		;GET DESTINATION ADDRESS
	HRLI T3,(POINT 8,)	;FORM DESTINATION POINTER

; PLACE ALL THE REGISTER DATA IN THE ASSIGNED BLOCK

RGF010:	SOSGE T4		;ANY BYTES LEFT TO MOVE ?
	JRST RGF020		;NO, RETURN BLOCK TO CALLER
	ILDB T2,RGFPTR		;GET A BYTE OF REGISTER DATA
	IDPB T2,T3		;STORE THE BYTE
	JRST RGF010		;LOOP OVER ALL BYTES

RGF020:	MOVE T1,RGFPTR		;RESTORE UPDATED POINTER
	MOVE T2,RGFCNT		; AND UPDATED COUNT OF BYTES LEFT IN MESSAGE
	MOVX T3,.EDREG		;GET "REGISTER DATA" TYPE CODE
	MOVE T4,RGFBLK		;GET ADDRESS OF BLOCK HOLDING REGISTER DATA
	RETSKP			;DONE, RETURN
;OPSFLD - ROUTINE TO EXTRACT OPERATING SYSTEM ID FROM NICE MESSAGES

OPSFLD:	STKVAR <OPFTYP>
	SOSGE T2		;AT TYPE CODE BYTE PRESENT ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,T1		;GET OPERATING SYSTEM TYPE CODE
	MOVEM T4,OPFTYP		;SAVE OPERATING SYSTEM TYPE
	HRLI T3,440000		;USE ptr WITH ZERO SIZE FIELD TO DISCARD text
	CALL GETIMA		;IGNORE ASCII SYSTEM ID
	 RETBAD ()		;FAILED
	MOVX T3,.EDOPS		;OPERATING SYSTEM CODE BEING RETURNED
	MOVE T4,OPFTYP		;GET OPERATING SYSTEM TYPE CODE
	RETSKP

;TIMFLD - ROUTINE TO EXTRACT THE TIME FROM A NICE EVENT LOGGING MESSAGE

TIMFLD:	CALL GETEXB		;GET EXTENSIBLE BINARY FIELD
	 RETBAD ()		;FAILED
	MOVX T3,.EDTIM		;GET TIME FIELD DATA TYPE CODE
	RETSKP			;DONE, RETURN SUCCESS
;RCVFLD - ROUTINE TO EXTRACT THE RECOVERY OPTION FROM NICE EVENT MESSAGES
;
; NOTE: THIS FIELD IS NEVER SENT, AND IS THEREFORE IGNORED

RCVFLD:	HRLI T3,440000		;USE PTR WITH ZERO SIZE FIELD TO DISCARD TEXT
	CALL GETIMA		;EXTRACT AND DISCARD RECOVERY ACTION
	 RETBAD ()		;FAILED
	MOVX T3,.EDRCV		;GET RECOVERY ACTION DATA TYPE CODE
	SETZM T4		;NO DATA UNTIL FIELD CONTENTS SPECIFIED
	RETSKP			;DONE, RETURN


;THRFLD - THRESHOLD VALUE

THRFLD:	CALL GETTWO		;GET TWO BYTE BINARY NUMBER
	 RETBAD ()		;FAILED
	MOVE T4,T3		;GET VALUE
	MOVX T3,.EDTHR		;GET THRESHOLD TYPE CODE
	RETSKP

TPRFLD:
LPRFLD:	RETBAD (.NRIMF)		;NOT CODED YET
;GET4 - ROUTINE TO GET A FOUR-BYTE FIELD FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;		CALL GET4
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ FOUR-BYTE NUMBER FROM MESSAGE

GET4:	ASUBR <GT4PTR,GT4NUM>

	MOVE T1,GT4PTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	MOVEI T2,4		;WE HAVE ENOUGH
	CALL GETTWO		;GO GET NEXT 2-BYTE NUMBER FROM MESSAGE
	 JFCL
	MOVEM T3,GT4NUM		;SAVE FIRST TWO BYTES OF FOUR BYTE NUMBER
	CALL GETTWO		;GET TWO HIGH ORDER BYTES OF THE NUMBER
	 JFCL
	DPB T3,[POINT 16,GT4NUM,19] ;ADD HIGH ORDER BYTES TO NUMBER
	MOVE T2,GT4NUM		;GET ENTIRE ASSEMBLED NUMBER
	RET			;RETURN




;GETNUM - ROUTINE TO EXTRACT A NODE NUMBER FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NUMBER IN MESSAGE
;	    T2/	COUNT OF BYTES LEFT IN MESSAGE
;		CALL GETNUM
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER
;			      T2/ UPDATED COUNT
;			      T3-T4/ BINARY NUMBER FROM MESSAGE

GETNUM::CALLRET GETEXB		;GET EXTENSIBLE BINARY FIELD FROM MESSAGE
;GETEXA - ROUTINE TO GET AN EXTENSIBLE ASCII STRING FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO FIRST BYTE OF STRING IN NICE MESSAGE
;	    T2/	DESTINATION ADDRESS FOR ASCIZ STRING
;	    T3/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GETEXA
;RETURNS: +1	 FAILURE, BADLY FORMED MESSAGE
;		SUCCESS, WITH	T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;				T2/ UPDATED POINTER TO DESTINATION STRING
;				T3/ UPDATED BYTE COUNT

GETEXA:	HRLI T2,(POINT 7,)	;FORM POINTER TO DESTINATION STRING

EXTAS2:	SOJL T3,R		;RETURN IF INSUFFICIENT BYTES LEFT IN MESSAGE
	ILDB T4,T1		;GET A BYTE FROM THE NICE MESSAGE
	IDPB T4,T2		;STORE ASCII CHARACTER INTO DESTINATION
	TXNE T4,EXTBIT		;IS NEXT BYTE PART OF THIS FIELD ?
	JRST EXTAS2		;YES, GO GET THE NEXT BYTE
	MOVEI T4,.CHNUL		;NO, GET A NULL
	IDPB T4,T2		;TERMINATE THE ASCIZ DESTINATION STRING
	RETSKP			;RETURN SUCCESS


;GETEXB - ROUTINE TO EXTRACT AN EXTENSIBLE BINARY FIELD FROM A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (EXTENSIBLE FIELD) IN MESSAGE
;	    T2/	COUNT OF BYTES REMAINING IN MESSAGE
;		CALL GETEXB
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES REMAINING IN MESSAGE
;			      T3-T4/ BINARY NUMBER FROM MESSAGE

GETEXB::ASUBR <GEBPTR,GEBCNT>

	SETZB T3,T4		;INITIALIZE THE BINARY NUMBER AC'S
	MOVEI T1,MAXEXT		;MAX # OF BYTES ACCEPTED IN EXTENSIBLE FIELDS

; LOOP OVER EACH BYTE IN THE EXTENSIBLE FIELD

GEB010:	SOJL T1,[RETBAD (.NRIMF)] ;FAIL IF THERE ARE MORE THAN MAX BYTES ALLOWED
	SOSGE GEBCNT		;ANOTHER BYTE LEFT IN THE MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	LSHC T3,7		;YES, POSITION PREVIOUS BYTES
	ILDB T2,GEBPTR		;GET NEXT BYTE FROM THE NICE MESSAGE
	DPB T2,[POINT 7,T4,35]	;ADD THE BYTE TO THE BINARY NUMBER BEING FORMED
	TXNE T2,EXTBIT		;IS THE NEXT BYTE PART OF THIS FIELD ?
	JRST GEB010		;YES, GO GET THE NEXT BYTE IN THE FIELD

; HERE WHEN DONE EXTRACTING BYTES - RETURN UPDATED POINTER AND COUNT

	MOVE T2,GEBCNT		;GET UPDATED COUNT
	MOVE T1,GEBPTR		;GET UPDATED POINTER TO NEXT FIELD
	RETSKP			;DONE, RETURN SUCCESS
;GETLOC - ROUTINE TO GET A NUMBER OF LOCATIONS FROM A MOP OR NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD (# OF LOCATIONS) IN MESSAGE
;	    T2/	COUNT OF BYTES REMAINING IN MESSAGE
;		CALL GETLOC
;RETURNS: +1	 FAILED, MESSAGE TOO SHORT
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES LEFT IN MESSAGE
;			      T3/ NUMBER OF LOCATIONS

GETLOC==GETTWO

;GETNOD - ROUTINE TO GET AN ASCIZ NODE NAME FROM A NICE PROTOCOL MESSAGE
;
;ACCEPTS IN T1/	POINTER TO FIRST BYTE OF NODE NAME IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN MESSAGE
;		CALL GETNOD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;		SUCCESS, WITH	T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;				T2/ UPDATED BYTE COUNT
;				T3/ POINTER TO ASCIZ NODE NAME STRING

GETNOD::ASUBR <NDMPTR,NDMCNT,NDMDST>
	SOSGE T2		;AT LEAST ONE BYTE LEFT IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, RETURN "INVALID MESSAGE FORMAT" ERROR
	MOVE T4,NDMPTR		;GET POINTER TO COUNT IN ASCII IMAGE FIELD
	ILDB T3,T4		;GET NUMBER OF CHARACTERS IN NODE NAME
	CAILE T3,NNAMSZ		;NAME LONGER THAN MAX ALLOWED IN NICE PROTOCOL ?
	RETBAD (.NRINI)		;YES, RETURN "INVALID NODE ID" ERROR
	MOVE T2,NDMCNT		;RESTORE ORIGINAL COUNT
	SETZM T3		;USE GENERAL STRING AREA
	CALL GETIMA		;GO GET ASCIZ STRING FROM IMAGE FIELD
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;RETURN SUCCESS, POINTER TO NODE NAME IS IN T3
;GETSEQ - ROUTINE TO EXTRACT THE SEQUENCE NUMBER FROM A NICE PROTOCOL
;	    EVENT LOGGING REQUEST MESSAGE
;
;ACCEPTS IN T1/	POINTER TO SEQUENCE NUMBER IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETSEQ
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES IN MESSAGE
;			      T3/ SEQUENCE NUMBER

GETSEQ:	SOSGE T2		;AT LEAST ONE BYTE LEFT IN MESSAGE ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T3,T1		;YES, GET SEQUENCE NUMBER
	RETSKP			;DONE, RETURN



;GETEVT - ROUTINE TO EXTRACT AN EVENT CODE FROM A NICE MESSAGE
;
;ACCEPTS IN T1/	POINTER TO EVENT CODE IN NICE MESSAGE
;	    T2/	NUMBER OF BYTES REMAINING IN NICE MESSAGE
;		CALL GETEVT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED COUNT OF BYTES IN MESSAGE
;			      T3/ EVENT CODE

GETEVT:	CALLRET GETTWO		;EXTRACE A TWO-BYTE FIELD FROM MESSAGE
SUBTTL	Routines to Assemble NICE Messages

;MAKLOD - ROUTINE TO ASSEMBLE A NICE LINE SERVICE MESSAGE TO INITIATE A
;	  DOWN LINE LOAD DIALOG.
;
;CALL:		CALL MAKLOD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ COUNT OF NUMBER OF BYTES IN THE MESSAGE

MAKLOD:	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF NICE MESSAGE
	MOVX T4,.NCLSV		;GET NICE "LINE SERVICE" FUNCTION CODE
	IDPB T4,T1		;ADD FUNCTION CODE TO MESSAGE
	MOVX T4,.LSLOD		;OPTION DESIRED IS "ESTABLISH LOAD DIALOG"
	IDPB T4,T1		;ADD OPTION FIELD TO MESSAGE
	MOVEI T2,2		;MESSAGE CONTAINS TWO BYTES SO FAR
	DMOVE T3,RQLLIN		;GET SERVER LINE ID
	CALL MAKLIN		;ADD LINE ID TO MESSAGE
	MOVE T4,RQLPGM		;GET TYPE OF PROGRAM TO BE LOADED
	IDPB T4,T1		;SAVE PROGRAM TYPE (.PTXXX) IN MESSAGE
	ADDI T2,1		;BUMP COUNT FOR PROGRAM TYPE
	HRLI T1,(POINT 8,)	;FORM POINTER TO START OF THE
	HRRI T1,MSGBLK		; ASSEMBLED MESSAGE
	RETSKP			;DONE, RETURN SUCCESS



;MAKDMP - ROUTINE TO ASSEMBLE A NICE LINE SERVICE MESSAGE TO INITIATE AN
;	  UP LINE DUMP DIALOG.
;
;CALL:		CALL MAKDMP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ COUNT OF NUMBER OF BYTES IN THE MESSAGE

MAKDMP:	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF NICE MESSAGE
	MOVX T4,.NCLSV		;GET NICE "LINE SERVICE" FUNCTION CODE
	IDPB T4,T1		;ADD FUNCTION CODE TO MESSAGE
	MOVX T4,.LsdmP		;OPTION DESIRED IS "ESTABLISH LOAD DIALOG"
	IDPB T4,T1		;ADD OPTION FIELD TO MESSAGE
	MOVEI T2,2		;MESSAGE CONTAINS TWO BYTES SO FAR
	DMOVE T3,RQDLIN		;GET SERVER LINE ID
	CALL MAKLIN		;ADD LINE ID TO MESSAGE
	MOVE T2,RQDADR		;GET STARTING ADDRESS FOR DUMP
	CALL MAK4		;GO ADD FOUR-BYTE FIELD TO MESSAGE
	MOVE T2,RQDCNT		;GET COUNT OF LOCATIONS TO DUMP
	CALL MAK4		;GO ADD COUNT TO DUMP MESSAGE
	MOVEI T2,^D15		;GET NUMBER OF BYTES IN DUMP MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO START OF
	HRRI T1,MSGBLK		; NICE LINE SERVICE MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
;MAKRLC - ROUTINE TO ASSEMBLE A NICE READ LINE COUNTERS MESSAGE
;
;ACCEPTS IN T1-T2/ NICE LINE ID FOR WHICH COUNTERS ARE DESIRED
;		CALL MAKRLC
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKRLC:	ASUBR <<MRLLIN,2>>

	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	MOVX T4,.NCRED		;GET NICE "READ INFORMATION" FUNCTION CODE
	IDPB T4,T1		;ADD FUNCTION CODE TO MESSAGE
	MOVX T4,.RDLCT		;GET "LINE COUNTERS" OPTION FOR READ FUNCTION
	IDPB T4,T1		;ADD OPTION TO MESSAGE
	MOVEI T2,2		;GET NUMBER OF BYTES IN MESSAGE SO FAR
	DMOVE T3,MRLLIN		;GET LINE FOR WHICH COUNTERS ARE DESIRED
	CALL MAKLIN		;GO ADD LINE ID TO MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO NICE "READ INFORMATION"
	HRRI T1,MSGBLK		; MESSAGE TO GET LINE COUNTERS
	RETSKP			;DONE, RETURN SUCCESS



;MAKLIN - ROUTINE TO ASSEMBLE A STANDARD LINE ID INTO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES ALREADY IN THE MESSAGE
;	    T3-T4/ STANDARD LINE ID:
;	      T3/ LINE DEVICE TYPE (.DTXXX),,LINE CONTROLLER #
;	      T4/ LINE UNIT NUMBER,,LINE STATION ADDRESS
;		CALL MAKLIN
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED COUNT OF BYTES IN THE MESSAGE

MAKLIN::ASUBR <MLNPTR>

	MOVX T1,.LTSTD		;GET STANDARD LINE TYPE CODE
	IDPB T1,MLNPTR		;ADD LINE ID TYPE CODE TO MESSAGE
	HLRZ T1,T3		;GET LINE DEVICE TYPE
	IDPB T1,MLNPTR		;ADD TO MESSAGE
	HRRZ T1,T3		;GET CONTROLLER NUMBER
	IDPB T1,MLNPTR		;ADD TO MESSAGE
	HLRZ T1,T4		;GET UNIT NUMBER
	IDPB T1,MLNPTR		;ADD TO MESSAGE
	HRRZ T1,T4		;GET STATION ADDRESS
	IDPB T1,MLNPTR		;ADD TO MESSAGE
	ADDI T2,5		;INCREMENT BYTE COUNT
	MOVE T1,MLNPTR		;RESTORE UPDATED POINTER
	RET			;RETURN, FIELD ADDED TO MESSAGE
;MAKMPL - ROUTINE TO MAKE A MOP LOAD-WITHOUT-TRANSFER-ADDRESS MESSAGE (.MPLOD)
;
;ACCEPTS IN T1/	POINTER TO MEMORY IMAGE DATA IN NICE LINE SERVICE DIALOG MSG
;	    T2/	NUMBER OF BYTES IN REMAINDER OF NICE MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL MAKMPL
;RETURNS: +1	 FAILED, UNEXPECTED NICE PROCESS PROGRAM ERROR
;	  +2	SUCCESS, WITH T1/ POINTER TO COMPLETED MOP MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MOP MESSAGE

MAKMPL:	ASUBR <MMLPTR,MMLCNT,MMLLIN>

; PUT THE FUNCTION CODE, LOAD NUMBER, AND LOAD ADDRESS INTO THE MESSAGE

	CALL CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVE T4,MMLLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO WHERE MOP MESSAGE GOES
	MOVX T2,.MPLOD		;GET MOP FUNCTION CODE
	IDPB T2,T1		;STORE FUNCTION CODE IN MOP MESSAGE
	MOVE T4,MMLLIN		;GET ADDRESS OF LINE TABLE
	LOAD T2,LNLDN,(T4)	;GET NEXT LOAD NUMBER TO USE
	IDPB T2,T1		;STORE LOAD NUMBER IN MOP MESSAGE
	LOAD T2,LNADR,(T4)	;GET LOAD ADDRESS
	CALL MAK4		;GO ADD A FOUR-BYTE NUMBER TO THE MOP MESSAGE

; ADD THE MEMORY IMAGE DATA TO THE MOP MESSAGE

	MOVE T2,MMLPTR		;GET POINTER TO LOAD RECORD
	MOVN T3,MMLCNT		;GET -NUMBER OF BYTES IN LOAD RECORD
	SOUT			;ADD THE LOAD RECORD TO THE MOP MESSAGE
	 ERJMP R		;SHOULD NOT FAIL
	MOVE T4,MMLLIN		;GET ADDRESS OF LINE TABLE
	LOAD T3,LNADR,(T4)	;GET PREVIOUS ADDRESS
	MOVE T2,MMLCNT		;GET PREVIOUS MESSAGE SIZE
	ADD T3,T2		;COMPUTE NEXT LOAD ADDRESS
	STOR T3,LNADR,(T4)	;STORE NEW ADDRESS
	ADDI T2,6		;ACCOUNT FOR MOP FUNCTION, LOAD #, ADDRESS
	STOR T2,LNCNT,(T4)	;STORE COUNT IN LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO START OF MESSAGE
	RETSKP			;RETURN (POINTER IS STILL IN T1)
;MAKBAS - ROUTINE TO ASSEMBLE A NICE LINE SERVICE "SET BASE ADR" MESSAGE
;
;ACCEPTS IN T1/	MEMORY ADDRESS TO BE SET
;		CALL MAKBAS
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO START OF MESSAGE
;			  T2/ NUMBER OF BYTES IN THE MESSAGE

MAKBAS:	ASUBR <MBSADR>

	CALL CLRMSG		;GO ZERO THE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	MOVX T4,.LMBAS		;GET LOAD DIALOG MESSAGE "SET BASE ADR" OPTION
	IDPB T4,T1		;ADD OPTION BYTE TO MESSAGE
	MOVE T2,MBSADR		;GET ADDRESS TO BE SET
	CALL MAK4		;GO ADD THE ADDRESS TO THE MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO THE START OF THE
	HRRI T1,MSGBLK		; NICE LINE SERVICE "SET BASE ADR" MESSAGE
	MOVX T2,5		;GET SIZE OF MESSAGE
	RET			;DONE, RETURN


;MAKMLP - ROUTINE TO ASSEMBLE A MOP "LOAD PARAMETERS AND TRANSFER" MESSAGE
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;	    T2/	ADDRESS AT WHICH TO START LOADED PROGRAM
;		CALL MAKMLP
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MOP MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MOP MESSAGE

MAKMLP:	ASUBR <MLPLIN,MLPADR,MLPCNT>
	CALL CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVE T4,MLPLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO START OF MESSAGE
	MOVX T4,.MPXFR		;GET MOP "PARAMETERS AND TRANSFER" CODE
	IDPB T4,T1		;PUT MOP FUNCTION CODE INTO THE MESSAGE
	MOVE T4,MLPLIN		;GET ADDRESS OF LINE TABLE
	LOAD T4,LNLDN,(T4)	;GET NEXT LOAD NUMBER
	IDPB T4,T1		;ADD LOAD NUMBER TO MESSAGE
	MOVEI T4,2		;GET NUMBER OF BYTES IN MESSAGE SO FAR
	MOVEM T4,MLPCNT		;SAVE MESSAGE SIZE

; ADD NODE-NAME PARAMETER IF SPECIFIED

	MOVE T3,RQLNAM		;GET POINTER TO NAME PARAMETER
	CAMN T3,[-1]		;WAS THIS PARAMETER SPECIFIED ?
	JRST MLP010		;NO, GO CHECK NEXT PARAMETER
	MOVX T4,.PVNAM		;YES, GET "NODE NAME" PARAMETER TYPE CODE
	IDPB T4,T1		;ADD TYPE CODE TO MESSAGE
	AOS MLPCNT		;INCREMENT BYTE COUNT
	MOVX T2,NNAMSZ		;GET MAX SIZE OF A NODE NAME
	CALL MAKIMA		;GO ADD IMAGE ASCII FIELD TO MOP MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	ADDM T2,MLPCNT		;ADD NUMBER OF BYTES IN NAME TO MESSAGE SIZE
	; ..
	; ..

; HERE TO ADD THE NODE NUMBER IF SPECIFIED

MLP010:	MOVE T2,RQLNUM		;GET NODE NUMBER
	CAMN T2,[-1]		;WAS THE NODE NUMBER SPECIFIED ?
	JRST MLP020		;NO, GO CHECK THE NEXT PARAMETER
	MOVX T3,.PVNUM		;YES, GET "NODE NUMBER" PARAMETER TYPE CODE
	IDPB T3,T1		;ADD PARAMETER TYPE TO MOP MESSAGE
	MOVX T3,2		;GET SIZE OF NODE NUMBER PARAMETER FIELD
	IDPB T3,T1		;ADD COUNT TO MOP MESSAGE
	MOVEI T3,4		;GET # OF BYTES IN NODE-NUMBER PARAMETER FIELD
	ADDM T3,MLPCNT		;INCREMENT TOTAL SIZE OF MOP MESSAGE
	CALL MAKTWO		;GO ADD 2-BYTE NODE NUMBER TO MOP MESSAGE

; HERE TO ADD HOST-NODE PARAMETER IF SPECIFIED

MLP020:	MOVE T3,RQLHST		;GET POINTER TO HOST PARAMETER
	CAMN T3,[-1]		;WAS THIS PARAMETER SPECIFIED ?
	JRST MLP030		;NO, GO ON
	MOVX T4,.PVHST		;YES, GET "HOST" PARAMETER TYPE CODE
	IDPB T4,T1		;ADD TYPE CODE TO MESSAGE
	AOS MLPCNT		;INCREMENT BYTE COUNT
	MOVX T2,NNAMSZ		;GET MAX SIZE OF A NODE NAME
	CALL MAKIMA		;GO ADD IMAGE ASCII FIELD TO MOP MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	ADDM T2,MLPCNT		;ADD NUMBER OF BYTES IN NAME TO MESSAGE SIZE

; HERE TO ADD TRANSFER ADDRESS TO THE MESSAGE

MLP030:	MOVX T4,.PVEND		;GET "END-OF-PARAMETERS" CODE
	IDPB T4,T1		;ADD END MARK TO MOP MESSAGE
	AOS MLPCNT		;INCREMENT MESSAGE SIZE
	MOVE T2,MLPADR		;GET TRANSFER ADDRESS
	CALL MAK4		;ADD A FOUR-BYTE ADDRESS TO THE MOP MESSAGE
	MOVE T2,MLPCNT		;GET MESSAGE SIZE
	ADDI T2,4		;INCREMENT FOR TRANSFER ADDRESS
	MOVE T4,MLPLIN		;GET ADDRESS OF LINE TABLE
	STOR T2,LNCNT,(T4)	;STORE COUNT IN TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO START OF MESSAGE
	RETSKP			;DONE, RETURN SUCCESS TO CALLER
;MAKIMD - ROUTINE TO ASSEMBLE A NICE MEMORY IMAGE MESSAGE FOR USE DURING
;	    A DUMP DIALOG.
;
;ACCEPTS IN T1/	ADDRESS OF DATA TO RETURN (8 BIT BYTES)
;	    T2/ COUNT OF BYTES TO RETURN
;		CALL MAKIMD
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKIMD:	ASUBR <MIDADR,MIDCNT,MIDNUM>

	MOVEM T2,MIDNUM		;SAVE ORIGINAL NUMBER OF BYTES
	CALL CLRMSG		;INITIALIZE THE MESSAGE AREA
	HRLI T1,(POINT 8,)	;FORM POINTER TO DESTINATION FOR
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	MOVX T4,.LMMEM		;GET "MEMORY IMAGE" TYPE CODE
	IDPB T4,T1		;STORE TYPE CODE IN LINE SERVICE MESSAGE
	MOVX T4,.CP11		;GET CPU TYPE OF TARGET SYSTEM
	IDPB T4,T1		;SAVE CPU TYPE IN MESSAGE
	MOVE T3,MIDADR		;GET ADDRESS OF DATA TO RETURN
	SKIPN MIDCNT		;NON-ZERO COUNT ?
	JRST MID040		;NO, ALL DONE
	MOVEI T2,0		;START WITH FIRST BYTE
	ANDI T2,3		;MODULO 4
MID020:	LDB T4,SLDTAB(T2)	;GET A DATA BYTE
	IDPB T4,T1		;ADD BYTE TO THE MESSAGE
	ADDI T2,1		;POINT TO NEXT BYTE POINTER
	ANDI T2,3		;KEEP JUST RIGHTMOST 2 BITS
	TRNN T2,3		;DONE FOUR BYTES YET ?
	ADDI T3,1		;YES, POINT TO NEXT WORD
	SOSLE MIDCNT		;DECREMENT NUMBER OF BYTES REMAINING TO BE MOVED
	JRST MID020		;LOOP OVER ALL BYTES TO MOVE
MID040:	MOVE T2,MIDNUM		;GET NUMBER OF DATA BYTES AGAIN
	ADDI T2,2		;ACCOUNT FOR TYPE CODE AND CPU TYPE
	HRLI T1,(POINT 8,)	;FORM POINTER TO DESTINATION FOR
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
;MAKMDT - ROUTINE TO ASSEMBLE A NICE MEMORY IMAGE MESSAGE FOR USE DURING
;	    A DUMP DIALOG.
;
;ACCEPTS IN T1/	ADDRESS OF DATA TO RETURN (8 BIT BYTES)
;	    T2/ COUNT OF BYTES TO RETURN
;	    T3/	NUMBER OF BYTES ALREADY EXTRACTED FROM MSG (MAKMDT ONLY)
;		CALL MAKMDT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKMDT:	ASUBR <MDTADR,MDTNUM,MDTCNT>

	CALL CLRMSG		;INITIALIZE THE MESSAGE AREA
	HRLI T1,(POINT 8,)	;FORM POINTER TO DESTINATION FOR
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	MOVX T4,.LMMEM		;GET "MEMORY IMAGE" TYPE CODE
	IDPB T4,T1		;STORE TYPE CODE IN LINE SERVICE MESSAGE
	MOVX T4,.CP11		;GET CPU TYPE OF TARGET SYSTEM
	IDPB T4,T1		;SAVE CPU TYPE IN MESSAGE
	MOVE T3,MDTADR		;GET ADDRESS OF DATA TO RETURN
	HRLI T3,(POINT 8,)	;FORM POINTER TO DATA TO RETURN
	SKIPN MDTCNT		;NON-ZERO COUNT ?
	JRST MDT040		;NO, ALL DONE
MDT020:	ILDB T4,T3		;GET A DATA BYTE
	IDPB T4,T1		;ADD BYTE TO THE MESSAGE
	SOSLE MDTCNT		;DECREMENT NUMBER OF BYTES REMAINING TO BE MOVED
	JRST MDT020		;LOOP OVER ALL BYTES TO MOVE
MDT040:	MOVE T2,MDTNUM		;GET NUMBER OF DATA BYTES AGAIN
	ADDI T2,2		;ACCOUNT FOR TYPE CODE AND CPU TYPE
	HRLI T1,(POINT 8,)	;FORM POINTER TO DESTINATION FOR
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
;MAKIMG - ROUTINE TO ASSEMBLE A "MEMORY IMAGE" LINE SERVICE MESSAGE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD BLOCK
;	    T2/	CPU TYPE OF TARGET SYSTEM (.CPXXX)
;		CALL MAKIMG
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKIMG:	ASUBR <MIMREC,MIMCPU,MIMCNT>

	CALL CLRMSG		;INITIALIZE THE MESSAGE AREA
	HRLI T1,(POINT 8,)	;FORM POINTER TO DESTINATION FOR
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	MOVX T4,.LMMEM		;GET "MEMORY IMAGE" TYPE CODE
	IDPB T4,T1		;STORE TYPE CODE IN LINE SERVICE MESSAGE
	MOVE T4,MIMCPU		;GET CPU TYPE OF TARGET SYSTEM
	IDPB T4,T1		;SAVE CPU TYPE IN MESSAGE
	MOVE T4,MIMREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T3,RBCNT,(T4)	;GET NUMBER OF BYTES IN THIS BLOCK
	CAIL T3,MAXMEM		;MORE TO SEND THAN MAX IN ONE IMAGE FIELD ?
	MOVX T3,MAXMEM		;YES, USE MAXIMUM INSTEAD
	MOVEM T3,MIMCNT		;SAVE # OF BYTES ACTUALY BEING SENT
	MOVN T3,T3		;GET - COUNT
	LOAD T2,RBPTR,(T4)	;GET POINTER TO THE DATA
	SOUT			;ADD THE DATA TO THE MESSAGE
	 ERJMP [RETBAD (.NRNPE)] ;FAILED, RETURN ERROR
	STOR T2,RBPTR,(T4)	;STORE POINTER IN CASE THERE IS MORE DATA
	MOVE T2,MIMCNT		;GET # OF DATA BYTES IN MESSAGE
	LOAD T3,RBCNT,(T4)	;GET TOTAL # OF BYTES TO BE SENT
	SUB T3,MIMCNT		;COMPUTE # OF BYTES LEFT TO SEND
	STOR T3,RBCNT,(T4)	;SAVE THAT NUMBER OF BYTES IN RECORD BLOCK
	MOVE T2,MIMCNT		;GET NUMBER OF DATA BYTES ACTUALLY IN MESSAGE
	ADDI T2,1+1		;ADD 1 FOR FUNCTION CODE, 1 FOR CPU TYPE
	HRLI T1,(POINT 8,)	;FORM POINTER TO START OF
	HRRI T1,MSGBLK		; "MEMORY IMAGE" MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
;MAKXFR -ROUTINE TO ASSEMBLE A "SYSTEM PARAMETERS AND TRANSFER" MESSAGE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD BLOCK
;		CALL MAKXFR
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO START OF MESSAGE
;			  T2/ NUMBER OF BYTES IN THE MESSAGE

MAKXFR:	ASUBR <MKXREC,MKXPTR,MKXCNT>

	SETZM MKXCNT		;INITIALIZE MESSAGE SIZE
	CALL CLRMSG		;GO CLEAR THE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	MOVX T4,.LMXFR		;GET "TRANSFER" LINE SERVICE MESSAGE TYPE
	IDPB T4,T1		;ADD MESSAGE TYPE TO THE MESSAGE

; SKIP OVER COUNT BYTE AND ADD PARAMETERS TO THE MESSAGE

	MOVEM T1,MKXPTR		;SAVE POINTER TO TOTAL COUNT FOR PARAMETERS
	IBP T1			;SKIP THE COUNT BYTE
	SKIPN T3,RQLNAM		;NAME OF THIS NODE SPECIFIED ?
	JRST MKX010		;NO, GO CHECK NODE NUMBER
	CAMN T3,[-1]		;IF PARAMETER NOT SPECIFIED, GO CHECK
	JRST MKX010		; NEXT PARAMETER
	MOVX T2,.PVNAM		;GET PARAMETER TYPE CODE FOR NODE NAME
	IDPB T2,T1		;ADD TYPE CODE TO MESSAGE
	AOS MKXCNT		;INCREMENT COUNT OF BYTES IN PARAMETERS
	MOVX T2,NNAMSZ		;GET MAX NUMBER OF CHARACTERS IN NODE NAMES
	CALL MAKIMA		;GO ADD NODE NAME TO MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	ADDM T2,MKXCNT		;UPDATE NUMBER OF BYTES IN PARAMETERS
MKX010:	SKIPN T4,RQLNUM		;NODE NUMBER SPECIFIED ?
	JRST MKX020		;NO, GO CHECK HOST FOR TASK LOADS
	CAMN t4,[-1]		;IF PARAMETER NOT SPECIFIED, GO CHECK
	JRST MKX020		; NEXT PARAMETER
	MOVX T2,.PVNUM		;YES, GET PARAMETER TYPE CODE FOR NODE NUMBER
	IDPB T2,T1		;ADD TYPE CODE TO THE MESSAGE
	MOVEI T2,4		;ACCOUNT FOR THE PARAMETER TYPE CODE, COUNT
	ADDM T2,MKXCNT		; BYTE, AND TWO BYTES OF NODE NUMBER
	MOVX T2,2		;NODE NUMBER IS TWO BYTES
	SETZM T3		;NUMBER IS ALREADY IN T4
	CALL MAKIMB		;GO ASSEMBLE THE NODE NUMBER INTO THE MESSAGE
MKX020:	SKIPN T3,RQLHST		;ANY HOST SPECIFIED FOR TASK LOADS ?
	JRST MKX030		;NO, GO ADD TOTAL LENGTH OF PARAMETER FIELD
	CAMN T3,[-1]		;IF PARAMETER NOT SPECIFIED, GO
	JRST MKX030		; ADD ADDRESS TO MESSAGE
	MOVX T2,.PVHST		;YES, GET HOST PARAMETER TYPE CODE
	IDPB T2,T1		;ADD PARAMETER TYPE CODE TO MESSAGE
	AOS MKXCNT		;UPDATE BYTE COUNT FOR PARAMETERS
	MOVX T2,NNAMSZ		;YES, GET MAX SIZE OF NODE NAMES
	CALL MAKIMA		;GO ADD ASCII HOST NAME TO MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	ADDM T2,MKXCNT		;UPDATE NUMBER OF BYTES IN PARAMETERS
	; ..
	; ..

MKX030:	MOVX T4,.PVEND		;GET "END-OF-PARAMETERS" MARK
	IDPB T4,T1		;MARK END OF PARMAETERS
	AOS T2,MKXCNT		;INCREMENT COUNT OF BYTES FOR PARAMETERS
	IDPB T2,MKXPTR		;STORE AS FIRST BYTE OF PARAMETER FIELD

; HERE TO ADD THE TRANSFER ADDRESS TO THE MESSAGE

	MOVE T4,MKXREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T2,RBXAD,(T4)	;GET TRANSFER ADDRESS FROM FILE
	CALL MAK4		;GO ASSEMBLE A FOUR-BYTE NUMBER

; MESSAGE IS NOW ASSMBLED - RETURN

	HRRI T1,MSGBLK		;GET ADDRESS OF MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO START OF MESSAGE
	MOVE T2,MKXCNT		;GET NUMBER OF BYTES IN PARAMETERS
	ADDI T2,1+1+4		;ADD TYPE CODE, PARAMS CNT, AND XFR ADR COUNT
	RETSKP			;RETURN TO CALLER
;MAKRQD - ROUTINE TO MAKE A MOP "REQUEST DUMP RECORD" MESSAGE
;
;ACCEPTS IN T1/	MEMORY ADDRESS TO START DUMPING
;	    T2/	NUMBER OF LOCATIONS TO DUMP
;	    T3/ DESTINATION POINTER FOR NICE MESSAGE
;		CALL MAKRQD
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO MOP MESSAGE
;			  T2/ NUMBER OF BYTES IN MOP MESSAGE

MAKRQD:	ASUBR <MRDADR,MRDCNT,MRDPTR>

	MOVE T1,MRDPTR		;GET POINTER TO DESTINATION OF MESSAGE
	MOVX T4,.MPRQD		;GET MOP "REQUEST DUMP RECORD" FUNCTION CODE
	IDPB T4,T1		;PUT FUNCTION CODE INTO MOP MESSAGE
	MOVE T2,MRDADR		;GET ADDRESS FROM WHICH TO BEGIN DUMPING
	CALL MAK4		;GO ADD THE ADDRESS TO THE MOP MESSAGE
	MOVE T2,MRDCNT		;GET NUMBER OF LOCATIONS TO DUMP
	CALL MAKTWO		;GO ADD COUNT TO THE MOP MESSAGE
	MOVE T1,[POINT 8,MOPMSG] ;GET POINTER TO START OF MOP MESSAGE
	MOVEI T2,7		;GET NUMBER OF BYTES IN "REQUEST DUMP" MESSAGE
	RET			;RETURN



;MAKEMM - ROUTINE TO MAKE A MOP "ENTER MOP MODE" MESSAGE
;
;ACCEPTS IN T1/	MAINTENANCE PASSWORD
;		CALL MAKEMM
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO MOP MESSAGE
;			  T2/ NUMBER OF BYTES IN MOP MESSAGE

MAKEMM:	ASUBR <MEMPSW>

	CALL CLRMOP		;CLEAR THE MOP MESSAGE AREA
	MOVE T1,[POINT 8,MOPMSG] ;GET POINTER TO START OF MOP MESSAGE AREA
	MOVX T4,.MPMOP		;GET "ENTER MOP MODE" MOP FUNCTION CODE
	IDPB T4,T1		;PUT FUNCTION CODE INTO MESSAGE
	MOVE T2,MEMPSW		;GET MAINTENANCE PASSWORD
	CALL MAK4		;ADD MAINTENANCE PASSWORD TO MESSAGE
	MOVEI T2,5		;GET SIZE OF "ENTER MOP MODE" MESSAGE
	MOVE T1,[POINT 8,MOPMSG] ;GET POINTER TO START OF MESSAGE
	RET			;RETURN
;MAKEND - ROUTINE TO CHECK A MOP PROGRAM REQUEST MESSAGE AND ASSEMBLE A
;	  NICE END-OF-DIALOG LINE SERVICE MESSAGE.
;
;ACCEPTS IN T1/	POINTER TO START OF MOP MESSAGE
;	    T2/	NUMBER OF BYTES IN THE MOP MESSAGE
;	    T3/	ADDRESS OF LINE TABLE
;		CALL MAKEND
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF NICE MESSAGE
;			      T2/ NUMBER OF BYTES IN THE NICE MESSAGE

MAKEND:	ASUBR <MKDPTR,MKDCNT,MKDLIN>

	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,MKDCNT		;GET # OF BYTES IN THE MOP MESSAGE
	SUBI T1,4		;AT LEAST FUNCTION, DEVICE, PROGRAM & STATION ?
	JUMPN T1,[RETBAD (.NRPRO)] ;IF NOT, RETURN "PROTOCOL ERROR"
	MOVEM T1,MKDCNT		;SAVE UPDATED COUNT
	MOVE T4,[POINT 8,MSGBLK] ;GET POINTER TO START OF NICE MESSAGE
	MOVX T1,.LMEND		;GET END-OF-DIALOG TYPE CODE
	IDPB T1,T4		;ADD TYPE CODE TO NICE LINE SERVICE MESSAGE
	MOVX T1,.NRSUC		;GET SUCCESS RETURN CODE
	IDPB T1,T4		;ADD RETURN CODE TO THE MESSAGE

; EXTRACT THE FUNCTION CODE, DEVICE TYPE, AND STATION FROM MOP MESSAGE

	ILDB T1,MKDPTR		;GET MOP FUNCTION CODE
	CAIE T1,.MPRQP		;REQUEST PROGRAM FUNCTION ?
	RETBAD (.NRPRO)		;NO, RETURN "PROTOCOL ERROR"
	ILDB T1,MKDPTR		;GET LOAD DEVICE TYPE (.DTXXX)
	CAIE T1,.DTDTE		;DTE20 ?
	RETBAD (.NRPRO)		;NO, RETURN "PROTOCOL ERROR"
	IDPB T1,T4		;YES, STORE DEVICE TYPE IN NICE MESSAGE
	MOVX T1,.CP11		;ADJACENT NODES ARE ALWAYS PDP-11'S FOR NOW
	IDPB T1,T4		;ADD CPU TYPE TO NICE MESSAGE
	ILDB T1,MKDPTR		;GET STATION ADDRESS FROM MOP MESSAGE
	CAIE T1,1		;STATION 1 ?
	RETBAD (.NRPRO)		;NO, RETURN "PROTOCOL ERROR"
	ILDB T1,MKDPTR		;YES, GET PROGRAM TYPE FROM MOP MESSAGE
	CAIL T1,.PTSLD		;VALID PROGRAM TYPE
	CAILE T1,.PTOPS		; IN THE MOP PROGRAM REQUEST MESSAGE ?
	RETBAD (.NRPRO)		;NO, RETURN "PROTOCOL ERROR"
	IDPB T1,T4		;YES, ADD PROGRAM TYPE TO NICE MESSAGE
	MOVE T2,MKDLIN		;GET ADDRESS OF LINE TABLE
	STOR T1,LNPGM,(T2)	;UPDATE TYPE OF PROGRAM BEING LOADED
	; ..
	; ..

; EXTRACT THE SOFTWARE ID FROM THE MOP MESSAGE

	SKIPG T2,MKDCNT		;ANY MORE BYTES LEFT IN MOP MESSAGE ?
	JRST MKD020		;NO, GO RETURN POINTER TO NICE MESSAGE
	CAILE T2,MSIDMX		;BIGGER THAN MAX SIZE OF MOP SOFTWARE ID FIELD ?
	RETBAD (.NRPRO)		;YES, PROTOCOL ERROR
	MOVE T3,[POINT 7,TMPSTR] ;SET UP POINTER TO TEMPORARY DESTINATION
MKD010:	SOJL T2,MKD020		;IF ALL BYTES NOW IN STRING, GO ADD TO NICE MSG
	ILDB T1,MKDPTR		;GET NEXT CHARACTER FROM MOP MESSAGE
	IDPB T1,T3		;ADD CHARACTER TO STRING BEING FORMED
	JRST MKD010		;LOOP OVER ALL BYTES IN THE SOFTWARE ID

; HERE WITH SOFTWARE ID EXTRACTED

MKD020:	MOVE T3,[POINT 7,TMPSTR] ;GET POINTER TO TEMP LOCATION OF STRING
	MOVE T1,T4		;COPY POINTER TO NEXT FIELD IN NICE MESSAGE
	CALL MAKIMA		;GO ADD IMAGE ASCII SOFTWARE ID TO NICE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER

; RETURN THE POINTER AND SIZE OF THE NICE END-OF-DIALOG LINE SERVICE MESSAGE

	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	ADDI T2,5		;INCREMENT COUNT FOR TYPE CODE, DEV, CPU, PGM
	RETSKP			;DONE, RETURN SUCCESS
;MAKMPT - ROUTINE TO MAKE A MOP LOAD-WITH-TRANSFER-ADDRESS MESSAGE (.MPLDT)
;
;ACCEPTS IN T3/	LOAD NUMBER FOR THIS MESSAGE
;	    T4/	TRANSFER ADDRESS FOR THIS RECORD
;		CALL MAKMPT
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO COMPLETED MOP MESSAGE

MAKMPT:	STKVAR <MMTLOD,MMTADR>
	MOVEM T3,MMTLOD		;SAVE LOAD NUMBER
	MOVEM T4,MMTADR		;SAVE LOAD ADDRESS

; PUT THE FUNCTION CODE AND LOAD NUMBER INTO THE MESSAGE

	CALL CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVE T4,[POINT 8,MOPMSG] ;GET POINTER TO WHERE MOP MESSAGE GOES
	MOVX T1,.MPLDT		;GET MOP FUNCTION CODE
	IDPB T1,T4		;STORE FUNCTION CODE IN MOP MESSAGE
	MOVE T1,MMTLOD		;GET THE LOAD NUMBER FOR THIS RECORD
	IDPB T1,T4		;STORE LOAD NUMBER IN MOP MESSAGE
	MOVE T1,T4		;GET POINTER TO NEXT FIELD IN MOP MESSAGE
	MOVE T2,MMTADR		;GET TRANSFER ADDRESS
	CALL MAK4		;GO ADD A FOUR-BYTE NUMBER TO THE MOP MESSAGE
	MOVEI T2,6		;GET NUMBER OF BYTES IN MESSAGE SO FAR
	MOVE T1,[POINT 8,MOPMSG] ;GET POINTER TO MOP LOAD MESSAGE
	RET			;RETURN


;MAKMRL - ROUTINE TO MAKE A MOP "REQUEST LOAD RECORD" MESSAGE
;
;ACCEPTS IN T1/	LOAD NUMBER BEING REQUESTED
;	    T2/	MOP RESPONSE CODE
;		CALL MAKMRL
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO MOP MESSAGE
;			  T2/ # OF BYTES IN MOP MESSAGE

MAKMRL:	ASUBR <MRLLOD,MRLCOD>

	CALL CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVE T4,[POINT 8,MOPMSG] ;GET A POINTER TO THE MESSAGE
	MOVX T1,.MPRQL		;GET "REQUEST LOAD" MOP FUNCTION CODE
	IDPB T1,T4		;PUT FUNCTION CODE INTO MESSAGE
	MOVE T1,MRLLOD		;GET LOAD NUMBER BEING REQUESTED
	IDPB T1,T4		;ADD LOAD NUMBER TO MESSAGE
	MOVE T1,MRLCOD		;GET RESPONSE CODE
	IDPB T1,T4		;STORE RESPONSE CODE IN MESSAGE
	MOVE T1,[POINT 8,MOPMSG] ;GET POINTER TO START OF MOP MESSAGE
	MOVEI T2,3		;GET NUMBER OF BYTES IN MOP MESSAGE
	RET			;RETURN
;MAKRQL - ROUTINE TO ASSEMBEL A NICE DOWN LINE LOAD REQUEST MESSAGE
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL MAKRQL
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ COUNT OF BYTES IN THE MESSAGE

MAKRQL:	ASUBR <MQLLIN>
	STKVAR <<MQLLID,2>,MQLCNT>

; GET AND SAVE THE NICE LINE ID FOR THIS DTE20

	MOVE T1,MQLLIN		;GET LINE TABLE
	LOAD T1,LNDTE,(T1)	;GET DTE20 NUMBER
	CALL CVTDEV		;CONVERT TO STANDARD NICE LINE ID
	 RETBAD ()		;FAILED
	DMOVEM T2,MQLLID	;SAVE LINE ID

; ASSEMBLE THE FUNCTION AND OPTION CODES

	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF NICE MESSAGE
	MOVX T4,.NCRQL		;GET NICE "REQUEST DOWN LINE LOAD" FUNCTION
	IDPB T4,T1		;ADD TO MESSAGE
	MOVX T4,<FLD(LO%TGT,.LOSRV)+FLD(LO%ROM,.LOPGM)>
	IDPB T4,T1		;ADD OPTIONS TO NICE MESSAGE

; ADD THE SERVER NODE NAME AND SERVER LINE ID TO THE MESSAGE

	MOVX T2,2		;CURRENT COUNT OF BYTES IN MESSAGE
	MOVE T3,OURNAM		;GET POINTER TO OUR NODE NAME
	CALL MAKNOD		;ADD OUR NODE NAME TO MESSAGE
	DMOVE T3,MQLLID		;GET NICE LINE ID
	CALL MAKLIN		;ADD NICE LINE ID TO THE MESSAGE

; ADD PROGRAM REQUEST DATA TO THE DOWN LINE LOAD MESSAGE

	MOVX T4,.DTDTE		;GET DTE20 DEVICE TYPE CODE
	IDPB T4,T1		;ADD DEVICE TYPE TO MESSAGE
	MOVX T4,.CP11		;GET PDP-11 CPU TYPE CODE
	IDPB T4,T1		;ADD CPU TYPE CODE TO MESSAGE
	MOVX T4,.PTSLD		;GET SECONDARY LOADER PROGRAM TYPE CODE
	IDPB T4,T1		;ADD PROGRAM TYPE CODE TO THE MESSAGE
	ADDI T2,3		;ACCOUNT FOR THE ADDED BYTES IN MESSAGE
;MAKIMB - ROUTINE TO ASSEMBLE A BINARY NUMBER INTO AN IMAGE FIELD IN
;	  A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES IN IMAGE FIELD TO BE ASSEMBLED
;	    T3-T4/ BINARY NUMBER TO BE ADDED TO MESSAGE
;		CALL MAKIMB
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;		     NOTE: CALLER MUST KEEP TRACK OF TOTAL MESSAGE SIZE

MAKIMB::IDPB T2,T1		;ADD BYTE COUNT TO THE IMAGE FIELD

; LOOP OVER EACH BYTE TO BE ADDED TO THE MESSAGE

MKB010:	SOJL T2,R		;IF NO MORE BYTES TO ADD, RETURN
	IDPB T4,T1		;ADD NEXT BYTE TO THE MESSAGE
	LSHC T3,-8		;RIGHT JUSTIFY REMAINING BYTES
	JRST MKB010		;LOOP OVER ALL BYTES IN THE FIELD


;MAKIMA - ROUTINE TO ASSEMBLE AN ASCII STRING INTO AN IMAGE FIELD
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	MAXIMUM NUMBER OF BYTES TO BE ASSEMBLED
;	    T3/ POINTER TO ASCIZ STRING TO BE ASSEMBLED
;		CALL MAKIMA
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ NUMBER OF BYTES ACTUALLY ASSEMBLED

MAKIMA::ASUBR <MKAPTR,MKACNT,MKASTR>

	IBP T1			;SKIP OVER COUNT BYTE UNTIL STRING MOVED
	MOVEI T4,0		;INITIALIZE BYTE COUNTER
	JUMPE T2,MKA020		;IF NOTHING TO BE ASSEMBLED, JUST ADD BYTE COUNT


; LOOP OVER EACH BYTE IN THE ASCIZ STRING

MKA010:	ILDB T3,MKASTR		;GET NEXT CHARACTER FROM ASCIZ STRING
	JUMPE T3,MKA020		;IF END OF STRING, GO FIX UP COUNT BYTE
	SOJL T2,MKA020		;IF MAX CHARS IN MESSAGE, GO WRAP UP
	IDPB T3,T1		;ADD THE BYTE TO THE MESSAGE
	ADDI T4,1		;INCREMENT COUNT OF CHARACTERS DEPOSITED
	JRST MKA010		;LOOP OVER ALL CHARACTERS IN THE STRING

; HERE WHEN ALL CHARACTERS ARE IN THE MESSAGE - FIX UP THE COUNT BYTE

MKA020:	IDPB T4,MKAPTR		;ADD COUNT TO THE IMAGE FIELD
	MOVEI T2,1(T4)		;COPY # OF CHARACTERS ASSEMBLED + COUNT BYTE
	RETSKP			;DONE, RETURN
;MAKNOD - ROUTINE TO ADD A NODE NAME TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE BEING ASSEMBLED
;	    T2/	NUMBER OF BYTES CURRENTLY IN MESSAGE
;	    T3/	POINTER TO ASCIZ NODE NAME
;		CALL MAKNOD
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED COUNT OF BYTES IN MESSAGE

MAKNOD::STKVAR <MNDCNT>

	MOVEM T2,MNDCNT		;SAVE CURRENT BYTE COUNT
	MOVX T2,NNAMSZ		;GET MAX SIZE OF NODE NAMES
	CALL MAKIMA		;ASSEMBLE NAME AS IMAGE ASCII FIELD
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	ADD T2,MNDCNT		;GET UPDATED BYTE COUNT
	RETSKP			;DONE, RETURN


;MAKMPW - ROUTINE TO ADD A MAINTENANCE PASSWORD TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES CURRENTLY IN MESSAGE
;	    T3/	MAINTENANCE PASSWORD
;		CALL MAKMPW
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED COUNT OF BYTES IN MESSAGE

MAKMPW:	ASUBR <MMPPTR,MMPCNT,MMPPSW>

	MOVE T1,MMPPTR		;GET POINTER TO NEXT FIELD
	MOVE T2,MMPPSW		;GET PASSWORD
	CALL MAK4		;ADD A FOUR-BYTE FIELD TO THE MESSAGE
	MOVE T2,MMPCNT		;GET PREVIOUS BYTE COUNT
	ADDI T2,4		;INCREMENT FOR PASSWORD SIZE
	RET			;RETURN
;MAKZRO - ROUTINE TO MAKE A "ZERO LINE COUNTERS" NICE MESSAGE
;
;ACCEPTS IN T1-T2/ STANDARD NICE LINE ID
;	      T1/ LINE DEVICE TYPE (.DTXXX),,LINE CONTROLLER #
;	      T2/ LINE UNIT NUMBER,,LINE STATION ADDRESS
;		CALL MAKZRO
;RETURNS: +1 ALWAYS, WITH T1/ POINTER TO START OF MESSAGE
;			  T2/ COUNT OF BYTES IN THE MESSAGE

MAKZRO:	ASUBR <MKZLIN>

	CALL CLRMSG		;INITIALIZE MESSAGE AREA
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE AREA
	MOVX T4,.NCZRO		;GET "ZERO COUNTERS" NICE FUNCTION CODE
	IDPB T4,T1		;ADD FUNCTION CODE TO MESSAGE
	MOVX T4,.NCZLN		;GET OPTION FOR "LINE COUNTERS"
	IDPB T4,T1		;ADD OPTION BYTE
	DMOVE T3,MKZLIN		;GET LINE ID
	MOVX T2,2		;GET NUMBER OF BYTES IN MESSAGE SO FAR
	CALL MAKLIN		;ADD LINE ID TO MESSAGE
	HRLI T1,(POINT 8,)	;GET POINTER TO START OF ASSEMBLED
	HRRI T1,MSGBLK		; "ZERO COUNTERS" MESSAGE
	RET			;DONE, RETURN.
;MAKEXA - ROUTINE TO ADD AN EXTENSIBLE STRING TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO DESTINATION FOR EXTENSIBLE STRING
;	    T2/	POINTER TO SOURCE STRING
;	    T3/ CURRENT NUMBER OF BYTES IN MESSAGE
;		CALL MAKEXA
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T3/ UPDATED COUNT OF BYTES IN MESSAGE

MAKEXA:	ASUBR <MKEDST,MKESRC>
	ILDB T1,MKESRC		;GET A SOURCE BYTE
	JUMPE T1,[IDPB T1,MKEDST ;IF NULL STRING, DEPOSIT THE NULL AND
		  RET]		; RETURN

MKEXA2:	ILDB T2,MKESRC		;GET NEXT CHARACTER FROM STRING
	CAIE T2,.CHNUL		;GO A NULL BYTE ?
	TXO T1,EXTBIT		;NO, NOTE THAT ANOTHER BYTE FOLLOWS
	IDPB T1,MKEDST		;STORE FIRST BYTE INTO DESTINATION
	ADDI T3,1		;INCREMENT # OF BYTES IN MESSAGE
	TXNN T1,EXTBIT		;HAS THE LAST BYTE BEEN ADDED TO STRING ?
	JRST MKEXA3		;YES, GO RETURN THE UPDATED POINTER AND COUNT
	MOVE T1,T2		;NO, MAKE "NEXT CHARACTER" BE "THIS CHARACTER"
	JRST MKEXA2		;GO TEST NEXT CHARACTER OF STRING

; HERE WHEN ALL CHARACTERS HAVE BEEN PLACED INTO EXTENSIBLE STRING

MKEXA3:	MOVE T1,MKEDST		;RETURN UPDATED POINTER TO MESSAGE
				;COUNT IS STILL IN T3
	RET			;RETURN WITH UPDATED BYTE POINTERS AND COUNT



;MAKMEM - ROUTINE TO ADD A MEMORY ADDRESS OR SIZE TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES CURRENTLY IN MESSAGE
;	    T3/	MEMORY ADDRESS OR SIZE
;		CALL MAKMEM
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED BYTE COUNT

MAKMEM:	ASUBR <MKMPTR,MKMCNT,MKMMEM>

	MOVE T1,MKMPTR		;GET POINTER TO NEXT FIELD
	MOVE T2,MKMMEM		;GET MEMORY ADDRESS OR SIZE
	CALL MAK4		;ADD A FOUR-BYTE FIELD TO MESSAGE
	MOVE T2,MKMCNT		;GET PREVIOUS BYTE COUNT
	ADDI T2,4		;ALLOW FOR MEMORY ADDRESS
	RET			;RETURN
;MAKLOC - ROUTINE TO ADD A "NUMBER OF LOCATIONS" FIELD TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES CURRENTLY IN MESSAGE
;	    T3/	NUMBER OF LOCATIONS
;		CALL MAKLOC
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED BYTE COUNT

MAKLOC:	ASUBR <MKLPTR,MKLCNT,MKLLOC>

	MOVE T1,MKLPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	MOVE T2,MKLLOC		;GET NUMBER OF LOCATIONS
	CALL MAKTWO		;ADD A TWO BYTE FIELD TO THE MESSAGE
	MOVE T2,MKLCNT		;GET PREVIOUS BYTE COUNT
	ADDI T2,2		;ADD SIZE OF LOCATION FIELD
	RET			;RETURN

;MAKNAM - ROUTINE TO ADD A NODE NAME PARAMETER TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	CURRENT MESSAGE SIZE (IN BYTES)
;	    T3/	POINTER TO ASCIZ NODE NAME
;		CALL MAKNAM
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED BYTE COUNT

MAKNAM::ASUBR <MNMPTR,MNMCNT,MNMNAM>

	MOVX T4,.PVNAM		;GET NODE NAME PARAMETER TYPE CODE
	IDPB T4,T1		;ADD PARAMETER TYPE TO MESSAGE
	ADDI T2,1		;INCREMENT BYTE COUNT FOR PARAMETER TYPE BYTE
	CALL MAKNOD		;GO ADD A NODE NAME TO THE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, RETURN SUCCESS

;MAKHST - ROUTINE TO ADD A HOST NODE NAME PARAMETER TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	CURRENT MESSAGE SIZE (IN BYTES)
;	    T3/	POINTER TO ASCIZ HOST NODE NAME
;		CALL MAKHST
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ UPDATED BYTE COUNT

MAKHST::ASUBR <MHNPTR,MHNCNT,MHNNAM>

	MOVX T4,.PVHST		;GET HOST NODE NAME PARAMETER TYPE CODE
	IDPB T4,T1		;ADD PARAMETER TYPE TO MESSAGE
	ADDI T2,1		;INCREMENT BYTE COUNT FOR PARAMETER TYPE BYTE
	CALL MAKNOD		;GO ADD A NODE NAME TO THE MESSAGE
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	RETSKP			;DONE, RETURN SUCCESS
;MAKSLN - ROUTINE TO ASSEMBLE A NICE "SET PARAMETERS" MESSAGE TO
;	    SET THE STATE OF A LINE
;
;ACCEPTS IN T1/	LINE STATE
;	    T2-T3/ STANDARD NICE LINE ID
;	    T4/	DESTINATION ADDRESS FOR MESSAGE
;		CALL MAKSLN
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MESSAGE
;			      T2/ COUNT OF BYTES IN THE MESSAGE

MAKSLN::STKVAR <MLNSTA,<MLNLIN,2>,MLNPTR>

	MOVEM T1,MLNSTA		;SAVE LINE STATE
	DMOVEM T2,MLNLIN	;SAVE LINE ID
	MOVE T1,T4		;COPY ADDRESS OF START OF MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO START OF MESSAGE
	MOVEM T1,MLNPTR		;SAVE POINTER TO START OF MESSAGE
	MOVX T4,.NCSET		;GET NICE PROTOCOL "SET PARAMETER" FUNCTION
	IDPB T4,T1		;ADD FUNCTION CODE TO MESSAGE
	MOVX T4,.NCSLN		;GET NICE "SET LINE STATE" OPTION CODE
	IDPB T4,T1		;ADD OPTION BYTE TO MESSAGE
	MOVX T2,2		;CURRENTLY TWO BYTES IN THE MESSAGE
	DMOVE T3,MLNLIN		;GET LINE ID
	CALL MAKLIN		;ADD LINE TO THE MESSAGE
	MOVE T4,MLNSTA		;GET LINE STATE
	IDPB T4,T1		;ADD STATE TO MESSAGE
	ADDI T2,1		;INCREMENT COUNT OF BYTES IN THE MESSAGE
	MOVE T1,MLNPTR		;RESTORE POINTER TO START OF MESSAGE
	RETSKP			;DONE, RETURN SUCCESS
;MAKEVT - ROUTINE TO ASSEMBLE THE HEADER PART OF AN EVENT LOG MESSAGE
;
;ACCEPTS IN T1/	POINTER TO DESTINATION FOR MESSAGE
;	    T2/ EVENT CODE (.EVXXX)
;		CALL MAKEVT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKEVT:	STKVAR <MKEEVT,MKECNT>
	MOVEM T2,MKEEVT		;SAVE EVENT CODE
	MOVX T4,.NCLOG		;GET NICE "LOG DATA" FUNCTION CODE
	IDPB T4,T1		;ADD TO NICE MESSAGE
	MOVX T4,.LGMNT		;GET MAINTENANCE LOG OPTION
	IDPB T4,T1		;ADD TO NICE MESSAGE
	MOVX T2,NNAMSZ		;GET MAX SIZE OF NODE NAMES
	MOVE T3,[POINT 7,OURNAM] ;GET POINTER TO NAME OF THIS NODE
	CALL MAKIMA		;ADD ASCII STRING TO MESSAGE
	 RETBAD ()		;FAILED
	MOVEM T2,MKECNT		;SAVE COUNT OF CHARS ACTUALLY ASSEMBLED
	MOVE T3,[POINT 7,[ASCIZ/NETCON/]] ;GET PROGRAM NAME
	MOVX T2,6		;GET SIZE OF OUR PROGRAM NAME
	CALL MAKIMA		;ADD PROGRAM NAME TO THIS MESSAGE
	 RETBAD ()		;FAILED
	AOS T4,EVTSEQ		;GET NEXT EVENT LOG SEQUENCE NUMBER TO USE
	IDPB T4,T1		;ADD SEQUENCE NUMBER TO MESSAGE
	MOVE T2,MKEEVT		;GET EVENT TYPE CODE
	CALL MAKTWO		;ADD EVENT CODE TO NICE MESSAGE
	MOVE T2,MKECNT		;GET NUMBER OF BYTES USED IN NODE NAME
	ADDI T2,^D12		;ACCOUNT OF NON-VARYING INFORMATION
	RETSKP			;RETURN SUCCESS
;MAKENA - ROUTINE TO ASSEMBLE A NICE SET PARAMETER MESSAGE TO ENABLE
;	  EVENT LOGGING AT A NODE
;
;CALL:		CALL MAKENA
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ ADDRESS OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKENA::MOVE T1,[POINT 8,[BYTE (8) .NCSET, .NCNLS, .NSON ]]
	MOVX T2,3		;3 BYTES IN MESSAGE
	RETSKP			;DONE



;MAKDIS - ROUTINE TO ASSEMBLE A NICE SET PARAMETER MESSAGE TO DISABLE
;	  EVENT LOGGING AT A NODE
;
;CALL:		CALL MAKDIS
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ ADDRESS OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKDIS::MOVE T1,[POINT 8,[BYTE (8) .NCSET, .NCNLS, .NSOFF ]]
	MOVX T2,3		;3 BYTES IN MESSAGE
	RETSKP			;DONE


;MAKENL - ROUTINE TO ASSEMBLE A NICE SET PARAMETER MESSAGE TO ENABLE
;	  EVENT LOGGING FOR A LINE OR LINES.
;
;ACCEPTS IN T1-T2/ STANDARD NICE LINE ID (-1 IN FIRST WORD FOR ALL LINES)
;	       T3/ DESTINATION ADDRESS FOR MESSAGE
;		CALL MAKENL
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ ADDRESS OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKENL::STKVAR <<MNLLID,2>,MNLDST>
	DMOVEM T1,MNLLID	;SAVE LINE ID
	HRRZ T1,T3		;GET DESTINATION ADDRESS FOR MESSAGE
	HRLI T1,(POINT 8,)	;FORM POINTER TO MESSAGE DESTINATION
	MOVEM T1,MNLDST		;SAVE POINTER TO MESSAGE
	MOVX T3,.NCSET		;GET NICE "SET PARAMETER" FUNCTION CODE
	IDPB T3,T1		;STORE IN MESSAGE
	MOVX T3,.NCLLS		;GET "LINE LOGGING STATE" OPTION
	IDPB T3,T1		;STORE OPTION IN MESSAGE
	MOVX T2,2		;TWO BYTES IN MESSAGE SO FAR
	DMOVE T3,MNLLID		;GET LINE ID
	CAMN T3,[-1]		;ALL LINES SPECIFIED ?
	JRST [	MOVX T3,.LTALL	;YES, GET "ALL LINES" CODE
		IDPB T3,T1	;STORE IN MESSAGE
		ADDI T2,1	;INCREMENT COUNT FOR LINE ID
		JRST MAKNL1 ]	;AND CONTINUE
	CALL MAKLIN		;ADD LINE ID TO MESSAGE

MAKNL1:	MOVX T3,.NSON		;GET STATE CODE FOR "ON"
	IDPB T3,T1		;ADD STATE TO MESSAGE
	ADDI T2,1		;ACCOUNT FOR STATE CODE IN BYTE COUNT
	MOVE T1,MNLDST		;RESTORE POINTER TO START OF MESSAGE
	RETSKP			;DONE, RETURN



;MAKDSL - ROUTINE TO ASSEMBLE A NICE SET PARAMETER MESSAGE TO DISABLE
;	  EVENT LOGGING FOR A LINE OR LINES.
;
;ACCEPTS IN T1-T2/ STANDARD NICE LINE ID (-1 IN FIRST WORD FOR ALL LINES)
;	       T3/ DESTINATION ADDRESS FOR MESSAGE
;		CALL MAKDSL
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ ADDRESS OF MESSAGE
;			      T2/ NUMBER OF BYTES IN THE MESSAGE

MAKDSL::STKVAR <<MDLLID,2>,MDLDST>
	DMOVEM T1,MDLLID	;SAVE LINE ID
	HRRZ T1,T3		;GET DESTINATION ADDRESS FOR MESSAGE
	HRLI T1,(POINT 8,)	;FORM DESTINATION ADDRESS FOR MESSAGE
	MOVEM T1,MDLDST		;SAVE ADDRESS OF START OF MESSAGE
	MOVX T3,.NCSET		;GET NICE "SET PARAMETER" FUNCTION CODE
	IDPB T3,T1		;STORE IN MESSAGE
	MOVX T3,.NCLLS		;GET "LINE LOGGING STATE" OPTION
	IDPB T3,T1		;STORE OPTION IN MESSAGE
	MOVX T2,2		;TWO BYTES IN MESSAGE SO FAR
	DMOVE T3,MDLLID		;GET LINE ID
	CAMN T3,[-1]		;ALL LINES SPECIFIED ?
	JRST [	MOVX T3,.LTALL	;YES, GET "ALL LINES" CODE
		IDPB T3,T1	;STORE IN MESSAGE
		ADDI T2,1	;INCREMENT COUNT FOR LINE ID
		JRST MAKNL1 ]	;AND CONTINUE
	CALL MAKLIN		;ADD LINE ID TO MESSAGE

MKLIN1:	MOVX T3,.NSOFF		;GET STATE CODE FOR "ON"
	IDPB T3,T1		;ADD STATE TO MESSAGE
	ADDI T2,1		;ACCOUNT FOR STATE CODE IN BYTE COUNT
	MOVE T1,MDLDST		;GET POINTER TO START OF MESSAGE
	RETSKP			;DONE, RETURN
;MAKNUM - ROUTINE TO ADD A NODE NUMBER PARAMETER TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER OF BYTES IN THE MESSAGE
;	    T3/	NODE NUMBER
;		CALL MAKNUM
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE
;			  T2/ UPDATED MESSAGE SIZE

MAKNUM::ASUBR <MNUPTR,MNUCNT,MNUNUM>

	MOVX T4,.PVNUM		;GET NODE NUMBER PARAMETER VALUE TYPE CODE
	IDPB T4,T1		;ADD PARAMETER TYPE CODE TO MESSAGE
	MOVX T4,2		;GET NUMBER OF BYTES IN THE NUMBER FIELD
	IDPB T4,T1		;ADD FIELD SIZE TO MESSAGE
	MOVE T2,MNUNUM		;GET NODE NUMBER TO ADD TO MESSAGE
	CALL MAKTWO		;GO ADD A TWO BYTE FIELD TO THE MESSAGE
	MOVE T2,MNUCNT		;GET ORIGINAL COUNT
	ADDI T2,3		;ACCOUNT FOR TYPE CODE AND 2-BYTE NUMBER
	RET			;DONE, RETURN


;MAKTWO - ROUTINE TO ADD A TWO-BYTE NUMBER TO A MESSAGE
;
;ACCEPTS IN T1/	BYTE POINTER TO DESTINATION IN MESSAGE
;	    T2/	NUMBER TO BE ADDED TO MESSAGE
;		CALL MAKTWO
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED BYTE POINTER TO NEXT FIELD IN MESSAGE

MAKTWO::	IDPB T2,T1		;PUT LOW ORDER BYTE INTO MESSAGE FIRST
	LSH T2,-8		;RIGHT-ADJUST HIGH ORDER BYTE OF NUMBER
	IDPB T2,T1		;DEPOSIT HIGH ORDER BYTE INTO MESSAGE NEXT
	RET			;RETURN, WITH UPDATED POINTER IN T1


;MAK4 - ROUTINE TO ADD A FOUR-BYTE NUMBER TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER TO BE ADDED TO THE MESSAGE
;		CALL MAK4
;RETURNS +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE

MAK4:	ASUBR <PT4PTR,PT4NUM>

; ADD THE FIRST TWO BYTES TO THE MESSAGE

	MOVE T1,PT4PTR		;GET POINTER TO NEXT FIELD
	MOVE T2,PT4NUM		;GET NUMBER TO BE ADDED
	CALL MAKTWO		;ADD NEXT TWO BYTES TO MESSAGE

; ADD THE NEXT TWO BYTES TO THE MESSAGE

	MOVE T2,PT4NUM		;GET THE NUMBER TO BE ADDED AGAIN
	LSH T2,-^D16		;SHIFT TO POSITION THE NEXT TWO BYTES TO ADD
	CALLRET MAKTWO		;ADD NEXT TWO BYTES TO THE MESSAGE AND RETURN
SUBTTL	Routines to Manipulate DTE-20's

;DTESTP - Routine to Terminate any Protocol Running on the Specified DTE20.
;
;ACCEPTS IN T1/	LINE TABLE ADDRESS
;		CALL DTESTP
;RETURNS: +1	 FAILED, DEVICE IS NOT IN KNOWN STATE
;	  +2	SUCCESS, READY TO LOAD SECONDARY BOOTSTRAP

DTESTP:	ASUBR <SDTLIN>
	CALL CLRBOT		;INITIALIZE THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE T4,SDTLIN		;GET LINE TABLE ADDRESS
	LOAD T4,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVEM T4,.BTDTE(T2)	;STORE DTE-20 NUMBER TO STOP
	MOVEI T1,.BTTPR		;FUNCTION IS "TERMINATE PROTOCOL"
	BOOT			;STOP THE SPECIFIED DTE-20
	 ERJMP R		;THIS IS NOT EXPECTED TO FAIL
	RETSKP			;SUCCESS, BOOTSTRAP CAN NOW BE LOADED



;DTESLD - ROUTINE TO SEND DATA ACROSS THE DTE20
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL DTESLD
;RETURNS: +1	 FAILED, TRANSFER ERROR
;	  +2	SUCCESS, DATA SENT

DTESLD:	ASUBR <LDTLIN>

	CALL CLRBOT		;CLEAR THE BOOT JSYS ARGUMENT BLOCK

; SEND SECONDARY BOOTSTRAP ACROSS THE DTE20

	MOVEI T2,BTARG		;GET ADDRESS OF BOOT ARGUMENT BLOCK
	MOVE T4,LDTLIN		;GET ADDRESS OF LINE TABLE ENTRY
	LOAD T1,LNMSG,(T4)	;GET ADDRESS OF DATA TO BE SENT
	HRRZM T1,.BTSEC(T2)	;SAVE ADDRESS OF SECONDARY DATA
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVEM T1,.BTDTE(T2)	;SAVE DTE20 NUMBER IN ARGUMENT BLOCK
	MOVEI T1,.BTLDS		;GET BOOT JSYS FUNCTION CODE
	BOOT			;LOAD THE SECONDARY BOOTSTRAP
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;RETURN
;DTESND - ROUTINE TO SEND A MOP MESSAGE ACROSS THE DTE20
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL DTESND
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, MESSAGE SENT ACROSS THE DTE20

DTESND:	ASUBR <SDTLIN>

	CALL CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE T4,SDTLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVEM T1,.BTDTE(T2)	;STORE PHYSICAL LINE NUMBER (DTE20 NUMBER)
	LOAD T1,LNMSG,(T4)	;GET POINTER TO MOP MESSAGE TO SEND
	MOVEM T1,.BTLPT(T2)	;PUT POINTER INTO BOOT JSYS ARGUMENT BLOCK
	MOVX T1,BT%BEL		;GET "DOORBELL WANTED" FLAG
	MOVEM T1,.BTFLG(T2)	;SAVE FLAGS IN ARGUMENT BLOCK
	LOAD T1,LNCNT,(T4)	;GET NUMBER OF BYTES IN THE MOP MESSAGE
	MOVEM T1,.BTCNT(T2)	;STORE BYTE COUNT IN BOOT JSYS ARGUMENT BLOCK
	MOVEI T1,.BTLOD		;GET "LOAD" FUNCTION CODE
	BOOT			;SEND THE DATA ACROSS THE DTE20
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;RETURN, DATA SENT


;DTEWAT - ROUTINE TO WAIT FOR A DOORBELL FROM A DTE20
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL DTEWAT
;RETURNS: +1	 FAILED
;	  +2	SUCCESS

DTEWAT:	ASUBR <DTWLIN>

	CALL CLRBOT		;CLEAR BOOT JSYS ARGUMENT BLOCK
	MOVE T4,DTWLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVX T2,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK
	MOVEM T1,.BTDTE(T2)	;SAVE DTE20 NUMBER
	MOVX T1,.BTBEL		;GET "WAIT FOR DOORBELL" FUNCTION CODE
	BOOT			;WAIT FOR THE DOORBELL
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;DONE, RETURN SUCCESS
;DTEDMP - ROUTINE TO GET DUMP DATA OVER THE DTE20
;
;ACCEPTS IN T1/	LINE TABLE ADDRESS
;		CALL DTEDMP
;RETURNS: +1	 FAILED, BOOT JSYS ERROR
;	  +2	SUCCESS, DATA BYTES DUMPED INTO DATA AREA FOR THIS LINE

DTEDMP:	ASUBR <DTDLIN>

	CALL CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE T3,DTDLIN		;GET ADDRESS OF LINE TABLE ENTRY
	LOAD T4,LNDTE,(T3)	;GET DTE20 NUMBER FOR THIS LINE
	MOVEM T4,.BTDTE(T2)	;STORE DTE20 NUMBER IN BOOT JSYS ARG BLOCK
	LOAD T1,LNDCT,(T3)	;GET TOTAL NUMBER OF BYTES LEFT TO BE DUMPED
	CAIL T1,MAXMEM		;LESS THAN MAX FOR ONE IMAGE DATA MESSAGE ?
	MOVX T1,MAXMEM		;NO, USE ENOUGH TO FILL ONE DATA MESSAGE
	TRNE T1,1		;ODD NUMBER OF BYTES ?
	SUBI T1,1		;YES, DUMP INTEGRAL NUMBER OF WORDS
	STOR T1,LNCNT,(T3)	;STORE # OF BYTES TO RETURN
	LSH T1,-1		;COMPUTE NUMBER OF WORDS TO DUMP
	MOVEM T1,.BTCNT(T2)	;STORE NUMBER OF BYTES TO TRANSFER
	LOAD T4,LNMSG,(T3)	;GET ADDRESS OF DATA AREA FOR THIS LINE
	HRLI T4,(POINT 8,)	;FORM BYTE POINTER TO DESTINATION
	STOR T4,LNPTR,(T3)	;STORE NEW POINTER TO DATA TO RETURN
	HRLI T4,(POINT 16,)	;FORM POINTER FOR BOOT JSYS
	MOVEM T4,.BTDPT(T2)	;STORE POINTER TO DESTINATION IN ARG BLOCK
	MOVEI T1,.BTDMP		;GET BOOT JSYS FUNCTION CODE (DUMP)
	BOOT			;DUMP THE DATA
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;SUCCESS, DONE.
;DTERCV - ROUTINE TO RECEIVE A MOP MESSAGE ACROSS THE DTE20
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;		CALL DTERCV
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ POINTER TO START OF MOP MESSAGE
;			      T2/ NUMBER OF BYTES IN MOP MESSAGE

DTERCV:	ASUBR <RDTLIN>

	CALL CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE T4,RDTLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVEM T1,.BTDTE(T2)	;STORE NUMBER OF DTE20 TO USE

; SYNCHRONIZE WITH THE BOOTSTRAP PROGRAM BY WAITING FOR A TO-20 DOORBELL

	MOVEI T1,.BTBEL		;GET "WAIT FOR DOORBELL" FUNCTION
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	BOOT			;WAIT TILL BOOTSTRAP STARTS UP
	 ERJMP R		;FAILED, RETURN ERROR

; THE PROGRAM JUST LOADED IS NOW READY TO SEND BACK A MOP MESSAGE

	MOVE T1,RDTLIN		;GET ADDRESS OF LINE TABLE
	CALL CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVEI T1,RCVMAX		;GET MAX NUMBER OF BYTES WE CAN RECEIVE
	MOVEM T1,.BTCNT(T2)	;STORE BYTE COUNT
	MOVE T4,RDTLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO MESSAGE AREA
	MOVEM T1,.BTDPT(T2)	;STORE POINTER TO WHERE MESSAGE GOES
	SETZM .BTFLG(T2)	;CLEAR FLAGS
	MOVEI T1,.BTRMP		;GET "READ MOP MESSAGE" FUNCTION CODE
	BOOT			;GET A MOP MESSAGE
	 ERJMP R		;FAILED, RETURN ERROR
	MOVE T4,RDTLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNMSG,(T4)	;GET POINTER TO MESSAGE AREA
	MOVE T2,.BTCNT+BTARG	;GET NUMBER OF BYTES RECEIVED
	RETSKP			;DONE, RETURN
;DTEINI - ROUTINE TO ACTIVATE THE ROM ASSOCIATED WITH A DTE20
;
;ACCEPTS IN T1/	LINE TABLE ADDRESS
;		CALL DTEINI
;RETURNS: +1	 FAILED, COULD NOT ACTIVATE THE ROM
;	  +2	SUCCESS, ROM ACTIVATED

DTEINI:	ASUBR <DTILIN>
	CALL CLRBOT		;CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK
	MOVE T4,DTILIN		;GET ADDRESS OF LINE TABLE
	LOAD T4,LNDTE,(T4)	;GET DTE20 NUMBER
	MOVEM T4,.BTDTE(T2)	;STORE DTE20 NUMBER IN JSYS ARG BLOCK
	MOVX T1,.BTROM		;GET "INITIALIZE ROM" FUNCTION CODE
	BOOT			;INITIALIZE THE ROM FOR THIS DTE20
	 ERJMP R		;RETURN ERROR IF FAILED
	RETSKP			; ELSE DONE, RETURN SUCCESS.



;DTEGO - ROUTINE TO INITIATE A PROTOCOL STARTUP ON A GIVEN DTE20
;
;ACCEPTS IN T1/	ADDRESS OF LINE TABLE
;	    T2/	PROTOCOL VERSION TYPE (.VNXXX) TO USE
;		CALL DTEGO
;RETURNS: +1	 FAILED, DTE20 ERROR
;	  +2	SUCCESS, PROTOCOL INITIATED

DTEGO:	ASUBR <DTGLIN,DTGPRO>

	CALL CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK
	MOVE T4,DTGLIN		;GET ADDRESS OF LINE TABLE
	LOAD T1,LNDTE,(T4)	;GET DTE20 NUMBER FOR THIS LINE
	MOVEM T1,.BTDTE(T2)	;STORE DTE20 NUMBER IN JSYS ARG BLOCK
	MOVE T1,DTGPRO		;GET PROTOCOL VERSION TYPE
	MOVEM T1,.BTPRV(T2)	;SAVE PROTOCOL TO USE IN BOOT JSYS ARG BLOCK
	MOVEI T1,.BTIPR		;GET "INITIATE PROTOCOL" FUNCTION CODE
	BOOT			;STARTUP THE PROTOCOL
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;DONE, RETURN SUCCESS
SUBTTL	I/O Subroutines

;INPBYT - ROUTINE TO INPUT THE NEXT BYTE FROM A PDP-11 FORMAT FILE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD TABLE ENTRY
;		CALL INPBYT
;RETURNS: +1	 ERROR OR END OF FILE
;	  +2	SUCCESS, WITH BYTE IN T2

INPBYT:	MOVE T4,T1		;SAVE RECORD TABLE ENTRY ADDRESS
	LOAD T3,RBBYT,(T4)	;GET NUMBER OF NEXT BYTE IN WORD
	CAIGE T3,BPWRD		;ALREADY GOT LAST BYTE IN WORD ?
	JRST GTBT10		;NO, GO GET NEXT BYTE IN WORD

; ALL BYTES IN CURRENT WORD HAVE BEEN READ.  INPUT THE NEXT DATA WORD

	SETZRO RBBYT,(T4)	;WRAP AROUND TO FIRST BYTE IN WORD
	LOAD T1,RBJFN,(T4)	;GET JFN OF CURRENT INPUT FILE
	BIN			;INPUT THE NEXT WORD
	 ERJMP R		;FAILED, RETURN ERROR
	STOR T2,RBDAT,(T4)	;STORE NEXT DATA WORD FROM INPUT FILE

; HERE TO ACTUALLY GET THE NEXT BYTE OF DATA

GTBT10:	LOAD T1,RBDAT,(T4)	;GET CURRENT DATA WORD
	LOAD T3,RBBYT,(T4)	;GET NUMBER OF NEXT BYTE TO LOAD
	LDB T2,BYTTAB(T3)	;LOAD NEXT BYTE FROM CURRENT WORD
	INCR RBBYT,(T4)		;POINT TO NEXT BYTE IN WORD
	RETSKP			;RETURN WITH BYTE IN T2


; INPWRD -- INPUT A 16-BIT WORD AS TWO 8-BIT BYTES
;
; ACCEPTS IN T1/ ADDRESS OF RECORD BLOCK FOR THIS OPERATION
;
; RETURNS:
;	+1:	I/O ERROR OR END-OF-FILE
;	+2:	SUCCESS,
;			T1/	SUM OF BYTES
;			T2/	16-BIT WORD, RIGHT-JUSTIFIED
;
INPWRD:
	PUSH P,T1		;SAVE RECORD BLOCK ADDRESS
	CALL INPBYT		;READ FIRST (LOW) BYTE
	 RET			;ERROR-- RETURN +1 FROM INPWRD
	POP P,T1		;RESTORE RECORD BLOCK ADDRESS
	PUSH P,T2		;SAVE LOW BYTE
	CALL INPBYT		;READ SECOND (HIGH) BYTE
	 RET			;ERROR-- RETURN +1 FROM INPWRD
	POP P,T3		;RESTORE LOW BYTE
	MOVE T1,T3		;COPY IT FOR SUM
	ADD T1,T2		;COMPUTE SUM OF BYTES TO T1
	LSH T2,^D8		;SHIFT HIGH BYTE TO BITS 15-8
	IOR T2,T3		;MUSH TOGETHER WITH LOW BYTE INTO WORD IN T2
	RETSKP			;RETURN +2 FROM INPWRD, SUM IN T1, WORD IN T2
;WRTDMP - ROUTINE TO OUTPUT A DUMP RECORD TO THE DUMP FILE
;
;ACCEPTS IN T1/	POINTER TO DATA TO BE OUTPUT
;	    T2/	NUMBER OF BYTES TO OUTPUT
;	    T3/	ADDRESS OF RECORD TABLE ENTRY
;		CALL WRTDMP
;RETURNS: +1	 FAILED, FILE DATA OR OTHER ERROR
;	  +2	SUCCESS, DATA OUTPUT TO FILE

WRTDMP:	ASUBR <WTDPTR,WTDCNT,WTDREC>

WDMP10:	SOSG WTDCNT		;DECREMENT # OF BYTES LEFT TO WRITE
	RETSKP			;DONE, ALL BYTES OUTPUT
	MOVE T1,WTDREC		;GET RECORD TABLE ENTRY ADDRESS
	ILDB T2,WTDPTR		;GET NEXT BYTE TO OUTPUT
	CALL WRTBYT		;GO OUTPUT THE BYTE
	 RET			;FAILED, RETURN ERROR
	JRST WDMP10		;LOOP OVER ALL BYTES TO OUTPUT



; TABLE OF BYTE POINTERS TO GET THE "NEXT" BYTE IN PDP-11 FORMAT

BYTTAB:	POINT 8,T1,17
	POINT 8,T1,9
	POINT 8,T1,35
	POINT 8,T1,27
;WRTBYT - ROUTINE TO WRITE A BYTE INTO A PDP-11 FORMAT FILE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD TABLE ENTRY
;	    T2/	BYTE TO BE OUTPUT
;		CALL WRTBYT
;RETURNS: +1	 FAILED, OUTPUT ERROR
;	  +2	SUCCESS, BYTE HAS BEEN OUTPUT

WRTBYT:	ASUBR <WTDREC,WTDBYT>

; DETERMINE IF AN ENTIRE WORD HAS BEEN FILLED - IF SO, OUTPUT THE WORD

	MOVE T4,WTDREC		;GET ADDRESS OF RECORD TABLE ENTRY
	LOAD T3,RBBYT,(T4)	;GET NUMBER OF NEXT BYTE TO DEPOSIT
	CAIGE T3,BPWRD		;THIS WORD ENTIRELY FILLED YET ?
	JRST WTDT10		;NO, GO DEPOSIT THE BYTE

; THE CURRENT WORD HAS NO MORE ROOM AND MUST BE WRITTEN INTO THE FILE

	LOAD T1,RBJFN,(T4)	;GET JFN OF OUTPUT FILE
	LOAD T2,RBDAT,(T4)	;GET WORD TO BE WRITTEN
	BOUT			;OUTPUT THE WORD
	 ERJMP R		;FAILED, RETURN ERROR
	SETZRO RBBYT,(T4)	;RESET THE BYTE COUNTER

; HERE TO DEPOSIT THE BYTE INTO THE CURRENT DATA WORD

WTDT10:	MOVE T4,WTDREC		;GET ADDRESS OF RECORD TABLE ENTRY
	LOAD T3,RBBYT,(T4)	;GET NUMBER OF NEXT BYTE TO DEPOSIT
	LOAD T1,RBDAT,(T4)	;GET THE CURRENT DATA WORD
	MOVE T2,WTDBYT		;GET THE DATA BYTE TO DEPOSIT
	DPB T2,BYTTAB(T3)	;STORE THE BYTE INTO PROPER PLACE IN THE WORD
	STOR T1,RBDAT,(T4)	;REPLACE CURRENT DATA WORD
	INCR RBBYT,(T4)		;INCREMENT NUMBER OF NEXT BYTE TO DEPOSIT
	RETSKP			;RETURN SUCCESS, DONE.
;OPNIFL - ROUTINE TO OPEN A FILE FOR INPUT
;
;ACCEPTS IN T1/	POINTER TO ASCIZ FILESPEC
;		CALL OPNIFL
;RETURNS: +1	 FAILED, GTJFN OR OPENF FAILURE
;	  +2	SUCCESS, WITH T1/ JFN OF INPUT FILE
;			T2/ FILE FORMAT TYPE (.FTXXX)

OPNIFL:	STKVAR <<OPITYP,8>,OPIJFN>
	MOVE T2,T1		;COPY POINTER TO FILESPEC
	MOVX T1,GJ%OLD!GJ%SHT	;EXISTING FILE, SHORT CALL
	GTJFN			;GET A JFN FOR INPUT FILE
	 RET			;FAILED, RETURN
	MOVE T2,[440000,,OF%RD]	;36-BIT BYTES, READ ACCESS ONLY
	OPENF			;OPEN THE FILE
	 JRST [	RLJFN		;FAILED, RELEASE THE JFN
		 JFCL		;IGNORE ERRORS HERE
		RET ]		;RETURN ERROR

; FIND THE FILE FORMAT TYPE FROM THE FILE TYPE

	MOVEM T1,OPIJFN		;SAVE JFN
	HRRZ T2,T1		;COPY THE JFN FOR JFNS
	HRROI T1,OPITYP		;POINT STRING POINTER TO SCRATCH
	MOVX T3,<FLD(.JSAOF,JS%TYP)> ;GET ONLY FILE TYPE
	JFNS
	 ERJMP R		;FAILED, RETURN ERROR
	MOVEI T1,FTYTAB		;POINT TO FILE TYPE TABLE
	HRROI T2,OPITYP		;POINT TO SCRATCH STRING
	TBLUK			;FIND FILE TYPE
	 ERJMP R		;FAILED, RETURN ERROR
	MOVE T3,T2		;COPY FLAGS
	HRRZ T2,(T1)		;GET TABLE ENTRY, FILE TYPE FORMAT
	TXNN T3,TL%EXM		;EXACT MATCH?
	RET			;FAIL IF UNKNOWN FILE TYPE
	MOVE T1,OPIJFN		;RESTORE JFN
	RETSKP			;SUCCESS, RETURN WITH T1/ JFN, T2/ FILE FORMAT TYPE

; FILE FORMAT TYPE TABLE FOR OPNIFL (TBLUK FORMAT)

FTYTAB:
	XWD FTYTBZ,FTYTBZ
	TB (.FTLDA,BIN)
	TB (.FTDMP,DMP)
	TB (.FTLDA,LDA)
	TB (.FTTSK,SYS)
	TB (.FTTSK,TSK)
FTYTBZ==.-FTYTAB-1
;OPNOFL - ROUTINE TO OPEN A FILE FOR OUTPUT
;
;ACCEPTS IN T1/	POINTER TO ASCIZ FILESPEC
;		CALL OPNOFL
;RETURNS: +1	 FAILED, GTJFN OR OPENF FAILURE
;	  +2	SUCCESS, WITH T1/ JFN OF OUTPUT FILE

OPNOFL:	MOVE T2,T1		;COPY POINTER TO FILESPEC
	MOVX T1,GJ%FOU!GJ%SHT	;FILE FOR OUTPUT USE, SHORT CALL
	GTJFN			;GET A JFN FOR OUTPUT FILE
	 RET			;FAILED, RETURN
	MOVE T2,[440000,,OF%WR]	;36-BIT BYTES, WRITE ACCESS ONLY
	OPENF			;OPEN THE FILE
	 JRST [	RLJFN		;FAILED, RELEASE THE JFN
		 JFCL		;IGNORE ERRORS HERE
		RET ]		;RETURN ERROR
	RETSKP			;SUCCESS, RETURN WITH T1/ JFN



;CLSOFL - ROUTINE TO CLOSE AN OUTPUT FILE.  ANY DATA REMAINING IN THE
;	  RECORD TABLE ENTRY MUST BE WRITTEN INTO THE FILE BEFORE THE
;	  FILE IS ACUTALLY CLOSED.
;
;ACCEPTS IN T1/	ADDRESS OF RECORD BLOCK
;		CALL CLSOFL
;RETURNS: +1	 FAILED, COULD NOT CLOSE FILE
;	  +2	SUCCESS, ALL DATA OUTPUT AND FILE CLOSED

CLSOFL:	MOVE T4,T1		;COPY ADDRESS OF RECORD TABLE ENTRY
	LOAD T1,RBJFN,(T4)	;GET JFN OF OUTPUT FILE
	LOAD T2,RBDAT,(T4)	;GET CURRENT DATA WORD
	JE RBBYT,(T4),CLOF10	;IF NO BYTES IN THIS WORD, SKIP OUTPUT
	BOUT			;OUTPUT THE REMAINING BYTES
	 ERJMP CLOF10		;TRY TO CLOSE FILE ANYWAY ON ERROR
CLOF10:	CLOSF			;CLOSE THE FILE
	 ERJMP R		;RETURN FAILURE IF COULD NOT CLOSE FILE
	RETSKP			;DONE, RETURN SUCCESS
;INPLDA - ROUTINE TO INPUT ONE BLOCK FROM A PDP-11 FORMAT .LDA FILE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD BLOCK
;		CALL INPLDA
;RETURNS: +1	 FAILED, BAD FILE FORMAT, PREMATURE EOF, OR BAD CHECKSUM
;	  +2	SUCCESS, WITH DATA INPUT INTO RECORD BLOCK

INPLDA:	ASUBR <IBKREC,IBKSUM,IBKCTR,IBKCNT>
	STKVAR <IBKPTR>
	SETZM IBKSUM		;INITIALIZE THE CHECKSUM

; SKIP OVER INITIAL ZERO BYTES

IBLK10:	MOVE T1,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPBYT		;GO GET A BYTE FROM THE INPUT FILE
	 RET			;FAILED, RETURN
	JUMPE T2,IBLK10		;SKIP OVER ZERO BYTES

; THE NEXT TWO BYTES SHOULD BE A 1-BYTE FOLLOWED BY A 0-BYTE

	ADDM T2,IBKSUM		;ADD BYTE JUST INPUT TO CHECKSUM
	CAIE T2,1		;NEXT BYTE A 1-BYTE ?
	RET			;NO, BAD FILE FORMAT
	MOVE T1,IBKREC		;YES, GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPBYT		;GO GET THE NEXT BYTE FROM THE INPUT FILE
	 RET			;FAILED, RETURN
	ADDM T2,IBKSUM		;ADD BYTE JUST INPUT TO CHECKSUM
	CAIE T2,0		;JUST READ A 0-BYTE ?
	RET			;NO, BAD FILE FORMAT

; INPUT THE BYTE COUNT (2 BYTES)

	MOVE T1,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPWRD		;GET NEXT WORD FROM FILE
	 RET			;FAILED, RETURN
	ADDM T1,IBKSUM		;UPDATE THE CHECKSUM
	MOVEM T2,IBKCNT		;SAVE BYTE COUNT
	; ..
	; ..

; READ THE LOAD OR TRANSFER ADDRESS (2 BYTES)

	MOVE T1,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPWRD		;GO GET A WORD FROM THE INPUT FILE
	 RET			;FAILED, RETURN ERROR
	ADDM T1,IBKSUM		;ADD THIS WORD TO THE CHECKSUM
	MOVE T4,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	STOR T2,RBNAD,(T4)	;STORE LOAD ADR IN RECORD TABLE ENTRY
	STOR T2,RBXAD,(T4)	;STORE TRANSFER ADR IN RECORD TABLE ENTRY

; SET UP TO READ THE DATA BYTES FROM THE BLOCK

	MOVE T1,IBKCNT		;GET BYTE COUNT
	SUBI T1,BINHDR		;ALLOW FOR BYTES IN HEADER
	MOVEM T1,IBKCTR		;SAVE NUMBER OF DATA BYTES TO READ
	MOVE T4,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	STOR T1,RBCNT,(T4)	;SAVE NUMBER OF DATA BYTES IN RECORD TABLE ENTRY
	LOAD T1,RBPTR,(T4)	;GET POINTER TO DESTINATION FOR DATA
	MOVEM T1,IBKPTR		;SAVE POINTER TO DESTINATION OF NEXT DATA BYTE

; READ THE DATA BYTES FROM THE BLOCK

IBLK20:	SOSGE IBKCTR		;ANOTHER BYTE TO READ ?
	JRST IBLK30		;NO, GO READ AND VERIFY BLOCK CHECKSUM
	MOVE T1,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPBYT		;GET A BYTE FROM THE FILE
	 RET			;FAILED, RETURN ERROR
	ADDM T2,IBKSUM		;UPDATE THE CHECKSUM
	IDPB T2,IBKPTR		;STORE THE BYTE IN THE RECORD BLOCK
	JRST IBLK20		;GO GET THE NEXT BYTE FROM THE FILE

; HERE TO READ AND VERIFY THE CHECKSUM AFTER READING THE DATA BYTES

IBLK30:	MOVE T1,IBKREC		;GET ADDRESS OF RECORD TABLE ENTRY
	CALL INPBYT		;GO GET A BYTE FROM THE FILE
	 RET			;FAILED, RETURN ERROR
	MOVN T1,IBKSUM		;GET -CHECKSUM
	LDB T1,[POINT 8,T1,35]	;GET JUST THE LOW ORDER BYTE OF CHECKSUM
	CAME T1,T2		;CHECKSUM VERIFY CORRECLTY ?
	RET			;NO, RETURN FAILURE

; HERE WHEN DONE - RETURN TO CALLER

	RETSKP			;RETURN SUCCESS
; INPTSK/INPDMP - INPUT A BLOCK FROM A TASK-IMAGE OR DUMP FORMAT FILE
;
; ACCEPTS IN:
;	T1/	RECORD BLOCK ADDRESS
;
; RETURNS:
;	+1:	FAILED, I/O ERROR, INVALID FORMAT OR PREMATURE EOF
;	+2:	SUCCESS, DATA LOADED INTO RECORD BLOCK
;
INPDMP:
INPTSK:
	TRVAR <ITSREC,ITSCNT,ITSPTR>
	MOVEM T1,ITSREC		;SAVE ADDRESS OF RECORD BLOCK
;
; SEE IF WE HAVE READ LABEL BLOCKS ALREADY
; SET NEW ADDRESS FOR THIS BLOCK
;
	LOAD T2,RBCAD,(T1)	;GET CURRENT ADDRESS
	STOR T2,RBNAD,(T1)	;SET CURRENT ADDRESS AS NEXT ADDRESS
	CAME T2,[EXP -1]	;HAS ADDRESS
	CAIL T2,777777		; BEEN SET YET?
	 SKIPA			;NO-- READ LABEL BLOCKS
	JRST ITSCBC		;YES-- JUST MOVE DATA FROM FILE
;
; SET UP BYTE COUNTS, READING LABEL BLOCKS IF NEEDED

	CALL INPCNT		;GO SET UP COUNTS
	 RET			;FAILED
;
; COMPUTE BYTE COUNT FOR THIS RECORD
;
ITSCBC:	LOAD T2,RBFCT,(T1)	;GET REMAINING BYTE COUNT IN FILE
	MOVE T3,T2		;COPY BYTE COUNT
	CAILE T2,MAXMEM		;MORE THAN MAX ALLOWED IN MEMORY MESSAGES?
	 MOVX T2,MAXMEM		;YES-- USE MAXIMUM
	SUB T3,T2		;COMPUTE REMAINING BYTE COUNT
	STOR T3,RBFCT,(T1)	;STORE UPDATED COUNT
	MOVEM T2,ITSCNT		;REMEMBER THE COUNT
	STOR T2,RBCNT,(T1)	; ALSO FOR EVERYBODY ELSE
;
; READ BYTES INTO RECORD
;
	LOAD T2,RBPTR,(T1)	;GET POINTER TO DATA REGION
	MOVEM T2,ITSPTR		;SAVE THAT
;
; LOOP THROUGH THE BYTES . . .
;
ITSBLP:	SOSGE ITSCNT		;COUNT DOWN, WE DONE?
	 RETSKP			;YES-- RETURN +2 FROM INPTSK
	MOVE T1,ITSREC		;GET RECORD BLOCK ADDRESS
	CALL INPBYT		;GET NEXT FILE BYTE
	 RET			;ERROR OR EOF-- RETURN NOW
	IDPB T2,ITSPTR		;STORE BYTE
	JRST ITSBLP		;LOOP FOR ALL BYTES
; INPCNT - SET UP COUNTS AND READ LABEL BLOCKS IF NEEDED
;
; ACCEPTS IN:
;	ITSREC/ ADDRESS OF RECORD BLOCK
;
; RETURNS:
;	+1	ERROR
;	+2	SUCCESS, WITH RBFCT, RBSAD, RBNAD SET UP
;
INPCNT:	MOVE T1,ITSREC		;GET ADDRESS OF RECORD BLOCK
	LOAD T2,RBTYP,(T1)	;GET FILE TYPE (.FTXXX)
	CAIL T2,0		;RANGE CHECK THE FILE
	CAIL T2,FTYPLN		; TYPE CODE
	RET			;FAIL, INVALID FILE TYPE
	CALLRET @FLTYPE(T2)	;DISPATCH TO ROUTINE TO SET UP COUNTS

FLTYPE:	RET			; 0 IS ILLEGAL
	RET			; .FTLDA - SHOULD NOT BE HERE FOR LDA FILES
	INPTCT			; .FTTSK - TASK-IMAGE FILE TYPE
	INPDCT			; .FTDMP - DUMP FORMAT FILE TYPE
FTYPLN==.-FLTYPE		;SIZE OF TYPE DISPATCH TABLE


; INPTCT - INPUT COUNTS FOR A TASK-IMAGE FILE TYPE
;
; ACCEPTS:
;	ITSREC/ ADDRESS OF RECORD BLOCK
;
; RETURNS:
;	+1	FAILED
;	+2	SUCCESS, WITH COUNTS SET UP IN RECORD BLOCK

INPTCT:
;
; READ LABEL BLOCKS
;
; SETS UP RBFCT, RBXAD, AND RBNAD
;
	MOVEI T2,L$BSA-0	;SKIP TO L$BSA
	CALL ITSSKP		; . .
	 RET			;ERROR OR END-OF-FILE
;
	CALL INPWRD		;GET BASE ADDRESS: L$BSA
	 RET			;ERROR/EOF
	MOVE T1,ITSREC		;POINT TO RECORD BLOCK
	STOR T2,RBNAD,(T1)	;STORE BASE ADDRESS
;
	MOVEI T2,L$BLDZ-<L$BSA+2> ;SKIP TO L$BLDZ
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET LOAD SIZE / 64.: L$BLSZ
	 RET			;ERROR/EOF
	LSH T2,^D6		;CONVERT LOAD SIZE TO BYTES
	MOVE T1,ITSREC		;POINT TO RECORD BLOCK
	STOR T2,RBFCT,(T1)	;STORE LOAD SIZE AS BYTES LEFT IN FILE
;
	MOVEI T2,L$BFLG-<L$BLDZ+2> ;SKIP TO L$BFLG
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET FLAGS WORD: L$BFLG
	 RET			;ERROR/EOF
	TXNN T2,TS$NHD		;TASK FILE HAVE NO HEADER: TS$NHD= 1?
	 RET			;NO-- NOT SYSTEM IMAGE
;
	MOVEI T2,L$BXFR-<L$BFLG+2> ;SKIP TO L$BXFR
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET TRANSFER ADDRESS: L$BXFR
	 RET			;ERROR/EOF
	MOVE T1,ITSREC		;POINT TO RECORD BLOCK
	STOR T2,RBXAD,(T1)	;STORE TRANSFER ADDRESS
;
	MOVEI T2,L$BHRB-<L$BXFR+2> ;SKIP TO L$BHRB
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET RELATIVE BLOCK OF IMAGE: L$BHRB
	 RET			;ERROR/EOF
	LSH T2,^D9		;CONVERT TO BYTES (512. BYTES/BLOCK)
	SUBI T2,L$BHRB+2	;MINUS BYTES ALREADY READ
	CALL ITSSKP		;SKIP REMAINING LABEL BLOCKS
	 RET			;ERROR/EOF
	RETSKP			;DONE, RETURN SUCCESS
; INPDCT - ROUTINE TO SET UP THE COUNT FOR A DUMP FORMAT FILE
;
; ACCEPTS:
;	ITSREC/ ADDRESS OF RECORD BLOCK
;
; RETURNS:
;	+1	FAILED
;	+2	SUCCESS, WITH COUNTS SET UP

INPDCT:	MOVE T1,ITSREC		;GET ADDRESS OF RECORD BLOCK
	SETZRO <RBNAD,RBXAD>,(T1) ;INITIALIZE COUNTS
	LOAD T1,RBJFN,(T1)	;GET JFN OF INPUT FILE
	MOVX T2,<2,,.FBBYV>	;TWO WORDS, BYTE SIZE WORD & FILE SIZE
	MOVX T3,T2		;PUT RESULTS INTO T2 AND T3
	GTFDB			;GET FILE DATA
	 ERJMP R		;FAILED
	LOAD T2,FB%BSZ,T2	;GET FILE BYTE SIZE
	MOVX T1,^D36		;GET # OF BITS PER WORD
	IDIV T1,T2		;COMPUTE NUMBER OF BYTES PER WORD IN FILE
	ADDI T3,-1(T1)		;FILE SIZE + BYTES/WORD -1
	IDIV T3,T1		;ROUND FILES SIZE
	IMULI T3,BPWRD		;COMPUTE NUMBER OF KL20 WORDS
	MOVE T1,ITSREC		;GET ADDRESS OF RECORD BLOCK
	STOR T3,RBFCT,(T1)	;STORE COUNT
	RETSKP			;DONE, RETURN



; ITSSKP -- SKIP SOME BYTES IN T2
;
; ACCEPTS IN:
;	T2/	COUNT OF BYTES TO SKIP
;
; RETURNS:
;	+1:	ERROR/EOF
;	+2:	SUCCESS, T1 POINTS TO RECORD BLOCK
;
ITSSKP:
	MOVEM T2,ITSCNT		;SAVE COUNT
ITSSLP:
	MOVE T1,ITSREC		;POINT TO RECORD BLOCK
	SOSGE ITSCNT		;BYTES LEFT?
	 RETSKP			;NO-- RETURN +2 FROM ITSSKP
	CALL INPBYT		;GET A BYTE
	 RET			;ERROR/EOF
	JRST ITSSLP		;SKIP MORE....
;GETLNK - ROUTINE TO GET A LOGICAL LINK TO A NICE PROCESS
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NODE NAME OF DESTINATION
;		CALL GETLNK
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ LOGICAL LINK NUMBER (I.E., JFN)

GETLNK:	STKVAR <GLLNOD,<GLLNAM,20>,<GLLBLK,20>>
	MOVEM T1,GLLNOD		;SAVE POINTER TO NAME OF DESTINATION NODE
	MOVSI T1,GLLBLK		;SET UP TO CLEAR
	HRRI T1,1+GLLBLK	; THE GTJFN BLOCK
	SETZM GLLBLK		;CLEAR FIRST WORD OF BLOCK
	BLT T1,17+GLLBLK	;CLEAR REMAINDER OF BLOCK
	HRROI T1,[ASCIZ/DCN/]	;GET POINTER TO ASCIZ DEVICE NAME OF DESTINATION
	MOVEM T1,.GJDEV+GLLBLK	;SAVE POINTER TO DEVICE
	HRROI T1,GLLNAM		;GET POINTER TO TEMPORARY STRING AREA
	MOVE T2,GLLNOD		;GET POINTER TO NAME OF DESTINATION NODE
	SETZM T3		;TERMINATE ON NULL
	SOUT			;COPY THE NAME OF THE DESTINATION NODE
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNCATIONS ERROR"
	MOVEI T2,"-"		;GET DELIMITER BETWEEN NODE AND SERVER NAME
	IDPB T2,T1		;ADD DELIMITER TO FILE NAME
	HRROI T2,[ASCIZ/NCU/]	;GET POINTER TO NAME OF NICE PROCESS SERVER
	SOUT			;ADD SERVER NAME TO FILESPEC
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	HRROI T1,GLLNAM		;GET POINTER TO FILE NAME
	MOVEM T1,.GJNAM+GLLBLK	;SAVE POINTER TO NAME OF FILE
	SETZM .GJEXT+GLLBLK	;NO EXTENSION NEEDED
	SETZM .GJGEN+GLLBLK	;NO FLAGS
	MOVE T1,[.NULIO,,.NULIO] ;NO JFN'S NEEDED
	MOVEM T1,.GJSRC+GLLBLK	;SAVE NULL JFN'S AS SOURCE, ECHOING JFN'S
	SETZM T2		;NO STRING POINTER
	MOVEI T1,GLLBLK		;GET ADDRESS OF GTJFN BLOCK
	GTJFN			;GET A JFN FOR THE NICE PROCESS
	 ERJMP [RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	MOVEM T1,T4		;SAVE JFN IN CASE OPENF FAILS
	MOVE T2,[100000,,OF%RD+OF%WR] ;8 BIT BYTES, READ AND WRITE ACCESS
	OPENF			;OPEN THE LOGICAL LINK
	 ERJMP [MOVE T1,T4	;FAILED, RESTORE JFN
		RLJFN		;RELEASE JFN
		 JFCL		;IGNORE FAILURE, NOT CRITICAL
		RETBAD (.NRCME)] ;FAILED, RETURN "COMMUNICATIONS ERROR"
	RETSKP			;DONE, JFN (LOGICAL LINK NUMBER) IS IN T1
SUBTTL	SYSERR Routines

;LOGGER - ROUTINE TO PERFORM LOGGING OF LINE COUNTER DATA
;

LOGGER::MOVE P,[-PDLEN,,LOGPDL-1] ;SET UP STACK POINTER
	MOVEI P5,LOGFFP_9	;GET ADDRESS OF SCRATCH AREA FOR LOGGING PROCESS


; PERIODICALLY LOG LINE COUNTERS

LOGR20:	CALL TSTLOG		;DO ANY LINE COUNTER LOGGING NEEDED
	MOVE T1,LOGTIM		;GET TIME INTERVAL BETWEEN LOGGINGS
	DISMS			;WAIT
	JRST LOGR20		;GO CHECK TO SEE IF LOGGING IS STILL ENABLED
;TSTLOG - ROUTINE TO LOOP OVER ALL NODES LOOKING FOR LINES WHOSE
;	    COUNTERS ARE TO BE LOGGED

TSTLOG:

; LOOP OVER ALL NIBS, CHECKING FOR LINES FOR WHICH COUNTERS SHOULD BE LOGGED

TSTL05:	MOVEI P1,NIBTAB		;GET BASE ADDRESS OF NIB TABLES
	SKIPGE P2,NXTNIB	;GET NUMBER OF NIBS
	RET			;NO NIBS DEFINED YET, DONE
TSTL10:	MOVE T1,P1		;GET NIB ADDRESS
	CALL CHKLOG		;GO SEE IF ANY OF THESE LINES SHOULD BE LOGGED
	ADDI P1,NIBSIZ		;POINT TO NEXT NIB
	SOJGE P2,TSTL10		;DO ALL NIBS
	RET			;DONE, RETURN
;CHKLOG - ROUTINE TO CHECK IF ANY LINES SHOULD HAVE COUNTERS LOGGED
;	    FOR A GIVEN NODE.
;
;ACCEPTS IN T1/	NIB ADDRESS FOR THE NODE
;		CALL CHKLOG
;RETURNS: +1 ALWAYS, COUNTERS LOGGED IF NEEDED

CHKLOG:	ASUBR <CHLNIB,CHLNAM>
	ACVAR <W3,W4>
	LOAD T4,NDNAM,(T1)	;GET POINTER TO NAME OF THIS NODE
	MOVEM T4,CHLNAM		;SAVE POINTER TO NAME

; LOCK THE NODE IN CASE IT IS BEING LOADED OR DUMPED

	MOVE T1,CHLNIB		;GET NIB ADDRESS
	MOVX T2,RM%PRI		;PRIMARY RESOURCE (LOAD OR DUMP)
	CALL LOKNOD		;LOCK THE NODE

; LOOP OVER THE NODE'S LINES

	MOVE T1,CHLNIB		;GET NIB ADDRESS
	LOAD W4,NDLIN,(T1)	;GET ADDRESS OF LINE TABLE FOR OUR NODE
	MOVSI W3,-MXLNOD	;SET UP TO LOOP OVER EACH ENTRY IN LINE TABLE
CHL010:	MOVE T1,CHLNAM		;GET POINTER TO NAME
	DMOVE T2,(W4)		;GET LINE ID
	JE LTUSE,(W4),CHL020	;SKIP THIS ENTRY IF NOT IN USE
	JE LTLOG,(W4),CHL020	;IF LOGGING NOT ENABLES FOR THIS LINE, GO ON
	CALL LOGCTR		;LOG COUNTERS IF THIS LINE ENABLED
	 NON.FATAL.ERROR (.ERR21)
CHL020:	ADDI W4,LATSIZ		;POINT TO NEXT TABLE ENTRY
	AOBJN W3,CHL010		;LOOP OVER ALL LINE TABLE ENTRIES

; UNLOCK THE NODE AND RETURN

	MOVE T1,CHLNIB		;GET NIB ADDRESS
	MOVX T2,RM%PRI		;PRIMARY RESOURCE
	CALL ULKNOD		;UNLOCK THE NIB
	RET			;DONE, RETURN
;LOGCTR - ROUTINE TO LOG LINE COUNTERS FOR A SPECIFIED LINE
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NODE NAME
;	    T2-T3/ LINE ID OF LINE FOR WHICH COUNTERS ARE WANTED
;		CALL LOGCTR
;RETURNS: +1	 FAILED, COULD NOT LOG COUNTERS
;	  +2	SUCCESS, COUNTERS LOGGED IN SYSERR FILE

LOGCTR:	ASUBR <LCTNOD,LCTBLK,LCTNUM>
	STKVAR <LCTPTR,LCTCNT,LCTLEN,<LCTLIN,2>>
	DMOVEM T2,LCTLIN	;SAVE LINE ID

; READ THE LINE COUNTERS FROM THE OBJECT NODE NCU

	MOVE T1,LCTNOD		;GET POINTER TO ASCIZ NODE NAME
	DMOVE T2,LCTLIN		;GET LINE ID
	CALL REDCTR		;GO READ THE COUNTERS
	 RET			;FAILED
	ILDB T4,T1		;GET COUNTER TYPE CODE
	CAIE T4,.RDLCT		;LINE COUNTERS RETURNED ?
	RET			;NO, FAIL
	SUBI T2,1		;ACCOUNT FOR TYPE CODE

; EXTRACT THE LINE ID FROM THE NICE MESSAGE

	CALL GETLIN		;GO GET THE LINE ID
	 RET			;FAILED, RETURN ERROR TO CALLER
	CAMN T3,LCTLIN		;DID WE RECEIVE THE INFO FOR THE LINE
	CAME T4,1+LCTLIN	; FOR WHICH IT WAS REQUESTED ?
	RET			;NO, ERROR
	MOVEM T1,LCTPTR		;YES, SAVE POINTER TO NEXT FIELD IN MESSAGE
	MOVEM T2,LCTCNT		;SAVE NUMBER OF BYTES REMAINING IN MESSAGE

; GET A BLOCK TO USE FOR SYSERR ENTRIES

	MOVEI T1,MAXSYE		;GET MAX SIZE OF SYSERR ENTRIES
	CALL GETFRE		;ASSIGN A BLOCK
	 RET			;FAILED, RETURN ERROR
	ADDI T1,1		;POINT PAST THE HEADER
	MOVEM T1,LCTBLK		;SAVE ADDRESS OF SYSERR BLOCK

; ASSEMBLE THE SYSERR ENTRY HEADER

	MOVX T1,SY%LCT		;GET ENTRY TYPE CODE (LINE COUNTERS)
	MOVX T2,^D11		;SIZE OF LINE COUNTER ENTRIES
	MOVE T3,LCTBLK		;ADDRESS OF SYSERR ENTRY
	CALL SYRHDR		;ASSEMBLE A SYSERR ENTRY HEADER
	;..
	;..

; MARK FIELDS IN ENTRY THAT ARE NOT APPROPRIATE OR KNOWN

	MOVE T1,LCTBLK		;GET ADDRESS OF SYSERR BLOCK
	ADDI T1,.SYDAT		;POINT TO START OF COUNTER ENTRY DATA
	MOVX T2,2		;PERIODIC ENTRY
	STOR T2,SYRSN,(T1)	;NO REASON
	SETONE SYRCT,(T1)	;NO COUNT
	SETONE SYNTM,(T1)	;NO NODE UPTIME
	SETONE SYSEQ,(T1)	;SEQ NUMBER UNKOWN
	SETONE SYFCN,(T1)	;SYSTEM TYPE UNKNOWN
	SETONE SYADJ,(T1)	;ADJACENT NODE NOT KNOWN
	SETONE SYMID,(T1)	;ID'S NOT KNOWN


; ADD THE COUNTERS TO THE SYSERR ENTRY

	SETZM LCTNUM		;INITIALIZE NUMBER OF COUNTERS
	MOVE P1,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	ADDI P1,.SYCTR		;COMPUTE STARTING ADDRESS OF COUNTER DATA
	MOVE T1,LCTPTR		;RESTORE POINTER TO NICE MESSAGE
LCT010:	MOVE T2,LCTCNT		;GET NUMBER OF BYTES LEFT IN MESSAGE
	CALL GETEXB		;GO GET COUNTER TYPE FROM MESSAGE
	 JRST LCT020		;NO MORE COUNTERS, DONE
	STOR T4,SYTYP,(P1)	;STORE COUNTER TYPE IN SYSERR ENTRY
	CALL GETTWO		;EXTRACT COUNTER VALUE FROM MESSAGE
	 JFCL
	MOVEM T2,LCTCNT		;SAVE UPDATED COUNT
	STOR T3,SYCTR,(P1)	;STORE COUNTER VALUE IN SYSERR ENTRY
	AOS LCTNUM		;INCREMENT NUMBER OF COUNTERS IN THE ENTRY
	AOJA P1,LCT010		;LOOP OVER EACH COUNTER RETURNED

; ADD NUMBER OF COUNTERS TO THE SYSERR ENTRY

LCT020:	MOVE T4,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	ADDI T4,.SYDAT		;COMPUTE START OF DATA PORTION OF SYSERR ENTRY
	MOVE T1,LCTNUM		;GET NUMBER OF COUNTERS
	STOR T1,SYNCT,(T4)	;ADD NUMBER OF COUNTERS TO SYSERR ENTRY

; COMPUTE POINTER TO LOG DATA (IE TO THE COUNTERS)

	MOVNS T1		;GET -NUMBER OF COUNTERS
	HRL T1,T1		;GET -# OF COUNTERS,,0
	HRRI T1,.SYCTR-.SYDAT	;FORM -# OF COUNTERS,,OFFSET TO COUNTER DATA
	MOVE T2,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	ADDI T2,.SYDAT		;COMPUTE BASE ADDRESS FOR DATA PART OF ENTRY
	STOR T1,SYPTR,(T2)	;STORE THE POINTER TO THE LOG DATA
	;..
	;..

; ADD THE TRANSMITTING NODE NAME TO THE SYSERR ENTRY

	MOVE T1,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	MOVE P2,P1		;COPY ADDRESS WHERE NAME WILL GO
	SUBI P2,.SYDAT(T1)	;COMPUTE OFFSET TO NAME IN ENTRY
	HRROI T1,(P1)		;FORM POINTER TO WHERE NAME GOES
	MOVE T2,LCTNOD		;GET POINTER TO ASCIZ NODE NAME
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD NODE NAME TO SYSERR ENTRY
	IBP T1			;INCREMENT POINTER FOR MULTIPLES OF 5 BYTES
	MOVE T2,T1		;COPY CURRENT POINTER
	SUBI T2,-1(P1)		;COMPUTE NUMBER OF WORDS USED
	MOVN T2,T2		;COMPUTE -WORD COUNT
	HRL P2,T2		;COMPUTE -WORD COUNT,,OFFSET
	MOVE T2,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	ADDI T2,.SYDAT		;COMPUTE START OF DATA AREA
	STOR P2,SYNOD,(T2)	;STORE OFFSET TO ASCIZ NODE NAME
	MOVEI P1,1(T1)		;POINT TO NEXT WORD IN SYSERR ENTRY

; ADD DESTINATION NODE (OUR NAME)

	MOVE T1,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	MOVE P2,P1		;COPY ADDRESS WHERE NAME WILL GO
	SUBI P2,.SYDAT(T1)	;COMPUTE OFFSET TO NAME IN ENTRY
	HRROI T1,(P1)		;FORM POINTER TO WHERE NAME GOES
	HRROI T2,OURNAM		;WE ARE DESTINATION NODE
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD NODE NAME TO SYSERR ENTRY
	MOVE T2,T1		;COPY CURRENT POINTER
	SUBI T2,-1(P1)		;COMPUTE NUMBER OF WORDS USED
	MOVN T2,T2		;COMPUTE -WORD COUNT
	HRL P2,T2		;COMPUTE -WORD COUNT,,OFFSET
	MOVE T2,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	ADDI T2,.SYDAT		;COMPUTE START OF DATA AREA
	STOR P2,SYDST,(T2)	;STORE OFFSET TO ASCIZ NODE NAME
	MOVEI P1,1(T1)		;POINT TO NEXT WORD IN SYSERR ENTRY
	HRRZI T1,1(T1)		;GET JUST ADDRESS OF LAST WORD IN ENTRY
	SUB T1,LCTBLK		;COMPUTE SIZE OF ENTIRE SYSERR ENTRY
	MOVEM T1,LCTLEN		;SAVE SYSERR ENTRY LENGTH
	SUBI T1,.SYDAT		;COMPUTE SIZE OF DATA PORTION OF ENTRY
	MOVE T2,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	STOR T1,SYLEN,(T2)	;STORE SIZE OF DATA PART OF SYSERR ENTRY
	; ..
	; ..

; ADD THE LINE ID TO THE SYSERR ENTRY

	MOVE T2,LCTBLK		;GET BASE ADDRESS OF SYSERR ENTRY
	ADDI T2,.SYDAT		;POINT TO DATA PORTION OF ENTRY
	HRL T3,LCTLIN		;GET CONTROLLER #
	HLR T3,1+LCTLIN		;GET UNIT NUMBER
	STOR T3,SYLID,(T2)	;SAVE LINE ID
	HRRZ T4,1+LCTLIN	;GET STATION ADDRESS AND SAVE IN
	STOR T4,SYLI1,(T2)	; IN SYSERR ENTRY
	HLRZ T3,LCTLIN		;GET HARDWARE OPTION TYPE
	MOVSI T4,-HDWSZ		;SET UP TO LOOK FOR DEVICE TYPE
LCT030:	HRRZ T1,HDWTB(T4)	;GET OUR DEVICE TYPE CODE
	CAMN T1,T3		;FOUND RIGHT DEVICE TYPE ?
	JRST [HLRZ T3,HDWTB(T4)	;YES, GET SYSERR TYPE CODE
	      JRST LCT040]	;GO STORE CODE
	AOBJN T4,LCT030		;LOOP OVER ALL CODES
	SETOM T3		;COULD NOT FIND CODE, USE UNKNOWN
LCT040:	STOR T3,SYHDW,(T2)	;STORE HARDWARE DEVICE TYPE

; ADD THE ENTRY TO THE SYSERR FILE

	MOVE T1,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	MOVE T2,LCTLEN		;GET LENGTH OF ENTRY
	SYERR			;MAKE A SYSERR ENTRY
	 ERJMP LCTERR		;FAILED, RELEASE SPACE AND RETURN

; RELEASE FREE SPACE

	MOVE T1,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	SUBI T1,1		;RESTORE FREE BLOCK ADDRESS
	CALL RELFRE		;RETURN THE BLOCK
	 FATAL.ERROR		; Die on release failure

; ZERO THE COUNTERS JUST REQUESTED AND RETURN TO CALLER

	MOVE T1,LCTNOD		;GET POINTER TO NODE NAME
	DMOVE T2,LCTLIN		;GET LINE ID
	CALL ZROCTR		;GO ZERO THE COUNTERS
	 JFCL			;FAILED, IGNORE FAILURE SINCE LOGGING WORKED OK
	RETSKP			;DONE, RETURN SUCCESS

; HERE ON AN ERROR TO RELEASE THE FREE SPACE AND RETURN

LCTERR:	MOVE T1,LCTBLK		;GET ADDRESS OF SYSERR ENTRY
	SUBI T1,1		;RESTORE FREE BLOCK ADDRESS
	CALL RELFRE		;RETURN THE BLOCK
	 FATAL.ERROR		; Die on release failure
	RET			;RETURN ERROR TO CALLER
;ZROCTR - ROUTINE TO ZERO THE LINE COUNTERS FOR A LINE
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NODE NAME
;	    T2-T3/ LINE ID
;		CALL ZROCTR
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, COUNTERS CLEARED

ZROCTR:	ASUBR <ZCTNOD,<ZCTLID,2>,ZCTLNK>

; GET A LOGICAL LINK TO THE NCU ON THE NODE

	MOVE T1,ZCTNOD		;GET POINTER TO ASCIZ NODE NAME
	CALL GETLNK		;GO GET A LOGICAL LINK TO THE NCU
	 RET			;FAILED
	MOVEM T1,ZCTLNK		;SAVE LOGICAL LINK TO NCU

; ASSEMBLE A NICE PROTOCOL "ZERO COUNTERS" MESSAGE

	DMOVE T1,ZCTLID		;GET LINE ID TO PUT INTO MESSAGE
	CALL MAKZRO		;GO ASSEMBLE ZERO COUNTERS MESSAGE

; SEND THE MESSAGE TO THE NCU ON THE SPECIFIED NODE

	MOVN T3,T2		;GET -COUNT OF BYTES IN MESSAGE
	MOVE T2,T1		;GET POINTER TO START OF MESSAGE
	MOVE T1,ZCTLNK		;GET LOGICAL LINK TO NCU
	SOUTR			;OUTPUT THE NICE PROTOCOL MESSAGE
	 ERJMP ZCTERR		;FAILED, CLEAN UP AND RETURN FAILURE

; RECEIVE THE RESPONSE MESSAGE FROM THE NCU

	CALL CLRMSG		;GO CLEAR NICE MESSAGE AREA
	MOVE T1,ZCTLNK		;GET LOGICAL LINK TO NCU
	MOVE T2,[POINT 8,MSGBLK] ;GET POINTER TO WHERE MESSAGE GOES
	MOVNI T3,-MAXNIC	;GET MAX BYTE COUNT
	SINR			;RECEIVE THE MESSAGE
	 ERJMP ZCTERR		;FAILED, CLEAN UP AND RETURN ERROR
	MOVEI T2,MAXNIC(T3)	;GET NUMBER OF BYTES RECEIVED
	CAIE T2,1		;JUST RESPONSE CODE ?
	JRST ZCTERR		;NO, CLEAN UP AND RETURN ERROR
	LDB T1,[POINT 8,MSGBLK,7] ;GET NICE RETURN CODE VALUE
	CAIE T1,.NRSUC		;SUCCESS CODE ?
	JRST ZCTERR		;NO, FAIL

; COUNTERS SUCCESSFULLY ZERO'ED - CLEAN UP LOGICAL LINK AND RETURN SUCCESS

	MOVE T1,ZCTLNK		;GET LOGICAL LINK
	CLOSF			;CLOSE THE LINK
	 JFCL			;IGNORE FAILURE, FUNCTION WAS COMPLETED OK
	RETSKP			;DONE, RETURN SUCCESS
; HERE ON ERROR - RELEASE LOGICAL LINK AND RETURN FAILURE

ZCTERR:	MOVE T1,ZCTLNK		;GET LOGICAL LINK
	CLOSF			;CLOSE THE LINK
	 JFCL			;IGNORE FAILURE, FUNCTION WAS COMPLETED OK
	RET			;RETURN FAILURE TO CALLER
;REDCTR - ROUTINE TO GET THE LINE COUNTERS FROM AN OBJECT NODE
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NODE NAME
;	    T2-T3/ LINE ID
;		CALL REDCTR
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ POINTER TO COUNTER DATA FROM NICE MESSAGE
;			      T2/ NUMBER OF BYTES REMAINING IN COUNTER DATA

REDCTR:	ASUBR <RCTNOD,<RCTLIN,2>,RCTLNK>
	STKVAR <RCTPTR,RCTCNT,RCTERR>
; SEND A NICE PROTOCOL "READ INFORMATION" MESSAGE TO GET LINE COUNTERS

	MOVE T1,RCTNOD		;GET POINTER TO ASCIZ NODE NAME
	CALL GETLNK		;GO GET A LOGICAL LINK TO NCU ON THAT NODE
	 RET			;FAILED
	MOVEM T1,RCTLNK		;SAVE LOGICAL LINK (JFN) TO NCU

; REQUEST THE COUNTERS FROM THE NCU

	SETZM RCTERR		;INITIALIZE ERROR CODE
	MOVE T1,RCTLNK		;GET LOGICAL LINK
	DMOVE T2,RCTLIN		;GET LINE ID
	CALL REQCTR		;GO GET THE COUNTERS
	 MOVEM T1,RCTERR	;FAILED, SAVE ERROR CODE
	MOVEM T2,RCTCNT		;SAVE NUMBER OF BYTES IN COUNTER DATA

; DISCONNECT THE LOGICAL LINK

	MOVE T1,RCTLNK		;GET LOGICAL LINK
	CLOSF			;DISCONNECT THE LINK
	 JFCL			;FAILED, IGNORE FAILURE.

; RETURN POINTER TO COUNTER DATA

	SKIPE T1,RCTERR		;ANY ERRORS GETTING COUNTERS ?
	RETBAD ()		;YES, RETURN THE ERROR
	MOVE T1,[POINT 8,MSGBLK] ;NO, GET POINTER TO START OF MESSAGE
	MOVE T2,RCTCNT		;GET SIZE OF COUNTER DATA
	RETSKP			;DONE, RETURN SUCCESS
;REQCTR - ROUTINE TO REQUEST THE LINE COUNTERS FROM A NODE
;
;ACCEPTS IN T1/	LOGICAL LINK TO NCU IN THE NODE
;	    T2-T3/ LINE ID FOR WHICH COUNTERS ARE DESIRED
;		CALL REQCTR
;RETURNS: +1	 FAILED, ERROR CODE IN T1
;	  +2	SUCCESS, WITH T2/ COUNT OF BYTES IN RESPONSE MESSAGE

REQCTR:	ASUBR <RQCLNK,<RQCLIN,2>>
	DMOVE T1,RQCLIN		;GET LINE ID
	CALL MAKRLC		;GO ASSEMBLE A NICE "READ INFO" MESSAGE
	 RETBAD ()		;FAILED
	MOVN T3,T2		;GET -COUNT
	MOVE T2,T1		;GET POINTER TO START OF READ INFO MESSAGE
	MOVE T1,RQCLNK		;GET LOGICAL LINK (JFN) TO NCU
	SOUTR			;SEND NICE "READ INFO" MSG TO GET LINE COUNTERS
	 ERJMP [RETBAD (.NRNCE)] ;RETURN IF SEND FAILED

; RECEIVE THE REPLY FROM THE NCU

	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,RQCLNK		;GET LOGICAL LINK (JFN) TO NCU
	HRLI T2,(POINT 8,)	;FORM POINTER TO START
	HRRI T2,MSGBLK		; OF NICE MESSAGE AREA
	MOVNI T3,MAXNIC		;GET -MAX COUNT
	SINR			;RECEIVE REPLY FROM NCU
	 ERJMP [RETBAD (.NRNCE)] ;RETURN IF SEND FAILED
	MOVEI T2,MAXNIC(T3)	;GET NUMBER OF BYTES RECEIVED
	CAIE T2,3		;RECEIVED 1-BYTE RETURN CODE & 2-BYTE COUNT ?
	RETBAD (.NRIMF)		;NO, RETURN FAILURE
	MOVE T1,[POINT 8,MSGBLK] ;GET POINTER TO START OF MESSAGE
	ILDB T4,T1		;GET NICE RETURN CODE
	CAIE T4,.NRSUC		;GOT SUCCESS RETURN CODE ?
	RETBAD (,<MOVE T1,T4>)	;NO, FAIL AND RETURN THE NICE ERROR CODE
	MOVEI T2,2		;HAVE TWO BYTES
	CALL GETTWO		;YES, GO GET TWO-BYTE COUNT
	 JFCL
	CAIE T3,1		;ONE DATA BLOCK TO BE RECEIVED ?
	RETBAD (.NRIMF)		;NO, RETURN FAILURE

; RECEIVE THE LINE COUNTERS FROM THE NCU

	CALL CLRMSG		;GO CLEAR THE NICE MESSAGE AREA
	MOVE T1,RQCLNK		;GET LOGICAL LINK (JFN) TO NCU
	HRLI T2,(POINT 8,)	;FORM POINTER TO START
	HRRI T2,MSGBLK		; OF NICE MESSAGE AREA
	MOVNI T3,MAXNIC		;GET -MAX COUNT
	SINR			;RECEIVE REPLY FROM NCU
	 ERJMP [RETBAD (.NRNCE)] ;RETURN IF SEND FAILED
	MOVEI T2,MAXNIC(T3)	;GET NUMBER OF BYTES RECEIVED
	RETSKP			;DONE, RETURN SUCCESS
;SYRHDR - ROUTINE TO MAKE A SYSERR ENTRY HEADER
;
;ACCEPTS IN T1/	SYSERR EVENT CODE (SY%XXX)
;	    T2/	LENGTH OF ENTRY
;	    T3/	ADDRESS OF SYSERR BLOCK
;		CALL SYRHDR
;RETURNS: +1 ALWAYS, WITH HEADER SET UP AT LOCATION "SYRENT"

SYRHDR:	STOR T1,SYCOD,(T3)	;STORE EVENT CODE (SY%XXX)
	STOR T2,SYLEN,(T3)	;STORE LENGTH OF ENTRY
	MOVX T1,4		;GET LENGTH OF SYSERR ENTRY HEADER
	STOR T1,SYHLN,(T3)	;STORE IN HEADER
	MOVX T1,1		;GET VERSION OF SYSERR HEADER
	STOR T1,SYVER,(T3)	;STORE IN HEADER
	SETONE SYT20,(T3)	;NOTE THAT THIS ENTRY MADE BY TOPS-20
	GTAD			;GET CURRENT TIME AND DATE
	STOR T1,SYDAT,(T3)	;STORE TIME AND DATE IN ENTRY
	TIME			;GET CURRENT UPTIME
	IDIV T1,[<^D1000*^D3600*^D24>/<1_^D18>] ;CONVERT TO DAYS,,FRACTIONS OF DAYS
	STOR T1,SYUPT,(T3)	;STORE UPTIME IN ENTRY HEADER
	MOVE T1,[SIXBIT/APRID/]	;GET TABLE NAME
	SYSGT			;GET PROCESSOR SERIAL NUMBER
	STOR T1,SYPSN,(T3)	;SAVE PROCESSOR SERIAL NUMBER
	RET			;DONE, RETURN
;SYRSTR - ROUTINE TO ADD A STRING TO A SYSERR ENTRY
;
;ACCEPTS IN T1/	BASE ADDRESS OF SYSERR ENTRY
;	    T2/	POINTER TO ASCIZ STRING TO ADD
;	    T3/	DESTINATION ADDRESS IN ENTRY FOR STRING
;		CALL SYRSTR
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ ADDRESS OF NEXT WORD TO USE IN SYSERR ENTRY
;			      T2/ -WORD COUNT,,OFFSET TO STRING

SYRSTR:	ASUBR <STRBLK,STRSTR,STRDST,STROFS>
	MOVE T4,STRDST		;COPY ADDRESS WHERE NAME WILL GO
	SUBI T4,.SYDAT(T1)	;COMPUTE OFFSET TO NAME IN ENTRY
	MOVE T1,STRDST		;GET DESTINATION ADDRESS FOR STRING
	HRLI T1,(POINT 7,)	;FORM POINTER TO WHERE STRING GOES
	MOVE T2,STRSTR		;GET POINTER TO ASCIZ NODE NAME
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD NODE NAME TO SYSERR ENTRY
	IBP T1			;INCREMENT POINTER FOR MULTIPLES OF 5 BYTES
	HRRZ T2,T1		;COPY CURRENT ADDRESS
	MOVE T3,STRDST		;GET DESTINATION ADDRESS AGAIN
	SUBI T2,-1(T3)		;COMPUTE NUMBER OF WORDS USED
	MOVN T2,T2		;COMPUTE -WORD COUNT
	HRL T4,T2		;COMPUTE -WORD COUNT,,OFFSET
	MOVE T2,T4		;COPY -WORD COUNT,,OFFSET TO STRING
	MOVEI T1,1(T1)		;POINT TO NEXT WORD IN SYSERR ENTRY
	RETSKP			;DONE, RETURN
;SYRLOD - ROUTINE TO MAKE A SYSERR ENTRY WHEN A NODE IS LOADED
;
;ACCEPTS IN T1/	NICE RETURN CODE
;		CALL SYRLOD
;RETURNS: +1 ALWAYS

SYRLOD:	ASUBR <SYLCOD,SYLTGT,SYLSRV,SYLSVL>
	STKVAR <SYLFIL,SYLSIZ,SYLBLK>

; ALLOCATE A BLOCK FOR THE SYSERR ENTRY

	MOVX T1,MAXSYE		;GET MAX SIZE OF SYSERR ENTRIES
	CALL GETFRE		;GO GET SOME FREE SPACE
	 RETBAD (.NRRES)	;FAILED, RESOURCE ERROR
	ADDI T1,1		;ALLOW FOR BLOCK HEADER
	MOVEM T1,SYLBLK		;SAVE ADDRESS OF SYSERR BLOCK
	MOVE T4,SYLBLK		;GET ADDRESS OF SYSERR ENTRY
	HRROI T1,.SYLDD(T4)	;FORM POINTER TO DESTINATION

; PUT TARGET NODE NAME INTO ENTRY

	HRRZM T1,SYLTGT		;SAVE ADDRESS OF TARGET NAME
	MOVE T2,RQLTGT		;GET POINTER TO NAME OF TARGET NODE
	SETZM T3		;ASCIZ STRING, ENDS IN NULL
	SOUT			;PUT THE TARGET NODE NAME INTO ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY

; PUT NAME OF SERVER NODE INTO SYSERR ENTRY

	HRRZM T1,SYLSRV		;SAVE ADDRESS OF SERVER NODE NAME
	MOVE T2,RQLSRV		;GET POINTER TO NAME OF SERVER NODE
	SOUT			;ADD SERVER NODE NAME STRING TO ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY

; PUT NAME OF SERVER LINE INTO SYSERR ENTRY

	HRRZM T1,SYLSVL		;SAVE ADDRESS OF SERVER LINE NAME
	DMOVE T2,RQLLIN		;GET SERVER LINE ID
	CALL ASCLIN		;OUTPUT LINE AS ASCIZ
	 JFCL			;IGNORE ERROR
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY
	; ..
	; ..

; PUT FILE-SPEC INTO SYSERR ENTRY

	HRRZM T1,SYLFIL		;SAVE ADDRESS OF FILESPEC
	MOVE T2,RQLOPS		;GET POINTER TO OPERATING SYSTEM FILE
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD FILE SPEC TO SYSERR ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER

; ADD NICE RETURN CODE AND OFFSETS TO ENTRY

	HRRZI T1,1(T1)		;KEEP JUST ADDRESS
	SUB T1,SYLBLK		;COMPUTE SIZE OF SYSERR BLOCK
	MOVEM T1,SYLSIZ		;SAVE SIZE OF SYSERR BLOCK
	MOVE T4,SYLBLK		;GET ADDRESS OF SYSERR ENTRY
	MOVE T2,SYLCOD		;GET NICE RETURN CODE
	STOR T2,SYRCD,(T4)	;STORE RETURN CODE IN ENTRY
	MOVEI T3,.SYDAT(T4)	;OFFSETS ARE FROM END OF HEADER
	MOVE T2,SYLTGT		;GET ADDRESS OF TARGET STRING
	SUB T2,t3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYTGT,(T4)	;STORE OFFSET TO TARGET NODE NAME
	MOVE T2,SYLSRV		;GET ADDRESS OF SERVER NODE NAME
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYSRV,(T4)	;STORE OFFSET TO SERVER NODE NAME
	MOVE T2,SYLSVL		;GET ADDRESS OF SERVER LINE STRING
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYSVL,(T4)	;STORE OFFSET TO SERVER LINE NAME
	MOVE T2,SYLFIL		;GET ADDRESS OF FILESPEC
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYFIL,(T4)	;STORE OFFSET TO FILE SPEC
	MOVEI T1,SY%LOD		;ASSUME LOADING OPERATION
	MOVE T2,SYLSIZ		;GET SIZE OF ENTRY
	SUBI T2,.SYDAT		;COMPUTE SIZE OF ENTRY MINUS HEADER
	MOVE T3,SYLBLK		;GET ADDRESS OF ENTRY
	CALL SYRHDR		;GO MAKE THE SYSERR HEADER
	MOVE T1,SYLBLK		;GET ADDRESS OF SYSERR BLOCK
	MOVE T2,SYLSIZ		;GET BACK SIZE OF BLOCK
	SYERR			;MAKE A SYSERR ENTRY
	 ERJMP .+1		;DO NOT DIE IF THIS FAILS

; RELEASE SYSERR BLOCK AND RETURN

	MOVE T1,SYLBLK		;GET ADDRESS OF SYSERR BLOCK
	SUBI T1,1		;RESTORE FREE BLOCK ADDRESS
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		; Die on release failure
	RET			;DONE, RETURN
;SYRDMP - ROUTINE TO MAKE A SYSERR ENTRY WHEN A NODE IS DUMPED
;
;ACCEPTS IN T1/	NICE RETURN CODE
;		CALL SYRDMP
;RETURNS: +1 ALWAYS

SYRDMP:	ASUBR <SYDCOD,SYDTGT,SYDSRV,SYDSVL>
	STKVAR <SYDFIL,SYDSIZ,SYDBLK>

; ALLOCATE A BLOCK FOR THE SYSERR ENTRY

	MOVX T1,MAXSYE		;GET MAX SIZE OF SYSERR ENTRIES
	CALL GETFRE		;GO GET SOME FREE SPACE
	 RETBAD (.NRRES)	;FAILED, RESOURCE ERROR
	ADDI T1,1		;ALLOW FOR BLOCK HEADER
	MOVEM T1,SYDBLK		;SAVE ADDRESS OF SYSERR BLOCK
	MOVE T4,SYDBLK		;GET ADDRESS OF SYSERR ENTRY
	HRROI T1,.SYLDD(T4)	;FORM POINTER TO DESTINATION

; PUT TARGET NODE NAME INTO ENTRY

	HRRZM T1,SYDTGT		;SAVE ADDRESS OF TARGET NAME
	MOVE T2,RQDTGT		;GET POINTER TO NAME OF TARGET NODE
	SETZM T3		;ASCIZ STRING, ENDS IN NULL
	SOUT			;PUT THE TARGET NODE NAME INTO ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY

; PUT NAME OF SERVER NODE INTO SYSERR ENTRY

	HRRZM T1,SYDSRV		;SAVE ADDRESS OF SERVER NODE NAME
	MOVE T2,RQDSRV		;GET POINTER TO NAME OF SERVER NODE
	SOUT			;ADD SERVER NODE NAME STRING TO ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY

; PUT NAME OF SERVER LINE INTO SYSERR ENTRY

	HRRZM T1,SYDSVL		;SAVE ADDRESS OF SERVER LINE NAME
	DMOVE T2,RQDLIN		;GET SERVER LINE ID
	CALL ASCLIN		;OUTPUT LINE AS ASCIZ
	 JFCL			;IGNORE ERROR
	IBP T1			;POINT TO TERMINATING CHARACTER
	HRROI T1,1(T1)		;FORM POINTER TO NEXT STRING IN ENTRY
	; ..
	; ..

; PUT FILE-SPEC INTO SYSERR ENTRY

	HRRZM T1,SYDFIL		;SAVE ADDRESS OF FILESPEC
	MOVE T2,RQDFIL		;GET POINTER TO OPERATING SYSTEM FILE
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD FILE SPEC TO SYSERR ENTRY
	 ERJMP .+1		;DO NOT DIE ON ERRORS
	IBP T1			;POINT TO TERMINATING CHARACTER

; ADD NICE RETURN CODE AND OFFSETS TO ENTRY

	HRRZI T1,1(T1)		;KEEP JUST ADDRESS
	SUB T1,SYDBLK		;COMPUTE SIZE OF SYSERR BLOCK
	MOVEM T1,SYDSIZ		;SAVE SIZE OF SYSERR BLOCK
	MOVE T4,SYDBLK		;GET ADDRESS OF SYSERR ENTRY
	MOVE T2,SYDCOD		;GET NICE RETURN CODE
	STOR T2,SYRCD,(T4)	;STORE RETURN CODE IN ENTRY
	MOVEI T3,.SYDAT(T4)	;OFFSETS ARE FROM END OF HEADER
	MOVE T2,SYDTGT		;GET ADDRESS OF TARGET STRING
	SUB T2,t3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYTGT,(T4)	;STORE OFFSET TO TARGET NODE NAME
	MOVE T2,SYDSRV		;GET ADDRESS OF SERVER NODE NAME
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYSRV,(T4)	;STORE OFFSET TO SERVER NODE NAME
	MOVE T2,SYDSVL		;GET ADDRESS OF SERVER LINE STRING
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYSVL,(T4)	;STORE OFFSET TO SERVER LINE NAME
	MOVE T2,SYDFIL		;GET ADDRESS OF FILESPEC
	SUB T2,T3		;COMPUTE OFFSET INTO SYSERR BLOCK
	STOR T2,SYFIL,(T4)	;STORE OFFSET TO FILE SPEC
	MOVEI T1,SY%DMP		;ASSUME DUMPING OPERATION
	MOVE T2,SYDSIZ		;GET SIZE OF ENTRY
	SUBI T2,.SYDAT		;COMPUTE SIZE OF ENTRY MINUS HEADER
	MOVE T3,SYDBLK		;GET ADDRESS OF ENTRY
	CALL SYRHDR		;GO MAKE THE SYSERR HEADER
	MOVE T1,SYDBLK		;GET ADDRESS OF SYSERR BLOCK
	MOVE T2,SYDSIZ		;GET BACK SIZE OF BLOCK
	SYERR			;MAKE A SYSERR ENTRY
	 ERJMP .+1		;DO NOT DIE IF THIS FAILS

; RELEASE SYSERR BLOCK AND RETURN

	MOVE T1,SYDBLK		;GET ADDRESS OF SYSERR BLOCK
	SUBI T1,1		;RESTORE FREE BLOCK ADDRESS
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		; Die on release failure
	RET			;DONE, RETURN
;SYRNCU - ROUTINE TO MAKE A SYSERR ENTRY WHEN NETCON IS STARTED UP
;
;CALL:		CALL SYRNCU
;RETURNS: +1 ALWAYS

SYRNCU::STKVAR <SYNBLK,SYNSIZ,SYNOFS>

; ALLOCATE A BLOCK FOR THE SYSERR ENTRY

	MOVX T1,MAXSYE		;GET MAX SIZE OF SYSERR ENTRIES
	CALL GETFRE		;GO GET SOME FREE SPACE
	 RETBAD (.NRRES)	;FAILED, RESOURCE ERROR
	ADDI T1,1		;ALLOW FOR BLOCK HEADER
	MOVEM T1,SYNBLK		;SAVE ADDRESS OF SYSERR BLOCK

; ASSEMBLE THE SYSERR ENTRY

	MOVE T4,SYNBLK		;GET ADDRESS OF SYSERR ENTRY
	MOVX T1,VNETCON		;GET NETCON VERSION NUMBER
	STOR T1,SYNCV,(T4)	;ADD NETCON VERSION NUMBER TO ENTRY
	HRROI T1,.SYNDD(T4)	;FORM POINTER TO DESTINATION
	HRROI T2,OURNAM		;GET POINTER TO THIS NODE'S NAME
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD NODE NAME TO ENTRY
	 ERJMP .+1		;DO NOT CRUMP ON ERROR
	MOVE T3,T1		;COPY FINAL DESTINATION POINTER
	SUBI T3,.SYNDD-1(T4)	;COMPUTE NUMBER OF WORDS IN STRING
	MOVN T3,T3		;FORM WORD COUNT
	HRL T3,T3		;FORM -WORD COUNT,,0
	HRRI T3,.SYNDD-.SYDAT	;GET OFFSET TO NODE NAME STRING
	STOR T3,SYNAM,(T4)	;ADD OFFSET TO NODE NAME TO ENTRY
	HRROI T1,1(T1)		;POINT TO START OF NEXT WORD
	HRRZM T1,SYNOFS		;SAVE OFFSET TO PROGRAM NAME
	HRROI T2,[ASCIZ/NETCON/] ;GET PROGRAM NAME
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD PROGRAM NAME TO ENTRY
	 ERJMP .+1		;CONTINUE ON ERRORS
	MOVE T3,T1		;COPY FINAL DESTINATION POINTER
	SUB T3,SYNOFS		;COMPUTE WORD COUNT-1
	MOVNI T3,1(T3)		;COMPUTE -WORD COUNT
	HRL T3,T3		;FORM -WORD COUNT,,0
	HRRZ T2,SYNOFS		;GET OFFSET TO START OF PROGRAM NAME
	SUBI T2,.SYDAT(T4)	;COMPUTE OFFSET TO PROGRAM NAME STRING
	HRR T3,T2		;COMPUTE -WORD COUNT,,OFFSET
	STOR T3,SYPGM,(T4)	;STORE OFFSET TO PROGRAM NAME
	HRRZI T1,1(T1)		;COMPUTE THE SIZE OF THIS
	SUB T1,T4		; SYSERR ENTRY
	MOVEM T1,SYNSIZ		;SAVE ENTRY SIZE
	MOVEI T2,-.SYDAT(T1)	;GET JUST SIZE OF DATA PORTION
	MOVEI T1,SY%NCU		;GET NETCON-STARTED ENTRY TYPE
	MOVE T3,SYNBLK		;GET ADDRESS OF SYSERR ENTRY
	CALL SYRHDR		;ADD THE HEADER INFO TO THE ENTRY
	; ..
	; ..

; MAKE THE SYSERR ENTRY

	MOVE T1,SYNBLK		;GET ADDRESS OF SYSERR BLOCK
	MOVE T2,SYNSIZ		;GET SIZE OF THE ENTRY
	SYERR			;MAKE A SYSERR ENTRY
	 ERJMP .+1		;FAILED, IGNORE FAILURE
	MOVE T1,SYNBLK		;GET ADDRESS OF SYSERR BLOCK
	SUBI T1,1		;RESTORE ADDRESS OF FREE BLOCK
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		; Die on release failure
	RET			;DONE, RETURN
SUBTTL	Network Topology Change Server

;ADVTOP - ROUTINE TO ADVISE THE MONITOR OF TOPOLOGY CHANGES
;
;ACCEPTS IN T1/	ADDRESS OF TOPOLOGY CHANGE PROTOCOL MESSAGE
;	    T2/	NUMBER OF BYTES IN MESSAGE
;		CALL ADVTOP
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH MONITOR NOTIFIED

ADVTOP::SAVEPQ
	TRVAR <ADVPTR,ADVCNT,ADVUNI,ADVLST,ADVHST>
	STKVAR <<ADVSTR,2>,<ADVSTK,30>>

	MOVEM T1,ADVPTR		;SAVE POINTER TO MESSAGE
	MOVEM T2,ADVCNT		;SAVE NUMBER OF BYTES IN MESSAGE
	MOVEM T3,ADVHST		;SAVE POINTER TO HOST NODE NAME
	SETZM ADVLST		;INITIALIZE ADR OF NODE LIST

; SET UP STACK OF BLOCKS TO RELEASE ON CLEANUP

	HRRI P2,ADVSTK		;GET ADDRESS OF BLOCK STACK
	SUBI P2,1		;FORM STACK POINTER TO
	HRLI P2,-30		; CLEANUP PDL

; ASSIGN SPACE FOR NEW NODE LIST

	MOVX T1,MAXTOP		;NUMBER OF NODES PLUS BLOCK HEADER
	CALL GETFRE		;GET SOME FREE SPACE
	 RETBAD (.NRRES)	;No more free space .. give error return
	ADDI T1,1		;POINT TO START OF LIST
	MOVEM T1,ADVLST		;SAVE ADDRESS OF NODE LIST
	MOVX T4,MAXTOP		;GET MAX SIZE OF NODE LIST
	MOVEM T4,(T1)		;INITIALIZE NODE LIST TABLE (TBLUK FORMAT)

; ASSIGN FREE SPACE FOR THE NODE JSYS ARG BLOCK

	MOVX T1,^D300		;ALLOCATE LOTS OF SPACE FOR MANY NODE UNITS
	CALL GETFRE		;ASSIGN SPACE
	 JRST ADVTPX		;GO CLEAN UP FREE SPACE AND RETURN ERROR
	PUSH P2,T1		;SAVE ADDRESS OF BLOCK ON CLEANUP STACK
	ADDI T1,1		;POINT PAST BLOCK HEADER
	MOVE Q1,T1		;SAVE ADDRESS OF NODE JSYS ARG BLOCK
	MOVEI P1,.NDBK1(T1)	;GET POINTER TO NEXT ARG BLOCK ADR TO USE

; FIRST FIELD MUST BE THE COUNT OF THE NUMBER OF NODE UNITS FOLLOWING

	SOSGE ADVCNT		;AT LEAST ONE BYTE ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,ADVPTR		;YES, GET FIELD TYPE
	CAIE T4,.TPCNT		;COUNT OF NODE UNITS TO FOLLOW ?
	JRST ADVTPX		;NO, FAIL
	SOSGE ADVCNT		;AT LEAST ONE BYTE ?
	RETBAD (.NRIMF)		;NO, FAIL
	ILDB T4,ADVPTR		;GET NUMBER OF NODE UNITS
	MOVEM T4,ADVUNI		;SAVE NUMBER OF NODE UNITS TO FOLLOW
	MOVEM T4,.NDNND(Q1)	;STORE NUMBER OF NODE UNITS IN NODE JSYS BLOCK
; PROCESS THE NEXT NODE UNIT IN THE MESSAGE

ADVT10:	SOSGE ADVUNI		;ANOTHER NODE UNIT TO PROCESS ?
	JRST [	SKIPE ADVCNT	;NO.  SHOULD BE NO MORE BYTES IN MESSAGE
		JRST ADVTPX	;FAIL, MESSAGE TOO LONG
		JRST ADVT30 ]	;DONE, NOTIFY MONITOR OF NEW TOPOLOGY
	MOVEI P4,0		;INITIALIZE "LAST FIELD TYPE" SEEN
	MOVX T1,.NDNBS+1	;GET NUMBER OF WORDS FOR NODE UNIT
	CALL GETFRE		;ASSIGN A FREE BLOCK FOR NODE UNIT
	 JRST ADVTPX		;FAILED, GO CLEAN UP
	PUSH P2,T1		;ADD BLOCK TO CLEANUP LIST
	ADDI T1,1		;POINT PAST HEADER BLOCK
	MOVEM T1,(P1)		;STORE POINTER TO NODE UNIT IN ARG BLOCK
	MOVE P3,T1		;GET ADDRESS OF NODE UNIT

; EXTRACT AND PROCESS EACH FIELD OF THE MESSAGE

ADVT20:	SOSGE T2,ADVCNT		;AT LEAST ONE BYTE ?
	JRST ADVT30		;NO, MUST BE END OF MESSAGE
	ILDB T4,ADVPTR		;YES, GET FIELD TYPE
	CAIL T4,FTPLEN		;WITHIN VALID RANGE ?
	JRST ADVTPX		;NO, FAIL
	CAMG T4,P4		;NEXT FIELD HAVE HIGHER FIELD TYPE THAN LAST ?
	JRST ADVT25		;NO, MUST BE NEXT NODE UNIT
	MOVE P4,T4		;UPDATE "LAST FIELD SEEN"
	MOVE T1,ADVPTR		;GET POINTER TO NEXT FIELD IN MESSAGE
	CALL @FTPTAB(T4)	;YES, DISPATCH BASED ON FUNCTION CODE
	 JRST ADVTPX		;FAILED, GO CLEAN UP
	JRST ADVT20		;GO EXTRACT NEXT FIELD FROM MESSAGE

; HERE AT END OF EACH NODE UNIT

ADVT25:	SETOM T4		;DECREMENT BYTE POINTER BY ONE
	ADJBP T4,ADVPTR		; BYTE BECAUSE WE'VE ALREADY PROCESSED
	MOVEM T4,ADVPTR		; FIRST BYTE OF THE NEXT NODE UNIT
	AOS ADVCNT		;AND UNDO DECREMENTING OF COUNT
	ADDI P1,1		;POINT TO WHERE ADR OF NEXT NODE UNIT GOES
	JRST ADVT10		;GO PROCESS NEXT NODE UNIT


; TABLE OF TOPOLOGY PROTOCOL FIELD PROCESSING ROUTINES

FTPTAB:	RET			;  0 ILLEGAL
	TPNOD			;  1 NODE NAME
	TPNUM			;  2 NODE NUMBER
	TPNST			;  3 NODE STATE
	TPLID			;  4 LINE ID
	TPLST			;  5 LINE STATE
	TPVER			;  6 VERSION INFO
	TPUNI			;  7 NODE UNITS TO FOLLOW

FTPLEN==.-FTPTAB
; HERE WHEN DONE WITH ALL NODE UNITS

ADVT30:	MOVX T1,.NDSNT		;GET "SET NETWORK TOPOLOGY" FUNCTION CODE
	MOVE T2,Q1		;GET ADDRESS OF NODE JSYS ARG BLOCK
	MOVX T4,.NDNBS		;GET SIZE OF A NODE BLOCK
	MOVEM T4,.NDCNT(T2)	;STORE IN ARG BLOCK
	NODE			;TELL MONITOR ABOUT NETWORK TOPOLOGY
	 ERJMP ADVTPX		;FAILED, CLEAN UP AND RETURN ERROR

; CLEAN UP ALL THE FREE BLOCKS ON THE BLOCK STACK

ADVT40:	HLRE T1,P2		;GET STACK COUNTER
	CAMG T1,[-30]		;MORE BLOCKS ON STACK ?
	JRST [	MOVE T1,ADVLST	;NO, GET ADDRESS OF NODE LIST
		RETSKP ]	;DONE. RETURN SUCCESS
	POP P2,T1		;YES, GET BLOCK ADDRESS
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		;FAILED
	JRST ADVT40		;LOOP OVER ALL BLOCKS ASSIGNED

; HERE ON AN ERROR TO CLEAN UP THE FREE BLOCKS

ADVTPX:	MOVE T1,ADVLST		;GET ADDRESS OF NODE LIST
	CALL TOPFRE		;Release the topology table

ADVTX1:	HLRE T1,P2		;GET STACK COUNTER
	CAMG T1,[-30]		;MORE BLOCKS ON STACK ?
	RET			;NO, DONE. RETURN FAILURE
	POP P2,T1		;YES, GET BLOCK ADDRESS
	CALL RELFRE		;RELEASE THE BLOCK
	 FATAL.ERROR		;FAILED
	JRST ADVTX1		;LOOP OVER ALL BLOCKS ASSIGNED
; ROUTINES TO PROCESS FIELDS FROM TOPOLOGY CHANGE MESSAGES

TPNOD:	MOVEI T3,ADVSTR		;GET ADDRESS OF TEMPORARY STRING AREA
	HRLI T3,(POINT 7,)	;FORM POINTER TO TEMPORARY STRING DESTINATION
	CALL GETIMA		;GET NODE NAME FROM MESSAGE
	 RET			;FAILED, RETURN ERROR
	MOVEM T1,ADVPTR		;SAVE POINTER TO NEXT FIELD
	MOVEM T2,ADVCNT		;SAVE COUNT OF REMAINING BYTES
	MOVEI T1,0		;NO OLD BLOCK TO RELEASE
	MOVEI T2,ADVSTR		;GET ADDRESS WHERE STRING IS
	HRLI T2,(POINT 7,)	;FORM POINTER TO STRING
	MOVX T3,2		;NODE NAMES ARE TWO WORDS MAX
	CALL CPYASC		;PUT NODE NAME IN A BLOCK
	 RET			;FAILED, RETURN ERROR
	MOVEM T1,.NDNAM(P3)	;STORE POINTER TO NODE NAME
	HRLZI T2,1(T1)		;GET ADDRESS OF NODE NAME STRING
	MOVE T1,ADVLST		;GET ADDRESS OF NODE LIST
	TBADD			;ADD THIS NODE TO NODE LIST
	 ERJMP R		;FAILED
	MOVE T1,.NDNAM(P3)	;GET NODE NAME POINTER
	MOVE T2,ADVHST		;GET POINTER TO SOURCE NODE NAME
	CALL STOHST		;STORE SOURCE NODE NAME IF NEEDED
	 RETBAD ()		;FAILED
	RETSKP			;DONE, RETURN SUCCESS


TPNUM:	CALL GETEXB		;GET NODE NUMBER FROM MESSAGE
	 RET			;FAILED, RETURN ERROR
	MOVEM T1,ADVPTR		;SAVE POINTER TO NEXT FIELD
	MOVEM T2,ADVCNT		;SAVE COUNT OF ITEMS IN MESSAGE
				;IGNORE NODE NUMBER
	RETSKP			;DONE, RETURN SUCCESS


TPNST:	SOSGE ADVCNT		;AT LEAST ONE BYTE IN THE MESSAGE ?
	RET			;NO, FAIL
	ILDB T4,ADVPTR		;YES, SKIP NODE STATE
	MOVEM T4,.NDSTA(P3)	;STORE STATE IN NODE BLOCK
	SOSGE ADVCNT		;ANOTHER BYTE IN MESSAGE ?
	RET			;NO, FAIL
	IBP ADVPTR		;YES, SKIP NODE TYPE
	RETSKP			;DONE, RETURN SUCCESS


TPLID:	SUBI T2,5		;ENOUGH BYTES IN MESSAGE FOR A LINE ID ?
	JUMPL T2,R		;NO, FAIL
	MOVEM T2,ADVCNT		;SAVE NEW BYTE COUNT
	MOVX T1,5		;GET NUMBER OF BYTES IN LINE ID
	ADJBP T1,ADVPTR		;SKIP OVER LINE ID IN MESSAGE
	MOVEM T1,ADVPTR		;SAVE POINTER TO NEXT FIELD
	RETSKP			;DONE, RETURN SUCCESS


TPLST:	SOSGE ADVCNT		;AT LEAST ONE MORE BYTE ?
	RET			;NO, FAIL
	IBP ADVPTR		;YES, SKIP TO NEXT FIELD IN MESSAGE
	RETSKP			;DONE, RETURN SUCCESS


TPVER:	RET			;FAIL, VERSION SHOULD NOT APPEAR IN MIDDLE
				;  OF TOPOLOGY INFORMATION


TPUNI:	RET			;FAIL, SHOULD NOT SEE NODE UNIT COUNT
;STOHST - ROUTINE TO STORE THE SOURCE NODE NAME IN THE NODE BLOCK
;
;ACCEPTS IN T1/	POINTER TO NAME OF THIS NODE
;	    T2/	POINTER TO NAME OF SOURCE NODE
;		CALL STOHST
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, POINTER STORED IF NEEDED

STOHST:	ASUBR <STHNOD,STHHST>

	MOVE T1,STHNOD		;GET POINTER TO NODE NAME
	MOVE T2,STHHST		;GET POINTER TO SOURCE NODE NAME
	STCMP			;DID SOURCE TELL US ABOUT ITSELF ?
	 ERJMP R		;FAILED, RETURN ERROR
	JUMPE T1,RSKP		;YES, DO NOT STORE SOURCE NAME
	MOVE T1,STHNOD		;GET NODE NAME
	HRROI T2,OURNAM		;GET POINTER TO OUR NODE NAME
	STCMP			;DID SOURCE NODE TELL US ABOUT US ?
	 ERJMP R		;FAILED, RETURN ERROR
	JUMPE T1,RSKP		;YES, DO NOT STORE SOURCE NAME
	MOVE T1,STHHST		;NO, GET SOURCE NODE NAME
	MOVEM T1,.NDNXT(P3)	;STORE IN NODE BLOCK
	RETSKP			;DONE, RETURN
;TOPFRE - Routine to release a topology table.
;
;Accepts in T1/ Address of topology table.
;
;Returns: +1	Always

TOPFRE:: ASUBR	<TOPTBL>	; Address of topology table
	JUMPE T1,R		; If no address given .. just return
	PUSH P,P1		; Save a register
	HLRZ P1,(T1)		; Get count of entries in table
	MOVNI P1,1(P1)		; Put count in LH for AOBJP index
	HRLZS P1
	HRRI P1,(T1)		; Get address of start of table

TPF.1:	AOBJP P1,TPF.D		; If no more entries .. return table block
	SKIPN T1,(P1)		; Get address of node name entry
	 JRST TPF.1		;  Not really there if zero .. move on
	HLRZS T1		; Put into right half
	SUBI T1,1		; Point to beginning of allocated block
	CALL RELFRE		; Release the block
	 FATAL.ERROR		;  Couldn't do it .. die
	JRST TPF.1		; Go release the next entry

TPF.D:	MOVE T1,TOPTBL		; Get address of table again
	SUBI T1,1		; Point to actual allocated block
	CALL RELFRE		; Release the table
	 FATAL.ERROR		;  Can't so crap out
	POP P,P1		; Restore register (inane comment)
	RET			; Return to caller
SUBTTL	Utility Routines

;STOSTR - ROUTINE TO STORE A STRING IN THE GENERAL STRING AREA
;
;ACCEPTS IN T1/	CURRENT ADDRESS OF STRING
;		CALL STOSTR
;RETURNS: +1	 FAILED, INSUFFICIENT ROOM TO STORE STRING
;	  +2	SUCCESS, WITH T1/ ADDRESS OF STRING IN STRING AREA

STOSTR:	HRLI T1,(POINT 7)	;FORM POINTER TO EXISTING STRING
	MOVE T2,STRPTR		;GET POINTER TO WHERE STRING WILL GO
	MOVN T3,STRSIZ		;GET # OF WORDS REMAINING IN STRING STORAGE AREA
	IMULI T3,NCHPW		;COMPUTE -# OF CHARACTERS REMAINING IN AREA

; LOOP OVER EACH CHARACTER IN THE STRING, MOVING IT TO THE STRING AREA

STOST2:	AOJG T3,R		;RETURN FAILURE IF NO ROOM FOR NEXT CHARACTER
	ILDB T4,T1		;GET NEXT CHARACTER IN STRING
	IDPB T4,STRPTR		;STORE CHARACTER IN STRING AREA
	JUMPN T4,STOST2		;IF NOT NULL, GO MOVE NEXT CHARACTER
	AOS T1,STRPTR		;POINT TO NEXT FREE LOCATION IN STRING AREA
	HRLI T1,(POINT 7,)	;POINT TO FIRST CHARACTER IN NEXT WORD
	MOVEM T1,STRPTR		;SAVE NEW POINTER TO FREE LOC IN STRING AREA
	MOVE T4,STREND		;GET ADDRESS OF LAST LOCATION IN STRING AREA
	SUBI T4,1(T1)		;COMPUTE LENGTH OF REMAINING STRING AREA
	MOVEM T4,STRSIZ		;SAVE NUMBER OF WORDS LEFT IN STRING AREA
	MOVE T1,T2		;GET ORIGINAL POINTER TO STRING
	RETSKP			;RETURN SUCCESS
;CLRMOP - ROUTINE TO CLEAR THE MOP MESSAGE AREA
;
;CALL:		CALL CLRMOP
;RETURNS: +1 ALWAYS

CLRMOP:	HRRI T1,1+MOPMSG	;GET ADDRESS OF MOP MESSAGE AREA + 1
	HRLI T1,-1(T1)		;FORM ADDRESS,,ADDRESS+1 FOR BLT
	SETZM MOPMSG		;CLEAR THE FIRST WORD OF THE AREA
	BLT T1,MOPSIZ-1+MOPMSG	;CLEAR REMAINDER OF MOP MESSAGE AREA
	RET			;RETURN

;CLRBOT - ROUTINE TO CLEAR THE BOOT JSYS ARGUMENT BLOCK
;
;CALL:		CALL CLRBOT
;RETURNS: +1 ALWAYS

CLRBOT:	HRRI T1,1+BTARG		;GET ADDRESS OF BOOT JSYS ARG BLOCK+1
	HRLI T1,-1(T1)		;FORM ADDRESS,,ADDRESS+1 FOR BLT
	SETZM BTARG		;CLEAR THE FIRST WORD OF THE AREA
	BLT T1,BTSIZ-1+BTARG	;CLEAR REMAINDER OF AREA
	RET			;RETURN

;CLRMSG - ROUTINE TO CLEAR THE NICE MESSAGE BLOCK
;
;CALL:		CALL CLRMSG
;RETURNS: +1 ALWAYS

CLRMSG:	HRRI T1,1+MSGBLK	;GET ADDRESS OF NICE MESSAGE AREA + 1
	HRLI T1,-1(T1)		;FORM ADDRESS,,ADDRESS+1 FOR BLT
	SETZM MSGBLK		;CLEAR THE FIRST WORD OF THE AREA
	BLT T1,MSGSIZ-1+MSGBLK	;CLEAR REMAINDER OF NICE MESSAGE AREA
	RET			;RETURN


;CHKLIN - ROUTINE TO CHECK A STANDARD NICE LINE ID
;
;ACCEPTS IN T3/	LINE DEVICE TYPE (.DTXXX),,LINE CONTROLLER NUMBER
;	    T4/	LINE UNIT NUMBER,,STATION ADDRESS
;		CALL CHKLIN
;RETURNS: +1	 FAILED, NO SUCH LINE. NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ DTE20 NUMBER

CHKLIN:	HLRZ T1,T3		;GET DEVICE TYPE CODE
	CAIE T1,.DTDTE		;DTE TYPE DEVICE ?
	RETBAD (.NRILN)		;NO, RETURN "INVALID LINE ID"
	HRRZ T1,T4		;GET STATION ADDRESS
	JUMPN T1,[RETBAD (.NRILN)] ;RETURN ERROR IF NOT CONTROLLER 0
	HRRZ T1,T3		;GET CONTROLLER NUMBER (DTE20 NUMBER)
	RETSKP			;DONE, RETURN SUCCESS
;SETPGM - ROUTINE TO GET A POINTER TO A FILESPEC GIVEN A PROGRAM TYPE
;	  AND A LOAD DEVICE.
;
;CALL:		CALL SETPGM
;RETURNS: +1	 FAILED, NO FILESPEC FOR THAT DEVICE/PROGRAM
;	  +2	SUCCESS, WITH T1/ POINTER TO ASCIZ FILESPEC

SETPGM:	STKVAR <SPGTAB>

; DETERMINE IF PROGRAM ABOUT TO BE LOADED IS AN OPERATING SYSTEM OR
; A BOOTSTRAP PROGRAM.

	MOVE T1,RQLPGM		;GET PROGRAM TYPE TO BE LOADED (.PTXXX)
	CAIN T1,.PTOPS		;ABOUT TO LOAD AN OPERATING SYSTEM ?
	JRST [	MOVE T1,rqlops	;YES, GET POINTER TO PRIMARY FILESPEC
		RETSKP ]	;DONE, RETURN SUCCESS

; LOADING A BOOTSTRAP - DETERMINE FILESPEC BASED ON LOAD DEVICE AND CPU

	MOVE T4,[-MAXPGM,,PGMTAB] ;SET UP TO LOOP OVER ALL PROGRAM TABLE ENTRIES
SPGM10:	LOAD T1,PGLDV,(T4)	;GET LOAD DEVICE FROM THIS TABLE ENTRY
	CAME T1,RQLLDV		;FOUND DESIRED LOAD DEVICE ?
	JRST SPGM20		;NO, GO LOOK AT NEXT ENTRY
	LOAD T1,PGCPU,(T4)	;GET CPU TYPE FROM THIS TABLE ENTRY
	CAME T1,RQLCPU		;SAME AS TYPE OF SYSTEM BEING LOADED ?
	JRST SPGM20		;NO, GO CHECK NEXT ENTRY
	LOAD T1,PGPGM,(T4)	;GET PROGRAM TYPE CODE
	CAMN T1,RQLPGM		;FOUND DESIRED PROGRAM TYPE ?
	JRST SPGM30		;YES, GO GET THE FILESPEC
SPGM20:	ADDI T4,PGLEN-1		;SET UP TO POINT TO NEXT ENTRY
	AOBJN T4,SPGM10		;NO, LOOP OVER ALL ENTRIES IN THE TABLE
	RET			;FAIL, NO SUCH PROGRAM TYPE KNOWN

SPGM30:	LOAD T1,PGFIL,(T4)	;GET POINTER TO FILE-SPEC TO BE LOADED
	RETSKP			;DONE, RETURN SUCCESS



;CVTDEV - ROUTINE TO CONVERT A DTE20 NUMBER INTO A STANDARD NICE
;	  LINE ID.
;
;ACCEPTS IN T1/	DTE20 NUMBER
;		CALL CVTDEV
;RETURNS: +1	 FAILED, INVALID DTE20 NUMBER
;	  +2	SUCCESS, WITH T2-T3/ STANDARD NICE LINE ID

CVTDEV::CAIL T1,MAXDTE		;VALID DTE20 NUMBER
	RETBAD (.NRILN)		;NO, RETURN "INVALIID LINE ID"
	MOVSI T2,.DTDTE		;GET DEVICE TYPE CODE
	HRR T2,T1		;YES, GET CONTROLLER (DTE20 #)
	SETZM T3		;NO UNIT OR CONTROLLER NUMBER
	RETSKP			;DONE, RETURN SUCCESS
;GETNIB - ROUTINE TO RETURN THE ADDRESS OF THE NIB FOR A GIVEN NODE
;
;ACCEPTS IN T1/	POINTER TO ASCIZ NODE NAME
;		CALL GETNIB
;RETURNS: +1	 FAILURE, NO SUCH NODE IS KNOWN
;	  +2	SUCCESS, WITH T1/ ADDRESS OF NODE INFORMATION BLOCK

GETNIB::MOVE T2,T1		;GET STRING TO SEARCH FOR (NODE NAME)
	MOVEI T1,NODTAB		;GET ADDRESS OF KNOWN NODE TABLE
	TBLUK			;SEARCH FOR THE SPECIFIED NODE
	 ERJMP R		;FAILED, RETURN ERROR
	TXNN T2,TL%EXM		;EXACT MATCH ?
	RET			;NO, RETURN FAILURE
	HRRZ T1,(T1)		;GET ADDRESS OF NODE INFORMATION BLOCK
	RETSKP			;RETURN SUCCESS



;ASGREC - ROUTINE TO ASSIGN A BLOCK TO HOLD A RECORD BEING SENT IN A
;	  SERIES OF MOP "LOAD RECORD" MESSAGES.
;
;ACCEPTS IN T1/ FLAGS:
;		  OF%RD IF INPUT IS TO BE DONE
;		  OF%WR IF OUTPUT IS TO BE DONE
;		CALL ASGREC
;RETURNS: +1	 FAILED, NO MORE BLOCKS AVAILABLE
;	  +2	SUCCESS, WITH T1/ ADDRESS OF BLOCK ASSIGNED

ASGREC:	ASUBR <ARBFLG>

;	MOVEI T1,RCTSIZ+MAXREC	;GET SIZE OF A RECORD BLOCK
	MOVEI T1,500		;Big record size.. so that INPLDA doesn't
				;read into area not assigned
	CALL GETFRE		;GET A FREE BLOCK FOR THE RECORD BLOCK
	 RETBAD ()		;FAILED, RETURN ERROR TO CALLER
	MOVE T3,ARBFLG		;GET FLAGS
	MOVX T2,BPWRD		;GET NUMBER OF PDP-11 BYTES PER -20 WORD
	TXNE T3,OF%WR		;OUTPUT TO BE DONE ?
	MOVEI T2,0		;YES, START WITH BYTE NUMBER 0
	STOR T2,RBBYT,(T1)	;INITIALIZE THE NEXT BYTE TO READ
	SETZRO RBJFN,(T1)	;INITIALIZE JFN FIELD FOR THIS ENTRY
	MOVEI T4,.RBDAT(T1)	;GET OFFSET TO DATA AREA IN RECORD BLOCK
	HRLI T4,(POINT 8,)	;FORM POINTER TO WHERE THE DATA GOES
	STOR T4,RBPTR,(T1)	;STORE POINTER TO DESTINATION FOR DATA
	RETSKP			;RETURN
;CHKDEV - ROUTINE TO VERIFY A DEVICE TYPE CODE
;
;ACCEPTS IN T1/	DEVICE TYPE CODE (.DTXXX)
;		CALL CHKDEV
;RETURNS: +1	 FAILED, DEVICE TYPE CODE IS INVALID
;	  +2	SUCCESS, DEVICE ISOK, T1/ POINTER TO ASCIZ DEV NAME

CHKDEV:	HLRZ T4,LINNAM		;GET NUMBER OF ENTRIES IN DEVICE TABLE
	MOVNS T4		;GET -NUMBER OF ENTRIES
	HRL T4,T4		;GET -TABLE SIZE,,0
	HRRI T4,LINNAM+1	;FORM AOBJN POINTER TO SEARCH DEVICE TABLE

CHKDV1:	HRRZ T2,(T4)		;GET A DEVICE TYPE FROM TABLE
	CAMN T2,T1		;FOUND DESIRED DEVICE TYPE CODE ?
	JRST CHKDV2		;YES, GO ADD NAME TO STRING
	AOBJN T4,CHKDV1		;LOOP OVER ALL TABLE ENTRIES
	RET			;NOT FOUND, FAILED

CHKDV2:	HLR T1,(T4)		;GET ADDRESS OF DEVICE NAME STRING
	HRLI T1,(POINT 7,)	;FORM POINTER TO NAME
	RETSKP			;DONE, SUCCESS



;FNDTGT - ROUTINE TO FIND A TARGET NODE'S NIB GIVEN A LINE ADJACENCY TABLE
;	  AND A SERVER LINE ID.
;
;ACCEPTS IN T1/	ADDRESS OF A LINE ADJACENCEY TABLE
;	    T2-T3/ STANDARD LINE ID
;		CALL FNDTGT
;RETURNS: +1	 FAILED, NICE RETURN CODE IN T1
;	  +2	SUCCESS, WITH T1/ ADDRESS OF NIB FOR NODE AT END OF THE
;				  GIVEN SERVER LINE.

FNDTGT:	MOVSI T4,-MXLNOD	;SET UP TO LOOP OVER EACH ENTRY IN THE TABLE

FTGT10:	JE LTUSE,(T1),FTGT20	;IF THIS ENTRY NOT IN USE, GO ON TO NEXT ENTRY
	CAMN T2,0(T1)		;TYPE AND CONTROLLER NUMBER COMPARE ?
	CAME T3,1(T1)		;  AND ALSO UNIT NUMBER AND STATION ADDRESS ?
	SKIPA			;NO, GO CHECK NEXT ENTRY
	JRST [	LOAD T1,LTNIB,(T1) ;YES, GET ADDRESS OF NIB FOR TARGET NODE
		RETSKP ]	;DONE, RETURN SUCCESS
FTGT20:	ADDI T1,LATSIZ		;FORM ADDRESS OF NEXT ENTRY IN TABLE
	AOBJN T4,FTGT10		;LOOP OVER ALL ENTRIES IN TABLE
	RETBAD (.NRICF)		;ENTRY NOT FOUND, RETURN "DATABASE ERROR"
;ASCLIN - ROUTINE TO CONVERT A STANDARD NICE LINE ID TO A STRING
;
;ACCEPTS IN T1/	DESTINATION POINTER FOR STRING
;	    T2-T3/ NICE LINE ID
;		CALL ASCLIN
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, WITH T1/ UPDATED DESTINATION POINTER

ASCLIN::ASUBR <ASLPTR,<ASLLIN,2>>

; ADD DEVICE TYPE NAME TO THE STRING

	HLRZ T1,ASLLIN		;GET DEVICE TYPE CODE (.DTXXX)
	CALL CHKDEV		;GO CHECK DEVICE TYPE
	 RET			;FAILED, BAD DEVICE
	MOVE T2,T1		;COPY POINTER TO DEVICE NAME STRING
	MOVE T1,ASLPTR		;GET DESTINATION POINTER
	SETZM T3		;TERMINATE ON NULL
	SOUT			;ADD DEVICE TYPE TO TABLE

; ADD CONTROLLER, UNIT, AND STATION TO DESTINATION STRING

	MOVX T4,"_"		;GET UNDERSCORE
	IDPB T4,T1		;ADD UNDERSCORE TO DESTINATION STRING
	HRRZ T2,ASLLIN		;GET CONTROLLER NUMBER
	MOVX T3,10		;USE OCTAL
	NOUT			;ADD CONTROLLER TO STRING
	 ERJMP R		;FAILED, RETURN ERROR
	IDPB T4,T1		;ADD UNDERSCORE TO STRING
	HLRZ T2,1+ASLLIN	;GET UNIT NUMBER
	NOUT			;ADD UNIT TO STRING
	 ERJMP R		;FAILED, RETURN ERROR
	HRRZ T2,1+ASLLIN	;GET STATION ADDRESS
	SKIPN T2		;If the station number is zero
	 JRST [	HLRZ T2,ASLLIN	; Get device type code (.DTXXX)
		CAIE T2,.DTKDP	; Check for KDP
		CAIN T2,.DTKDZ	; or KDZ
		SKIPA		; Yes .. output a tab
		RETSKP		; No .. just return
		MOVEI T2,.CHTAB	; Get a tab
		BOUT		; Put it instead of _n
		RETSKP]		; And return
	IDPB T4,T1		;ADD UNDERSCORE TO STRING
	NOUT			;ADD STATION TO STRING
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;DONE, RETURN WITH UPDATED POINTER IN T1
SUBTTL Constants and Tables

; INTERVAL BETWEEN LINE COUNTER LOGGINGS IN SYSERR FILE

LOGTIM::EXP ^D60*^D60*^D1000


; TABLE OF DEVICE NAME/DEVICE TYPE CORRESPONDENCES

LINNAM:	LINSIZ,,LINSIZ-1
	TB (.DTA11,DA11A)
	TB (.DTL1A,DL11A)
	TB (.DTL1E,DL11E)
	TB (.DTDLV,DLV11)
	TB (.DTDMC,DMC11)
	TB (.DTP11,DP11)
	TB (.DTQ11,DQ11)
	TB (.DTDTE,DTE20)
	TB (.DTU11,DU11)
	TB (.DTDUP,DUP11)
	TB (.DTDV1,DV11)
	TB (.DTKDP,KDP)
	TB (.DTKDZ,KDZ)
LINSIZ=.-LINNAM


; TABLE OF NETCON DEVICE TYPE/SYSERR DEVICE TYPE CORRESPONDENCE

HDWTB:	.SYDTE,,.DTDTE
	.SYKDP,,.DTKDP
	.SYDUP,,.DTDUP
	.SYDMC,,.DTDMC

	HDWSZ==.-HDWTB



; BYTE POINTER TABLES

PTRTAB:	.PTSLD,,SLDTAB		;POINTERS FOR LOADING SECONDARY BOOTSTRAPS
	.PTOPS,,OPSTAB		;POINTERS FOR LOADING OPERATING SYSTEMS

	PTRSIZ==.-PTRTAB


OPSTAB:	POINT 8,(T3),7
	POINT 8,(T3),15
	POINT 8,(T3),23
	POINT 8,(T3),31

SLDTAB:	POINT 8,(T3),15
	POINT 8,(T3),7
	POINT 8,(T3),31
	POINT 8,(T3),23
SUBTTL	Variable Data Storage

;NETCON FREE SPACE AND VARIABLES


; LOGGING PROCESS PAGES

LOGFFP==300			;FIRST FREE PAGE FOR LOGGING PROCESS
NLOGPG==10			;NUMBER OF PAGES FOR THE LOGGING PROCESS

;START OF SPACE THAT IS ZEROED AT PROGRAM START UP

BEGFRE::
OURNAM::BLOCK 2			;NAME OF NODE NETCON IS RUNNING ON
OURNUM::BLOCK 1			;OUR NODE NUMBER

EXCUTR::0			;POINTER TO EXECUTOR NAME

	ERRSTL==20		;LENGTH OF ERROR STRING
ERRSTR::BLOCK ERRSTL		;USED BY ERROR TO HOLD ERROR STRING

LEV1PC::0			;LEVEL 1 PC ADDRESS
LEV2PC::0
LEV3PC::0

L1SAV1::0			;AC SAVE AREA
L1SAV2::0
L1SAV3::0
L1SAV4::0
L1SAVC::0

L2SAV1::0
L2SAV2::0
L2SAV3::0
L2SAV4::0
L2SAVC::0

L3SAV1::0
L3SAV2::0
L3SAV3::0
L3SAV4::0
L3SAVC::0

;NCU VARIABLE DEFINITIONS

SAVRET:	BLOCK 1			;RETURN ADDRESS OF CMDINI CALLER
SAVREP:	BLOCK 1			;SAVED STACK POINTER TO RESTORE ON REPARSE
RHDWC1:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 1
RHDWC2:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 2
RHDWC3:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 3


NXTNIB::BLOCK 1			;NEXT FREE NODE INFORMATION BLOCK
NXTLIN::BLOCK 1			;NEXT FREE LINE TABLE IN ADJTAB


TMPSTR:	BLOCK 50		;TEMPORARY STRING STORAGE LOCATION
NXTTIM:	BLOCK 1			;REMAINING CURRENT TIME INTERVAL
EVTSEQ::BLOCK 1			;NEXT SEQUENCE NUMBER FOR EVENT LOGGING MESSAGES
;GLOBAL STORAGE DEFINITIONS


; PROGRAM TABLE USED TO DETERMINE WHAT BOOTSTRAP FILE TO LOAD

PGMTAB::BLOCK PGLEN*MAXPGM	;TABLE OF BOOT FILE-DEVICE/CPU CORRESPONDENCE


; LINE TABLES CONTAINING INFO FOR LINE SERVICE PART OF PROGRAM

LINTAB:	BLOCK MAXNOD*MXLNOD	;NUMBER OF NODES * NUMBER OF LINES/NODE

; TABLE OF NODE NAMES FOR COMMAND PARSING (TBLUK JSYS FORMAT)

NODTAB::0 ,, MAXNOD		;CURRENT,,MAX NUMBER OF ENTRIES
	BLOCK MAXNOD		;ALLOCATE SPACE FOR MAX NUMBER OF NODES

LOGFLG:	BLOCK 1			;NON-ZERO IF LOGGING PROBLEMS GET REPORTED


LSTFRE==:.-1			;LAST LOCATION IN ZEROED FREE SPACE

ITPTR:	BLOCK 1			;INPUT TRACING POINTER
OTPTR:	BLOCK 1			;OUTPUT TRACING POINTER
LOGPDL:	BLOCK PDLEN		;LOGGER PROCESS PDL


	XLIST			;THE LITERALS ARE ASSEMBLED IN THIS
	LIT
	LIST			; "XLIST'ED" CODE.


	END