Google
 

Trailing-Edge - PDP-10 Archives - BB-W661B-BM_1984 - tools/xmr.mac
There are no other files named xmr.mac in the archive.
	TITLE	XMR	PMR WITH X25 SUPPORT
;
;
;                COPYRIGHT (c) 1975,1976,1977,1978,1979
;                    DIGITAL EQUIPMENT CORPORATION
;
;     THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;     AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
;     AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS
;     SOFTWARE  OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
;     OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON.  NO  TITLE  TO
;     AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;     THE INFORMATION  IN  THIS  SOFTWARE  IS  SUBJECT  TO  CHANGE
;     WITHOUT  NOTICE  AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;     BY DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
;     OF  ITS  SOFTWARE  ON  EQUIPMENT  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.
;
	PAGE
;
;	REVISION HISTORY
;	VERSION 1.0  FEB 83	G.FAUSER


	PAGE
	SUBTTL	DEFINITIONS
	SEARCH	MONSYM,MACSYM
	SEARCH	TXTUNV			;FOR TXTLIB

	SALL				;SUPPRESS MACRO EXPANSIONS

;VERSION INFORMATION
	XMRVER==0			;MAJOR VERSION NUMBER
	XMRMIN==0			;MINOR VERSION NUMBER
	XMREDT==0			;EDIT LEVEL
	XMRWHO==0			;WHO LAST PATCHED

	%XMR==<BYTE (3)XMRWHO(9)XMRVER(6)XMRMIN(18)XMREDT>

;STORE VERSION NUMBER IN JOBVER
	LOC	137
.JBVER::EXP	%XMR
	RELOC	0


;	AC's

	F=0
	S1=1				;SCRATCH AC'S
	S2=2
	T1=3				;TEMP-AC'S
	T2=4
	T3=5
	T4=6
	Q1=7				;
	Q2=10
	Q3=11
	P1=12				;PERMANET AC'S
	P2=13
	P3=14
	P4=15
	CX=16				;SPECIAL AC
	P=17				;PDL-P

	PAGE
	SUBTTL	X25 SUPPORT ROUTINES, SYMBOLS
;
;
	XC%SUC==0			;GENERAL SUCCESS CODE
	XC%NMD==1B14			;SPECIAL FLAG USED
;
;	X25 PORT STATES
;
	XS%UND==0			;UNDEFINED
	XS%OPN==1			;OPEN
	XS%CAG==2			;CALLING
	XS%LSN==3			;LISTENING
	XS%CAD==4			;CALLED
	XS%RUN==5			;RUNNING
	XS%SYN==6			;SYNCHRONIZING
	XS%UNS==7			;UNSYNCHRONIZED
	XS%CLG==10			;CLEARING
	XS%CLD==11			;CLEARED
	XS%ERR==12			;ERROR
	XS%NCM==13			;NO COMMUNICATION

;
;	ERROR CODES AS RETURN BY GATWAY ACCESS ROUTINES
;
	XS%RSS==1B18			;RESET SEEN
	XS%VSK==1B19			;VERSION SKREW
	XS%BTS==1B20			;BUFFER TOO SHORT
	XS%BTL==1B21			;BUFFER TOO LONG
	XS%SDL==1B22			;SOURCE DTE SUBADDR. TOO LONG.
	XS%DDL==1B23			;DEST. DTE SUBADDR. TOO LONG
	XS%NIC==1B24			;NO INTR. CONFIRMATION REQUESTED
	XS%AIC==1B25			;AWAITING INTR. CONFIRMATION
	XS%NDN==1B26			;NO DESTIGNATION
	XS%INA==1B27			;ILLEGAL NETWORK ACCESS CODE
	XC%DFT==1B28			;DATA FIELD TRUNCATION
	XS%FFT==1B29			;FACILITIES FIELD TRUNCATION
	XS%UNN==1B30			;UNDEFINED NETWORK NAME
	XS%NIN==1B31			;NO INTERRUPT TO READ
	XS%NDA==1B32			;NO DATA TO READ
	XS%PER==1B33			;PROCEDURE ERROR
	XS%IAR==1B34			;INSUFFICIENT ACCESS RESOURCES
	XS%IGR==1B35			;INSUFFICIENT GATEWAY RESOURCES

;
;	ERROR STATUS FIELD AS RETURNED BY X%RPS
;
	XE%VSK==1B7			;VERSION SKREWED
	XE%DDL==1B8			;DESTIGNATION DTE ADDR. TOO LONG
	XE%SDL==1B9			;SOURCE DTE ADDR. TOO LONG.
	XE%FFT==1B10			;FACILITIES FIELD TRUNCATION
	XE%DFT==1B11			;DATA FIELD TRUNCATION
	XE%NCM==1B12			;NO COMM. WITH GATEWAY
	XE%UNN==1B13			;UNDEFINED NETWORK NAME
	XE%UCN==1B14			;UNDEFINED CIRCUIT NAME
	XE%INU==1B15			;CIRCUIT IN USE (RESERVED)
	XE%IGR==1B16			;INSUFFICIENT RECOURCES (GATWAY)
	XE%UNK==1B17			;UNKNOWN ERROR

;
;	BIT AS RETURNED BY X%RPS INTERRUPT-DATA BIT MASK
;
	XM%IIP==400000			;INCOMMING INTERRUPT CONFIRM PENDING
	XM%OIP==200000			;OUTGOING  INTERRUPT CONFIRM PENDING
	XM%IDA==100000			;INCOMMING DATA AVAILABLE
	XM%IIA== 40000			;INCOMMING INTERRUPT DATA AVAILABLE
	XM%MSK==740000			;MASK FOR ALL DATA
;
;	BITS AS RETURNED BY X%RDM
;
	XS%MOR==1B0			;MORE DATA AVAILABLE
	XS%QDA==1B1			;QUALIFIED DATA FLAG
;
;	INTERRUPT CHANNELS USED
;
	CO%X25==0			;X25 INTERRUPT CHANNEL
	CO.X25==1B0
	CI%X25==1
	CI.X25==1B1			;INCOMMING CALL CHANNEL
	CI%DCN==2			;DECNET DCN CHANNEL
	CI.DCN==1B2			;
	CO%SRV==3			;SERVER SRV:123
	CO.SRV==1B3
	CO%DCN==4			;DECNET DCN CHANNEL
	CO.DCN==1B4

	PS%IDL==0			;PROTOCOL IDLE
	PS%VIR==1			;PROTOCOL VIRGIN STATE
	PS%WFC==2			;PROTOCOL WAIT FOR CONNECTED STATE
	PS%DMR==3			;PROTOCOL DATA MODE RUNNING



	PAGE
	SUBTTL	MACROS

	OPDEF	CONFRM	[PUSHJ P,CMDCNF]	;COMND CONFIRN FUNCTION

	DEFINE	NOISE ($TEXT),<		;;MACRO TO DO COMND GUIDEWORD CALL
	XLIST
	MOVEI	S2,[ASCIZ/$TEXT/]
	PUSHJ	P,CMDNOS
	LIST
>
	DEFINE	TMSX ($TEXT)<
	XLIST
	JRST	[ HRROI	S1,[ASCIZ\$TEXT\]
		  PSOUT
		  JRST	.+1 ]
	LIST
>
	DEFINE SKIPF<
	XLIST
	SKIPE	0
	LIST
>
	DEFINE SKIPT<
	XLIST
	SKIPN	0
	LIST
>
	DEFINE	RETF<
	XLIST
IFDEF ..RETF,< JRST ..RETF 
>
IFNDEF ..RETF,< JRST [
	..RETF: SETZM	0
		  POPJ	P, ] >
	LIST
>
	DEFINE	RETT<
	XLIST
IFDEF ..RETT,< JRST ..RETT
>
IFNDEF ..RETT,< JRST [
	..RETT: SETOM	0
		  POPJ	P, ] >
	LIST
>
	DEFINE	AA (X,Y),<		;;MACRO FOR COMMAND TABLES
	XLIST
	XWD	[ASCIZ/X/],Y
	LIST
>

	DEFINE ERROR (ADR,ARG)<
	XLIST
	PUSHJ	P,[ $TEXT (LOGMSG,<^H/[-1]/ 'ARG>)
	IFN ADR,< ADJSP P,-1
		  JRST	ADR ]>
	IFE ADR,< POPJ P, ]>
	LIST
>
	DEFINE ERRJMP (ADR,ARG)<
	XLIST
	ERJMP	 [ $TEXT (LOGMSG,<^H/[-1]/ 'ARG>)
		  JRST	ADR ]
	LIST
>
	DEFINE TRACE(A,B),<
	XLIST
	SKIPE	DEBUG
	$TEXT	(A,B)
	LIST
>

	DEFINE	PICON ($CHN),<
	XLIST
	MOVE	S2,[$CHN]
	CALL	.CHON
	LIST
>
	DEFINE PICOFF ($CHN),<
	XLIST
	MOVE	S2,[ $CHN ]
	CALL	.CHOFF
	LIST
>

	PAGE
	SUBTTL	MAIN INITIALIZATION AND TERMINATION CODE
;
;
;
XMR:	RESET				;RESET THE WORLD
	MOVE	P,[ IOWD PDLSZ,PDL ]	;GET A PDL
	SETZM	LOGJFN			;NO LOGGING YET
	CALL	TXTINI##		;INITIALIZE TEXTLIB
	MOVEI	P4,XMRDB		;POINT TO OUTGOING ROUTING DB
	MOVE	P3,P4			;AND POINT TO NORMAL GDB
	CALL	X25INI			;INITIALIZE X25 STUFF
	ERROR	XMRXIT,<?XMR Failed setting up X25TAB name table>
	CALL	INTON			;INIT INTERRUPT SYSTEM
	CALL	XMRSRV			;CREATE DECNET SERVER ON 123
	JRST	XMRXIT			;STOP IF FAILED
	PUSH	P,P4			;SAVE DATA BASE POINTER
	PUSH	P,P3			;THIS ONE TOO
	MOVEI	P4,XMLDB		;AND POINT TO SERVER
	MOVE	P3,P4			;POINT TO NORMAL GDB
	CALL	X25SRV			;CREATE X25 LISTENER
	SKIPT				;SUCCESS?
	ERROR	XMRXIT,<?XMR Failed to create X25 Listener>
	POP	P,P3			;RESTORE
	POP	P,P4			;RESTORE POINTER
	SKIPT				;SUCCESS?
	ERROR	XMRXIT,<?XMR Failed creating X25 Listner>
					;
	MOVE	S1,.JBVER		;GET VERSION OF ROUTER
	$TEXT	(LOGMSG,<^H/[-1]/ XMR    X25  Network Router Version ^V/S1/ started>)
					;
XMRCMD:	MOVEI	S2,[FLDDB.( .CMINI)]	;INITIALIZATION FUNCTION
	MOVEI	S1,XMRBLK		;POINT TO OUR (ONLY) COMMAND BLOCK
	COMND				;PARSE THE FUNCTION
	TXNE	S1,CM%NOP	;DID IT PARSE?
	ERROR	XMRXIT,<?XMRCMD Failed to initialize command JSYS>
	MOVEM	P,XMRSVP		;SAVE STACK FOR REPARSING
					;
XMRCML:	MOVE	P,XMRSVP		;RESTORE THE STACK
	MOVEI	S2,[FLDDB. (.CMKEY,,XMRTAB)];POINT TO COMMAND TABLE
	MOVEI	S1,XMRBLK		;POINT TO OUR (ONLY) COMMAND BLOCK
	COMND				;PARSE THE FUNCTION
	TXNE	S1,CM%NOP		;DID IT PARSE?
	JRST	XMRCMX			;NO-COMPLAIN
	MOVE	S2,0(S2)		;GET ADDRESS OF ROUTINE
	CALL	0(S2)			;CALL IT
	SKIPF				;ERROR SEEN?
	JRST	XMRCMD			;NO-GET A NEW COMMAND
	MOVEI	T1,.PRIIN		;GET READY
	CFIBF				;CLEAR INPUT BUFFER
	JRST	XMRCML			;AND GO START OVER
;
;	HERE ON ILLEGAL COMMAND, COMPLAIN ABOUT
;
XMRCMX:	TMSX	<
? UNDEFINED COMMAND >
	MOVE	S1,XMRBLK+.CMBFP	;GET POINTER TO COMMAND
	PSOUT				;AND OUTPUT ERROR COMMAND
	MOVEI	T1,.PRIIN		;GET READY
	CFIBF				;CLEAR INPUT BUFFER
	JRST	XMRCMD			;AND RESTART COMMAND

	PAGE
;
;	COMMAND DISPATCH TABLE
;
XMRTAB:	XMRTBX,,XMRTBX			;HEADER
	AA	DETACHE,XMRDET		;DETACHE COMMAND
	AA	HELP,XMRHLP		;HELP COMMAND
	AA	LOG,XMRLOG		;LOG OUTPUT COMMAND
	AA	NOLOG,XMRNLG		;NOLOG OUTPUT COMMAND
	AA	NOTRACE,XMRNTC		;NOTRACE COMMAND
	AA	STOP,XMRSTP		;STOP COMMAND
	AA	TRACE,XMRTRC		;TRACE COMMAND
	XMRTBX==.-XMRTAB-1		;ENTRIES IN THIS TABLE

;
;	HELP COMMAND
;
XMRHLP:	TMSX	<
 Sorry no help available yet
>
	RETT


	PAGE
	SUBTTL	XMRIDL  XMR IDLE LOOP
;
;	XMRIDL	IDLE LOOP.BECAUSE EVERYTHING HAPPENS AT INTERRUPT LEVEL,
;		THIS LOOP IS EXECUTED IF NOTHING ELSE NEEDS TO BE DONE,
;		E.G. IF ROUTER RUNS DETACHED.
;
XMRIDL:	WAIT				;WAIT FOR SOMETHING HAPPEN
	JRST	.-1			;AND GO WAIT ONCE MORE


	PAGE
	SUBTTL	XMRCMD COMMAND EXECUTION ROUTINES
;
;	HERE FOR DETACHE COMMAND.
;	DEATCHE THIS JOB FROM TERMINAL, TURN OFF DEBUG AND LOGGING TO TERMINAL
;
XMRDET:	NOISE	(from Terminal)		;BE NICE
	CONFRM				;TERMINATE COMMAND
	SETZM	LOGTTY			;TURN OFF ANY OUTPUT TO TTY
	SETZM	DEBUG			;AND DEBUG SWITCH TOO
	$TEXT	( ,<^H/[-1]/ %XMRDET Detaching Job >)
	DTACH				;AND DO SO
	JRST	XMRIDL			;AND JUMP INTO IDLE LOOP

	PAGE
;
;	HERE FOR LOG COMMAND, TURN ON LOGGING OUTPUT TO TTY
;	THIS IS THE DEFAULT AT START UP.
;
XMRLOG:	NOISE	(output to Terminal)	;BE NICE
	CONFRM				;AND TERMINATE COMMAND
	MOVEI	S1,.PRIOU		;WHERE TOGGING SHOULD GO
	MOVEM	S1,LOGTTY		;AND SET IT UP
	$TEXT	(,<^H/[-1]/ %XMRCMD Logging on terminal enabled>)
	RETT				;ALL DONE, RETURN


	PAGE
;
;	HERE FOR NOLOG COMMAND, TURN OFF LOGGING TO TERMINAL
;
XMRNLG:	NOISE	(output to Terminal)	;BE NICE AND HELPFUL
	CONFRM				;AND TERMINATE COMMAND
	SETZM	LOGTTY			;TURN OFF LOGING
	$TEXT	(,<^H/[-1]/ %XMRCMD Logging on terminal disabled>)
	RETT				;ALL DONE, RETURN

	PAGE
;
;	HERE ON TRACE COMMAND, TURN ON OUTPUT LOGGING TO TERMINAL
;	AND DEBUG.
;
XMRTRC:	NOISE	(all Router actions)	;
	CONFRM				;AND TERMINATE COMMAND
	MOVEI	S1,.PRIOU		;WHERE TOGGING SHOULD GO
	MOVEM	S1,LOGTTY		;AND SET IT UP
	SETOM	DEBUG			;TURN ON DEBUG FLAG
	$TEXT	(,<^H/[-1]/ %XMRCMD Trace on terminal enabled>)
	RETT				;ALL DONE, RETURN

	PAGE
;
;	HERE ON NO TRACE COMMAND, TURN OFF DEBUG, USE NOLOG TO DISABLE
;	LOGGING	TO TTY.
;
XMRNTC:	NOISE	(Router actions)
	CONFRM				;AND TERMINATE COMMAND
	SETZM	DEBUG			;TURN OFF DEBUG SWITCH
	$TEXT	(,<^H/[-1]/ %XMRCMD Trace on terminal disabled>)
	RETT				;ALL DONE, RETURN


	PAGE
;
;	HERE ON STOP COMMAND, STOP ROUTER AND EXIT TO MONITOR
;	MAKE SURE, LOG BUFFER HAS BEEN WRITTEN OUT.
;
XMRSTP:	NOISE	(Router imediately)
	CONFRM				;AND TERMINATE COMMAND
	$TEXT	(LOGMSG,<^H/[-1]/ %XMRCMD Router termination requested>)
	CALL	LOGDMP			;DUMP OUT PENDING LOG BUFFER
	RESET				;AND CLEARE OUT ALL
					;FALL INTO TERMINATION CODE
;	HERE TO STOP XMR
;
XMRXIT:	HALTF				;STOP HERE
	JRST	XMR			;AND ALLOW RESTART


	PAGE
	SUBTTL	SRVINT	DECNET SERVER INTERRUPT PROCESSING
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	HERE FOR VARIOUS DECNET SRV INTERRUPTS.
;
SRVINT:	SAVCH2				;SAVE ALL
	MOVEI	P4,XMRDB		;POINT TO DATA BASE
	MOVE	P3,P4			;AND POINT TO NORMAL GDB
	CALL	SRVRLS			;GET LINK STATUS
	TRACE	(LOGTRC,<%SRVXMR DECnet SRV channel interrupt received P=^D/SRVPST(P4)/ S=^O/T1/>)
					;
	MOVE	S1,SRVPST(P4)		;GET CURRENT PROTOCOL STATE
	JRST	@[ XWD	0,SRVERX	;=0 SHOULD NEVER COME UP
		   XWD	0,SRVIVR	;=1 VIRGIN
		   XWD	0,SRVWFC	;=2 WAIT FOR CONNECT
		   XWD	0,SRVIDT](S1)	;=3 DATA MODE RUNNING
;
;	HERE IF WE GOT AN INTERRUPT ON ILLEGAL PROTOCOL STATE
;
SRVERX:	ERROR	SRVERT,<?SRVXMR DECnet server SRV:123 illegal  state ^D/SRVPST(P4)/ at interrupt>
;
;
;	HERE IF PROTOCOL STATE WAS "VIRGIN". OUR SRV JUST CAMED UP.
;	ACCEPT INCOMMING CALL AND CHANGE TO WAIT FOR CONNECT STATE
;
SRVIVR:	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	ERROR	SRVERT,<?SRVXMR DECnet server SRV:123 failed to get connected>
	TXNN	T1,MO%WCC		;BUT WAITING FOR CONN.CONF.
	RET				;NOT YET, WAIT FOR
					;
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVXMR Accepting connection from DECnet SRV:123>)
	MOVE	S1,SRVJFN(P4)		;GET JFN WR'RE ON
	MOVEI	S2,.MOCC		;AND ACCEPT CONNECT FUNCTION
	HRROI	T1,T2			;DUMMY DATA
	SETZM	T2			;NO ACCEPT DATA
	MTOPR				;ACCEPT CONNECTION
	ERRJMP	SRVERT,<?SRVXMR Failed to accept connect request on SRV:123>
					;
	MOVEI	S1,PS%WFC		;SET NEW STATE TO
	MOVEM	S1,SRVPST(P4)		;"WAIT FOR CONNECTION"
	RET				;ALL DONE, RETURN


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	SRVINT CONT.......
;
;	HERE IF PROTOCOL STATE WAS "WAIT FOR CONNECTION".
;	CHECK FOR DATA TO READ, READ ROUTING STRING AND CREATE
;	DCN FOR.
;
SRVWFC:	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	ERROR	SRVERT,<?SRVXMR DECnet server SRV:123 failed to get connected>
	TXNN	T1,MO%CON		;BUT CONNECTED
	RET				;NOT YET, WAIT FOR
	TXNN	T1,MO%EOM		;DO WE HAVE DATA TO READ?
	RET				;NOT YET, WAIT FOR
					;
	MOVE	S1,SRVJFN(P4)		;YES-GET JFN FOR SRV:
	HRROI	S2,SRVBUF(P4)		;AND BUFFER ADDRESS
	MOVNI	T1,SINRMX		;AND BUFFER SIZE
	SINR				;READ MESSAGE
	ERRJMP	SRVERT,<?SRVXMR Failed reading connect data from SRV:123>
	SETZM	T2			;GET A ZERO
	IDPB	T2,S2			;AND TIE OFF STRING
;
;	HERE WE GOT INITIAL CONNECTION ON OUR SERVER, START UP
;	DCN OR, IF REQUESTED X25 OUTGOING PORT.
;
	TRACE	(LOGTRC,<%SRVXMR Parsing Routing string "^T/SRVBUF(P4)/">)
					;
	SETZM	X25RTY(P4)		;SET RETRY COUNT TO 0 (USED FOR X25)
	MOVE	T1,[POINT 7,SRVBUF(P4)]	;GET POINTER TO ROUTING MESSAGE
	CALL	PRS			;AND PARSE IT
	ERROR	SRVERT,<?SRVXMR Failed parsing routing string ^T/SRVBUF(P4)/>
	CALL	CHKX25			;IS IT A X25 NODE?
	JRST	SRVIWX			;YES-GO OPEN LINK TO
;
;	HERE IF IT IS A DECNET ROUTING REQUEST, CREATE DCN TO
;	REQUESTED OBJECT.
;
	CALL	DCNBLD			;CREATE DCN FOR
					;
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVXMR Creating DECnet link to destination ^T/NODSTR(P4)/>)
	MOVE	T1,[POINT 7,DCNSTR(P4)]	;AND POINT TO
	CALL	OPNCOM			;AND OPEN DCN HERE
	JRST	[ ERROR	,<?SRVXMR Failed creating DCN to Node ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/>
		  MOVEI	T1,.DCX39	;SAY NOT REACHABLE
		  JRST	DCNVIN ]	;AND NAK CONNECT REQUEST
					;
	MOVE	S1,DCNJFN(P4)		;GET JFN FOR
	MOVEI	S2,.MOACN		;AND PUT IT ON PSI
	MOVE	T1,[BYTE (9)CO%DCN,CO%DCN,CO%DCN,0]
	MTOPR				;
	ERRJMP	SRVERT,<?SRVXMR Failed to put DECnet DCN on PSI>
					;
	MOVEI	S1,PS%VIR		;INITIALIZE DCN STATE
	MOVEM	S1,DCNPST(P4)		;TO "VIRGIN".
					;
	MOVEI	S1,PS%DMR		;SET NEW PROTOCOL STATE TO
	MOVEM	S1,SRVPST(P4)		;"DATA MODE RUNNING".
	RET				;ALL DONE HERE, RETURN


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	SRVINT CONT......
;
;	HERE IF NODE WE HAVE TO GO TO IS A X25NODE.
;	OPEN NETWORK AND DO ERROR PROCESSING IF FAILED
;
SRVIWX:	SKIPN	X25RTY(P4)		;DOING RETRY ON PORT?
	$TEXT (LOGMSG,<^H/[-1]/ %SRVXMR Creating X25 link to DTE ^T/X25DTE(P4)/>)
	SKIPE	X25RTY(P4)		;USE DIFFERENT MESSAGE HERE
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVXMR Retry ^D/X25RTY(P4)/ creating X25 link to DTE ^T/X25DTE(P4)/>)
	CALL	X25OPN			;YES-OPEN NETWORK FOR IT
	SKIPF				;SUCCESS?
	JRST	[ MOVEI S1,PS%DMR	;SET NEW STATE TO
		  MOVEM S1,SRVPST(P4)	; DATA MODE RUNNING
		  RET	]		;ALL DONE HERE, RETURN
	CALL X25EPR			;GET ERROR MESSAGE SET UP
	MOVE	T4,T1			;GET ERROR MSG. PNTR. IN HERE
	ERROR ,<?SRVXMR Failed to open port because ^Q/T4/>
	MOVE	S1,[POINT 8,SRVBUF(P4)]	;POINT TO SERVER BUFFER
	MOVEI	S2,2			;AND GET NAK CODE
	IDPB	S2,S1			;AND PUT IN NAK CODE
	MOVEM	S1,STRPNT(P4)		;SET POINTER FOR STROUT
	$TEXT	(STROUT,<(^T/X25DTE(P4)/) failed because ^Q/T4/^0>)
					;
	MOVE	S1,SRVJFN(P4)		;GET SERVER JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND POINTER TO BUFFER
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;SEND IT OFF
	ERJMP	XMRABO			;ABORT IF THIS FAILES
	JRST	XMRABO			;AND FINISH UP


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	SRVINT CONT......
;
;	HERE ON ERROR DURING INTERRUPT PROCESSING,
;	DO APPROPIATE ACTIONS
;
SRVERT:	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVXMR Aborting SRV:123 due to error>)
	JRST	XMRABO			;GO ABORT ALL


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	SRVINT CONT ......
;
;	HERE IF PROTOCOL STATE IS "DATA MODE RUNNING".
;	CHECK FOR DATA AND FORWARD IT TO EITHER X25 NETWORK OR
;	DCN.
;
SRVIDT:	CALL	SRVRLS			;GET LINK STATUS
	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	ERROR	SRVERT,<?SRVXMR DECnet server SRV:123, aborted or closed.>
REPEAT 0,<
	TXNN	T1,MO%EOM		;DO WE HAVE DATA TO READ?
	RET				;NO-ALL DONE FOR NOW
>
;	THE FOLLOWING CODE IS A CROCK, BUT AS LONG AS WE HAVE THE MULTI
;	SEGMENT BUG I CAN'T DO ANYTHING ELSE.( THANKS TO SON VOBA HERE)
;
	MOVE	S1,SRVJFN(P4)		;GET SRV JFN
	SIBE				;ANYTHING TO READ
	SKIPA				;YES-GO GET IT
	RET				;NO-RETURN FOR NOW
					;
	SKIPE	X25CON(P4)		;TALKING TO X25 NETWORK
	JRST	SRVIDX			;YES-GO DO IT SEPERATE HERE
					;
	MOVE	S1,SRVJFN(P4)		;GET SERVER JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND BUFFER ADDRESS
	MOVNI	T1,SINRMX		;BUFFER SIZE
	SINR				;READ MESSAGE
	ERRJMP	SRVERT,<?SRVXMR Failed reading data from DECnet SRV:123>
					;
	ADDI	T1,SINRMX		;COMPUTE BYTE COUNT
	JUMPE	T1,SRVIDZ		;JUMP IF ZERO LENGHT DATA
					;
	TRACE	(LOGTRC,<%SRVXMR Sending data message size ^D/T1/ to DECnet DCN/>)
	MOVNS	T1			;SET BUFFER BYTE COUNT
	MOVE	S1,DCNJFN(P4)		;AND JFN FOR
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;THIS BUFFER
	SOUTR				;SEND IT OFF
	ERRJMP	SRVERT,<?SRVXMR Failed sending data message to DECnet DCN>
	JRST	SRVIDT			;GO CHECK FOR MORE
;
SRVIDZ:	ERROR	SRVERT,<?SRVXMR Received zero lenght record form SRV:123>


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	SRVINT CONT......
;
;	HERE IF WE ARE TALKING TO X25 NETWORK, THINGS GOING LITTLE
;	DIFFERENT HERE.
;
SRVIDX:	MOVE	S1,SRVJFN(P4)		;GET OUR SRV JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND POINTER TO ITS BUFFER
	SETZM	T2			;GET A ZERO
	IDPB	T2,S2			;AND ZERO OUT BYTE COUNT
	IDPB	T2,S2			;( TWO BYTES NEEDED )
	MOVNI	T1,SINRMX-2		;MAX NUMBER OF BYTES WE HANDLE
	SINR				;AND READ DATA MESSAGE
	ERRJMP	SRVERT,<?SRVXMR Failed reading data message from SRV:123>
					;
	ADDI	T1,SINRMX-2		;COMPUTE BYTE COUNT WE GOT
	JUMPE	T1,SRVIDZ		;TERMINATE IF NONE
	ANDI	T1,177777		;ONLY 16 BITS WE WANT
	TRACE	(LOGTRC,<%SRVXMR Received data message size ^D/T1/ from DCN>)
	MOVE	S1,[POINT 16,SRVBUF(P4)]	;POINT TO BEGINNING
	IDPB	T1,S1			;AND PUT IT IN
	ADDI	T1,2			;COUNT FOR OVERHEAD
	MOVEM	T1,X25TBC(P4)		;AND SAVE IT
					;
	MOVE	T1,[POINT 8,SRVBUF(P4)]	;POINT BACK TO BUFFER
	MOVEM	T1,X25TBP(P4)		;AND SAVE WHERE WE ARE ON
					;
SRVIDL:	SKIPG	T2,X25TBC(P4)		;ANYTHING LEFT TO TRANSMIT?
	JRST	SRVIDT			;NO-ALL DONE, RETURN
	MOVE	T1,X25TBP(P4)		;GET CURRENT BUFFER POINTER
	MOVE	T2,X25TBC(P4)		;AND BYTE COUNT LEFT TO TRANSMIT
	CAILE	T2,X25BFZ		;YES-MORE WE CAN HANDLE IN ONE MESSAGE?
	MOVEI	T2,X25BFZ		;YES-REDUCE TO BUFFER SIZE
	MOVN	S1,T2			;GET COUNT NEGATIVE
	ADDM	S1,X25TBC(P4)		;AND COUNT FOR
	TRACE	(LOGTRC,<%SRVXMR Sending data message size ^D/T2/ to X25 Link>)
	CALL	X25SND			;TRANSMIT THIS BUFFER
	SKIPT				;SUCCESS?
	ERROR	SRVERT,<?SRVXMR Failed sending data buffer over X25 Network>
	MOVEM	S1,X25TBP(P4)		;AND SAVE UPDATED POINTER
	JRST	SRVIDL			;YES-KEEP GOING UNTIL DONE


	PAGE
	SUBTTL	DCNINT	DECNET DCN INTERRUPT PROCESSOR
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	VARIOS DECNET DCN INTERRUPTS COMMES IN HERE
;
DCNINT:	SAVCH2				;SAVE ALL
	MOVEI	P4,XMRDB		;POINT TO OUR DATA BASE
	MOVE	P3,P4			;AND POINT TO NORMAL GDB
	CALL	DCNRLS			;GET LINK STATUS
	TRACE	(LOGTRC,<%DCNXMR DECnet DCN channel interrupt received P=^D/DCNPST(P4)/ S=^O/T1/>)
					;
	MOVE	S1,DCNPST(P4)		;GET CURRENT PROTOCOL STATE
	JRST	@[ XWD	0,DCNERX	;=0 SHOULD NEVER HAPPEN
		   XWD	0,DCNVIR	;=1 THIS ONE EITHER
		   XWD	0,DCNWFC	;=2 WAIT FOR CONNECT
		   XWD	0,DCNDMR](S1)	;=3 DATA MODE RUNNING

;
;	HERE IF ILLEGAL PROTOCOL STATE AT INTERRUPT
;
DCNERX:	ERROR	DCNERT,<?DCNXMR DECnet DCN illegal state ^D/DCNPST(P4)/ at inetrrupt>

	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DCNINT CONT .......
;
;	HERE IF PROTOCOL STATE WAS "VIRGIN".
;	CHECK IF WE GOT A CONNECTION AND,
;	IF WE ARE LAST SERVER IN THE ROUTING, SEND ACK MESSAGE BACKWARD
;	AND CHANGE DIRECTLY TO "DATA MODE RUNNING" STATE, ELSE
;	CHANGE TO "WAIT FOR CONNECT" STATE AND READ RESPONSE FROM NEXT
;	ROUTER IN THE ROUTING STRING.
;	IF CONNECT FAILED, SEND IMEDIATELY NAK MESSAGE BACKWARD.
;
DCNVIR:	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR BIT SET?
	JRST	DCNVIN			;YES-SEND NAK BACKWARD
	TXNN	T1,MO%CON		;ARE WE CONNECTED?
	RET				;NO-WAIT SOME MORE
	SKIPE	RTRFLG(P4)		;DOING MULTI ROUTING?
	JRST	DCNVIX			;YES-NEED FIRST TO SEND ROUTING STRING
;
;	HERE OUR DCN/OBJECT NOW IS CONNECTED, SEND ACK MESSAGE TO SRV:
;
	TRACE	(LOGTRC,<%DCNXMR Connect to Node ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/ established, sending ACK message>)
	MOVE	S1,SRVJFN(P4)		;GET JFN
	MOVEI	S2,1			;AND ACK CODE
	BOUT				;PUT IT IN
	ERRJMP	DCNERT,<?DCNXMR Failed sending ACK message to SRV:123>
					;
	HRROI	S2,NODSTR(P4)		;ADD OUR NODE STRING TOO
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;AND SEND MESSAGE
	ERRJMP	DCNERT,<?DCNXMR Failed sending ACK message to SRV:123>
					;
	MOVEI	S1,PS%DMR		;GET NEW PROTOCOL STATE
	MOVEM	S1,DCNPST(P4)		;TO "DATA MODE RUNNING".
	RET				;ALL DONE, RETURN
;
;	HERE IF ARE DOING MULTI ROUTING, SEND ROUTING STRING TO
;	NEXT SERVER NOW CONNECTED ON OUR DCN AND CHANGE STATE TO
;	"WAIT FOR CONNECT".
;
DCNVIX:	MOVE	S1,DCNJFN(P4)		;GET JFN FOR
	HRROI	S2,PMRSTR(P4)		;AND POINTER TO ROUTING STRING
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;SEND IT OUT
	ERRJMP	DCNERT,<?DCNXMR Failed sending routing string to next router>
	MOVEI	S1,PS%WFC		;GET NEW STATE
	MOVEM	S1,DCNPST(P4)		;AND SET TO "WAIT FOR CONNECT"
	RET				;ALL DONE, RETURN


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DCNINT CONT........
;
;	HERE IF CONNECT TO DCN FAILED, SEND BACK NAK MESSAGE
;
DCNVIN:	TRACE	(LOGTRC,<%DCNXMR Connect to ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/ failed, sending NAK message backward>)
	HRRZ	T4,T1			;PRESERVE ERROR CODE\
	MOVE	S1,SRVJFN(P4)		;AND GET JFN FOR SERVER
	MOVEI	S2,2			;AND NAK CODE
	BOUT				;PUT IT IN
	ERJMP	DCNIWE			;ABORT IF FAILED
	MOVEI	S2,"%"			;
	BOUT				;PUT IT IN
	ERJMP	DCNIWE			;ABORT IF FAILED
	HRROI	S2,NODSTR(P4)		;AND NODE NAME TOO
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;PUT IT IN
	ERJMP	DCNIWE			;ABORT IF FAILED
	HRROI	S2,[ASCIZ/ not reachable because /]
	SOUT				;PUT IT IN
	ERJMP	DCNIWE			;ABORT IF FAILED
	MOVE	S2,MSGTBL(T4)		;GET MESSAGE FOR
	SOUTR				;AND SEND IT OFF
	ERJMP	DCNIWE			;ABORT IF FAILED
	JRST	XMRABO			;AND STOP ALL HERE

DCNIWE:	ERROR	DCNERT,<?DCNXMR Failed sending NAK message to SRV:123>


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DCNINT CONT ......
;
;	HERE IF DATA MODE IS "WAIT FOR CONNECT".
;	THIS STATE ONLY GETS INVOLVED IF MULTI ROUTING IS IN PROGRESS.
;	READ REPLAY FROM NEXT ROUTER, ADD IN OUR NODE AND SEND
;	MESSAGE BACKWARD, CHANGE TO "DATA MODE RUNNING" STATE IF REPLAY
;	WAS AN ACK, ELSE ABORT LINK.
;
DCNWFC:	CALL	DCNRLS			;READ LINK STATUS
	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	ERROR	DCNERT,<?DCNXMR DCN failed, aborted or closed.>
REPEAT 0,<
	TXNN	T1,MO%EOM		;WE HAVE A DATA MESSAGE?
	RET				;NO-ALL DONE FOR NOW
>
;	THE FOLLOWING CODE IS A CROCK, BUT AS LONG AS WE HAVE THE MULTI
;	SEGMENT BUG I CAN'T DO ANYTHING ELSE.( THANKS TO SON VOBA HERE)
;
	MOVE	S1,DCNJFN(P4)		;GET DCN JFN
	SIBE				;ANYTHING TO READ
	SKIPA				;YES-GO GET IT
	RET				;NO-RETURN FOR NOW
					;
	MOVE	S1,DCNJFN(P4)		;GET JFN TO READ THE DATA
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND BUFFER ADDRESS
	MOVNI	T1,SINRMX		;BUFFER SIZE
	SINR				;READ THE DATA
	ERRJMP	DCNERT,<?DCNXMR Failed reading data on DECnet DCN>
					;
	ADDI	T1,SINRMX		;COMPUTE BYTE COUNT
	SKIPN	T1			;ZERO LENGHT RECORD?
	ERROR	DCNERT,<?DCNXMR Received zero lenght replay from next router>
					;
	MOVE	S1,[POINT 8,DCNBUF(P4)]	;POINT TO DATA MSG.
	ILDB	S2,S1			;AND GET ACK FIELD
	CAIN	S2,1			;IS IT AN ACK?
	$TEXT	(LOGMSG,<%DCNXMR Received ACK message from Node ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/ to SRV:123>)
	CAIN	S2,2			;OR IS IT A NAK?
	$TEXT	(LOGMSG,<%DCNXMR Received NAK message from Node ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/ to SRV:123>)
	MOVNS	T1			;
	MOVE	S1,SRVJFN(P4)		;GET JFN WHERE TO SEND TO
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND BUFFER ADDRESS
	SOUTR				;SEND IT OFF
	ERRJMP	DCNERT,<?DCNXMR Failed sending data message to SRV:123>
					;
	MOVEI	S1,PS%DMR		;GET NWE STATE
	MOVEM	S1,DCNPST(P4)		;SAY DATA MODE RUNNING NOW
	JRST	DCNDMR			;CHECK FOR MORE




	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DCNINT CONT......
;
;	HERE IF PROTOCOL STATE WAS "DATA MODE RUNNING".
;	READ DATA FROM DCN AND SEND FORWARD IT TO SRV.
;
DCNDMR:	CALL	DCNRLS			;READ LINK STATUS
	TXNE	T1,MO%ABT!MO%SYN		;ANY ERROR SEEN?
	ERROR	DCNERT,<?DCNXMR DCN failed, aborted or closed.>
REPEAT 0,<
	TXNN	T1,MO%EOM		;WE HAVE A DATA MESSAGE?
	RET				;NO-ALL DONE FOR NOW
>
;	THE FOLLOWING CODE IS A CROCK, BUT AS LONG AS WE HAVE THE MULTI
;	SEGMENT BUG I CAN'T DO ANYTHING ELSE.( THANKS TO SON VOBA HERE)
;
	MOVE	S1,DCNJFN(P4)		;GET DCN JFN
	SIBE				;ANYTHING TO READ
	SKIPA				;YES-GO GET IT
	RET				;NO-RETURN FOR NOW
					;
	MOVE	S1,DCNJFN(P4)		;GET JFN TO READ THE DATA
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND BUFFER ADDRESS
	MOVNI	T1,SINRMX		;BUFFER SIZE
	SINR				;READ THE DATA
	ERRJMP	DCNERT,<?DCNXMR Failed reading data on DECnet DCN>
					;
	ADDI	T1,SINRMX		;COMPUTE BYTE COUNT
	JUMPE	T1,DCNIDZ		;JUMP IF ZERO BYTE COUNT
					;
	TRACE	(LOGTRC,<%DCNXMR Sending data message size ^D/T1/ to DECnet SRV:123>)
	MOVNS	T1			;
	MOVE	S1,SRVJFN(P4)		;GET JFN WHERE TO SEND TO
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND BUFFER ADDRESS
	SOUTR				;SEND IT OFF
	ERRJMP	DCNERT,<?DCNXMR Failed sending data message to SRV:123>
	JRST	DCNDMR			;CHECK FOR MORE

DCNIDZ:	ERROR	DCNERT,<?DCNXMR Received zero lenght record from DCN>


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DCNINT CONT......
;
;	HERE ON ERROR DURING DCN INTERRUPT PROCESSING
;
DCNERT:	$TEXT	(LOGMSG,<^H/[-1]/ %DCNXMR Aborting connection due to error>)
	JRST	XMRABO			;AND TERMINATE ALL

	PAGE
	SUBTTL	X2OINT	OUTGOING X25  NETWORK INTERRUPT ENTRY
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	DISPATCH ON PORT AND PROTOCOL STATE
;
X2OINT:	SAVCH1				;SAVE AWAY AC'S WE NEED
	MOVEI	P4,XMRDB		;POINT TO OUTGOING DATA BASE
	MOVEI	P3,X25GDZ(P4)		;POINT TO ALTERNATE GDB
	CALL	X25STA			;GET PORT STATUS
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ Failed reading port status>
	HRRZ	S1,X25PSC(P4)		;GET PORT STATE
	HLRZ	S2,X25PSC(P4)		;AND ERROR BITS TOO
	TRACE	(LOGTRC,<%DCNPRT Interrupt received S1=^O/S2/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>)
	DMOVE	T1,X25PSC(P4)		;GET PORT STATUS
	HRRZ	S1,T1			;ONLY STATE HERE
	JRST	@X2OINX(S1)		;DISPATCH PORT STATE
;
;	HERE IF PORT IS IN RUN STATE, DISPATCH PROTOCOL STATE
;
X2OINC:	MOVE	S1,X25PST(P4)		;GET CURRENT PROTOCOL STATE
	JRST	@[ XWD	0,X2OERX	;0= IDLE
		   XWD	0,X2OVIR	;1= VIRGIN
		   XWD	0,X2OWFC	;2= WAIT FOR RESPONSE
		   XWD	0,X2ODAT](S1)	;3= DATA MODE RUNNING
;
;	HERE ON ILLEGAL PROTOCOL STATE AT INTERRUPT
;
X2OERX:	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ illegal state ^D/X25PST(P4)/ at interrupt>
;
;
;	PORT STATE DISPATCH TABLE
;
X2OINX:	XWD	0,X2OERP		;0= UNDEFINED
	XWD	0,X2OERP		;1= OPEN
	XWD	0,[ RET ]		;2= CALLING
	XWD	0,X2OERP		;3= LISTENING
	XWD	0,X2OERP		;4= CALLED
	XWD	0,X2OINC		;5= RUNNING
	XWD	0,X2OERP		;6= SYNC
	XWD	0,X2OERP		;7= UNSYNC
	XWD	0,[ RET ]		;10= CLEARING
	XWD	0,X2ORCD		;11= CLEARED
	XWD	0,X2OERP		;12= ERROR
	XWD	0,X2OERP		;13= NO COMMUNICATION

	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT .......
;
;	HERE IF PORT WENT INTO AN ILLEGAL STATE
;	CHECK CURRENT PROTOCOL STATE, IF NOT DATA MODE RUNNING SEND
;	NAK WITH AN ERROR MESSAGE TO SRV:123.
;
X2OERP:	DMOVE	S1,X25PSC(P4)		;GET LAST STATUS SEEN SO FAR
	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ failed state S1=^O/S1/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>
	MOVE	S1,[POINT 8,SRVBUF(P4)]	;POINT TO SERVER BUFFER
	MOVEI	S2,2			;AND GET NAK CODE
	IDPB	S2,S1			;AND PUT IN NAK CODE
	MOVEM	S1,STRPNT(P4)		;SET POINTER FOR STROUT
	HRRZ	S1,X25PSC(P4)		;GET PORT STATUS
	$TEXT	(STROUT,<%X25 Port failed, port went into illegal state ^Q/X25STT(S1)/>)
						;
	MOVE	S1,SRVJFN(P4)		;GET SERVER JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND POINTER TO BUFFER
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;SEND IT OFF
	ERJMP	XMRABO			;ABORT IF THIS FAILES
	JRST	XMRABO			;AND FINISH UP

	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT ......
;
;	HERE IF PORT WENT INTO CLEARED STATE, READ CLEAR CAUSE CODE
;	CHECK CURRENT PROTOCOL STATE ,IF NOT DATA MODE RUNNING SEND
;	NAK WITH ERROR MESSAGE TO SRV:123
;
X2ORCD:	CALL	X25RCD			;READ IT
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Failed reading clear cause data>
	HRRZ	T1,X25CCC(P4)		;GET USER CODE
	HLRZ	T2,X25CCC(P4)		;AND PPSN CODE
	$TEXT	(LOGMSG,<^H/[-1]/ ?DCNPRT Port ^D/X25PRT(P4)/ cleared, PPSN code ^D/T2/ User code ^D/T1/>)
;
	MOVE	S1,X25PST(P4)		;GET PROTOCOL STATE
	CAIL	S1,PS%DMR		;NOTHING WE CAN DO IN DMR
	JRST	X2OERT			;GO ABORT ALL
	SKIPN	T2			;PPSN FAILURE?
	JRST	X2ORCN			;NO-GO SEND NAK MESSAGE
					;
	CALL	SRVRLS			;GET STATUS OF SRV:
	TXNE	T1,MO%ABT!MO%SYN	;ANY PROBLEM
	ERROR	SRVERT,<?DCNPRT DECnet server SRV:123 aborted or closed>
	MOVE	S1,X25RTY(P4)		;GET RETRY COUNT
	CAML	S1,MAXRTY		;REACHED MAXIMUM?
	JRST	X2ORCN			;YES-GIVE UP AND SEND NAK
	AOS	X25RTY(P4)		;COUNT THIS RETRY
	CALL	X25TPA			;TERMINATE THIS PORT
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ failed to terminate on retry ^D/X25RTY(P4)/>
	JRST	SRVIWX			;AND GO RETRY
;
;	HERE IF WE HAVE TO GIVE UP BUT DATA MODE NOT RUNNING YET,
;	SEND NAK MESSAGE TO OUR SRV.
;
X2ORCN:	DMOVE	S1,X25PSC(P4)		;GET LAST STATUS SEEN SO FAR
	$TEXT	(LOGMSG,<^H/[-1]/ ?DCNPRT Port ^D/X25PRT(P4)/  Aborting connection due to error State S1=^O/S1/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>)
	MOVE	S1,[POINT 8,SRVBUF(P4)]	;POINT TO SERVER BUFFER
	MOVEI	S2,2			;AND GET NAK CODE
	IDPB	S2,S1			;AND PUT IN NAK CODE
	MOVEM	S1,STRPNT(P4)		;SET POINTER FOR STROUT
	HRRZ	T1,X25CCC(P4)		;GET USER CODE
	HLRZ	T2,X25CCC(P4)		;AND PPSN CODE
	$TEXT	(STROUT,<%X25 Port cleared, PPSN code ^D/T2/ User code ^D/T1/ ^0>)
					;
	MOVE	S1,SRVJFN(P4)		;GET SERVER JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND POINTER TO BUFFER
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;SEND IT OFF
	ERJMP	XMRABO			;ABORT IF THIS FAILES
	JRST	XMRABO			;AND FINISH UP
;
;
;
;	HERE IF ERROR DURING INTERRUPT PROCESSING
;
X2OERT:	HRRZ	S1,X25PSC(P4)		;GET PORT STATE
	HLRZ	S2,X25PSC(P4)		;AND ERROR BITS TOO
	$TEXT	(LOGMSG,<^H/[-1]/ ?DCNPRT Port ^D/X25PRT(P4)/ Aborting connection due to error State S1=^O/S2/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>)
	$TEXT	(LOGMSG,<^H/[-1]/ %DCNPRT Port ^D/X25PRT(P4)/ statistic Received P/B ^D/X2ARPC(P4)/ ^D/X2ARBC(P4)/ Transmitted P/B ^D/X2ATPC(P4)/ ^D/X2ATBC(P4)/>)
	JRST	XMRABO			;GO ABORT ALL

	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT...........
;
;	HERE ON PROTOCOL STATE VIRGIN, PORT JUST CAMED UP TO RUNNING
;	SEND ROUTING STRING TO OTHER END DTE AND CHANGE TO NEXT PROTOCOL
;	STATE.
;
X2OVIR:	TRACE	(LOGTRC,<%DCNPRT Sending routing string to other end DTE "^T/PMRSTR(P4)/">)
	$TEXT	(LOGMSG,<^H/[-1]/ %DCNPRT Port ^D/X25PRT(P4)/ running>)
	MOVE	T1,[POINT 7,PMRSTR(P4)]	;GET STRING POINTER
	CALL	STRSIZ			;FIND SIZE OF THIS STRING
	MOVE	T2,S1			;GET IT
	CALL	X25SND			;AND SEND IT OUT
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ Failed sending routing string>
	MOVEI	S1,PS%WFC		;GET NEW PORT STATE
	MOVEM	S1,X25PST(P4)		;SET TO WAIT FOR RESPONSE
	RET				;AND ALL DONE, RETURN


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;
;	X2OINT CONT...........
;
;	HERE IN PROTOCAOL STATE "WAIT FOR RESPONSE".
;	READ RESPONSE FROM OTHER END DTE AND FORWARD IT TO OUR DECNET SRV:
;
X2OWFC:	CALL	X25STA			;UPDATE STATUS
	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IDA		;INPUT DATA AVAILABLE?
	RET				;NO-WAS A STATUS CHANGE
					;
	MOVE	T1,[ POINT 8,X25BFR(P4)];POINT TO BUFFER
	CALL	X25RDM			;YES-READ IT
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Failed reading ACK message>
	MOVE	P1,S1			;SAVE RETURNED FLAGS
	HRRZS	S1			;GET BYTE COUNT
	JUMPE	S1,[ RET ]		;DON'T ACCEPT ZERO SIZE
					;
	MOVE	T4,[POINT 8,X25BFR(P4)]	;POINT TO RECEIVER BUFFER
	ILDB	T3,T4			;AND GET ACK FIELD
					;
;	HERE GENERATE MESSAGE OF THE FORM:
;	our-node::( DTE # ) received-message
;
	MOVE	S1,[POINT 7,SRVBUF(P4)]	;POINT TO SERVER BUFFER
	IDPB	T3,S1			;AND PUT IN ACK CODE
	MOVEM	S1,STRPNT(P4)		;AND SET POINTER FOR STROUT
	$TEXT	(STROUT,<(^T/X25DTE(P4)/)^A>)
	MOVE	S1,STRPNT(P4)		;GET BACK UPDATED POINTER
	MOVE	S2,T4			;GET SAVED PNTR. TO RCEIVED MESSAGE
	HRRZ	T1,P1			;GET MESSAGE SIZE
	MOVNS	T1			;BUT NEGATIVE
	SOUT				;ADD IT TO THE REST
	SETZM	T2			;GET A ZERO
	IDPB	T2,S1			;AND TERMINATE THIS STRING
					;
	MOVE	S1,SRVJFN(P4)		;GET SERVER JFN
	HRROI	S2,SRVBUF(P4)		;AND POINTER TO STRING
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUTR				;SEND IT OFF
	ERJMP	X2OERT			;ABORT IF THIS FAILES
					;
	CAIE	T3,1			;WAS IT AN ACK?
	ERROR	X2OERT,<?DCNPRT Received NAK for routing request>
	TRACE	(LOGTRC,<%DCNPRT Sending ACK to DECnet SRV>)
	MOVEI	S1,PS%DMR		;GET NEW PROTOCOL STATE
	MOVEM	S1,X25PST(P4)		;AND SET DATA MODE RUNNING NOW
	MOVE	S1,[POINT 8,SRVBUF(P4)]	;AND POINTER FOR DATA
	MOVEM	S1,X25BFP(P4)		;SET IT
	SETZM	X25TBC(P4)		;ZERO BUFFER COUNT
	SETZM	X25RBC(P4)		;THIS ONE TOO
	JRST	X2ODAT			;TRY GET DATA NOW


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT...........
;
;	HERE IF PROTOCOL STATE IS "DATA MODE RUNNING".
;	CHECK IF WE GOT DATA TO READ AND READ IT IN.
;	REPACK DATA MESSAGES TO NSP MESSAGES AND SEND IT TO
;	OUR DECNET SRV:
;
X2ODAT:	CALL	X25STA			;UPDATE STATUS
	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IDA		;INPUT DATA AVAILABLE?
	JRST	X2OIDA			;NO-CHECK FOR INTERRUPT
;
;
X2ODAN:	MOVE	T1,X25BFP(P4)		;GET CURRENT BUFFER POINTER
	CALL	X25RDM			;GO READ MESSAGE
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Failed reading Network data>
	MOVE	P1,S1			;HOLD FLAGS RETURNED
	TXNE	P1,XC%NMD		;NO MORE DATA?
	RET				;YES-ALL DONE HERE
	TXNE	P1,XS%QDA		;QUALIFIED DATA RECIEVED?
	JRST	X2OCON			;YES-MUST BE CONTROL MESSAGE
					;
	HRRZ	T1,P1			;AND NUMBER OF BYTES RECEIVED
	MOVEM	S2,X25BFP(P4)		;AND UPDATED BUFFER POINTER
	JUMPE	T1,X2ODAZ		;JUMP IF ZERO LENGHT BUFFER
	TRACE	(LOGTRC,<%DCNPRT Received data size ^D/T1/ from Network>)
					;
	SKIPE	X25RBC(P4)		;THIS IS A NEW NSP MESSAGE?
	JRST	X2ODAL			;NO-REST OF A PREVIOUS ONE
	MOVE	S1,[POINT 16,SRVBUF(P4)];GET NSP BYTE COUNT
	ILDB	T2,S1			;GET BYTE COUNT
	ADDI	T2,2			;AND COUNT FOR OVERHEAD
	MOVEM	T2,X25RBC(P4)		;AND SET IT
					;
X2ODAL:	MOVN	S1,T1			;GET BYTES TO SEND
	ADDM	S1,X25RBC(P4)		;COUNT FOR THIS BUFFER
	SKIPLE	T1,X25RBC(P4)		;WE GOT EVERYTHING?
	JRST	X2ODAN			;NO-GO EXIT FOR NOW
					;
	MOVE	S1,SRVJFN(P4)		;YES-GET OUR JFN
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND BUFFER POINTER
	ILDB	T1,S2			;GET NSP MESSAGE COUNT
	LSH	T1,^D8			;MAKE SPACE FOR LOW BYTE
	ILDB	T2,S2			;AND GET LOW BYTE COUNT
	IORM	T2,T1			;ASSEMBLE 16 BIT MESSAGE SIZE
	TRACE	(LOGTRC,<%DCNPRT Sending data size ^D/T1/ to DECnet SRV:123>)
	MOVNS	T1			;
	SOUTR				;SEND IT OFF
	ERJMP	X2OERT			;ABORT IF ERROR
	SETZM	X25RBC(P4)		;NO MORE DATA IN BUFFER
	MOVE	S2,[POINT 8,SRVBUF(P4)]	;AND REWIND BUFFER
	MOVEM	S2,X25BFP(P4)		;SET IT
	JRST	X2ODAN			;AND TRY GET MORE DATA
;
;	HERE IF WE RECEIVED ZERO LENGHT BUFFER
;
X2ODAZ:	ERROR	X2OERT,<?DCNPRT Received zero lenght buffer from Network>


	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT ..........
;
;	HERE IF WE ARE IN "DATA MODE RUNNING" AND RECEIVED A CONTROL
;	MESSAGE. CONTROL MESSAGES ARE FLAGGED AS QUALIFIED DATA.
;
X2OCON:	HRRZ	T1,P1			;GET BYTE COUNT RECEIVED
	JUMPE	T1,[ RET ]		;IGNORE IF ZERO BYTES
					;
	MOVE	T1,X25BFP(P4)		;GET CURRENT BUFFER POINTER
	ILDB	S1,T1			;AND GET HEADER BYTE
	$TEXT  (LOGMSG,<^H/[-1]/ ?SRVPRT Port ^D/X25PRT(P4)/ received illegal control message code ^O/S1/,message ignored>)
	RET				;IGNORE IT , RETURN

	PAGE
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	X2OINT CONT.............
;
;	HERE IF PROTOCOL STATE IS "DATA MODE RUNNING".
;	CHECK FOR INTERRUPT MESSAGE RECEIVED.
;
X2OIDA:	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IIA		;INTERRUPT MESSAGE?
	RET				;NO-IGNORE IT
	TRACE	(LOGTRC,<%DCNPRT Port ^D/X25PRT(P4)/ Received interrupt message>)
	CALL	X25RIM			;GO READ IT
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?DCNPRT Port ^D/X25PRT(P4)/ Failed reading inetrrupt message>
	RET				;ALL DONE, RETURN

	PAGE
	SUBTTL	XMR	ERROR HANDLER
;
;	*********** D E C N E T  S R V : 1 2 3  S E R V E R F O R K ************
;
;
;	NOTE:	WE ARE STILL ON INTERRUPT LEVEL HERE
;
;	ALL FATAL ERRORS FROM XMR ENDS UP HERE.
;	CLOSE DOWM ALL SRV:,DCN:,AND PORT AND RESTART SRV:123
;
XMRABO:	MOVE	S1,DCNJFN(P4)		;GET JFN FOR
	JUMPE	S1,XMRAB1		;JUMP OVER IF NONE
	MOVE	S2,.MOACN		;AND FUCTION
	MOVE	T1,[BYTE (9).MOCIA,.MOCIA,.MOCIA,0]
	MTOPR				;REMOVE FROM INTERRUPT CHANNEL
	ERJMP	.+1			;IGNORE ERRORS HERE
					;
	SETZM	S1			;GET A ZERO
	EXCH	S1,DCNJFN(P4)		;GET DCN JFN
	TXO	S1,CZ%ABT		;ABORT/RELEASE THIS JFN
	CLOSF				;AND DO SO
	JFCL				;CAN'T HANDLE IT HERE
	SETZM	DCNPST(P4)		;AND PROTOCOL STATE TO IDLE
;
;	NEXT RESET X25 OUTGOING PORT
;
					;
XMRAB1:
REPEAT 0,<
	SKIPN	X25PST(P4)		;PORT HAS BEEN OPENED?
	JRST	XMRAB2			;NO-NO NEED TO TERMIATE IT
>
	CALL	X25TPA			;TERMINATE PORT ACCESS
	SKIPT				;SUCCESS?
	$TEXT	(LOGMSG,<^H/[-1]/ ?XMRABO Failed to terminate port access>)
	SETZM	X25PST(P4)		;AND PROTOCOL IDLE
;
;	NOW TERMINATE AND RESET SRV:123
;
XMRAB2:	MOVE	S1,SRVJFN(P4)		;GET JFN FOR
	JUMPE	S1,XMRAB3		;JUMP OVER IF NONE
	MOVE	S2,.MOACN		;AND FUCTION
	MOVE	T1,[BYTE (9).MOCIA,.MOCIA,.MOCIA,0]
	MTOPR				;REMOVE FROM INTERRUPT CHANNEL
	ERJMP	.+1			;IGNORE ERRORS HERE
					;
	SETZM	S1			;GET A ZERO
	EXCH	S1,SRVJFN(P4)		;GET JFN
	CLOSF				;AND CLOSE IT NOW
	JFCL				;CAN'T HANDLE IT HERE
	SETZM	SRVPST(P4)		;SET PROTOCOL TO IDLE
					;
XMRAB3:	CALL	XMRSRV			;CREATE A NEW SRV:123 NOW
	RET				;NOTHING ELSE I CAN DO HERE
	$TEXT	(LOGMSG,<^H/[-1]/ %XMRABO  DECnet Server SRV:123 restarted>)
	RET				;ALL DONE, RETURN
					;
	PAGE
	SUBTTL	X2IINT	INCOMMING CALL INTERRUPT ROUTINE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
X2IINT:	SAVCH1				;SAVE AWAY AC'S WE NEED
	MOVEI	P4,XMLDB		;POINT TO OUTGOING DATA BASE
	MOVEI	P3,X25GDZ(P4)		;POINT TO ALTERNATE GDB
	CALL	X25STA			;GET PORT STATUS
	SKIPT				;SUCCESS?
	ERROR	X2OERT,<?SRVPRT Failed reading port status>
	HRRZ	S1,X25PSC(P4)		;GET PORT STATE
	HLRZ	S2,X25PSC(P4)		;AND ERROR BITS TOO
	TRACE	(LOGTRC,<%SRVPRT Interrupt received S1=^O/S2/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>)
	DMOVE	T1,X25PSC(P4)		;GET PORT STATUS
	HRRZ	S1,T1			;ONLY STATE HERE
	JRST	@X2IINX(S1)		;DISPATCH PORT STATE
;
;	HERE IF PORT IS IN RUN STATE, DISPATCH PROTOCOL STATE
;
X2IINC:	MOVE	S1,X25PST(P4)		;GET CURRENT PROTOCOL STATE
	JRST	@[ XWD	0,X2ICAL	;0= IDLE
		   XWD	0,X2IVIR	;1= VIRGIN
		   XWD	0,[ RET ]	;2= WAIT FOR RESPONSE
		   XWD	0,X2IDAT](S1)	;3= DATA MODE RUNNING
;
;	HERE ON ILLEGAL PROTOCOL STATE AT INTERRUPT
;**********NOT NEEDED ANYMORE ????????????
;
X2IERX:	ERROR	X2OERT,<?SRVPRT Port ^D/X25PRT(P4)/ illegal state ^D/X25PST(P4)/ at interrupt>
;
;
;	PORT STATE DISPATCH TABLE
;
X2IINX:	XWD	0,X2IERP		;0= UNDEFINED
	XWD	0,X2IERP		;1= OPEN
	XWD	0,X2IERP		;2= CALLING
	XWD	0,[ RET ]		;3= LISTENING
	XWD	0,X2ICAL		;4= CALLED
	XWD	0,X2IINC		;5= RUNNING
	XWD	0,X2IERP		;6= SYNC
	XWD	0,X2IERP		;7= UNSYNC
	XWD	0,[ RET ]		;10= CLEARING
	XWD	0,X2IRCD		;11= CLEARED
	XWD	0,X2IERP		;12= ERROR
	XWD	0,X2IERP		;13= NO COMMUNICATION
;
;	HERE IF PORT WENT INTO ILLEGAL STATE
;
X2IERP:	ERROR	X2IERT,<?SRVPRT Port ^D/X25PRT(P4)/ failed state S1=^O/S1/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>
;
;	HERE IF PORT WENT INTO CLEARED STATE, READ CLEAR CAUSE CODE
;
X2IRCD:	CALL	X25RCD			;READ IT
	SKIPT				;SUCCESS?
	HRRZ	S1,X25CCC(P4)		;GET USER CODE
	HLRZ	S2,X25CCC(P4)		;AND PPSN CODE
	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVPRT Port ^D/X25PRT(P4)/ cleared, PPSN code ^D/S2/ User code ^D/S1/>)
	JRST	X2IERT			;AND FINISH UP
;
;	HERE ON ERROR
;
X2IERT:	HRRZ	S1,X25PSC(P4)		;GET PORT STATE
	HLRZ	S2,X25PSC(P4)		;AND ERROR BITS TOO
	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVPRT Port ^D/X25PRT(P4)/ Aborting connection due to error State S1=^O/S1/ ^Q/X25STT(S1)/ S2=^O/X25PSC+1(P4)/ P=^D/X25PST(P4)/>)
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Port ^D/X25PRT(P4)/ statistic Received P/B ^D/X2ARPC(P4)/ ^D/X2ARBC(P4)/ transmitted P/B ^D/X2ATPC(P4)/ ^D/X2ATBC(P4)/>)
					;
	SETZM	S1
	EXCH	S1,DCNJFN(P4)		;GET DCN JFN
	JUMPE	S1,X2IER1		;JUMP OVER IF NO DCN JFN OPEN
	TXO	S1,CZ%ABT		;ABORT/RELEASE THIS JFN
	CLOSF				;AND DO SO
	JFCL				;CAN'T HANDLE IT HERE
					;
X2IER1:	CALL	X25TPA			;TERMINATE PORT ACCESS
	SKIPT				;SUCCESS?
	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVABO Failed terminate port access>)
	SETZM	X25PST(P4)		;AND PROTOCAL STATE IDLE
	CALL	X25SRV			;CREATE A NEW SERVER
	SKIPT				;SUCCESS?
	JRST	[ ERROR	,<?SRVPRT Failed to create X25 Listener>
		  RET ]			;NOTHING ELSE WE CAN DO HERE
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT X25 Port restarted on port ^D/X25PRT(P4)/>)
	RET				;AND RETURN
;
;
	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT .........
;
;	HERE IF WE RECEIVED A CALL FROM NETWORK,
;	READ CALL DATA AND ACCEPT CALL HERE
;
X2ICAL:	CALL	X25RIC			;READ CALL DATA
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed reading incomming call data>
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Received call from Network DTE ^T/X25DTE(P4)/>)
	CALL	X25AIC			;ACCEPT THIS  CALL
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed to accept incomming call >
	CALL	X25ACD			;CHECK ACCESS ALLOWED
	JRST	X2ICAB			;NO-TELL HIM BAD NEWS
;
;	HERE IF ACCESS TO OUR DTE IS ALLOWED FOR THE CALLING DTE.
;	ACCPET CALL AND START PROTOCOL
;
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Call accepted from Network DTE ^T/X25DTE(P4)/>)
	MOVEI	S1,PS%VIR		;GET PROTOCOL VIRGIN STATE
	MOVEM	S1,X25PST(P4)		;AND SET PROT. STATE
	RET				;ALL DONE, RETURN
;
;	HERE IF CALLING DTE IS NOT ALLOWED TO ACCESS OUR DTE.
;	SEND BACK MESSAGE, CLEARE CIRCUIT AND DO NORMAL RESTART
;
X2ICAB:	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVPRT Access refused for DTE ^T/X25DTE(P4)/>)
	MOVE	S1,[POINT 8,X25UDB(P4)]	;POINT TO USER-DATA BUFFER
	HRROI	S2,[ASCIZ/?REFUSED/]	;GET A SHORT,SHORT MESSAGE
	SETZM	T1			;TERMINATE NORMAL
	SOUT				;AND COPY IT IN HERE
					;
	MOVEI	T1,^D 98		;GET DIAG CODE
	CALL	X25CSC			;AND CLEAR CIRCUIT
	JRST	X2IERT			;FINISH UP HERE
					;
	JRST	X2IERT			;AND FINISH UP HERE


	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT .........
;
;	HERE TO PROCESS INITIAL DATA MESSAGE ( PMR STRING).
;	DECODE THE PMR STRING AND CREATE REQUESTED DECNET
;	LINK FOR IT.
;
X2IVIR:	CALL	X25STA			;UPDATE STATUS
	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IDA		;INPUT DATA AVAILABLE?
	RET				;NO DATA YET, WAS JUST STATUS CHANGE
					;
	MOVE	T1,[ POINT 8,X25BFR(P4)];POINT TO BUFFER
	CALL	X25RDM			;AND GO READ THE DATA
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed reading initial data message>
	SETZM	T1			;GET A ZERO
	IDPB	T1,S2			;AND TIE OFF STRING
	MOVE	T4,S1			;GET FLAGS RETURNED
	TXNN	T4,XS%QDA		;IS IT QUALIFIED DATA
	TRACE	(LOGTRC,<%SRVPRT Routing data not flagged qualified>)
	HRRZ	T3,T4			;GET SIZE OF BUFFER
	SKIPG	T3			;SHOULD NOT BE ZERO
	ERROR	X2IERT,<?SRVPRT zero lenght routing string received>
	MOVE	T1,[ POINT 8,X25BFR(P4)];GET POINTER TO DATA MESSAGE
	CALL	PRS			;AND PARSE ROUTING STRING
	ERROR	X2IERT,<?SRVPRT Failed parsing routing string ^T/X25BFR(P4)/>
	SKIPE	RTRFLG(P4)		;GOING TO ANOTHER ROUTER?
	ERROR	X2IERT,<?SRVPRT Routing not yet implemented>
					;
	CALL	X25ACO			;ACCESS CONTROL REQUESTED OBJECT
	JRST	X2IVIN			;NEGATIVE, GO DISCONNECT
;
;	HERE IF WE GOT A VALID ROUTING STRING,
;	CREATE DCN TO THE REQUESTED OBJECT.
;
	CALL	DCNBLD			;BUILD DECNET DCN:
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Creating DECnet DCN Link to ^T/NODSTR(P4)/ Object ^T/OBJSTR(P4)/>)
					;
	MOVE	T1,[ POINT 7,DCNSTR(P4)];AND GET A POINTER TO
	CALL	OPNCOM			;OPEN FOR THIS DCN
	ERROR	X2IERT,<?SRVPRT Failed creating DCN to local object>
					;
	MOVE	S1,DCNJFN(P4)		;GET JFN WE'RE ON
	MOVEI	S2,.MOACN		;SET INTERRUPT ON CHANNEL
	MOVE	T1,[ BYTE (9) CI%DCN,CI%DCN,CI%DCN,0]
	MTOPR				;AND DO IT
	ERJMP	X2IERT			;ABORT ON ERROR
	MOVEI	S1,PS%WFC		;GET PROT. STATE WAIT CONNECT
	MOVEM	S1,X25PST(P4)		;AND SET IT
	RET				;ALL DONE,WE WILL GET AN INTERUPT
					;IF THIS DCN GETS TO CONNECT STATE

	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT .........
;
;	HERE IF ACCESS TO REQUESTED OBJECT NOT ALLOWED,
;	SEND BACK NAK MESSAGE AND CLEARE THE PORT.
;
X2IVIN:	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Refused access to Object ^T/OBJSTR(P4)/>)
	MOVE	S1,[POINT 8,X25BFT(P4)]	;POINT TO TRANSMIT BUFFER
	MOVEI	S2,2			;AND GET NAK CODE
	IDPB	S2,S1			;PUT IT IN
	MOVEM	S1,STRPNT(P4)		;SETUP POINTER NEEDED BY STROUT
	$TEXT	(STROUT,<%^T/NODSTR(P4)/::,access to Object not permitted ^0>)
	MOVE	T1,[POINT 8,X25BFT(P4)]	;POINT BACK TO STRING
	CALL	STRSIZ			;AND FIND IT'S SIZE
	MOVE	T2,S1			;GET SIZE OF
	CALL	X25SND			;AND SEND IT OUT
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed sending NAK message>
	RET				;NOTE, OTHER END ROUTER WILL TERMINATE
					;LINK.


	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT..........
;
;	HERE IF WE RECEIVED DATA FROM NETWORK,
;	REPACK IT AND SEND IT TO OUR DECNET DCN.
;
;
X2IDAT:	CALL	X25STA			;UPDATE STATUS
	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IDA		;INPUT DATA AVAILABLE?
	JRST	X2IIDA			;NO-CHECK FOR INTERRUPT
;
;
X2IDAN:	MOVE	T1,X25BFP(P4)		;GET CURRENT BUFFER POINTER
	CALL	X25RDM			;GO READ MESSAGE
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed reading Network data>
	MOVEM	S2,X25BFP(P4)		;AND UPDATED BUFFER POINTER
	MOVE	P1,S1			;HOLD FLAGS RETURNED
	TXNE	P1,XC%NMD		;NO MORE DATA?
	RET				;YES-ALL DONE HERE
	TXNE	P1,XS%QDA		;QUALIFIED DATA RECIEVED?
	JRST	X2ICON			;YES-MUST BE CONTROL MESSAGE
					;
	HRRZ	T1,P1			;GET NUMBER OF BYTES RECEIVED
	TRACE	(LOGTRC,<%SRVPRT Received data message size ^D/T1/ from Network>)
	JUMPE	T1,X2IDAZ		;JUMP IF ZERO LENGHT BUFFER
					;
	SKIPE	X25RBC(P4)		;THIS IS A NEW NSP MESSAGE?
	JRST	X2IDAL			;NO-REST OF A PREVIOUS ONE
	MOVE	S1,[POINT 16,DCNBUF(P4)];GET NSP BYTE COUNT
	ILDB	T2,S1			;GET NSP MESSAGE SIZE
	ADDI	T2,2			;COUNT FOR OVERHEAD
	MOVEM	T2,X25RBC(P4)		;AND SET IT
					;
X2IDAL:	MOVN	S1,T1			;GET COUNT
	ADDM	S1,X25RBC(P4)		;COUNT FOR THIS BUFFER
	SKIPLE	T1,X25RBC(P4)		;WE GOT EVERYTHING?
	JRST	X2IDAN			;NO-GO TRY GET MORE DATA
					;
	MOVE	S1,DCNJFN(P4)		;YES-GET OUR JFN
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND BUFFER POINTER
	ILDB	T1,S2			;GET NSP MESSAGE COUNT
	LSH	T1,^D8			;MAKE SPACE FOR LOW BYTE
	ILDB	T2,S2			;AND GET LOW BYTE COUNT
	IORM	T2,T1			;ASSEMBLE 16 BIT BYTE COUNT
	TRACE	(LOGTRC,<%SRVPRT Sending data size ^D/T1/ to DECnet DCN>)
	MOVNS	T1			;
	SOUTR				;SEND IT OFF
	ERJMP	X2IERT			;ABORT IF ERROR
	SETZM	X25RBC(P4)		;NO MORE DATA IN BUFFER
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND REWIND BUFFER
	MOVEM	S2,X25BFP(P4)		;SET IT
	JRST	X2IDAN			;AND TRY GET MORE DATA
;
;	HERE IF WE RECEIVED ZERO LENGHT BUFFER
;
X2IDAZ:	ERROR	X2IERT,<?SRVPRT Received zero lenght buffer from Network>



	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT ..........
;
;	HERE IF WE ARE IN "DATA MODE RUNNING" AND RECEIVED A CONTROL
;	MESSAGE. CONTROL MESSAGES ARE FLAGGED AS QUALIFIED DATA.
;
X2ICON:	HRRZ	T1,P1			;GET BYTE COUNT RECEIVED
	JUMPE	T1,[ RET ]		;IGNORE IF ZERO BYTES
					;
	MOVE	T1,X25BFP(P4)		;GET CURRENT BUFFER POINTER
	ILDB	S1,T1			;AND GET HEADER BYTE
	$TEXT  (LOGMSG,<^H/[-1]/ ?SRVPRT Port ^D/X25PRT(P4)/ received illegal control message code ^O/S1/,message ignored>)
	RET				;IGNORE IT, RETURN

	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	X2IINT CONT .........
;
;	HERE IF PROTOCOL STATE IS "DATA MODE RUNNING".
;	CHECK FOR INTERRUPT MESSAGE RECEIVED.
;
X2IIDA:	MOVE	T1,X25PSC+1(P4)		;GET PORT STATE FLAGS
	TLNN	T1,XM%IIA		;INTERRUPT DATA MESSAGE?
	RET				;NO-IGNORE IT
	TRACE	(LOGTRC,<%DCNPRT Port ^D/X25PRT(P4)/ Received interrupt message>)
	CALL	X25RIM			;GO READ IT
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Port ^D/X25PRT(P4)/ Failed reading inetrrupt message>
	RET				;ALL DONE, RETURN

	PAGE
	SUBTTL	X25 INCOMMING CALL SERVER DECNET DCN INTERRUPT
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;
;	HERE FOR VARIOUS DECNET DCN INTERRUPTS
;
X2IDCI:	SAVCH2				;SAVE ALL
	MOVEI	P4,XMLDB		;POINT TO INCOMMING DATA BASE
	MOVE	P3,P4			;AND POINT TO NORMAL GDB
					;
	CALL	DCNRLS			;READ LINK STATUS
	TRACE	(LOGTRC,<%SRVPRT DECnet DCN channel interrupt received P=^D/X25PST(P4)/ S=^O/T1/>)
	MOVE	S1,X25PST(P4)		;GET PROTOCOL STATE
	JRST	@[XWD	0,X2IERT	;=O NEVER SHOULD HAPPEN
		  XWD	0,[ RET ]	;=1 IDLE
		  XWD	0,X2IDCW	;=2 WAIT FOR CONNECT
		  XWD	0,X2IDCD](S1)	;=3 DATA MODE RUNNING
;
;	HERE IF WE ARE WAITING FOR CONNECTION DONE,
;	CHECK DCN: STATUS AND SEND ACK MESSAGE IF CONNECTION OK,
;	ELSE SEND NAK TOGETHER WITH THE ERROR MESSAGE BACK TO
;	THE CALLING ROUTER.
;
X2IDCW:	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	JRST	X2IDCX			;YES-TELL OTHER END ABOUT
	TXNN	T1,MO%CON		;BUT CONNECTED NOW
	RET				;NOT YET, WAIT FOR
					;
	$TEXT	(LOGMSG,<^H/[-1]/ %SRVPRT Sending ACK message to other end router>)
					;
	MOVE	S1,[POINT 8,X25BFT(P4)]	;POINT TO TRANSMIT BUFFER
	MOVEI	S2,1			;AND GET ACK CODE
	IDPB	S2,S1			;PUT IT IN
	MOVEM	S1,STRPNT(P4)		;SET UP PNTR. FOR STROUT
	$TEXT	(STROUT,<^T/NODSTR(P4)/::,connect OK ^0>)
					;
	MOVE	T1,[POINT 8,X25BFT(P4)]	;POINT BACK TO BEGINNING
	CALL	STRSIZ			;AND GET SIZE FOR
	MOVE	T2,S1			;INTO RIGHT REGISTER
	CALL	X25SND			;AND SEND THIS MESSAGE OUT
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed sending ACK message>
					;
	MOVEI	S1,PS%DMR		;GET STATE DATA MODE RUNNING
	MOVEM	S1,X25PST(P4)		;AND SET IT
	MOVE	S1,[POINT 8,DCNBUF(P4)]	;AND POINTER FOR DATA
	MOVEM	S1,X25BFP(P4)		;SET IT
	SETZM	X25TBC(P4)		;ZERO BUFFER COUNT
	SETZM	X25RBC(P4)		;THIS ONE TOO
	JRST	X2IDCD			;GO CHECK FOR DATA RECEIVED


	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;	X2IDC CONT........
;
;	HERE IF CONNECT TO REQUESTED OBJECT FAILED, SEND
;	BACK ERROR MESSAGE.
;
X2IDCX:	$TEXT	(LOGMSG,<^H/[-1]/ ?SRVPRT Sending NAK message to other end server>)
					;
	HRRZ	T4,T1			;GET DCN: STATUS ON A SAVE PLACE
	MOVE	S1,[POINT 8,X25BFT(P4)]	;POINT TO TRANSMIT BUFFER
	MOVEI	S2,2			;AND GET NAK CODE
	IDPB	S2,S1			;PUT IT IN
	MOVEM	S1,STRPNT(P4)		;SETUP POINTER NEEDED BY STROUT
	$TEXT	(STROUT,<%^T/NODSTR(P4)/::,not reachable because ^Q/MSGTBL(T4)/^0>)
	MOVE	T1,[POINT 8,X25BFT(P4)]	;POINT BACK TO STRING
	CALL	STRSIZ			;AND FIND IT'S SIZE
	MOVE	T2,S1			;GET SIZE OF
	CALL	X25SND			;AND SEND IT OUT
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed sending NAK message>
	JRST	X2IERT			;AND TERMINATE ALL


	PAGE
;
;	*********** X 2 5  I N C O M M I N G  C A L L  S E R V E R *************
;
;	X2IDC CONT........
;
;	HERE IF WE RECEIVED DATA FROM DCN TO BE TRANFERED OVER X25
;	TO THE OTHER END X25 ROUTER.
;
X2IDCD:	CALL	DCNRLS			;GET LINK STATUS
	TXNE	T1,MO%ABT!MO%SYN	;ANY ERROR SEEN?
	ERROR	X2IERT,<?SRVPRT DECnet DCN failed,closed or aborted>
REPEAT 0,<
	TXNN	T1,MO%EOM		;WE HAVE A DATA MESSAGE?
	RET				;NO-ALL DONE FOR NOW
>
;	THE FOLLOWING CODE IS A CROCK, BUT AS LONG AS WE HAVE THE MULTI
;	SEGMENT BUG I CAN'T DO ANYTHING ELSE.( THANKS TO SON VOBA HERE)
;
	MOVE	S1,DCNJFN(P4)		;GET DCN JFN
	SIBE				;ANYTHING TO READ
	SKIPA				;YES-GO GET IT
	RET				;NOTHING, RETURN
					;
	MOVE	S1,DCNJFN(P4)		;GET OUR DCN JFN
	MOVE	S2,[POINT 8,DCNBUF(P4)]	;AND POINTER TO ITS BUFFER
	SETZM	T2			;GET A ZERO
	IDPB	T2,S2			;AND ZERO OUT BYTE COUNT
	IDPB	T2,S2			;( TWO BYTES NEEDED )
	MOVNI	T1,SINRMX-2		;MAX NUMBER OF BYTES WE HANDLE
	SINR				;AND READ DATA MESSAGE
	ERRJMP	X2IERT,<?SRVPRT Failed reading data message from DECnet DCN>
					;
	ADDI	T1,SINRMX-2		;COMPUTE BYTE COUNT WE GOT
	JUMPE	T1,X2IDCE		;TERMINATE IF NONE
	ANDI	T1,177777		;ONLY 16 BITS WE WANT
	TRACE	(LOGTRC,<%SRVPRT Received Data message size ^D/T1/ from DECnet DCN>)
	MOVE	S1,[POINT 16,DCNBUF(P4)]	;POINT TO BEGINNING
	IDPB	T1,S1			;AND PUT IT IN
	ADDI	T1,2			;COUNT FOR OVERHEAD
	MOVEM	T1,X25TBC(P4)		;AND SAVE IT
					;
	MOVE	T1,[POINT 8,DCNBUF(P4)]	;POINT BACK TO BUFFER
	MOVEM	T1,X25TBP(P4)		;AND SAVE WHERE WE ARE ON
					;
X2IDCL:	SKIPG	T2,X25TBC(P4)		;ANYTHING LEFT TO TRANSMIT?
	JRST	X2IDCD			;NO-CHECK FOR MORE DATA
					;
	MOVE	T1,X25TBP(P4)		;GET CURRENT BUFFER POINTER
	MOVE	T2,X25TBC(P4)		;AND BYTE COUNT LEFT TO TRANSMIT
	CAILE	T2,X25BFZ		;YES-MORE WE CAN HANDLE IN ONE MESSAGE?
	MOVEI	T2,X25BFZ		;YES-REDUCE TO BUFFER SIZE
	MOVN	S1,T2			;GET COUNT NEGATIVE
	ADDM	S1,X25TBC(P4)		;AND COUNT FOR
	TRACE	(LOGTRC,<%SRVPRT Sending data message size ^D/T2/ to Network>)
	CALL	X25SND			;TRANSMIT THIS BUFFER
	SKIPT				;SUCCESS?
	ERROR	X2IERT,<?SRVPRT Failed sending data buffer>
	MOVEM	S1,X25TBP(P4)		;AND SAVE UPDATED POINTER
	JRST	X2IDCL			;YES-KEEP GOING UNTIL DONE
;
;	HERE IF BYTE COUNT RECEIVED WAS ZERO,
;
X2IDCE:	ERROR	X2IERT,<?DCNPRT Zero lenght message received from DCN>

	PAGE
	SUBTTL	PMRPRS	PARSE ROUTING STRING
;
;	PRS	ROUTINE TO PARSE ROUTING STRINGS
;
;	PARSES STRINGS OF THE FORM:
;
;	(#)[[ Node::] Node::..] Node " Attribute ":: " Object ="
;
;	ENTER WITH T1 <== POINTER TO THE FULL ROUTING STRING
;
;	RETURNS:	NON-SKIP IF FAILED
;			SKIP IF SUCCESS
;
;	SETS UP THE FOLLOWING STRINGS:
;
;	NODSTR	NAME OF THE FIRST NODE IN THE ROUTING STRING
;	ATTSTR	ATTRIBUTE STRING ( AS USED BY NFT )
;		NOTE: PARSED AS: USRSTR,ACCSTR,PSWSTR
;	PMRSTR	ROUTING STRING IF WE ARE NOT LAST NODE
;	OBJSTR	OBJECT CODE, IF WE ARE THE LAST NODE IN STRING
;	RTRFLG	0  IF WE ARE LAST IN THE ROUTING STRING
;		-1 IF WE ARE NOT LAST IN THE ROUTING STRING.
;
;
PRS:	SAVET				;GET SOME REGISTERS
	SAVEP				;WE NEED THIS ONE TOO
	SETZM	RTRFLG(P4)		;ASSUME WE ARE LAST NODE
	MOVE	T4,T1			;GET STRING TO PARSE
	MOVE	P1,T1			;AND A COPY FOR LATER
	ILDB	S1,T4			;MOVE OVER START BYTE
	MOVE	T3,[ POINT 7,NODSTR(P4)];WHERE TO STORE FIRST NODE
	SETZM	USRSTR(P4)		;ASSUME NO ATTRIBUTE MESSAGE
	SETZM	ACCSTR(P4)		;
	SETZM	PSWSTR(P4)		;
					;
PRS01:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIE	S1,":"			;NODE TERMINATOR?
	CAIN	S1,42			;OR START OF ATTRIBUTE
	JRST	PRS02			;YES-JUMP OFF
	IDPB	S1,T3			;ELSE COPY IT OVER
	JRST	PRS01			;AND KEEP GOING
					;
PRS02:	SETZM	T1			;GET TERMINATOR
	IDPB	T1,T3			;AND TERMINATE IT
	CAIE	S1,42			;WE ARE ON START OF ATTRIBUTE?
	JRST	PRS05			;NO-JUMP OVER
					;
;	HERE WE ARE ON START OF ATTRIBUTE STRING
;	PARSE USER-NAME<BLANK>ACCOUNT<BLANK>PASSWORD
;
	MOVE	T3,[ POINT 7,USRSTR(P4)];GET POINTER TO USER NAME
PRS03:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIN	S1,42			;TERMINATOR FOR
	JRST	PRS035			;YES-ALL DONE HERE
	CAIN	S1,40			;DELEMITTER?
	JRST	PRS031			;YES-TERMINATE THIS ARG.
	IDPB	S1,T3			;COPY BYTE TO OUTPUT
	JRST	PRS03			;AND KEEP GOING
					;
PRS031:	SETZM	S1			;GET TERMINATOR
	IDPB	S1,T3			;AND TERMINATE STRING
					;
	MOVE	T3,[POINT 7,PSWSTR(P4)]	;POINT TO ACCOUNT STRING
PRS032:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIN	S1,42			;TERMINATOR FOR
	JRST	PRS035			;YES-ALL DONE HERE
	CAIN	S1,40			;DELEMITTER?
	JRST	PRS033			;YES-TERMINATE THIS ARG.
	IDPB	S1,T3			;COPY BYTE TO OUTPUT
	JRST	PRS032			;AND KEEP GOING
					;
PRS033:	SETZM	S1			;GET TERMINATOR
	IDPB	S1,T3			;AND TERMINATE STRING
					;
	MOVE	T3,[POINT 7,ACCSTR(P4)]	;PASSWORD STRING
PRS034:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIN	S1,42			;TERMINATOR FOR
	JRST	PRS035			;YES-ALL DONE HERE
	CAIN	S1,40			;DELEMITTER?
	JRST	PRS035			;YES-TERMINATE THIS ARG.
	IDPB	S1,T3			;COPY BYTE TO OUTPUT
	JRST	PRS034			;AND KEEP GOING
					;
PRS035:	SETZM	S1			;GET TERMINATOR
	IDPB	S1,T3			;AND TERMINATE STRING
					;
PRS04:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIE	S1,":"			;FIND NODE TERMINATOR
	JRST	PRS04			;KEEP GOING
					;
PRS05:	ILDB	S1,T4			;STEP OVER SECOND ":"
;
;	HERE SEACH IF THERE IS A SECOND NODE NAME IN THIS STRING,
;	IF YES, WE ARE NOT THE LAST IN THE ROUTING STRING AND
;	NEED TO SET UP PMRSTR FROM REST OF THE STRING.
;
	MOVE	T1,T4			;GET POINTER WE'RE ON
PRS06:	ILDB	S1,T1			;GET NEXT BYTE
	JUMPE	S1,PRS09		;IF DONE, NO MORE NODES FOUND
	CAIE	S1,":"			;A NODE TERMINATOR
	JRST	PRS06			;NO-KEEP GOING
	SETOM	RTRFLG(P4)		;YES-REMEMBER IT
	MOVE	T3,[ POINT 7,PMRSTR(P4)];GET A POINTER TO
	MOVE	T2,P1			;GET OUR SAVED INP. POINTER
	ILDB	S1,T2			;GET START BYTE
	ADDI	S1,1			;INCREMENT IT
	IDPB	S1,T3			;AND PUT IT IN
PRS07:	ILDB	S1,T4			;AND START COPYING THE
	JUMPE	S1,PRS08		;THE REST OF THE STRING
	IDPB	S1,T3			;INTO NWE ROUTING STRING
	JRST	PRS07			;KEEP GOING
					;
PRS08:	IDPB	S1,T3			;TERMINATE STRING
	SETZM	OBJSTR(P4)		;WE DON'T NEED IT
	RETSKP				;ALL DONE, RETURN + 1
;
;	HERE IF WE ARE THE LAST NODE IN THE ROUTING STRING,
;	EXTRACT OBJECT AND PUT IT INTO OBJECT STRING.
;	COPY RECEIVED ROUTING STRING INTO PMRSTR FOR X25 CONNECTIONS.
;
PRS09:	MOVE	S1,[POINT 7,PMRSTR(P4)]	;OUTPUT STRING
	MOVE	S2,P1			;AND OUR SAVED INPUT POINTER
	ILDB	T1,S2			;GET FLAG BYTE FROM INPUT
	ADDI	T1,1			;INCREMENT IT
	IDPB	T1,S1			;AND PUT IT IN
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;COPY THE REST
	IDPB	T2,S1			;AND TERMINATE STRING
					;
PRS10:	ILDB	S1,T4			;GET A BYTE
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIE	S1,42			;AND SEARCH FOR OBJECT
	JRST	PRS10			;KEEP GOING
					;
	MOVE	T3,[ POINT 7,OBJSTR(P4)];GET POINTER TO
PRS11:	ILDB	S1,T4			;GET A BYTE FROM
	JUMPE	S1, [ RET ]		;STOP ON ERROR
	CAIN	S1,"="			;FINAL TERMINATOR
	JRST	PRS12			;YES-DONE HERE
	IDPB	S1,T3			;NO-COPY IT OVER
	JRST	PRS11			;AND KEEP GOING
					;
PRS12:	SETZM	S1			;GET A TERMINATOR
	IDPB	S1,T3			;AND TERMINATE IT
	RETSKP				;ALL DONE, RETURN


	PAGE
;
;	DCNBLD	ROUTINE TO BUILD DCN:nodename-oject FROM ROUTING STRING
;		ROUTINE TO BUILD DCN:nodename-123   FROM ROUTING STRING
;
					;
DCNBLD:	SAVET				;GET SOME REGISTERS
	HRROI	S1,DCNSTR(P4)		;WHERE WE WANT TO CREATE DCN:
	HRROI	S2,[ASCIZ/DCN:/]	;THIS IS THE FIRST PART
	SETZB	T1,T2			;NORMAL TERMINATION
	SOUT				;PUT IT IN
	HRROI	S2,NODSTR(P4)		;GET POINTER TO NODE NAME
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;COPY IT IN
	MOVEI	T1,"-"			;DECNET NEEDS IT
	IDPB	T1,S1			;AT THE END OF THE NODE NAME
	SKIPE	OBJSTR(P4)		;BUILDING FIXED 123 OBJECT?
	JRST	DCN010			;NO-JUMP OVER
	HRROI	S2,[ASCIZ/123=/]	;YES-GET IT
	SETZB	T1,T2			;NORMAL TERMINATION
	SOUT				;AND PUT IT IN
	JRST	DCNBDT			;GO FINISH UP
					;
DCN010:	HRROI	S2,OBJSTR(P4)		;GET POINTER TO OBJECT
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;COPY IT IN
;
;	FINALY, SEE IF WE HAVE SOME ATTRIBUTES TO PUT IN
;	CREATE ;USER:<USRSTR>;PASSWORD:<PSWSTR>;CHARGE:<ACCSTR>
;
DCNBDT:	SKIPN	USRSTR(P4)		;WE HAVE ATTRIBUTES AT ALL?
	JRST	DCNBDN			;NO-TERMINATE STRING AND EXIT
					;
	HRROI	S2,[ASCIZ/;USER:/]	;YES-START WITH USER
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;AND PUT IT IN
	HRROI	S2,USRSTR(P4)		;POINT TO NAME
	SOUT				;AND PUT IT IN
					;
	SKIPN	PSWSTR(P4)		;WE GOT AN PASSWORD STRING?
	JRST	DCNBDN			;DONE IF NO MORE ARGS.
					;
	HRROI	S2,[ASCIZ/;PASSWORD:/]	;CREATE PASSWORD ENTRY
	SOUT				;
	HRROI	S2,PSWSTR(P4)		;YES-POINT TO PASSWORD
	SOUT				;AND PUT IT IN
					;
	SKIPN	ACCSTR(P4)		;IF WE DON'T HAVE PASSWORD MEANS
	JRST	DCNBDN			;WE HAVN'T GOT AN ACCOUNT
	HRROI	S2,[ASCIZ/;CHARGE:/]	;WE GOT AN ACCOUNT
	SOUT				;PUT IT IN
	HRROI	S2,ACCSTR(P4)		;GET IT
	SOUT				;AND PUT IT IN
					;
DCNBDN:	SETZM	T1			;GET A TERMINATOR
	IDPB	T1,S1			;AND TERMINATE IT
	RET				;ALL DONE, RETURN

	PAGE
	SUBTTL	XMRSRV	ROUTINE TO CREATE SRV: 123 SERVER
;
;
;	RETURN NON-SKIP IF FAILED
;
XMRSRV:	MOVE	S1,[ GJ%SHT ]		;SHORT FORM
	HRROI	S2,[ASCIZ/SRV:123/]	;SERVER
	GTJFN				;GET A JFN FOR
	ERROR	XMRSRX,<?XMR Failed creating JFN for SRV:123>
	MOVEM	S1,SRVJFN(P4)		;SAVE JFN WE GOT
	MOVE	S2,[ 100000,,300000]	;GET SOME BITS
	OPENF				;AND OPEN THE LINK
	ERRJMP	XMRSRX,<?XMR Failed opening SRV:123>
					;
	MOVEI	S2,.MOACN		;PUT LINK ON PSI
	MOVE	T1,[BYTE (9) CO%SRV,CO%SRV,CO%SRV,0]
	MTOPR				;
	ERRJMP	XMRSRX,<?XMR Failed putting SRV:123 on PSI>
					;
	MOVEI	S1,PS%VIR		;SET NEW PROTOCOL STATE TO
	MOVEM	S1,SRVPST(P4)		;"VIRGIN".
	RETSKP				;ALL DONE, RETURN

XMRSRX:	RET


	PAGE
	SUBTTL	PMROPN	OPEN PATH TO NEXT DESTIGNATION
;
;

OPNCOM:	MOVX 1,GJ%SHT
	MOVE 2,T1		;GET STRING POINTER
	GTJFN			;OPEN THE LINE
	 POPJ P,			;ERROR
	MOVEM 1,DCNJFN(P4)		;SAVE OTHER SIDE OF THE LINK
	MOVE 2,[100000,,300000]
	OPENF
	 ERJMP[	SETZM 1
		EXCH 1,DCNJFN(P4)
		RLJFN
		 JFCL
		POPJ P,]
	RETSKP			;DID IT


;
;	STRSIZ	ROUTINE TO FIND SIZE OF A STRING
;		ENTER WITH T1<== POINTER TO STRING
;		RETURN     S1 SIZE OF STRING IN BYTES
;
STRSIZ:	PUSH	P,T1			;SAVE THIS ONE
	SETZM	S1			;AND START COUNTING IN HERE
STRSZ1:	ILDB	S2,T1			;GET A BYTE
	SKIPE	S2			;STOP IF TERMINATOR
	AOJA	S1,STRSZ1		;ELSE KEEP LOOPING FOR
	POP	P,T1			;RESTORE REGISTER
	RET				;AND RETURN


	PAGE
;
;	CHKX25	ROUTINE TO DETERMINE WHAT KIND OF CONNACTION TO BE USED.
;		USE X25 IF NODE NAME KNOWN TO THE X25NM TABLE, ELSE USE
;		DECNET CONNECTION. ALSO SET UP NODE NAME NODNAM
;		AND X25CON TO BE -1 FOR A X25 CONNECTION.
;	ENTER WITH T1<== POINTING TO THE START OF THE NODE NAME IN
;		         THE ROUTING STRING.
;	RETURN NON-SKIP IF X25 NODE ELSE SKIP RETURN.
;
CHKX25:	SAVET				;GET SOME ACCUS
	SETZM	X25CON(P4)		;ASSUME DECNET LINK
	MOVEI	S1,X25TAB		;GET OUR KNOWN NODE TABLE
	HRROI	S2,NODSTR(P4)		;AND THE NODE NAME
	TBLUK				;AND FIND IT
	TXNN	S2,TL%EXM		;EXACT MATCH FOUND?
	RETSKP				;NO-MUST BE DECNET HOST
	SETOM	X25CON(P4)		;TELL EVERYBODY THIS IS A X25 CONNECTION
	HLRZ	T1,(S1)			;GET ADDRESS TO HOST STRING
	HLL	T1,[ POINT 7,0]		;AND MAKE A POINTER FROM
;
;	HERE START SEARCHING FOR THE TERMINATOR. THE DTE NUMBER
;	IS STORED IMEDIATELY BEHIND THE NODE NAME.
;
	ILDB	S1,T1			;GET A BYTE FROM
	JUMPN	S1,.-1			;KEEP SERCHING FOR THE END
					;
	MOVE	T2,[ POINT 7,X25DTE(P4)];AND WHERE TO STORE THE DTE NUMBER
	ILDB	S1,T1			;GET A BYTE FROM DTE NUMBER
	IDPB	S1,T2			;AND PUT IT INTO DTE NUMBER
	JUMPN	S1,.-2			;LOOP UNTIL TERMINATOR SEEN
					;
	IDPB	S1,T2			;TERMINATE IT PROP.
	RET				;RETURN X25 NODE


	PAGE
	SUBTTL	XMR	READ LINK STATUS ROUTINES
;
;
SRVRLS:	MOVE	S1,SRVJFN(P4)		;GET OUR JFN FOR SRV
	MOVEI	S2,.MORLS		;READ LINK STATUS
	MTOPR				;
	ERRJMP	SRVERT,<?SRVXMR Failed reading Link status for SRV:123>
	MOVEM	T1,SRVSTA(P4)		;AND SAVE LAST STATUS SEEN
	RET				;ALL DONE, RETURN STA IN T1
					;
DCNRLS:	MOVE	S1,DCNJFN(P4)		;GET JFN FOR
	MOVEI	S2,.MORLS		;AND READ LINK STATUS
	MTOPR				;
	ERRJMP	DCNERT,<?DCNXMR Failed reading DECnet DCN status>
	MOVEM	T1,DCNSTA(P4)		;AND SAVE LAST STATUS SEEN
	RET				;ALL DONE, RETURN STA. IN T1
					;
	PAGE
	SUBTTL	XMR	LOGGING ROUTINES
;
;	LOGTRC	TXTLIB OUTPUT ROUTINES FOR TRACE MESSAGES
;		THIS ROUTINE IS CALLED FROM TRACE ROUTINE
;		TO OUTPUT TRACE MESSAGES.
;	ENTER WITH CHARACTER IN S1
;
LOGTRC:	PBOUT				;YES-OUTPUT IT
	ERJMP	[ RET ]			;SHOULD NEVER HAPPEN
	MOVE	S2,S1			;GET BYTE OVER HERE
;	SKIPN	S1,LOGJFN		;WE HAVE TO DO LOGGING?
	RET				;NO-ALL DONE
	BOUT				;YES-SO DO IT
	ERJMP	[ RET ]			;
	RETT				;ALL DONE, RETURN
;
;	LOGMSG	LOG FILE MESSAGE OUTPUT ROUTINE.
;		THIS ROUTINE IS CALLED FROM TEXTLIB TO OUTPUT
;		ONE CHARACTER TO THE LOG-FILE.
;

LOGMSG:	SKIPE	S2,LOGTTY		;DOING LOG TO TTY?
	JRST	[ EXCH S1,S2		;YES-GET CHARACTER
		  BOUT			;SEND IT OUT
		  MOVE S1,S2		;GET IT BACK TO RIGHT PLACE
		  JRST	.+1 ]		;AND CONTINUE IN CODE
	SKIPN	LOGJFN			;WE ARE DOING LOGGING?
	RETT				;NO-JUST RETURN
	SOSGE	LOGCTR			;ROOM IN THE BUFFER?
	JRST	[ PUSHJ P,LOGDMP	;NO, DUMP THE BUFFER
		  JRST LOGMSG ]		;AND RETRY
	JUMPE	S1,[ RETT ]		;IF NULL CHARACTER, RETURN NOW
	IDPB	S1,LOGPTR		;DEPOSIT THE CHARACTER
	RETT				;ALWAYS RETURN TRUE

LOGDMP:	PUSH	P,S1			;SAVE CHARACTER
	PUSH	P,S2			;
	MOVEI	S1,0			;GET NULL CHARACTER
	IDPB	S1,LOGPTR		;STORE TERMINATING NULL INTO BUFFER
	MOVE	S1,[POINT 7,LOGBUF]	;GET BUFFER POINTER
	MOVEM	S1,LOGPTR		;STORE IT
	SKIPN	LOGBUF			;TOTAL BUFFER EMTY?
	JRST	LOGDM1			;YES-DON'T WRITE IT OUT
	PUSHJ	P,.LGOUT		;ELSE WRITE IT OUT
	SKIPT				;SUCCESS?
	SETZM	LOGJFN			;NO-TERMINATE LOGGING
LOGDM1:	SETZM	LOGBUF			;CLEAR FIRST WORD OF BUFFER
	MOVEI	S1,LOGMAX		;RESET THE BUFFER COUNTER
	MOVEM	S1,LOGCTR		;TO ITS MAXIMUM
	POP	P,S2			;UNSAVE
	POP	P,S1			;RESTORE THE CHARACTER
	RETT				;AND RETURN
;
;
;	ROUTINE TO OUTPUT LOG MESSAGE TO OUR LOG-FILE
;	OPEN/WRITE-APPEND/CLOSE LOG FILE
;
;		RETURNS FALSE IF OUTPUT FAILS.
;
.LGOUT:	SAVET				;SAVE THIS REGISTERS
	HRRZ	S1,LOGJFN		;GET OUR LOG-JFN
	MOVE	S2,[ 7B5+OF%APP ]	;APPEND MODE
	OPENF				;TRY TO GET TO
	RETF				;SAY LOGING FAILED
	HRROI	S2,LOGBUF		;GET STRING FOR OUTPUT
	SETZB	T1,T2			;TERMINATE NORMAL
	SOUT				;PUT IT IN THE ACCOUNT FILE
	ERJMP	[ RETF ]		;GIVE UP ON ERROR
	TXO	S1,CO%NRJ		;BUT DON'T GIVE UP JFN
	CLOSF				;CLOSE DOWN ACCOUNT FILE
	JFCL				;IGNORE ERROR
	RETT				;PASS ON ERROR


	PAGE
;
;	STROUT	ROUTINE CALLED FROM TEXTLIB TO OUTPUT INTO
;		A STRING POINTED TO BY STRPNT.
;		ENTER WITH STRPNT SET UP
;
STROUT:	EXCH	S2,STRPNT(P4)		;GET POINTER WHERE TO STORE
	IDPB	S1,S2			;THIS CAHARACTER
	EXCH	S2,STRPNT(P4)		;AND SAVE UPDATED POINTER
	RETT				;DONE, RETURN


	PAGE
	SUBTTL	PMRLIB	PMR SERVICE ROUTINES

;MACRO TO MAKE ENTRIES IN NSP ERROR TABLE

	MAXMSG==^D50		; Maximum number of NSP error messages

DEFINE NSPERR (CODE,TEXT,BASE<MSGTBL>),<
	.ORG BASE+CODE
	POINT 7,[ASCIZ\: TEXT\]
	.ORG
>
MSGTBL:				;DECNET ERROR TEXT TABLE

REPEAT MAXMSG,<POINT 7,[ASCIZ\: Undefined NSP error\]> ;MAKE TABLE SPACE
				; & UNDEFINED ENTRIES

	NSPERR (.DCX0,<No special error>)
	NSPERR (.DCX1,<Resource allocation failure>)
	NSPERR (.DCX2,<Destination node does not exist>)
	NSPERR (.DCX3,<Node shutting down>)
	NSPERR (.DCX4,<Destination NRT process does not exist>)
	NSPERR (.DCX5,<Invalid name field>)
	NSPERR (.DCX9,<NRT server aborted link>)
	NSPERR (.DCX11,<Undefined error>)
	NSPERR (.DCX21,<CI with illegal destination address>)
	NSPERR (.DCX24,<Flow control violation>)
	NSPERR (.DCX32,<Too many connections to node>)
	NSPERR (.DCX33,<Too many connections to destination NRT process>)
	NSPERR (.DCX34,<Access not permitted>)
	NSPERR (.DCX35,<Logical link services mismatch>)
	NSPERR (.DCX36,<Invalid account>)
	NSPERR (.DCX37,<Segment size too small>)
	NSPERR (.DCX38,<Process aborted>)
	NSPERR (.DCX39,<No path to destination node>)
	NSPERR (.DCX40,<Link aborted due to data loss>)
	NSPERR (.DCX41,<Destination logical link address does not exist>)
	NSPERR (.DCX42,<Confirmation of disconnect initiate>)
	NSPERR (.DCX43,<Image data field too long>)



	PAGE
	SUBTTL	X25INI	X25 INITIALIZATION CODE
;
;	X25TAB	SET UP DEFAULT HOSTS TABLE
;	READS IN SYSTEM:XMR.INI AND SET X25TAB TABLE FROM
;
X25INI:	MOVX S1,GJ%OLD!GJ%SHT		; Look for existing file
	HRROI S2,[ASCIZ /SYSTEM:XMR.INI/]
	GTJFN
	ERJMP	[ RET ]			;ERROR-GIVE UP
	MOVX S2,7B5+OF%RD
	OPENF				; open for read
	 ERJMP  [ RET ]			;ERROR, GIVE UP
	MOVEM	S1,XINJFN		;SAVE OUR JFN FOR INI FILE
	HRLM	S1,X2CBLK+.CMIOJ	;SAVE JFN FOR INPUT
	MOVE	T1,[ POINT 7,X25TBL]	;GET INITIAL POINTER TO NAME TABLE
	MOVEM	T1,X2TABL		;AND INIT. IT
	MOVEI	T1,777			;LENGHT OF HOST-TAB TABLE
	MOVEM	T1,X25TAB		;AND SET IT IN HOST TABLE
	MOVEM	T1,X25DTB		;ALSO INIT DTE-TABLE
	SETZM	X25GEF			;TURN OFF GLOBAL ENABLE FLAG
					;
X25INR:	MOVEI	S1,X2CBLK		;GET INITIALIZATION CMDBLK
	MOVEI	S2,[FLDDB. .CMINI]	;INITIALIZATION FUNCTION
	COMND				;GO DO IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RET				;JUST GIVE UP HERE
	MOVEM	P,XMRSVP		;SAVE STACK FOR REPARSING
					;
X25INL:	SETZM	0			;START OFF WITH OK
	MOVE	P,XMRSVP		;RESTORE THE STACK
	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[FLDDB. (.CMKEY,,X2CTAB)]	;POINT TO COMMAND TABLE
	COMND				;PARSE IT
	ERJMP	X25INE			;MAY BE EOF ON INPUT TOO
	TXNE	S1,CM%NOP		;SUCESS?
	JRST	X25INX			;NO-COMPLAIN
	MOVE	S2,0(S2)		;GET ADDRESS OF ROUTINE
	CALL	0(S2)			;CALL IT
	SKIPF				;ERROR SEEN?
	JRST	X25INR			;NO-GET A NEW COMMAND
					;YES-FALL INTO ERROR CODE
	PAGE
;
;	HERE ON ILLEGAL COMMAND, ABORT IT
;
X25INX:	$TEXT	(,<?XMRINI Failed parsing >)
	MOVE	S1,X2CBLK+.CMBFP	;GET POINTER TO COMMAND
	MOVE	S2,S1			;SET FOR OUTPUT TOO
	MOVEI	T1,CMDLEN		;MAX COMMAND SIZE
	MOVEI	T2,15			;AND STOP ON <CR>
	SOUT				;FIND END OF STRING
	ERJMP	[ RETF ]		;ABORT IF ERROR
	BKJFN				;ABCK UP OVER TERMINATOR
	SETZM	S2			;GET ANOTHER TERMINATOR
	IDPB	S2,S1			;AND REPLACE OLD ONE WITH
	MOVE	S1,X2CBLK+.CMBFP	;GET BACK OUR POINTER
	PSOUT				;AND OUTPUT ERROR COMMAND
	HRROI	S1,[ASCIZ/
/]
	PSOUT				;GET TO NEXT LINE
	JRST	X25INR			;AND RESTART COMMAND
;
;	HERE ON ERROR FROM COMND, CHECK FOR EOF ON INPUT
;
X25INE:	MOVE	S1,XINJFN			;GET OUR JFN FOR
	GTSTS				; See if eof or null
	TXNN S2,GS%EOF
	RET				;GIVE UP HERE
	CLOSF				; EOF - close file
	 JFCL
X25EXT:	RETSKP				; Return


;
;	INITIALIZATION COMMAND TABLE
;
X2CTAB:	X2CMAX,,X2CMAX			;HEADER
	AA	ACCESS-SERVER,X2CACS	;ACCESS-SERVER
	AA	DEFINE,X2CDEF		;DEFINE COMMAND
	AA	ENABLE-ACCESS,X2CEAC	;ENABLE ACCESS COMMAND
	AA	ENABLE-GLOBAL,X2CEGA	;ENABLE GLOBAL ACCESS
	AA	LOG,X2CLOG		;LOG-FILE COMMAND
	AA	NETWORK,X2CNET		;NETWORK
	AA	PASSWORD,X2CPSW		;PASSWORD
	X2CMAX==.-X2CTAB-1

	PAGE
;
;	INITIALIZATION COMMAND EXECUTION
;
;	EXECUTE NETWORK COMMAND,SET NETWORK NAME HERE FROM XMR.INI FILE
;
X2CNET:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB. (.CMFLD)]	;AND FUNCTION
	COMND				;DO IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;NO-SAY ERROR
	MOVE	S1,[ POINT 7,X25NAM(P4) ]	;GET WHERE TO STORE IT
	MOVE	S2,X2CBLK+.CMABP	;AND ATM. BUFFER PNTR.
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,X25NMZ		;OR ON MAX. PSW SIZE.
	SOUT				;COPY NAME STRING
	RETT				;ALL DONE RETURN

	PAGE
;
;	HERE FOR PASSWORD COMMAND, SET NETWORK ACCESS PASSWORD FROM XMR.INI.
;
X2CPSW:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB. (.CMFLD)]	;AND FUNCTION
	COMND				;DO IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;NO-SAY ERROR
	MOVE	S1,[ POINT 7,X25PSW(P4) ]	;GET WHERE TO STORE IT
	MOVE	S2,X2CBLK+.CMABP	;AND ATM. BUFFER PNTR.
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,X25PSZ		;OR ON MAX. PSW SIZE.
	SOUT				;COPY NAME STRING
	RETT				;ALL DONE RETURN

	PAGE
;
;	HERE FOR LOG COMMAND,OPEN LOG FILE
;
X2CLOG:	MOVEI	S1,X2CBLK		;COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMFIL)]	;FILE NAME
	COMND				;PARSE IT
	TXNE	S1,CM%NOP		;SUCESS?
	RETF				;NO-COMPLAIN ABOUT
	HRROI	S1,LOGFNM		;WHERE TO STORE THE NAME
	MOVE	T1,[ JS%DEV!JS%DIR!JS%NAM!JS%TYP!JS%PAF ]
	JFNS				;GET FILENAME FOR
	ERJMP	[ RET ]
	MOVEM	S2,LOGJFN		;AND SAVE LOGJFN
	RETT				;ALL DONE, RETURN

	PAGE
;
;	HERE FOR DEFINE COMMAND, ADD HOST NAME TO X25TAB.
;	THE NAME STRING IS STORED IN THE STRING SPACE POINTED TO BY
;	X2TABL AS FOLLOWING:
;	....ASCII HOST NAME<0>ASCII DTE NUMBER<0>.....
;
X2CDEF:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB. (.CMFLD)]	;AND FUNCTION
	COMND				;DO IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;NO-COMPLAIN ABOUT
	MOVE	S1,X2TABL		;GET CURRENT POINTER WE'R ON
	MOVE	S2,X2CBLK+.CMABP	;AND WHERE THE NAME IS STORED
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,^D 20		;AND MAX SIZE OF NAME
	SOUT				;COPY IT INTO NAME STING AREA
	MOVE	T2,S1			;SAVE END OF STRING
	SETZM	S1			;GET TERMINATOR
	IDPB	S1,T2			;AND PUT IT IN
	MOVEI	S1,X25TAB		;GET START OF HOST-TAB
	HRLZ	S2,X2TABL		;AND BEGINNING OF THIS NAME
	TBADD				;ADD IT TO HOST TABLE
	ERJMP	[ RET ]			;GIVE UP
					;
	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMFLD)]	;AND FUNCTION
	COMND				;PARSE DTE NUMBER FIELD
	TXNE	S1,CM%NOP		;SUCESS?
	RETF				;NO-COMPLAIN ABOUT
	MOVE	S1,T2			;WHERE TO STORE THE OUTPUT
	MOVE	S2,X2CBLK+.CMABP	;AND WHERE THE DTE NUMBER IS STORED
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,^D 20		;AND MAX SIZE OF
	SOUT				;COPY THE DTE NUMBER STRING
	IDPB	T1,S1			;TERMINATE WITH ZERO
	AOS	S1			;MOVE UP TO NEXT WORD
	HLL	S1,[ POINT 7,0 ]	;AND CREATE A NEW POINTER
	MOVEM	S1,X2TABL		;AND SAVE IT FOR NEXT NAME
	RETT				;ALL DONE, RETURN
;
	PAGE
;
;	HERE TO PROCESS THE ENABLE-ACCESS COMMAND.
;	GENERAL FORMAT:
;	ENABLE-ACCESS ALL (DTE'S) OBJECT ALL
;	ENABLE-ACCESS DTE-NUMBER  OBJECT ALL
;	ENABLE-ACCESS DTE-NUMBER  OBJECT 27,,,,,,,,,,30
;
X2CEAC:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMFLD)]	;AND FUNCTION
	COMND				;PARSE IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;NO-COMPLAIN ABOUT
					;
	MOVE	S1,X2TABL		;GET CURRENT POINTER WE'R ON
	MOVE	T4,S1			;AND GET COPY IN HERE
	MOVE	S2,X2CBLK+.CMABP	;AND WHERE THE NAME IS STORED
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,^D 20		;AND MAX SIZE OF DTE-NUMBER
	SOUT				;COPY IT INTO NAME STING AREA
	IDPB	T1,S1			;TERMINATE IT
	MOVE	T4,S1			;GET UPDATED STRING POINTER
					;
	MOVEI	S1,X25DTB		;GET START OF DTE-TABLE
	HRLZ	S2,X2TABL		;AND BEGINNING OF THIS DTE-NUMBER
	TBADD				;ADD IT TO DTE-TABLE
	ERJMP	[ RETF ]			;GIVE UP
;
;	HERE START PARSING OBJECTS
;
X2CEAO:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMTOK,,<POINT 7,[ASCIZ/OBJECT/]>)]
	COMND				;PARSE DTE NUMBER FIELD
	TXNE	S1,CM%NOP		;SUCESS?
	JRST	[ TXNE	S1,CM%EOC	;E-O-L?
		  JRST	X2CEA1		;YES-ENABLE FOR ALL OBJECTS
		  RETF	]		;ELSE RETURN ERROR
	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMTOK,,<POINT 7,[ASCIZ/ALL/]>)]
	COMND				;AND PARSE IT
	TXNN	S1,CM%NOP		;SUCCESS?
X2CEA1:	JRST	[ MOVE	S1,T4		;GET SAVED STRING POINTER
		  HRROI	S2,[ASCIZ/-1/]	;AND ALL OBJECT ENABLED CODE
		  SETZM	T1		;TERMINATE NORMAL
		  SOUT			;PUT IT IN
		  IDPB	T1,S1		;TERMINATE IT
		  MOVE	T4,S1		;GET UPDATED POINTER
		  JRST	X2CEAX	]	;AND GO FINISH UP
					;
X2CEAL:	MOVEI	S1,X2CBLK		;POINT TO COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMNUM,,^D8)]
	COMND				;PARSE OBJECT CODE
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;COMPLAIN ABOUT
					;
	MOVE	S1,T4			;GET OUR SAVED STRING POINTER
	MOVEI	T1,^D8			;SAY OCTAL CONVERSION
	NOUT				;CONVERT OJCET NUMBER WE GOT
	JFCL				;SHOULD NEVER HAPPEN
	SETZM	T1			;GET A ZERO
	IDPB	T1,S1			;AND TERMINATE STRING
	MOVE	T4,S1			;UPDATE STRING POINTER
					;
	MOVEI	S1,X2CBLK		;EATE ","
	MOVEI	S2,[ FLDDB.(.CMCMA)]	;WITH THIS FUNCTION
	COMND				;PARSE IT
	TXNN	S1,CM%NOP		;SUCCESS
	JRST	X2CEAL			;YES- PARSE NEXT OBJECT
	TXNN	S1,CM%EOC		;E-O-L?
	RETF				;NO-COMPLAIN ABOUT
;
;	HERE IF WE FOUND CM%EOC, LINE TERMINATED,
;	TERMINATE STRING WITH AN EXTRA <0>
;
X2CEAX:	SETZM	T1			;GET A ZERO
	IDPB	T1,T4			;TERMINATE WITH ZERO
	AOS	T4			;MOVE UP TO NEXT WORD
	HLL	T4,[ POINT 7,0 ]	;AND CREATE A NEW POINTER
	MOVEM	T4,X2TABL		;AND SAVE IT FOR NEXT NAME
	RETT				;ALL DONE, RETURN
;
	PAGE
;
;	HERE TO PROCESS ENABLE-GLOBAL-ACCESS COMMAND
;
;
X2CEGA:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMTOK,,<POINT 7,[ASCIZ/ALL/]>)]
	COMND				;PARSE IT
	TXNN	S1,CM%NOP		;SUCCESS?
	JRST	[ SETOM	X25GEF		;SAY GLOBAL OBJECTS ENABLED
		  MOVE	S1,[POINT 7,X25GEO ]
		  HRROI	S2,[ASCIZ/-1/]	;AND ALL OBJECT ENABLED CODE
		  SETZM	T1		;TERMINATE NORMAL
		  SOUT			;PUT IT IN
		  IDPB	T1,S1		;TERMINATE IT
		  MOVE	T4,S1		;GET UPDATED POINTER
		  JRST	X2CEGX	]	;AND GO FINISH UP
					;
	SETOM	X25GEF			;ENABLE GLOBAL OBJECTS
	MOVE	S1,[POINT 7,X25GEO ]	;WHERE TO STORE GLOBAL OBJECTS
	MOVE	T4,S1			;AND GET COPY IN HERE
;
;	HERE START PARSING OBJECTS
;
X2CGEL:	MOVEI	S1,X2CBLK		;POINT TO COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB.(.CMNUM,,^D8)]
	COMND				;PARSE OBJECT CODE
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;COMPLAIN ABOUT
					;
	MOVE	S1,T4			;GET OUR SAVED STRING POINTER
	MOVEI	T1,^D8			;SAY OCTAL CONVERSION
	NOUT				;CONVERT OJCET NUMBER WE GOT
	JFCL				;SHOULD NEVER HAPPEN
	SETZM	T1			;GET A ZERO
	IDPB	T1,S1			;AND TERMINATE STRING
	MOVE	T4,S1			;UPDATE STRING POINTER
					;
	MOVEI	S1,X2CBLK		;EATE ","
	MOVEI	S2,[ FLDDB.(.CMCMA)]	;WITH THIS FUNCTION
	COMND				;PARSE IT
	TXNN	S1,CM%NOP		;SUCCESS
	JRST	X2CGEL			;YES- PARSE NEXT OBJECT
	TXNN	S1,CM%EOC		;E-O-L?
	RETF				;NO-COMPLAIN ABOUT
;
;	HERE IF WE FOUND CM%EOC, LINE TERMINATED,
;	TERMINATE STRING WITH AN EXTRA <0>
;
X2CEGX:	SETZM	T1			;GET A ZERO
	IDPB	T1,T4			;TERMINATE WITH ZERO
	RETT				;ALL DONE, RETURN
;
	PAGE
	SUBTTL	HERE ON ACCESS-SERVER COMMAND
;
;	CREATE ACCESS SERVER AND SET UP X%WIC ON
;	NOTE: THAT P4 HERE IS POINTING TO THE OUTGOING DATA BASE
;
X2CACS:	MOVEI	S1,X2CBLK		;GET COMMAND STATE BLOCK
	MOVEI	S2,[ FLDDB. (.CMTXT)]	;AND FUNCTION
	COMND				;DO IT
	TXNE	S1,CM%NOP		;SUCCESS?
	RETF				;NO-SAY ERROR
	PUSH	P,P4			;SAVE DB-POINTER
	MOVEI	P4,XMLDB		;AND SET TEMP. FOR INCOMMING
	MOVE	S1,[ POINT 7,X25SVJ(P4)];GET WHERE TO STORE IT
	MOVE	S2,X2CBLK+.CMABP	;AND ATM. BUFFER PNTR.
	SETZM	T1			;TERMINATE ON ZERO
	MOVEI	T2,X25SVZ		;OR ON MAX. PSW SIZE.
	SOUT				;COPY NAME STRING
	POP	P,P4			;RESTORE DB-POINTER
	RETT				;ALL DONE RETURN

	PAGE
	SUBTTL	X25OPN	OPEN NETWORK AND INITIATE SWITCHED CIRCUIT
;
;	OPEN NETWORK AND INITIATE SWITCHED CIRCUIT
;
X25OPN:	SAVET				;GET SOME REGISTERS
	SETZM	X25PST(P4)		;MUST BE IDLE HERE
					;
	HRLZI	T1,CO%X25		;INTERRUPT CHANNEL
	HRRI	T1,X25PBK(P4)		;AND THE PORT-BLOCK
	MOVEM	T1,X25GDB(P3)		;SET IT UP
	SETZM	X25GDB+1(P3)		;INIT THIS
	MOVE	T1,[ POINT 7,X25NAM(P4)];GET NETWORK NAME
	MOVEM	T1,X25GDB+2(P3)		;NAME OF NETWORK
	SKIPN	X25PSW(P4)		;PASSWORD SPECIFIED?
	JRST	[ SETZM	X25GDB+3(P3)	;TRY WITH NO PASSWORD
		  JRST .+3 ]		;AND SKIP OVER
	MOVE	T1,[POINT 7,X25PSW(P4) ];
	MOVEM	T1,X25GDB+3(P3)		;PASSWORD
	MOVE	T1,[ POINT 7,X25DTE(P4) ];GET DTE NUMBER TO CALL
	MOVEM	T1,X25GDB+4(P3)		;DTE CALL NUMBER
	SKIPN	X25SUB(P4)		;SUB-DTE NUMBER GIVEN
	JRST	[ SETZM	T1		;NO-TRY WITHOUT IT
		  JRST .+2 ]		;SKIP OVER
	MOVE	T1,[POINT 7,X25SUB(P4) ]
	MOVEM	T1,X25GDB+5(P3)		;DTE-SUB-NUMBER
	SETZM	X25GDB+6(P3)		;USER GROUP NAME
	SETZM	X25GDB+7(P3)		;FACILITIES
	HRROI	S2,[ASCIZ/XMR/]		;POINT TO OUR CALL DATA
	MOVE	S1,[ POINT 8,X25UDB(P4)]; AND WHERE TO PUT IT
	SETZM	T1			;TERM. NORMAL
	SOUT				;AND COPY IT IN
	SETZM	X25UDB+1(P4)		;CLEARE OUT REST OF BUFFER
	SETZM	X25UDB+2(P4)		;
	SETZM	X25UDB+3(P4)		;
	HRLZI	T1,X25USZ		;SIZE OF BUFFER
	HRRI	T1,X25UDB(P4)		;AND ITS ADDRESS
	MOVEM	T1,X25GDB+10(P3)	;SET IT UP
					;
	MOVEI	S1,PS%VIR		;GET NEW PORT STATE
	MOVEM	S1,X25PST(P4)		;SET AS VIRGIN NOW
					;
	MOVEI	S1,X25GDB(P3)		;SET UP BLOCK
	CALL	X%ISC##			;AND DO IT
	HRRZ	T1,X25GDB(P3)		;GET PORT NUMBER
	MOVEM	T1,X25PRT(P4)		;AND SAVE IT
	MOVE	T1,X25GDB+1(P3)		;GET RETURN CODE
	CAIN	T1,XC%SUC		;SUCCESS
	RETT				;ALL DONE HERE
	SETZM	X25PST(P4)		;NO-RESET TO IDEL
	RETF				;AND FAILED RETURN

	PAGE
	SUBTTL	X25SRV	OPEN SERVER FOR INCOMMING CALLS
;
;
X25SRV:	SAVET				;GET SOME REGISTERS
	SETZM	X25PST(P4)		;MUST BE IDLE HERE
					;
	HRLI	T1,CI%X25		;GET INTERRUPT CHANNEL
	HRRI	T1,X25PBK(P4)		;AND PORT DATA BLOCK
	MOVEM	T1,X25GDB(P3)		;AND PUT IT IN ARG. BLK.
	SETZM	X25GDB+1(P3)		;NO RETURN CODE YET
	MOVE	T1,[ POINT 7,X25SVJ(P4)];AND POINTER TO SERVER
	MOVEM	T1,X25GDB+2(P3)		;PUT IT IN
	MOVEI	S1,X25GDB(P3)		;GET ARG. BLK ADDRESS
	CALL	X%WIC##			;SET UP WAIT FOR INC. CALL
	MOVE	T1,X25GDB(P3)		;GET PORT NUMBER WE GOT
	MOVEM	T1,X25PRT(P4)		;AND SAVE IT AWAY
	MOVE	S1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	S1,XC%SUC		;SUCCESS?
	RETF				;NO-FAIL
	RETT				;OK-RETURN


	PAGE
	SUBTTL	X25TPA	TERMINATE PORT ACCESS ROUTINE
;
;	TERMINATE PORT ACCESS ROUTINE
;
X25TPA:	SAVET				;GET SOME REGISTERS
	MOVE	S1,X25PRT(P4)			;GET OUR PORT IN USE
	MOVEM	S1,X25GDB(P3)		;SET IT UP
	SETZM	X25GDB+1(P3)		;CLEARE RET. STATUS
	MOVEI	S1,X25GDB(P3)		;GET BLOCK ADDRESS
	CALL	X%TPA##			;AND CLEARE THE PORT
	MOVE	S1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	S1,XC%SUC		;SUCCESS
	RETF				;NO-FAILED
	RETT				;ALL DONE

	PAGE
;
;	SEND INTERRUPT MESSAGE ROUTINE
;	NOT USED YET
;
X25SIM:	SAVET				;SAVE REGISTERS
	MOVE	T1,X25PRT(P4)		;GET PORT WE ARE ON
	MOVEM	T1,X25GDB+0(P3)		;AND SET IT
	SETZM	X25GDB+1(P3)		;NO RETURN CODE YET
	SETZM	T1,X25GDB+2(P3)		;ZERO INTR. DATA BYTE
	MOVEI	S1,X25GDB(P3)		;GET OUR ARG. BLOCK
	CALL	X%SIM##			;SEND IT OF
	HRRZ	T1,X25GDB+1(P3)		;GET RETURN CODE
	CAIN	T1,XC%SUC		;SUCCESS?
	RETT				;YES-ALL DONE
	RETF				;AND ERROR RETURN

;
;	X25RIM	ROUTINE TO READ/ACK INTERRUPT MESSAGE
;		NOTE USED YET
;		RETURN S1 INTERRUPT DATA BYTE.
;
X25RIM:	SAVET				;GET SOME REGISTERS
	MOVE	T1,X25PRT(P4)		;GET PORT WE ARE ON
	MOVEM	T1,X25GDB+0(P3)		;AND SET IT
	SETZM	X25GDB+1(P3)		;NO RETURN CODE YET
	SETZM	T1,X25GDB+2(P3)		;AND NO DATA YET
	MOVEI	S1,X25GDB(P3)		;GET OUR ARG. BLOCK
	CALL	X%RIM##			;SEND IT OF
	MOVE	T1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	T1,XC%SUC		;SUCCESS?
	RETF				;NO-FAILED
	MOVE	T4,X25GDB+2(P3)		;GET INT.DATA
	SETZM	X25GDB+1(P3)		;NO RET. CODE YET
	MOVEI	S1,X25GDB(P3)		;AND POINT TO GDB
	CALL	X%CIM##			;AND CONFIRM INTR. MESSAGE
	MOVE	T1,X25GDB+1(P3)		;GET RETURN STATUS
	CAIE	T1,XC%SUC		;SUCESS?
	RETF				;NO-FAILED
	MOVE	S1,T4			;RETURN INT. DATA HERE
	RETT				;YES-RETURN


	PAGE
;
;	X25SND	ROUTINE TO SENT OUT A DATA BUFFER OVER THE
;	NETWORK
;	ENTER	T1<== BYTE POINTER TO DATA BUFFER
;		T2<== NUMBER OF DATA BYTES IN BUFFER
;	RETURNS S1    UPDATED BYTE POINTER
;
X25SND:	MOVEM	T1,X25GDB+3(P3)		;SET BUFFER ADDRESS
	MOVEM	T2,X25GDB+2(P3)		;SET #OF BYTES TO SEND
	MOVE	T1,X25PRT(P4)		;GET OUR PORT #
	MOVEM	T1,X25GDB(P3)		;AND SET IT
	SETZM	X25GDB+1(P3)		;NO R CODE YET
	MOVEI	S1,X25GDB(P3)		;GET OUR DATA BLOCK
	CALL	X%SDM##			;SEND IT OFF
	MOVE	S1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	S1,XC%SUC		;SUCCESS
	RETF				;NO-TELL CALLER ABOUT
	AOS	X2ATPC(P4)		;COUNT FOR THIS PACKET
	ADDM	T2,X2ATBC(P4)		;AND THIS NUMBER OF BYTES
	MOVE	S1,X25GDB+3(P3)		;GET UPDATED POINTER
	RETT				;ALL DONE,RETURN

	PAGE
	SUBTTL	X25RDM	ROUTINE TO READ DATA FROM NETWORK
;
;	ENTER:	T1  POINTER TO BUFFER TO BE USED
;	RETURNS:  S1  M,Q,,NUMBER OF BYTES RECEIVED
;		  S2  UPDATED STRING POINTER TO X25BFR
;
X25RDM:	SAVET				;GET SOME REGISTERS
	MOVEM	T1,X25GDB+3(P3)		;SET UP BUFFER PNTR.
	MOVEI	T1,X25BFZ		;GET OUR BUFFER SIZE
	MOVEM	T1,X25GDB+2(P3)		;AND PUT IT IN
	MOVE	T1,X25PRT(P4)		;GET PORT WE'RE ON
	MOVEM	T1,X25GDB(P3)		;AND PUT IT IN
	SETZM	T1,X25GDB+1(P3)		;AND NO RETURN CODE YET
	MOVEI	S1,X25GDB(P3)		;GET ADDRESS OG ARGUMENT BLOCK
	CALL	X%RDM##			;AND GET THE DATA
	MOVE	T1,X25GDB+2(P3)		;GET FLAGS,,SIZE
	TLZ	T1,177777		;CLEARE UNUSED BITS
	HRRZ	S1,X25GDB+1(P3)		;GET STATUS RETURNED
	TXZE	S1,XS%NDA		;IGNORE THIS, NOT REALY AN ERROR
	TXO	T1,XC%NMD		;AND FLAG NO MORE DATA
	CAIE	S1,XC%SUC		;SUCCESS
	RETF				;NO-RETURN ERROR
	MOVE	S1,T1			;GET FLAGS,,SIZE
	MOVE	S2,X25GDB+3(P3)		;AND UPDATED STRING POINTER
	AOS	X2ARPC(P4)		;COUNT FOR THIS PACKET
	HRRZ	T1,S1			;GET PACKET SIZE
	ADDM	T1,X2ARBC(P4)		;AND COUNT FOR IT
	RETT				;ALL DONE, RETURN

	PAGE
;
;	ROUTINE CHECK NEW PORT STATUS
;	READS STATUS AS RETURNED BT X%RPS AND SETS UP
;	X25PSC ( PORT STATUS CODE ) FROM.
;
X25STA:	SAVEP				;SAVE THIS REGISTERS
	MOVE	P1,X25PRT(P4)		;GET OUR PORT
	MOVEM	P1,X25GDB(P3)		;SET IT UP
	SETZM	X25GDB+1(P3)		;NO CODE YET
	MOVEI	S1,X25GDB(P3)		;GET OUR ARG-BLK
	CALL	X%RPS##			;GO GET STATUS
	HRRZ	P1,X25GDB+1(P3)		;GET RET. CODE
	CAIE	P1,XC%SUC		;DONE WITH
	RETF				;NO-ERROR
	DMOVE	P1,X25GDB+2(P3)		;GET PORT STATUS
	DMOVEM	P1,X25PSC(P4)		;AND SAVE IT
	RETT				;ALL DONE, RETURN


	PAGE
	SUBTTL	X25RCD	ROUTINE TO READ CLEAR CAUSE DATA
;
;	NOTE:	BEFORE CALLING THIS ROUTINE,THE PORT STATE MUST BE CLARED
;
;		RETURNS:  S1 PPSN CLR.DATA,,REMOTE CODE CLR. DATA
;			  S2   SIZE,,UPDATED POINTER TO USER DATA
;
X25RCD:	SAVET				;GET SOME REGISTERS
	MOVE	T1,X25PRT(P4)		;GET PORT WE'RE ON
	MOVEM	T1,X25GDB(P3)		;AND SET IT UP
	SETZM	X25GDB+1(P3)		;AND NO RETURN CODE YET
	SETZM	X25GDB+2(P3)		;
	HRLZI	T1,X25FAZ		;FACILITIES BUFFER SIZE
	HRRI	T1,X25FAC(P4)		;AND BUFFER ADDRESS
	MOVEM	T1,X25GDB+3(P3)		;AND PUT IT IN
	HRLZI	T1,X25BFZ		;DATA BUFFER SIZE
	HRRI	T1,X25BFR(P4)		;AND NORMAL RECEIVER BUFFER
	MOVEM	T1,X25GDB+4(P3)		;PUT IT IN
					;
	MOVEI	S1,X25GDB(P3)		;GET ARG. BLOCK ADDRESS
	CALL	X%RCD##			;AND READ IN CLEARE DATA
					;
	HRRZ	S1,X25GDB+1(P3)		;GET RETURN CODE
	TXZ	S1,XS%NDA		;NOT REALY AN ERROR
	CAIE	S1,XC%SUC		;SUCCESS?
	RETF				;NO-FAILED
	MOVE	S1,X25GDB+2(P3)		;GET CLEAR CAUSE DATA
	MOVEM	S1,X25CCC(P4)		;AND ALSO SAVE IT HERE
	MOVE	S2,X25GDB+4(P3)		;AND DATA BUFFER ADDRESS
	RETT				;RETURN TO CALLER

	PAGE
	SUBTTL	X25RIC	ROUTINE TO READ INCOMING CALL DATA
;
;
;
;	HERE IF WE RECEIVED A NEW CALL, READ CALL DATA
;
X25RIC:	SAVET				;GET SOME REGISTERS
	MOVE	T1,X25PRT(P4)		;GET PORT NUMBER
	MOVEM	T1,X25GDB(P3)		;AND SET IT IN
	SETZM	X25GDB+1(P3)		;AND NO RET. CODE YET
	MOVE	T1,[POINT 7,X25NAM(P4)]	;GET OUR NETWORK NAME
	MOVEM	T1,X25GDB+2(P3)		;AND SET IT UP
	MOVE	T1,[POINT 7,X25DTE(P4)]	;WHERE STO STORE DTE NUMBER
	MOVEM	T1,X25GDB+3(P3)		;AND PUT IT IN
	MOVE	T1,[POINT 7,X25SUB(P4)]	;AN WHERE TO STORE SUB-DTE
	MOVEM	T1,X25GDB+4(P3)		;PUT IT IN
	MOVE	T1,[POINT 7,X25CUG(P4)]	;AND WHERE TO STORE USER GROUP
	MOVEM	T1,X25GDB+5(P3)
	HRLI	T1,X25FAZ		;SIZE OF FACILITY BUFFER
	HRRI	T1,X25FAC(P4)		;AND BUFFER FOR
	MOVEM	T1,X25GDB+6(P3)		;AND PUT IT IN
	HRLI	T1,X25USZ		;SIZE OF BUFFER
	HRRI	T1,X25UDB(P4)		;AND WHERE TO STORE USER DATA
	MOVEM	T1,X25GDB+7(P3)		;AND SET IT UP
	MOVEI	S1,X25GDB(P3)		;GET ARG. BLOCK ADDRESS
	CALL	X%RIC##			;AND READ THIS DATA
	MOVE	S1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	S1,XC%SUC		;SUCCESS?
	RETF				;FAILED
	RETT				;ALL OK, RETURN



	PAGE
	SUBTTL	X25AIC	ROUTINE TO ACCEPT AN INCOMMING CALL
;
;
X25AIC:	SAVET				;GET SOME REGISTERS
	MOVE	T1,X25PRT(P4)		;GET PORT NUMBER
	MOVEM	T1,X25GDB(P3)		;AND PUT IT IN
	SETZM	X25GDB+1(P3)		;NO RETURN CODE YET
	SETZM	X25GDB+2(P3)		;NO USER GROUP NAME
	SETZM	X25GDB+3(P3)		;AND NO FACILITIES
	SETZM	X25GDB+4(P3)		;AND NO USER DATA
	MOVEI	S1,X25GDB(P3)		;GET ARG. BLOCK ADDRESS
	CALL	X%AIC##			;AND ACCEPT THIS CALL
	MOVE	T1,X25GDB+1(P3)		;GET RETURN CODE
	CAIE	T1,XC%SUC		;SUCCESSFULL
	RETF				;NO-FAILED
	RETT				;YES-RETURN

	PAGE
	SUBTTL	X25CSC	CLEARE SWITCHED CIRCUIT
;
;	THIS ROUTINE IS CALLED TO CLEARE SWITCHED CIRCUIT
;	AND RETURN THE CURRENT CONTENS OF X25UDB ( USER DATA BUFFER)
;
;	ENTER WITH  T1<== USER DIAG CODE
;
X25CSC:	MOVEM	T1,X25GDB+2(P3)		;SET DIAG. CODE
	MOVE	T1,X25PRT(P4)		;GET PORT NUMBER
	MOVEM	T1,X25GDB+0(P3)		;AND SET IT
	SETZM	X25GDB+1(P3)		;NO RETURN CODE YET
	SETZM	X25GDB+3(P3)		;HAVE NO FACILITIES
	HRLZI	T1,X25USZ		;GET USER BUFFER SIZE
	HRRI	T1,X25UDB(P4)		;AND USER DATA BUFFER
	MOVEM	T1,X25GDB+4(P3)		;SET IT UP
	MOVEI	S1,X25GDB(P3)		;GET GDB ADDRESS
	CALL	X%CSC##			;AND GO DO THE WORK
	MOVE	S1,X25GDB(P3)		;GET RETURN CODE
	CAIE	S1,XC%SUC		;SUCCESS?
	RETF				;NO-FAILED
	RETT				;YES-RETURN



	PAGE
	SUBTTL	X25ACC	ROUTINE TO CHECK ACCESS TO OUR DTE
;
;	THIS ROUTINE IS USED TO CHECK IF A CALLING DTE IS
;	ALLOWED TO GET ACCESS TO THE SYSTEM.
;	FIRST LOOKUP THE DTE NUMBER IN THE KNOWN DTE'S TABLE AND RETURN
;	SKIP IF IT IS AN KNOWN DTE, ELSE SEE IF THERE ARE GLOBAL ENABLED
;	OBJECTS. IF YES, ALLWAYS RETURN SKIP ELSE RETURN +1 SAYING
;	ACCESS NOT ALLOWED.
;	THIS ROUTINE ALSO SETS UP X25SOP WHO WILL BE USED IN THE FINAL
;	OBJECT CHECK.
;
X25ACD:	SAVET				;GET SOME REGISTERS
	HRROI	S2,X25DTE(P4)		;POINT TO DTE-NUMBER
	MOVEI	S1,X25DTB		;AND POINT TO KNOWN DTE'S TABLE
	TBLUK				;GO FIND IT
	ERJMP	[ RETF ]		;IF FAILED GIVE UP
	TXNN	S2,TL%EXM		;EXACT MATCH FOUND?
	JRST	[ SKIPN	X25GEF		;UNKNOWN DTE, SEE IF GLOBAL ENABLED
		  RETT			;NO-TOO BAD, ACCESS NOT ALLOWED
		  MOVE	S1,[POINT 7,X25GEO ];POINT TO GLOBAL ENABLED OBJECTS
		  MOVEM	S1,X25SOP(P4)	;SAVE IT TEMP. HERE
		  RETSKP ]		;AND RETURN ALLOWING ACCESS
	HLRZ	T1,(S1)			;POINT TO DTE-NUMBER STRING
	HLL	T1,[POINT 7,0]		;AND MAKE A POINTER FROM
;
;	HERE IF WE HAVE A KNOWN DTE, FIND END OF THE DTE STRING AND
;	RETURN POINTER TO OBJECT STRING FOR THIS DTE.
;
	ILDB	S1,T1			;GET A BYTE
	JUMPN	S1,.-1			;LOOP OVER DTE NAME
					;
	MOVEM	T1,X25SOP(P4)		;AND SAVE IT TEMP. HERE
	RETSKP				;AND RETURN ACCESS ALLOWED


	PAGE
;
;	ROUTINE TO CHECK IF A INCOMMING DTE IS ALLOWED TO ACCESS
;	A SPECIFIED DECNET OBJECT.
;	ASSUMES X25ACD HAS PREVIOUS BEEN CALLED.
;
X25ACO:	HRROI	S1,OBJSTR(P4)		;POINT TO REQUESTED OBJECT
	MOVEI	T1,^D 8			;AND CONVERT TO AN OCTAL NUMBER
	NIN				;
	RET				;IF FAILED GIVE UP HERE
	MOVE	T3,S2			;GET VALUE ON A SAVE PLACE
	MOVE	S1,X25SOP(P4)		;GET OUR SAVED OBJECT POINTER
					;
X25ACL:	CALL	GETOBJ			;GET NEXT OBJECT FROM OBJ-STRING
	RET				;SAY NOT ALLOWED IF NO MORE OBJ.
	SKIPGE	S2			;GLOBALY ALLOWED?
	RETSKP				;YES-RETURN OK THEN
	CAME	T3,S2			;MATCH FOUND ON?
	JRST	X25ACL			;NOT YET, TRY ONCE MORE
	RETSKP				;YES-RETURN OK.
;
;	GETOBJ	WORKER ROUTINE FOR X25ACO
;
GETOBJ:	MOVE	S2,S1			;GET POINTER TO OBJECT
	ILDB	S2,S2			;FETCH NEXT BYTE
	SKIPN	S2			;TERMINATOR?
	RET				;YES-SAY NO MORE OBJECTS
	MOVEI	T1,^D 8			;SAY OCTAL CONVERSION
	NIN				;AND CONVERT THIS OBJECT
	RET				;DONE IF FAILED
	RETSKP				;AND RETURN OBJECT IN S2

	PAGE
;
;	ROUTINE TO SET POINTER TO ERROR EXPLANATION FOR 
;	X25 GATEWAY ACCESS ROUTINE RETURN CODES
;	RETURN  T1  POINTER TO ERROR MESSAGE
;
X25EPR:	PUSH	P,T2			;GET SOME REGISTERS
	MOVE	T1,X25GDB+1(P3)		;GET ERROR CODE RETURNED
	JFFO	T1,.+1			;CONVERT ERROR CODE
	SUBI	T2,^D18			;
	MOVE	T1,X25ETB(T2)		;GET ADDRESS OF
	SKIPL	T1			;FOUND ERROR CODE?
	HRROI	T1,[ASCIZ/%No Error explanation available for this error code
/]
	POP	P,T2			;UNSAVE
	RET
;
;
;
X25ETB:	-1,,[ASCIZ/%Successful
/]
	-1,,[ASCIZ/%PSI Gateway software are not compatible,Version skrew
/]
	-1,,[ASCIZ/%Buffer too short
/]
	-1,,[ASCIZ/%Buffer too long
/]
	-1,,[ASCIZ/%Source DTE Subaddress too long
/]
	-1,,[ASCIZ/%Destignation DTE address to loong
/]
	-1,,[ASCIZ/%No interrupt confirmation required
/]
	-1,,[ASCIZ/%Awaiting interrupt confirmation
/]
	-1,,[ASCIZ/%No DTE address specified, or no destignation
/]
	-1,,[ASCIZ/%No Password or Password not valied
/]
	-1,,[ASCIZ/%Data-field truncation,field was to loong
/]
	-1,,[ASCIZ/%Facilities data field truncated
/]
	-1,,[ASCIZ/%Unknown Network name specified
/]
	-1,,[ASCIZ/%No interrupt to read
/]
	-1,,[ASCIZ/%No data to read
/]
	-1,,[ASCIZ/%X25 Port failed, procedure error
/]
	-1,,[ASCIZ/%No more circuit available
/]
	-1,,[ASCIZ/%Insufficient gateway recources
/]

	PAGE
;
;	PORT STATE TRANSLATION TABLE
;
X25STT:	-1,,[ASCIZ/Undefined/]
	-1,,[ASCIZ/Opening/]
	-1,,[ASCIZ/Calling/]
	-1,,[ASCIZ/Listening/]
	-1,,[ASCIZ/Called/]
	-1,,[ASCIZ/Running/]
	-1,,[ASCIZ/Synchronizing/]
	-1,,[ASCIZ/Unsynchronized/]
	-1,,[ASCIZ/Clearing/]
	-1,,[ASCIZ/Cleared/]
	-1,,[ASCIZ/Error/]
	-1,,[ASCIZ/No communication/]

	PAGE
	SUBTTL	COMMAND PARSING SUBROUTINES
;
;
;	CMDNOS - ROUTINE TO HANDLE GUIDEWORD STRINGS.
;	  S2/	ADDRESS OF ASCIZ GUIDEWORD STRING
;		CALL	CMDNOS	OR USE NOISE MACRO
;	RETURNS  +1:	ALWAYS


CMDNOS:	HRROM	S2,NOIBLK+.CMDAT	;SAVE AS DATA
	MOVEI	S2,NOIBLK		;POINT TO BLOCK
	MOVEI	S1,XMRBLK		;AND COMMAND STATE BLOCK
	COMND				;PARSE THE FUNCTION
	TXNN	S1,CM%NOP+CM%EOC	;DID IT PARSE?
	RETT				;YES, RETURN SUCCESSFULLY
	RETF				;NO, COMPLAIN
;
;
;	CMDCNF - ROUTINE TO HANDLE LINE CONFIRMATION FUNCTION.
;		CALL	CMDCNF	OR USE CONFRM MACRO
;	RETURNS  +1:	ALWAYS
;
;
;
CMDCNF:	MOVEI	S2,[FLDDB. (.CMCFM)]	;GET CONFIRM FUNCTION
	MOVEI	S1,XMRBLK	;POINT TO OUR (ONLY) COMMAND BLOCK
	COMND			;PARSE THE FUNCTION
	TXNN	S1,CM%NOP	;DID IT PARSE?
	RETT			;YES, RETURN SUCCESSFULLY
	RETF			;NO, COMPLAIN

	PAGE
	SUBTTL	REGISTER SAVE/UNSAVE ROUTINES
;
;
;	SAVE PERMANENT REGISTER
;	CALLED JSP CX,.SAVEP
;
	DEFINE	SAVEP<
	XLIST
	JSP	CX,.SAVEP
	LIST
>
;
.SAVEP:	ADJSP	P,4			;MAKE SPACE ON STACK
	DMOVEM	P1,-3(P)		;SAVE P1,P2
	DMOVEM	P3,-1(P)		;SAVE P2,P3
	PUSHJ	P,(CX)			;CALL BACK CALLER
	SKIPA				;NORMAL RETURN
	AOS	-4(P)			;MAKE SKIP RETURN
	DMOVE	P3,-1(P)		;GET BACK SAVED REGISTER
	DMOVE	P1,-3(P)
	ADJSP	P,-4			;CLEAN UP STACK
	POPJ	P,			;AND DO THE RETURN
;
;	SAVE TEMP REGISTER
;	CALLED JSP CX,.SAVET
;
	DEFINE	SAVET<
	XLIST
	JSP	CX,.SAVET
	LIST
>
;
.SAVET:	ADJSP	P,4			;MAKE SPACE ON STACK
	DMOVEM	T1,-3(P)		;SAVE T1,T2
	DMOVEM	T3,-1(P)		;SAVE T2,T3
	PUSHJ	P,(CX)			;CALL BACK CALLER
	SKIPA				;NORMAL RETURN
	AOS	-4(P)			;MAKE SKIP RETURN
	DMOVE	T3,-1(P)		;GET BACK SAVED REGISTER
	DMOVE	T1,-3(P)
	ADJSP	P,-4			;CLEAN UP STACK
	POPJ	P,			;AND DO THE RETURN

	PAGE
	SUBTTL	INTXXX	INTERRUPT INITIALIZATION AND CONTROL ROUTINES
;
;	INITIALIZE INTERRUPT SYSTEM
;
INTON:	MOVE	S1,[ .FHSLF ]		;OUR PROCESS
	MOVE	S2,[ LEVTAB,,CHNTAB ]	;INT-TABLES
	SIR				;SET SOFT. TABLE INT. ADDR.
	MOVE	S2,[ CO.X25!CI.X25!CI.DCN!CO.SRV!CO.DCN ]
	MOVEM	S2,INTMSK		;SET UP MASK FOR INTOFF
	AIC				;ACTIVATE IT
	EIR				;AND ENABLE SYSTEM
	RET				;ALL DONE
;
;	TURN OFF INTERRUPTS,CLEARE PENDING INTERRUPTS AND CLEARE
;	DEACTIVATE ALL OPENED CHANNELS.
;
INTOFF:	MOVE	S1,[ .FHSLF ]		;OUR PROCESS
	DIR				;TURN INT. SYSTEM OFF
	CIS				;CLEARE PENDING INTS.
	MOVE	S2,INTMSK		;GET ENABLED CHANNELS
	DIC				;AND TUN HIM OFF TOO
	RET				;ALL DONE

;
;	ROUTINE TO TEMP. TURN ON/OFF INTERRUPT SYSTEM
;
	DEFINE PION<
	XLIST
	PUSHJ	P,.PION
	LIST
>
.PION:	PUSH	P,S1
	MOVE	S1,[ .FHSLF ]		;OUR FORK
	EIR
	POP	P,S1
	POPJ	P,

	DEFINE PIOFF<
	XLIST
	PUSHJ	P,.PIOFF
	LIST
>
.PIOFF:	PUSH	P,S1
	MOVE	S1,[ .FHSLF ]		;OUR FORK
	DIR
	POP	P,S1
	POPJ	P,

RSKP:	AOS	(P)
	RET
;
;	ROUTINES TO ACTIVATE AND DEACTIVATE TEMPORARLY INTERRUPT CHANNELS
;
.CHON:	MOVE	S1,[ .FHSLF ]		;SAY OUR FORK
	AIC				;TURN ON CHANNEL
	RET				;DONE, RETURN

.CHOFF:	MOVE	S1,[ .FHSLF ]		;SAY OUR FORK
	DIC				;AND TURN OFF CHANNEL
	RET				;DONE, RETURN


	PAGE
	SUBTTL	INTXXX	INTERRUPT SAVEAC,DEBREAK AND WAIT CODE
;
;	INTERRUPT AC SAVE ROUNTINE
;
;	ASSUMES INRRUPT AT PRIORITY 1
;	CALLED BY SAVCH1
;
	DEFINE	SAVCH1 <
	XLIST
	JSR	SAVCH1
	LIST
>
SAVCH1:	Z				;SAVE RET PC HERE
	EXCH	17,SACCH1+17		;SAVE THIS ONE AWAY
	MOVEI	17,SACCH1		;AND WHERE TO STORE IT
	BLT	17,SACCH1+16		;SAVE THE REST OF
	MOVE	P,[ IOWD PDLSZ,PDLCH1]	;SET UP INTERRUPT PDL
	MOVE	CX,SAVCH1		;GET REURN ADDRESS
	PUSHJ	P,(CX)			;AND CALL BACK CALLER
	JFCL				;IN CASE OF SKIP RETURN
	MOVSI	17,SACCH1		;FROM WHERE TO LOAD REGISTERS
	BLT	17,17			;RESTORE THEM ALL
;
;	INTERRUPT DISMISS CODE
;	ASSUMES PRIORITY LEVEL 1 INTERRUPT
;
	AOS	INTCNT			;SHOW WE GOT AN INTERRUPT
	PUSH	P,S1			;GET A REGISTER
	HRRZ	S1,PC1			;GET INTERRUPT PC
	MOVE	S1,-1(S1)		;GET INTERRUPTED INSTRUCTION
	CAME	S1,[ WAIT ]		;WAS IT A WAIT INSTRUCTION?
	JRST	$DEBR0			;NO-JUST RETURN
	MOVE	S1,[ 1B5 ]		;GET USER MODE
	IORM	S1,PC1			;AND TURN IT ON
$DEBR0:	POP	P,S1			;UNSAVE REGISTER
	DEBRK				;AND DISMISS

	PAGE
;
;	INTERRUPT AC SAVE ROUNTINE
;
;	ASSUMES INRRUPT AT PRIORITY 2
;	CALLED BY SAVCH2
;
	DEFINE	SAVCH2 <
	XLIST
	JSR	SAVCH2
	LIST
>
SAVCH2:	Z				;SAVE RET PC HERE
	EXCH	17,SACCH2+17		;SAVE THIS ONE AWAY
	MOVEI	17,SACCH2		;AND WHERE TO STORE IT
	BLT	17,SACCH2+16		;SAVE THE REST OF
	MOVE	P,[ IOWD PDLSZ,PDLCH2]	;SET UP INTERRUPT PDL
	MOVE	CX,SAVCH2		;GET REURN ADDRESS
	PUSHJ	P,(CX)			;AND CALL BACK CALLER
	JFCL				;IN CASE OF SKIP RETURN
	MOVSI	17,SACCH2		;FROM WHERE TO LOAD REGISTERS
	BLT	17,17			;RESTORE THEM ALL
;
;	INTERRUPT DISMISS CODE
;	ASSUMES PRIORITY LEVEL 1 INTERRUPT
;
	AOS	INTCNT			;SHOW WE GOT AN INTERRUPT
	PUSH	P,S1			;GET A REGISTER
	HRRZ	S1,PC2			;GET INTERRUPT PC
	MOVE	S1,-1(S1)		;GET INTERRUPTED INSTRUCTION
	CAME	S1,[ WAIT ]		;WAS IT A WAIT INSTRUCTION?
	JRST	.+3			;NO-JUST RETURN
	MOVE	S1,[ 1B5 ]		;GET USER MODE
	IORM	S1,PC2			;AND TURN IT ON
					;
	POP	P,S1			;UNSAVE REGISTER
	DEBRK				;AND DISMISS

..PAT:	BLOCK	^D 100			;PATCH SPACE


	PAGE
	SUBTTL	INTDAT	INTERRUPT LEVTAB,,CHNTAB AND DATA
;
INTCNT:	Z				;COUNT INTERRUPTS DURING WAIT
INTMSK:	Z				;STORE INTERRUPT CHANNEL MASK HERE
LEVTAB:	PC1				;WHERE TO SAVE PC
	PC2
	PC3
;
PC1:	Z				;SAVE PC FOR CHANNEL ONE HERE
PC2:	Z
PC3:	Z
;
	DEFINE CHN (X,Y,ZA) <
	XLIST
	ZZZ=X-ZZ
	REPEAT ZZZ , < 0
>
	ZZ=X+1
	IFN Y, < Y,,ZA
>
	LIST
>
	ZZ==0
CHNTAB:
	CHN	(CO%X25,1,X2OINT)
	CHN	(CI%X25,1,X2IINT)
	CHN	(CI%DCN,2,X2IDCI)
	CHN	(CO%SRV,2,SRVINT)
	CHN	(CO%DCN,2,DCNINT)
	CHN	(^D35)

	PAGE
	SUBTTL	DATA STORAGE

;
;
;	DATA STORAGE MACRO
;
	DEFINE SS,(XX,YY)<
	XLIST
	BLOCK	YY
	XX=ZZ
	ZZ==ZZ+YY
	LIST
	>
;
;	GENERAL STORAGE
;
DEBUG:	0				;DEBUG MODE FLAG IF -1
MAXRTY:	^D 10				;MAXIMUM NUMBER OF RETRYS
	PDLSZ=^D200
PDL:	BLOCK	PDLSZ
SACCH1:	BLOCK	20			;SAVE REG. AT CH1 INTERRUPT HERE
PDLCH1:	BLOCK	PDLSZ			;CHANNEL 1 PDL
SACCH2:	BLOCK	20			;SAVE REG. AT CH1 INTERRUPT HERE
PDLCH2:	BLOCK	PDLSZ			;CHANNEL 2 PDL
;
;	XMR COMMAND STATE BLOCK
;
XMRBLK:	0,,XMRCML			;ADDRESS OF REPARSE ROUTINE
	.PRIIN,,.PRIOU			;INPUT,,OUTPUT JFNS
	-1,,[ASCIZ/XMR>/]		;CONTROL-R POINTER
	-1,,CMDBUF			;POINTER TO TEXT BUFFER
	-1,,CMDBUF			;POINTER TO CURRENT POSITION
	CMDLEN				;NUMBER OF CHARS IN BUFFER
	0				;NUMBER OF UNPARSED CHARACTERS
	-1,,CMDATM			;POINTER TO ATOM BUFFER
	CMDLEN				;NUMBER OF CHARACTERS IN BUFFER
	EXP	CMDJFN			;POINTER TO GTJFN BLOCK

NOIBLK:	FLDDB.	(.CMNOI)		;BLOCK FOR NOISE FUNCTION
;
;	X25INI COMMAND STATE BLOCK
;
X2CBLK:	0,,X25INL			;ADDRESS OF REPARSE ROUTINE
	Z				;INPUT,,OUTPUT JFNS
	-1,,CMDBUF			;CONTROL-R POINTER
	-1,,CMDBUF			;POINTER TO TEXT BUFFER
	-1,,CMDBUF			;POINTER TO CURRENT POSITION
	CMDLEN				;NUMBER OF CHARS IN BUFFER
	0				;NUMBER OF UNPARSED CHARACTERS
	-1,,CMDATM			;POINTER TO ATOM BUFFER
	CMDLEN				;NUMBER OF CHARACTERS IN BUFFER
	EXP	CMDJFN			;POINTER TO GTJFN BLOCK
CMDJFN:	BLOCK	20			;SPACE FOT COMMAND JFN BLOCK
					;
XMRSVP:	BLOCK	1			;TEMP STORAGE FOR STACK PNTR.
	CMDLEN==200			;MAX SIZE OF COMMAND LINE
CMDBUF:	BLOCK	CMDLEN/5+1		;BUFFER FOR COMMAND JSYS
CMDATM:	BLOCK	CMDLEN/5+1		;BUFFER FOR ATOM BUFFER
XINJFN:	Z				;JFN FOR X25-DEFAULTS FILE
;
X25GEF:	Z				;ALL DTE NUMBERS ENABLED FLAG
X25GEO:	BLOCK	^D20			;SPACE FOR GLOBAL ENABLED OBJECTS
X2TABL:	Z				;POINTER TO STRING SPACE
X25TAB:	BLOCK	512			;STRING SPACE
X25TBL:	BLOCK	512			;NODE NAME LOOKUP TABLE
X25DTB:	BLOCK	512			;DTE NUMBER LOOKUP TABLE
;
;
;	 LOGGING DATA STORAGE
;
LOGFNM:	BLOCK	10			;LOG-FILE NAME
LOGTTY:	.PRIOU				;0 IF LOGIN ON TTY DISABLED
LOGJFN:	Z				;LOG-FILE JFN
LOGCTR:	Z				;LOG-BUFFER COUNT
LOGPTR:	Z				;LOG-BUFFER POINTER
	LOGMAX==^D 200			;LOG-BUFFER SIZE
LOGBUF:	BLOCK	LOGMAX/5+1		;LOG-BUFFER
;
;	ROUTER (DRIVER) DATA BASE
;
	ZZ==0
XMRDB:	SS	SRVJFN,1			;DECNET SERVER JFN
	SS	SRVSTA,1			;LAST MTOPR STATUS ON SRV:
	SS	SRVPST,1			;SRV PROTOCOL STATE
	SS	DCNJFN,1			;DECNET DCN: JFN
	SS	DCNSTA,1			;LAST STATUS ON DCN:
	SS	DCNPST,1			;DCN PROTOCOL STATE
	SS	FORK,1				;FORK NUMBER
	SS	RTRFLG,1			;MULTI ROUTING FLAG
	SS	STRPNT,1			;TEMP. FOR TEXLIB POINTER
	SS	DCNSTR,^D 10			;SPACE FOR DCN:......
	SS	NODSTR,^D 10			;SPACE FOR NODE NAME
	SS	PMRSTR,^D 10			;PMR STRING STORAGE
	SS	USRSTR,^D 10			;DECNET USER ID
	SS	ACCSTR,^D 10			;DECNET CHARAGE
	SS	PSWSTR,^D 10			;DECNET PASSWORD
	SS	OBJSTR,^D 10			;OBJECT STRING
	SS	X25RTY,1			;ERROR RETRY COUNT
	SS	X25SOP,1			;LOC. TEMP STORAGE
	X25NMZ==64
	SS	X25NAM,X25NMZ/5+1		;SPACE TO STORE NETWORK NAME
	X25PSZ==64
	SS	X25PSW,X25PSZ/5+1		;SPACE TO STORE NETWORK PASW.
	X25DTZ==^D 20			;MAX SIZE OF DTE NUMBER
	SS	X25DTE,X25DTZ/5+1		;SPACE FOR DTE NUMBER
	SS	X25SUB,5			;DTE SUB-NUMBER
	X25CUZ== ^D16
	SS	X25CUG,X25CUZ/4+1		;CLOSED USER GROUP NAME BUFFER
	X25FAZ== ^D 16
	SS	X25FAC,X25FAZ/4+1		;FACILITIES BUFFER
	X25USZ==^D 16
	SS	X25UDB,X25USZ/4+1		;CALL DATA FIELD (63 BYTE MAX)
	PCKSZ==^D 128				;PACKET SIZE USED
	SS	X25PBK,^D 155+PCKSZ		;PORT DATA BUFER
	X25GDZ==^D 10				;SIZE OF GDB
	SS	X25GDB,X25GDZ			;ARGUMENT BLOCK FOR X25GAL
	SS	X25GDX,X25GDZ			;ALTERNATE GDB FOR LEVEL 1 INTR.
	SS	X25PRT,1			;PORT NUMBER IS SAVED HERE
	SS	X25PST,1			;PORT PROTOCOL STATE CODE
	SS	X25PSC,2			;SAVE STATUS RETURNED FROM X%RPS
	SS	X25CON,1			;FLAG X25 CONNECTION IF NOT 0
	SS	X25CCC,1			;PORT CLEARE CAUSE CODE
	SS	X25BFP,1			;RECEIVER BUFFER POINTER
	SS	X25TBP,1			;TRANSMITTER BUFFER POINTER
	SS	X25TBC,1			;TRANSMITTER BYTE COUNT
	SS	X25RBC,1			;RECEIVER BYTE COUNT
	SS	X2ARBC,1			;X25 RECEIVER BYTE COUNT
	SS	X2ARPC,1			;X25 RECEIVER PACKET COUNT
	SS	X2ATBC,1			;X25 TRANSMITTER BYTE COUNT
	SS	X2ATPC,1			;X25 TRANSMITTER PACKET COUNT
	X25SVZ== ^D 20
	SS	X25SVJ,X25SVZ/5+1		;SPACE FOR SERVER NAME
	SINRMX==3000*4				;MAX SIZE OF BUFFER
	SS	SRVBUF,^D 3000			;SRV: DATA BUFFER
	SS	DCNBUF,^D 3000			;DCN: DATA BUFFER
	X25BFZ== ^D 128
	SS	X25BFR,X25BFZ/4+1		;DATA BUFFER FOR NETWORK
	SS	X25BFT,X25BFZ/4+1		;DATA BUFFER FOR NETWORK

	SIZE==ZZ
;
;	ROUTER (SERVER) DATA BASE
;
XMLDB:	BLOCK	SIZE				;DATA BLOCK INCOMMING


	END	XMR