Google
 

Trailing-Edge - PDP-10 Archives - AP-D471B-SB_1978 - mcsopr.bli
There are no other files named mcsopr.bli in the archive.
!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
MODULE OPR(RESERVE(#11, #12, #13, #14), SREG = #17, FREG = #16,
 DREGS = 4, VREG = #15, MLIST, TIMER = EXTERNAL(SIX12), FSAVE ) = 
    BEGIN
	REQUIRE	 DATA.BLI;		! EVERYONE NEEDS THIS

	EXTERNAL
		CHKSRCTAB,
		CHKLFTAB,
		XTRIM,
		XDITEIT,
		XDOEO,
		XDOEOSRC,
		XDOEOLF,

		DPORT,
		DPORTS,
		DTERM,
		DTERMS,
		DNODE,
		DNODES,
		DNET,
		DNETS,

		QHASH,
		FINDPORT,

		BUILD,
		CHAIN,
		NEXTINTSN,
		INLOGMSG,
		DCHNKS,
		INSERT,
		LINK,
		UNLINK,
		INCREMENT,

		WAITCANCEL,
		PURGEO,
		KILGROUP;
COMMENT;

! MCSOPR.BLI
! ====== ===

! ROUTINE OPRTSEND
! ======= ========

! THIS ROUTINE PROCESS THE OPERATOR SENDS TO TERMINALS

GLOBAL ROUTINE OPRTSEND( TERMBLKPTR, CHUNKPTR ) =
    BEGIN

	REGISTER
		SRCPTR,
		UDX;

	MAP	FORMAT SRCPTR;

	IF .TERMBLKPTR EQL 0 THEN			! DO ALL TERMINALS?
	    BEGIN					! YES
		SRCPTR _ .SRCTAB + 1;			! THEN START AT THE BEGINNING OF THE SRC TABLE
		WHILE .SRCPTR[ S0IDW ] NEQ 0 DO		! AND UNTIL THE END DO
		    BEGIN
			IF (UDX _ .SRCPTR[ S0PORTPTR ]) NEQ 0 THEN	!IF CONNECTED
			 OUTMSG(.CHUNKPTR,.UDX,TRUE,FALSE);		!OUTPUT IT
			SRCPTR _ .SRCPTR + .S0SIZE			!STEP TO NEXT TERMINAL
		    END

	    END
	    ELSE
		IF ( SRCPTR _ CHKSRCTAB( .TERMBLKPTR ) ) EQL 0 THEN RETURN 1	! NOT ALL SO GET POINTER
										! TO THE RECIPIENT OF THIS MESSAGE
										! IF BAD LEAVE NOW
			ELSE IF (UDX _ .SRCPTR[ S0PORTPTR ]) EQL 0 THEN RETURN 2 ELSE
			 OUTMSG(.CHUNKPTR,.UDX,TRUE,FALSE); !OUTPUT IT

	0						! GOOD RETURN

    END;
COMMENT;

! ROUTINE OPRDI
! ======= =====

! THIS ROUTINE PERFORMS THE OPERATORS REQUEST TO DISABLE INPUT

GLOBAL ROUTINE OPRDI( ARGBLK ) =
    BEGIN

	REGISTER NODEPTR;
	MAP	FORMAT NODEPTR;

	IF .ARGBLK EQL 0 THEN			! DISABLE ALL?
	    BEGIN				! YES THEN
		NODEPTR _ ( TREE + 2 )<0,0>;	! GET THE FIRST NODE OF THE TREE
		DO TRIM( .NODEPTR ) WHILE ( NODEPTR _ .NODEPTR[ N0SAMND ] ) NEQ 0
	    END
	    ELSE				! NOT ALL SO
		IF ( NODEPTR _ QHASH( .ARGBLK ) ) EQL 0 THEN RETURN FALSE	! IF NODE BAD RETURN FALSE
		    ELSE TRIM( .NODEPTR );	! OTHERWISE TRIM IT
	TRUE
    END;
COMMENT;

! ROUTINE OPREI
! ======= =====

! THIS ROUTINE PERFORMS THE OPERATORS REQUEST TO ENABLE INPUT

GLOBAL ROUTINE OPREI( ARGBLK ) =
    BEGIN

	REGISTER NODEPTR;
	MAP	FORMAT NODEPTR;

	IF .ARGBLK EQL 0 THEN			! ENABLE ALL?
	    BEGIN				! YES THEN
		NODEPTR _ ( TREE + 2 )<0,0>;	! GET THE FIRST NODE OF THE TREE
		DO UNTRIM( .NODEPTR ) WHILE ( NODEPTR _ .NODEPTR[ N0SAMND ] ) NEQ 0
	    END
	    ELSE				! NOT ALL SO
		IF ( NODEPTR _ QHASH( .ARGBLK ) ) EQL 0 THEN RETURN FALSE	! IF NODE BAD RETURN FALSE
		    ELSE UNTRIM( .NODEPTR );	! OTHERWISE UNTRIM IT
	TRUE
    END;
COMMENT;

! ROUTINE OPRDIT
! ======= ======

! THIS ROUTINE PERFORMS THE OPERATOR'S DISABLE INPUT TERMINAL COMMAND

GLOBAL ROUTINE OPRDIT( TERMBLKPTR, NODEBLKPTR ) =
    BEGIN

	IF .TERMBLKPTR EQL 0 THEN RETURN 1;		! IF NO TERMINAL GIVEN RETURN ERROR 1

	SELECT XDITEIT( .TERMBLKPTR, .NODEBLKPTR, 1 %DISABLE% ) OF NSET
			! DISABLE THE TERMINAL AND CHECK WHAT XDITEIT RETURNS
		STSGOOD:	RETURN 0;	! EVERYTHING OK
		STSILLQNAME:	RETURN 2;	! BAD NODE SPECIFIED
		STSUNKDST:	RETURN 1;	! BAD TERMINAL GIVEN
		STSSRCNOTASS:	RETURN  3;	!SOURCE NOT ASSOC.WITH TERM
		OTHERWISE:	INFORM( PAZ 'FXDITEIT RETURNED UNKNOWN VALUE IN OPRDIT@',0,0,0,0,0);
						! SOMEONE BLEW IT
	    TESN

    END;
COMMENT;

! ROUTINE OPREIT
! ======= ======

! THIS ROUTINE PERFORMS THE OPERATOR'S ENABLE INPUT TERMINAL COMMAND

GLOBAL ROUTINE OPREIT( TERMBLKPTR, NODEBLKPTR ) =
    BEGIN

	IF .TERMBLKPTR EQL 0 THEN RETURN 1;		! IF NO TERMINAL GIVEN RETURN ERROR 1

	SELECT XDITEIT( .TERMBLKPTR, .NODEBLKPTR, 0 %ENABLE% ) OF NSET
			! ENABLE THE TERMINAL AND CHECK WHAT XDITEIT RETURNS
		STSGOOD:	RETURN 0;	! EVERYTHING OK
		STSILLQNAME:	RETURN 2;	! BAD NODE SPECIFIED
		STSUNKDST:	RETURN 1;	! BAD TERMINAL GIVEN
		STSSRCNOTASS:	RETURN 3;	!SOURCE NOT ASSOC. WITH TERM
		OTHERWISE:	INFORM( PAZ 'FXDITEIT RETURNED UNKNOWN VALUE IN OPREIT@',0,0,0,0,0);
						! SOMEONE BLEW IT
	    TESN

    END;
FORWARD	DOEOALLTERM, DOEOALLLEAF;

COMMENT;

! ROUTINE OPRDO
! ======= =====

! THIS ROUTINE PERFORMS THE OPERATORS REQUEST TO DISABLE OUTPUT

GLOBAL ROUTINE OPRDO( TERMARGBLK, TYPEFLAG ) =
    BEGIN

	IF .TERMARGBLK EQL 0 THEN			! DISABLE ALL?
	    BEGIN
		SELECT .TYPEFLAG OF NSET		! YES THEN DEPENDING UPON TYPEFLAG
			0:	DOEOALLTERM( 1 %DISABLE% );	! DISABLE ALL TERMINAL DESTINATIONS
			1:	DOEOALLLEAF( 1 %DISABLE% );	! DISABLE ALL LEAF TYPE DESTINATIONS
			2:	( DOEOALLTERM( 1 ); DOEOALLLEAF( 1 ) );	! DISABLE ALL DESTINATIONS
			OTHERWISE:	RETURN INFORM( PAZ 'FBAD TYPE GIVEN TO OPRDO ROUTINE@',0,0,0,0,0);
								! SOMEONE BLEW IT
		    TESN;
		TRUE						! RETURN GOODNESS
	    END
	    ELSE
		XDOEO( .TERMARGBLK, 1 %DISABLE% )		! NOT ALL SO DISABLE ONE

    END;
COMMENT;

! ROUTINE OPREO
! ======= =====

! THIS ROUTINE PERFORMS THE OPERATORS REQUEST TO ENABLE OUTPUT

GLOBAL ROUTINE OPREO( TERMARGBLK, TYPEFLAG ) =
    BEGIN

	IF .TERMARGBLK EQL 0 THEN			! ENABLE ALL?
	    BEGIN
		SELECT .TYPEFLAG OF NSET		! YES THEN DEPENDING UPON TYPEFLAG
			0:	DOEOALLTERM( 0 %ENABLE% );	! ENABLE ALL TERMINAL DESTINATIONS
			1:	DOEOALLLEAF( 0 %ENABLE% );	! ENABLE ALL LEAF TYPE DESTINATIONS
			2:	( DOEOALLTERM( 0 ); DOEOALLLEAF( 0 ) );	! ENABLE ALL DESTINATIONS
			OTHERWISE:	RETURN INFORM( PAZ 'FBAD TYPE GIVEN TO OPREO ROUTINE@',0,0,0,0,0);
								! SOMEONE BLEW IT
		    TESN;
		TRUE						! RETURN GOODNESS
	    END
	    ELSE
		XDOEO( .TERMARGBLK, 0 %ENABLE% )		! NOT ALL SO ENABLE ONE

    END;
COMMENT;

! ROUTINE DOEOALLLEAF
! ======= ===========

! THIS ROUTINE DISABLES OR ENABLES FOR OUTPUT ALL LEAF TYPE DESTINATIONS

GLOBAL ROUTINE DOEOALLLEAF( FCN ) =
    BEGIN
	REGISTER
		I;

	MAP	FORMAT LFTAB;

	I _ 1;					! START WITH 1
	WHILE .LFTAB[L0DSTW(.I)] NEQ 0 DO	! UNTIL WE RUN OUT OF LFTAB ENTRIES
	    BEGIN
		XDOEOLF( .I, .FCN);		! DISABLE OR ENABLE IT
		I _ .I + L0SIZE			! THEN TRY ANOTHER
	    END
    END;
COMMENT;

! ROUTINE DOEOALLTERM
! ======= ===========

! THIS ROUTINE DISABLES OR ENABLES FOR OUTPUT ALL TERMINAL TYPE DESTINATIONS

ROUTINE DOEOALLTERM( FCN ) =
    BEGIN

	REGISTER SRCPTR;
	MAP	FORMAT SRCPTR;

	SRCPTR _ .SRCTAB + 1;			! START AT THE BEGINNING OF THE SRC TABLE
	WHILE .SRCPTR[ S0IDW ] NEQ 0 DO		! AND UNTIL THE END DO
	    BEGIN
		XDOEOSRC( .SRCPTR, .FCN );	! DISABLE OR ENALE THE TERMINAL
		SRCPTR _ .SRCPTR + .S0SIZE	! GET NEXT IN TABLE
	    END

    END;
COMMENT;

! ROUTINE OPRCHK
! ======= ======
!  THIS ROUTINE PERFORMS THE OPERATOR FUNCTION
!	FOR SET CHECKPOINT AND SET NOCHECKPOINT

GLOBAL ROUTINE OPRCHK( LEAFARGBLK, FCN) =
	BEGIN
	  REGISTER I;
	  REGISTER LEAFPTR;
	  MAP FORMAT LEAFPTR;

	  IF .LEAFARGBLK EQL 0 THEN
	    BEGIN
		DECR I FROM .N0LFNO-1 TO 0 DO
		  BEGIN
		    LEAFPTR _ .LFPTRTAB[.I];	  !GET POINTER TO LEAF
		    LEAFPTR[N0CHKPNT] _ .FCN;	  !SET TO DESIRED VALUE
		  END;
	     END
		ELSE
	       BEGIN
		IF (LEAFPTR _ QHASH( .LEAFARGBLK)) EQL 0 THEN RETURN FALSE;
		IF .LEAFPTR[N0NXTND] NEQ 0 %IF NOT LEAF% THEN RETURN FALSE;
		%ELSE%
		  LEAFPTR[N0CHKPNT] _ .FCN
	      END;
	   TRUE	!RETURN GOOD VALUE
	END;
COMMENT;

! ROUTINE WNET
! ======= ====

! THIS ROUTINE EXECUTES THE WHAT NET COMMAND FOR THE OPERATOR

GLOBAL ROUTINE WNET( TERMARGBLK ) =
    BEGIN
	REGISTER SRCPTR;

	IF .TERMARGBLK EQL 0 THEN 
	    DNETS()				! IF "WHAT NET /ALL"
	  ELSE 
	    IF (SRCPTR _ CHKSRCTAB(.TERMARGBLK) ) EQL 0 THEN RETURN FALSE
						!RETURN FALSE BAD TERMINAL
	  ELSE
	    DNET( .SRCPTR );			!IF NOT, DO SPECIFIC TERMINALS
	TRUE					!RETURN WITH GOOD RETURN
    END;
COMMENT;

! ROUTINE WTERM
! ======= =====

! THIS ROUTINE EXECUTES THE WHAT TERMIANL OPERATOR COMMAND

GLOBAL ROUTINE WTERM( TERMARGBLK ) =
    BEGIN

	REGISTER SRCPTR;

	IF .TERMARGBLK EQL 0 THEN		! WHAT /ALL?
		DTERMS()			! YES DISPLAY ALL TERMINALS
	    ELSE				! NO THEN
		IF ( SRCPTR _ CHKSRCTAB( .TERMARGBLK ) ) EQL 0 THEN RETURN FALSE
						! GOOD TERMINAL SPECIFIED?
						! NOT GOOD THEN RETURN FALSE
		    ELSE DTERM( .SRCPTR );	! OTHERWISE DISPLAY IT

	TRUE					! RETURN GOODNESS

    END;
COMMENT;

! ROUTINE WPORT
! ======= =====

! THIS ROUTINE EXECUTES THE WHAT PORT OPERATOR COMMAND

FORWARD	CHKPORTTAB;

GLOBAL ROUTINE WPORT( PORTNAME ) =
    BEGIN

	REGISTER PORTPTR;

	IF .PORTNAME EQL 0 THEN		! WHAT /ALL?
		DPORTS()			! YES DISPLAY ALL PORTS
	    ELSE				! NO THEN
		IF ( PORTPTR _ CHKPORTTAB( .PORTNAME ) ) EQL 0 THEN RETURN FALSE
						! GOOD PORT SPECIFIED?
						! NOT GOOD THEN RETURN FALSE
		    ELSE DPORT( .PORTPTR );	! OTHERWISE DISPLAY IT

	TRUE					! RETURN GOODNESS

    END;
COMMENT;

! ROUTINE CHKPORTTAB
! ======= ========
! THIS ROUTINE SEARCHES THE PORT TABLE (PORTTAB) FOR A MATCH TO THE
! PORTNAME IT IS GIVEN
! CALLED WITH:	A PORTNAME
! RETURNS:	A POINTER TO THE PORT TABLE OF THE PORT WITH THE
!		    MATCHING PORTNAME

GLOBAL ROUTINE CHKPORTTAB(PORTNAME) =
    BEGIN
	REGISTER
		PORTADDR,
		PORTNAMEREG;
	MAP	FORMAT PORTADDR;

	PORTNAMEREG _ .PORTNAME;					! PUT THE PORTNAME IN A REGISTER BECAUSE
							! I DON'T TRUST BLISS' OPTIMIZER
	PORTADDR _ .PORTTAB;

	WHILE .PORTADDR[PT0NAMEW] NEQ .PORTNAMEREG DO		! UNTIL WE FIND THE PORT WE WANT
	    BEGIN
		PORTADDR _ .PORTADDR + PT0SIZE;		! STEP TO THE NEXT PORT
		IF .PORTADDR[PT0NAMEW] EQL 0 THEN		! IF WE RUN OUT OF PORTS THEN 
			RETURN 0
	    END;

	.PORTADDR					! ELSE RETURN WHAT WAS WANTED
    END;
COMMENT;

! ROUTINE WNODE
! ======= =====

! THIS ROUTINE EXECUTES THE WHAT NODE OPERATOR COMMAND

GLOBAL ROUTINE WNODE( NODEARGBLK ) =
    BEGIN

	REGISTER NODEPTR;

	IF .NODEARGBLK EQL 0 THEN		! WHAT /ALL?
		DNODES()			! YES DISPLAY ALL NODES
	    ELSE				! NO THEN
		IF ( NODEPTR _ QHASH( .NODEARGBLK ) ) EQL 0 THEN RETURN FALSE
						! GOOD NODE SPECIFIED?
						! NOT GOOD THEN RETURN FALSE
		    ELSE DNODE( .NODEPTR );	! OTHERWISE DISPLAY IT

	TRUE					! RETURN GOODNESS

    END;
COMMENT;

! ROUTINE KMPP
! ======= ====

! THIS ROUTINE IS CALLED BY THE KERNEL TO CLEAN UP WHEN AN MPP
! IS KILLED OUT FROM UNDER US BY THE OPERATOR OR JUST DIES FOR SOME
! REASON

GLOBAL ROUTINE KMPP(JOBSLOT) =
    BEGIN
	REGISTER
		GHPTR,
		MHPTR,
		NEXT;

	LOCAL	LEAFPTR;

	MAP	FORMAT RECVQ;
	MAP	FORMAT LEAFPTR;
	MAP	FORMAT GHPTR;
	MAP	FORMAT MHPTR;

	WAITCANCEL( .JOBSLOT );				! MAKE SURE IT ISN'T WAITING

	PURGEO( .JOBSLOT );				! PURGE OUTPUT

	! FOR INPUT'D GROUPS::::
	IF .RECVQ[R0FGH(.JOBSLOT)] EQL 0 THEN RETURN;	! IF NOTHING WAS RECEIVED BY THIS JOB THEN LEAVE NOW

	GHPTR _ .RECVQ[R0FGH(.JOBSLOT)];		!GET THE FIRST GH IN RECVQ
	UNTIL .GHPTR EQL 0 DO
	    BEGIN
		LEAFPTR_.GHPTR[ G0LFPTR ];
		NEXT _ .GHPTR[G0FORE];

		IF NOT (.GHPTR[G0CHKPNT] OR .GHPTR[G0ONDSK]) THEN KILGROUP(.GHPTR,.JOBSLOT)
				!IF CAN'T RECOVER THE TRANSACTION, GIVE UP NOW
		    ELSE						!  OTHERWISE FIX UP & REQUEUE
		    BEGIN
			IF .GHPTR[G0EMPTY] AND .GHPTR[G0OUTMH] NEQ 0 THEN DPAGE(.GHPTR[G0PADDR]^9);
			GHPTR[ G0OUTMH ] _ MHPTR _ .GHPTR[ G0FMHPTR ];
			DO IF .MHPTR[M0CHNKS] NEQ 0 THEN DCHNKS(.MHPTR) WHILE (MHPTR_.MHPTR[M0FORE]) NEQ 0;

			UNLINK( RECVQ[ R0GHS( .JOBSLOT ) ], .GHPTR );		! REMOVE THE GROUP FROM THE RECVQ
			GHPTR[G0EMPTY]_GHPTR[G0RECEIVING]_GHPTR[G0FINISHED]_GHPTR[G0LINK]_0;
			GHPTR[ G0ONDSK ]_TRUE;
			LINK( LEAFPTR[ N0GHS ], .GHPTR );	! REQUEUE
			LEAFPTR[ N0TSCORE ] _ .LEAFPTR[ N0TSCORE ] - 1;	!THIS TRANSACTION IS NOT IN CORE
			INCREMENT( .LEAFPTR, 1)

		    END;

		GHPTR _ .NEXT
					!GET THE NEXT GH IN RECVQ.
	    END
    END;
COMMENT;

! ROUTINE CHGALT
! ======= ======

! THIS ROUTINE SWITCHES A TERMINAL TO THE NEXT ALTERNATE

GLOBAL ROUTINE CHGALT( TERMARGBLK, RESETFLAG ) =
    BEGIN

	REGISTER	SRCPTR;

	MAP	FORMAT SRCPTR;

	MACRO	CURALT = (.SRCPTR[ S0ALTPTR ] )< IF .SRCPTR[ S0RIGHTALT ] THEN RIGHT ELSE LEFT, HALFWORD >$,

		NEXTALT = IF (SRCPTR[S0RIGHTALT]_NOT .SRCPTR[S0RIGHTALT]) EQL 0 THEN INC(SRCPTR[S0ALTPTR],1)$;


	IF .TERMARGBLK EQL 0 THEN RETURN FALSE;				! IF TERMINAL NAME NOT GIVEN LEAVE NOW

	IF ( SRCPTR _ CHKSRCTAB( .TERMARGBLK ) ) EQL 0 THEN RETURN FALSE;	! IF TERMINAL NAME UNKNOWN LEAVE NOW

	IF .SRCPTR[ S0ALTPTR ] EQL 0 THEN RETURN FALSE;			! IF NO ALTERNATES LEAVE NOW

	IF NOT .RESETFLAG THEN						! IF NOT RESETTING THE PRIMARY TERMINAL THEN
	    BEGIN
		IF .CURALT EQL 0 THEN RETURN FALSE;			! IF NO MORE ALTERNATES LEAVE WITH BAD
		IF .SRCPTR[ S0SELF ] THEN
			SRCPTR[ S0RIGHTALT ] _ SRCPTR[ S0SELF ] _ FALSE	! SET NOT RIGHT ALTERNATE & NO SELF
		    ELSE NEXTALT;
		RETURN TRUE						! RETURN GOODNESS
	    END;
									! RESETTING TO THE PRIMARY TERMINAL SO
	WHILE .CURALT NEQ 0 DO NEXTALT;					! FIND THE LAST ENTRY

	NEXTALT;							! THE NEXT WITH POINTS TO THE FIRST

	SRCPTR[ S0ALTPTR ] _ CURALT;					! GET THE FIRST ALTERNATE
	SRCPTR[ S0RIGHTALT ] _ FALSE;					! MAKE FIRST ALTERNATE ON LEFT
	SRCPTR[ S0SELF ] _ TRUE		%NOTE::::: NO SEMICOLON%	! MAKE SELF AGAIN

    END;
COMMENT;

! ROUTINE SETQUOTA
! ======= ========

! THIS ROUTINE PERFORMS THE OPERATOR SET QUOTA COMMAND

GLOBAL ROUTINE SETQUOTA( ARGBLK, N ) =
    BEGIN

	REGISTER
		LEAFPTR;

	MAP	FORMAT LEAFPTR;

	IF .ARGBLK EQL 0 THEN RETURN FALSE;		! IF NO QUEUE SPECIFIED RETURN FALSE
	IF ( LEAFPTR _ QHASH( .ARGBLK ) ) EQL 0 THEN RETURN FALSE;	! IF BAD QUEUE NAME RETURN FALSE
	IF .LEAFPTR[ N0NXTND ] NEQ 0 THEN RETURN FALSE;	! IF NOT LEAF RETURN BADNESS

	IF .N LSS 0 THEN RETURN FALSE;

	LEAFPTR[ N0QUOTA ] _ .N;

	TRUE

    END;
COMMENT;

! ROUTINE SETTHRESHOLD
! ======= ============

! THIS ROUTINE PERFORMS THE OPERATOR SET THRESHOLD COMMAND

GLOBAL ROUTINE SETTHRESHOLD( ARGBLK, N ) =
    BEGIN

	REGISTER NODEPTR;

	MAP FORMAT NODEPTR;

	IF .ARGBLK EQL 0 THEN RETURN FALSE;		! IF NO QUEUE SPECIFIED RETURN FALSE
	IF ( NODEPTR _ QHASH( .ARGBLK ) ) EQL 0 THEN RETURN FALSE;	! IF BAD QUEUE NAME RETURN FALSE

	IF .N LEQ 0 THEN RETURN FALSE;

	NODEPTR[ N0THRESH ] _ .N;

	TRUE

    END;
COMMENT;

! ROUTINE SETRUN
! ======= ======

! THIS ROUTINE EXECUTES THE OPERATOR SET MPP TO RUN AT NODE TO MPP

GLOBAL ROUTINE SETRUN( NODENAME, MPPINDEX ) =
    BEGIN

	REGISTER NODEPTR;

	MAP FORMAT NODEPTR;

	IF .NODENAME EQL 0 THEN RETURN 1;		! THE NODE NAME MUST BE SPECIFIED

	IF ( NODEPTR _ QHASH( .NODENAME ) ) EQL 0 THEN RETURN 1;

	NODEPTR[ N0MPP ] _ .MPPINDEX;			! SET THIS ONE

	0

    END;
COMMENT;

!ROUTINE CPORT
!======= =====

! THIS ROUTINE MAPS THE PORT JUST CONNECTED TO A LOGICAL TERMINAL

GLOBAL ROUTINE CPORT(PORT)=
  BEGIN
	REGISTER   SRCPTR;
	REGISTER MSGCHUNKS;
	MAP FORMAT PORT;
	MAP FORMAT SRCPTR;
	EXTERNAL OUTMSG;
	EXTERNAL MAKEMSG;
	EXTERNAL MCSNAM;

	IF (SRCPTR _ .PORT[PT0SRCPTR]) EQL 0 THEN
	  SRCPTR _ .PORT[PT0TMPSRCPTR]
	ELSE
	   IF .PORT[PT0UDX] NEQ 0 THEN 
	     BEGIN
	        MSGCHUNKS _ MAKEMSG(PAZ 'Connected to %0A% as terminal %1A%  %Z%?M?J@',
				MCSNAM<36,7>,SRCPTR[S0ID],0,0,0);
	        OUTMSG(.MSGCHUNKS,.PORT[PT0UDX],FALSE,FALSE)
	     END;
	IF .SRCPTR NEQ 0 THEN SRCPTR[S0PORTPTR]_.PORT[PT0UDX]
  END;
COMMENT;

!ROUTINE CUDX
!======= ====

!THIS ROUTINE CHECKS TO SEE IF THERE IS AN
!ENTRY IN THE SOURCE TABLE WITH A GIVEN
!UDX...IF THERE IS IT,THE UDX IN THE SOURCE
!TABLE,IS ZEROED

GLOBAL ROUTINE CUDX(UDX)=
	BEGIN
		EXTERNAL RESETTERMINAL;
		REGISTER SRCPTR;
		MAP FORMAT SRCPTR;

		SRCPTR _ .SRCTAB + 1;
		
		WHILE .SRCPTR[S0PORTPTR] NEQ .UDX DO
			BEGIN
				SRCPTR_.SRCPTR+.S0SIZE;
				IF .SRCPTR[S0IDW] EQL 0 THEN RETURN
			END;
		RESETTERMINAL(.SRCPTR);
		SRCPTR[S0PORTPTR]_0
	END;




END;

! END OF MCSOPR.BLI