Google
 

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

REQUIRE  DATA.BLI;
! LAST MODIFIED:	1 MAY 76    BY	CDO

EXTERNAL	OCHOPY, OSROPY;

MACRO	OUTC(Z)=OCHOPY(Z)$,
	OUTSA(Z)=OSROPY(Z)$,
	OUTS(Z)=OSROPY(PLIT ASCII Z)$,
	OUTSN(AP,N)=BEGIN
			REGISTER BP;
			BP_AP;
			DECR I FROM (N)-1 TO 0
				DO OUTC(SCANI(BP));
		   END$,
	OUTM(C,N)=DECR I FROM (N)-1 TO 0 DO OUTC(C)$,
	CR=OUTC(#15)$, LF=OUTC(#12)$, NULL=OUTC(0)$,
	CRLF=OUTCRLF()$,
	TAB=OUTC(#11)$;

ROUTINE OUTCRLF =
    BEGIN
	OUTS( '?M?J' )
    END;

ROUTINE	OUTN(NUM,BASE,REQD)=
    BEGIN
	OWN N,B,RD,T;
	%LOCAL% ROUTINE XN=
	    BEGIN
		LOCAL R;
		IF .N EQL 0 THEN RETURN OUTM("0",.RD-.T);
		R_.N MOD .B; N_.N/.B; T_.T+1; XN();
		OUTC(.R+"0")
	    END;

	IF .NUM LSS 0 THEN OUTC("-");
	B_.BASE; RD_.REQD; T_0; N_ABS(.NUM); XN()
    END;
MACRO	OUTD(Z)=OUTN(Z,10,1)$,
	OUTO(Z)=OUTN(Z,8,1)$,
	OUTDR(Z,N)=OUTN(Z,10,N)$,
	OUTOR(Z,N)=OUTN(Z,8,N)$;
COMMENT;

FORWARD DXTREE();

ROUTINE DTREE = DXTREE(0);

ROUTINE DSTATUS = DXTREE(1);

GLOBAL ROUTINE DCOUNT=
    BEGIN
	REGISTER NODEPTR, SUM;
	MAP FORMAT NODEPTR;

	NODEPTR _ TREE + 2;

	OUTS('TOTAL MESSAGES IN TREE:');
	SUM _ .NODEPTR[N0TSCNT];
	WHILE (NODEPTR _ .NODEPTR[N0SAMND]) NEQ 0 DO
	    SUM _ .SUM + .NODEPTR[N0TSCNT];
	OUTD( .SUM );
	CRLF;
	DXTREE(2);

    END;


ROUTINE DXTREE(TYPE)=
    BEGIN
	FORWARD DX();
	OWN	DEXECUTE;

	ROUTINE	XNULL = OUTM(" ",4);

	ROUTINE STATUS(NODEPTR) =
	    BEGIN
		MAP	FORMAT NODEPTR; 

		IF .NODEPTR[N0ED] EQL 0 THEN OUTS('ENA ') ELSE OUTS('DIS ')
	    END;

	ROUTINE MCOUNT(NODEPTR) =
	    BEGIN
		MAP	FORMAT NODEPTR; 
		REGISTER TSCNT;

		IF ( TSCNT _ .NODEPTR[N0TSCNT]) LSS 100 THEN OUTC(" ");
		IF .TSCNT LSS 10 THEN OUTC(" ");
		OUTD(.TSCNT);
		OUTC(" ")
	    END;


	ROUTINE	DX(ARG,LVL)=
	    BEGIN
		REGISTER NODEPTR, J, CHAR;

		MAP FORMAT NODEPTR;

		MACRO	NAME = NODEPTR[0,36,7]$,
			NEXTTHIS = NODEPTR[N0SAMND]$,
			NEXTLEVEL = NODEPTR[N0NXTND]$,
			LEAF = (.NEXTLEVEL EQL 0)$;

		LABEL B;

		NODEPTR_.ARG;

B:		WHILE 1 DO
		    BEGIN
			%PRINT NAME:% (.DEXECUTE)(.NODEPTR);
			J _ NAME;
			DECR I FROM LEAFNAMCHR - 1 TO 0 DO
			    BEGIN
				CHAR _ SCANI(J);
				OUTC( IF .CHAR EQL 0 THEN " " ELSE .CHAR)
			    END;
			OUTM(" ",2);

			IF NOT LEAF THEN DX(.NEXTLEVEL,.LVL+1);

			IF(NODEPTR_.NEXTTHIS) EQL 0 THEN LEAVE B;
			IF .NODEPTR<RH> GEQ ERLEAF<0,0> THEN LEAVE B;

			CRLF;
			DECR I FROM (.LVL-1)*(LEAFNAMCHR+6) TO 1 DO OUTC(" ")
		    END
	    END;

	REGISTER NODEPTR;
	MAP FORMAT NODEPTR;

	MACRO	NAME = NODEPTR[N0NAME]$,
		NEXTTHIS = NODEPTR[N0SAMND]$,
		NEXTLEVEL = NODEPTR[N0NXTND]$,
		LEAF = (.NEXTLEVEL EQL 0)$;

	NODEPTR _ TREE + 2;

	DEXECUTE _ .PLIT(XNULL,STATUS,MCOUNT)[.TYPE];
	DX(.NODEPTR,1);
	CRLF;

    END;
COMMENT;

FORWARD DG(3),DM(3),DGH(1);

BIND
	INTYPE=-1,
	OUTTYPE=1;

FORWARD	DMPP;

ROUTINE DLEAF(LEAFPTR)=
    BEGIN

	REGISTER COUNT;
	REGISTER GHPTR;

	MAP FORMAT LEAFPTR;
	MAP FORMAT GHPTR;
	MAP FORMAT LFTAB;

	CRLF;
	OUTS('LEAFNAME: '); OUTSA(LEAFPTR[N0NAME]); TAB;
	    OUTS('LEAF #'); OUTD(.LEAFPTR[N0LLFNO]); CRLF;
	DMPP( .LEAFPTR );
	IF .LEAFPTR[N0ED] THEN OUTS('DISABLED?M?J') ELSE OUTS('ENABLED?M?J');
	COUNT _ .LEAFPTR[N0LLFNO]*L0SIZE+1;
	IF NOT .LEAFPTR[N0CHKPNT] THEN OUTS('NOT ');
	OUTS('CHECKPOINTED?M?J');

	IF .LEAFPTR[N0TSCNT] EQL 0 THEN
	    BEGIN
		OUTS('LEAF EMPTY'); CRLF;
		RETURN
	    END;

	OUTS('TSCNT: '); OUTD(.LEAFPTR[N0TSCNT]); CRLF;
	OUTS('TSCORE: '); OUTD(.LEAFPTR[N0TSCORE]); CRLF;

	IF NOT .ILGCDO %IFNOT DEBUGGING% THEN RETURN;
	COUNT _ 1;
	GHPTR _ .LEAFPTR[N0FGH];

	DO (DG(.GHPTR,.COUNT,4); COUNT _ .COUNT + 1)
	    WHILE (GHPTR _ .GHPTR[G0FORE]) NEQ 0;

    END;
MACRO	LTAB = SPACE(.LTS)$;

COMMENT;

ROUTINE SPACE(K) = (WHILE .K GTR 8 DO (K _ .K - 8; TAB); OUTM(" ",.K));

COMMENT;

!ROUTINE DG
!======= ==
!DISPLAYS GROUP HEADER AND ALL MESSAGES IN THE GROUP

ROUTINE DG(GHPTR,COUNT,LTS)=
    BEGIN
	REGISTER MHPTR,OUTPTR,K,TYPE;

	MAP FORMAT MHPTR;
	MAP FORMAT GHPTR;

	CRLF;
	IF .COUNT NEQ 0 THEN (LTAB; OUTS('GROUP '); OUTD(.COUNT); CRLF);

	DGH(.GHPTR,.LTS);		! DISPLAY THE GROUP HEADER INFO

	K _ 1;

	TYPE _ IF .GHPTR[G0RHTSN] EQL 0 THEN INTYPE ELSE OUTTYPE;

	MHPTR _ .GHPTR[G0FMHPTR];

	OUTPTR _ IF .GHPTR[G0EMPTY] THEN 0 ELSE .GHPTR[G0OUTMH];

	WHILE .MHPTR NEQ 0 DO
	    BEGIN
		IF .MHPTR EQL .OUTPTR THEN OUTS('-->');
 		DM(.MHPTR,.TYPE,.K,.LTS+4);
		K _ .K + 1;
		MHPTR _ .MHPTR[M0FORE];
	    END;
    END;
COMMENT;

!ROUTINE DGH
!======= ===
!DISPLAY GROUP HEADER

ROUTINE DGH(GHPTR,LTS)=
    BEGIN
	MAP FORMAT GHPTR;

	LTAB;
	OUTS('TSN: '); OUTD(.GHPTR[G0LHTSN]); OUTS(',,'); OUTD(.GHPTR[G0RHTSN]); CRLF;

	LTAB;
	OUTS('SENDER: '); OUTSN((.GHPTR[G0SENDER])<36,7>,SRCNAMCHR); CRLF;

	LTAB;
	OUTS('OWNER:'); OUTS('LEAF #'); OUTD(
	    BEGIN REGISTER LEAFPTR;
		MAP FORMAT LEAFPTR;
		LEAFPTR _ .GHPTR[G0LFPTR];
		.LEAFPTR[N0LLFNO]
	    END); CRLF;

	LTAB;
	OUTS('FLAGS: ');
	IF .GHPTR[G0SENDING] THEN OUTS('SENDING') ELSE OUTS('NOT-SENDING');
	IF .GHPTR[G0ONDSK] THEN OUTS(', ON-DISK') ELSE OUTS(', IN-CORE');
	IF .GHPTR[G0EMPTY] THEN OUTS(', EMPTY') ELSE OUTS(', NOT-EMPTY');
	OUTS(', EPI/EGI '); IF .GHPTR[G0ENDI] THEN OUTS('ENCOUNTERED') ELSE OUTS('NOT-ENCOUNTERED');
	IF .GHPTR[G0FINISHED] THEN OUTS(', FINISHED') ELSE OUTS(', NOT-FINISHED');
	IF .GHPTR[G0PURGING] THEN OUTS(', PURGING') ELSE OUTS(', NOT-PURGING');
	IF .GHPTR[G0TYPEOFSENDER] THEN OUTS(', MPP') ELSE OUTS(', TERMINAL');
	IF .GHPTR[G0CHKPNT] THEN OUTS(', CHKPNTING') ELSE OUTS(', NOT-CHKPNTING');
	IF .GHPTR[G0RECEIVING] THEN OUTS(', RECEIVING') ELSE OUTS(', NOT-RECEIVING');
	CRLF;


	IF .GHPTR[G0EMPTY] AND (.GHPTR[G0OUTMH] NEQ 0) THEN
	    BEGIN
		LTAB;
		OUTS('WAITING JOB ON JSN: '); OUTD(.GHPTR[G0JSN]); CRLF;
		LTAB;
		OUTS('WAITING PAGE:  '); OUTD(.GHPTR[G0PADDR]^9); CRLF
	    END
	    ELSE
	    BEGIN
		IF .GHPTR[G0EMPTY] THEN
		    BEGIN
			LTAB;
			OUTS('GROUP EMPTY, BUT NO JOB WAITING');
			CRLF
		    END
	    END;

	LTAB;
	OUTS('DSKGHADDR: '); OUTO( .GHPTR[G0DSKGHADDR] ); CRLF

    END;
COMMENT;

ROUTINE DMESSAGE(MHPTR)=DM(.MHPTR,0,0,0);

COMMENT;

!ROUTINE DM
!======= ==
!DISPLAYS MESSAGE HEADER AND ALL CHUNKS OF THE MESSAGE
FORWARD DC(2),DMH(2);

ROUTINE DM(MHPTR,TYPE,COUNT,LTS)=
    BEGIN

	REGISTER CHUNKPTR,K,OUTPTR;
	MAP FORMAT MHPTR;
	MAP FORMAT CHUNKPTR;

	CRLF;
	IF .COUNT NEQ 0 THEN (LTAB; OUTS('MESSAGE '); OUTD(.COUNT); CRLF);

	DMH(.MHPTR,.TYPE,.LTS);

	IF .MHPTR[M0OUTCHNK] EQL 0 THEN
	    BEGIN
		LTAB;
		OUTS('ROLLED OUT'); CRLF;
	    END
	    ELSE
	    BEGIN
		K _ 1;
		CHUNKPTR _ .MHPTR[M0INCHNK];
		OUTPTR _ .MHPTR[M0OUTCHNK];
		WHILE .CHUNKPTR NEQ 0 DO
		    BEGIN
			IF .CHUNKPTR EQL .OUTPTR THEN OUTS('->');
			DC(.CHUNKPTR,.K,.LTS+4);
			CHUNKPTR _ .CHUNKPTR[C0LINK];
			K _ .K + 1;
		    END;
	    END
    END;
COMMENT;

!ROUTINE DMH
!======= ===
!DISPLAY A MESSAGE HEADER

ROUTINE DMH(MHPTR,TYPE,LTS)=
    BEGIN
	MAP FORMAT MHPTR;

	LTAB;
	OUTS('DSKADDR: '); OUTO( .MHPTR[M0DSKADDR] ); CRLF;

	SELECT .TYPE OF 
	NSET
	    INTYPE:
		    BEGIN
			LTAB;
			OUTS('DATE: '); OUTO(.MHPTR[M0DATE]);CRLF;
			LTAB;
			OUTS('TIME:'); OUTO(.MHPTR[M0TIME]);CRLF;
			LTAB;
			OUTS( 'SOT: '); OUTD( .MHPTR[M0SOT]);CRLF
		    END;

	    OUTTYPE:
		    BEGIN
			LTAB;
			OUTS('DESTINATION COUNT = '); OUTD(.MHPTR[M0DSCNT]);CRLF;
			LTAB;
			OUTS('MODE: '); OUTO(.MHPTR[M0MODE]); CRLF
		    END;

	    OTHERWISE:
		    BEGIN
			LTAB;
			OUTS('WORD 1: '); OUTO(.MHPTR[M0DATE]); CRLF;
			LTAB;
			OUTS('WORD 2: '); OUTO(.MHPTR[M0TIME]); CRLF
		    END;
	TESN
    END;
COMMENT;

!ROUTINE DC
!======= ==
!DISPLAYS THE CONTENTS OF A CHUNK(BOTH HEAD AND DATA)

ROUTINE DC(CHUNKPTR,COUNT,LTS)=
    BEGIN

	MAP FORMAT CHUNKPTR;

	CRLF;
	IF .COUNT NEQ 0 THEN (LTAB; OUTS('CHUNK '); OUTD(.COUNT); CRLF);

	LTAB;
	OUTS('POS='); OUTD(.CHUNKPTR[C0BPOS]); OUTS('	SIZE='); OUTD(.CHUNKPTR[C0BSIZ]);CRLF;

	LTAB;
	OUTS('ENDI= ');
	CASE .CHUNKPTR[C0ENDI] OF
	    SET
		OUTS('NULL');
		OUTS('ESI');
		OUTS('EMI');
		OUTS('EGI');
		OUTS('EPI');
	    TES;
	CRLF;

	LTAB;
	OUTS('WORD COUNT='); OUTD(.CHUNKPTR[C0WORDS]); OUTS('	BYTE COUNT=');
	OUTD(.CHUNKPTR[C0BCNT]);CRLF;

	LTAB;
	OUTC(""""); OUTSN((.CHUNKPTR+C0HEADSIZE)<.CHUNKPTR[C0BPOS],.CHUNKPTR[C0BSIZ]>,.CHUNKPTR[C0BCNT]);
	OUTC(""""); CRLF
    END;
COMMENT;

ROUTINE OUTTFLAGS( SRCPTR ) =
    BEGIN
	MAP FORMAT SRCPTR;

	IF .SRCPTR[S0ED] EQL ENABLED THEN OUTS('EO')
	   ELSE OUTS('DO');
	IF .SRCPTR[S0PURGE] THEN OUTS(',PRG')
	   ELSE OUTS(',NPRG');
	CASE .SRCPTR[S0DIT] OF
	    SET
		%0%  OUTS(',EITA');
		%1%  OUTS(',*BAD');
		%2%  OUTS(',DITS');
		%3%  OUTS(',DITA');
	    TES;
    END;
COMMENT;

ROUTINE OUTTNAME( SRCPTR ) =
    BEGIN
	REGISTER NAME,
		 CHAR;
	MAP FORMAT SRCPTR;
	NAME _ SRCPTR[ S0ID ];
	DECR I FROM SRCNAMCHR - 1 TO 0 DO
	    BEGIN
		CHAR _  SCANI( NAME );
		OUTC ( IF .CHAR EQL 0 THEN " " ELSE .CHAR)
	    END;
	TAB;
    END;
COMMENT;

FORWARD DTRM;

GLOBAL ROUTINE DTERMS =
    BEGIN
	REGISTER
		SRCPTR;
	SRCPTR _ .SRCTAB + 1;
	INCR I FROM 0 TO .S0CNT - 1 DO
	    BEGIN
		DTRM( .SRCPTR, 0 );
		SRCPTR _ .SRCPTR + .S0SIZE
	    END
   END;
COMMENT;

GLOBAL ROUTINE DTERM( SRCPTR ) = DTRM( .SRCPTR, 0 );

COMMENT;

ROUTINE DTRM( SRCPTR, LTS ) =
    BEGIN

	REGISTER
		GHPTR,
		MHPTR,
		CHUNKPTR;

	OWN
		ALTPTR,
		COUNT;

	MAP	FORMAT SRCPTR;
	MAP	FORMAT CHUNKPTR;
	MAP	FORMAT GHPTR;
	MAP	FORMAT MHPTR;
	MAP	FORMAT ALTPTR;

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

	LTAB;
	OUTS( 'NAME: '); OUTSA( SRCPTR[S0ID]); CRLF;

	LTAB;
	OUTS( 'UDX: '); OUTO( .SRCPTR[S0PORTPTR]); CRLF;

	LTAB;
	OUTS( 'TSN: '); OUTO( .SRCPTR[S0TSN]); OUTS(',,0'); CRLF;

	IF .ILGCDO % IF DEBUGGING % THEN 
	 IF ( GHPTR _ .SRCPTR[S0FIGHPTR] ) NEQ 0 THEN
	    BEGIN
		COUNT _ 1;
		DO (DG(.GHPTR,.COUNT,4); COUNT _ .COUNT + 1)
		WHILE (GHPTR _ .GHPTR[G0FORE]) NEQ 0
	    END
	    ELSE
	    BEGIN
		LTAB;
		OUTS( 'NO IMMEDIATE MESSAGES' );
		CRLF
	    END;

	LTAB;
	OUTS('SOT: '); OUTD(  .SRCPTR[S0SOT]); CRLF;

	IF .ILGCDO % IF DEBUGGING % THEN  BEGIN
	 IF ( GHPTR _ .SRCPTR[S0FDGHPTR] ) NEQ 0 THEN
	    BEGIN
		LTAB;
		OUTS('DEFERRED COUNT: '); OUTD ( .SRCPTR[S0DFGCNT]); CRLF;
		COUNT _ 1;
		DO (DG(.GHPTR,.COUNT,4); COUNT _ .COUNT + 1)
		WHILE (GHPTR _ .GHPTR[G0FORE]) NEQ 0
	    END
	    ELSE
	    BEGIN
		LTAB;
		OUTS( 'NO DEFERRED MESSAGES' );
		CRLF
	    END;
	   LTAB;
	   IF ( CHUNKPTR _ .SRCPTR[S0FCHNK] ) NEQ 0 THEN
	      BEGIN
		COUNT _ 1;
		WHILE .CHUNKPTR NEQ 0 DO
		    BEGIN
			DC(.CHUNKPTR,.COUNT,.LTS+4);
			CHUNKPTR _ .CHUNKPTR[C0LINK];
			COUNT _ .COUNT + 1;
		    END
	      END
	    ELSE
	      BEGIN
		LTAB;
		OUTS( 'NO INPUT CHUNKS' );
		CRLF
	      END


	END;	!END OF DEBUGGING OUTPUT


	  LTAB;
	  OUTS( 'GHPTR: '); IF .SRCPTR[ S0PURGE ] THEN OUTO(0) ELSE
			BEGIN
				OUTO( .SRCPTR[S0GHPTR]);
				IF .SRCPTR[S0GHPTR] NEQ 0 AND .ILGCDO THEN DG( .SRCPTR[S0GHPTR], 0, .LTS + 4);
			END;
	  CRLF;

	LTAB;
	OUTS('FLAGS: ');  OUTTFLAGS(.SRCPTR);
	IF .SRCPTR[ S0SELF ] THEN OUTS( ',SELF' ) ELSE OUTS( ',NOT-SELF' );
	CRLF;

	! NOTE ****************
	! AS WELL AS PUTTING OUT THE CURRENT ALTERNATE IT MIGHT BE NICE
	!  TO PUT OUT THE ALTERNATE LIST

	IF NOT .SRCPTR[ S0SELF ] THEN
	    BEGIN
		LTAB;
		OUTS( 'CURRENT ALTERNATE TO SEND TO:	' );
		ALTPTR _ .CURALT;
		IF .ALTPTR EQL 0 THEN OUTS( '<NONE>' )
		   ELSE OUTSA( ALTPTR[ S0ID ] );
		CRLF
	    END;

	LTAB;	! ****** LOOP TO OUTPUT LEAF STATUS TABLE ******
	OUTS('LEAF STATUS TABLE:'); CRLF;
	LTAB;
	COUNT _ 0;
	INCR K FROM 0 TO .N0LFNO - 1 DO
	    BEGIN
		OUTO( .SRCPTR[S0LFSTS( .K, 2)] );
		IF (COUNT _ .COUNT + 1) GTR 7 THEN
		    BEGIN
			COUNT _ 0;
			CRLF;
			LTAB
		    END
		    ELSE IF .K NEQ .N0LFNO - 1 THEN  OUTS(', ')
	    END;

	CRLF; CRLF

    END;
COMMENT;
	FORWARD DNT(1);

GLOBAL ROUTINE DNETS = 
    BEGIN
	REGISTER SRCPTR;
	OUTS('NAME?I?IUDX?IICNT?IDCNT?IFLAGS');
	CRLF;
	SRCPTR _ .SRCTAB + 1;
	INCR I FROM 0 TO .S0CNT - 1 DO
	    BEGIN
	        DNT( .SRCPTR) ; 
		SRCPTR _ .SRCPTR + .S0SIZE
	    END;
        CRLF;
    END;

COMMENT;
GLOBAL ROUTINE DNET( SRCPTR ) = 
    BEGIN
	OUTS('NAME?I?IUDX?IICNT?IDCNT?IFLAGS');
	CRLF;
	DNT ( .SRCPTR);
    END;
COMMENT;

ROUTINE DNT( SRCPTR ) =
    BEGIN
	REGISTER 
	  ALTPTR,
	  GHPTR,
	  COUNT;
	MAP FORMAT SRCPTR;
	MAP FORMAT GHPTR;
	MACRO CURALT = (.SRCPTR[S0ALTPTR] )< IF .SRCPTR[S0RIGHTALT]
			THEN RIGHT ELSE LEFT,HALFWORD> $;

	OUTTNAME( .SRCPTR );
	IF .SRCPTR[ S0PORTPTR ] NEQ 0 THEN OUTOR(.SRCPTR[S0PORTPTR],6);
	TAB;
	COUNT _ 0;
	GHPTR _ .SRCPTR[ S0FIGHPTR ];	!COUNT IMMEDIATE MESSAGES
	WHILE .GHPTR NEQ 0 DO
	    BEGIN
		COUNT _ .COUNT + 1;
		GHPTR _ .GHPTR[ G0FORE ]
	    END;
	OUTD( .COUNT ) ;
	TAB;
	OUTD( .SRCPTR[ S0DFGCNT ] ) ;  !OUTPUT DEFERRED COUNT TOO
	TAB;
	OUTTFLAGS( .SRCPTR );
	IF NOT .SRCPTR[ S0SELF ] THEN
	BEGIN
	  CRLF;
	  OUTS('?ICURRENT ALTERNATE: ');
	  IF (ALTPTR _ .CURALT) EQL 0 THEN OUTS( '<none>')
	      ELSE OUTTNAME( .ALTPTR );
	  CRLF
	END;
	CRLF
    END;
COMMENT;

! ROUTINE DNODES
! ======= ======

! THIS ROUTINE DISPLAYS ALL THE NODES IN THE TREE

FORWARD	DALLNODES;

GLOBAL ROUTINE DNODES =
    BEGIN

	REGISTER	NODEPTR;
	MAP	FORMAT NODEPTR;

	NODEPTR _ ( TREE + 2 )<0,0>;

	DALLNODES( .NODEPTR )

    END;
COMMENT;

! ROUTINE DALLNODES
! ======= =========
! THIS ROUTINE DISPLAYS ALL THE NODES IN THE TREE

FORWARD	DNODE;

ROUTINE	DALLNODES(ARG)=
    BEGIN
	REGISTER NODEPTR;
	MAP FORMAT NODEPTR;
	MACRO
	    NAME = NODEPTR[N0NAME]$,
	    NEXTTHIS = NODEPTR[N0SAMND]$,
	    NEXTLEVEL = NODEPTR[N0NXTND]$,
	    LEAF = (.NEXTLEVEL EQL 0)$;
	LABEL B;
	NODEPTR_.ARG;
B: 	REPEAT
	   BEGIN
	        IF .NODEPTR GEQ ERLEAF<0,0> THEN LEAVE B;
		DNODE(.NODEPTR);
		IF NOT LEAF THEN DALLNODES(.NEXTLEVEL);
		IF(NODEPTR_.NEXTTHIS) EQL 0 THEN LEAVE B;
	    END
    END;
COMMENT;

! ROUTINE DFULL
! ======= =====
! THIS ROUTINE DISPLAYS THE FULL NAME OF A NODE

ROUTINE DFULL( NODEPTR ) =
    BEGIN
	MAP FORMAT NODEPTR;

	IF .NODEPTR[N0PARENT] NEQ 0 THEN
		DFULL( .NODEPTR[N0PARENT] )
	    ELSE
	    BEGIN
		OUTSA( .NODEPTR );
		RETURN
	    END;

	OUTC( "." );
	OUTSA( .NODEPTR )
    END;
	COMMENT;

! ROUTINE DNODE
! ======= =====

! THIS ROUTINE DISPLAYS INFORMATION ABOUT A NODE

GLOBAL ROUTINE DNODE( NODEPTR ) =
    BEGIN
	MAP	FORMAT NODEPTR;

	IF .NODEPTR[ N0NXTND ] EQL 0 THEN RETURN DLEAF( .NODEPTR );
	CRLF; OUTS( 'NODE NAME:	' ); DFULL( .NODEPTR ); CRLF; DMPP( .NODEPTR );

    END;
COMMENT;

! ROUTINE DMPP
! ======= ====

! THIS ROUTINE DISPLAYS ALL THE INFORMATION ABOUT AN MPP CONNECTED
!  TO A NODE

ROUTINE DMPP( NODEPTR ) =
    BEGIN
	EXTERNAL
		?MP$DEV,
		?MP$MPP,
		?MP$PPN;
	MAP	FORMAT NODEPTR;

	IF .NODEPTR[ N0MPP ] EQL #777777 THEN
		OUTS( 'NO MPP TO START?M?J' )
	    ELSE
	    BEGIN
		OUTS( 'MPP:	');
		OUTSA( .MPPTAB[ .NODEPTR[ N0MPP ] ] + ?MP$DEV );
		OUTC( ":" );
		OUTSA( .MPPTAB[ .NODEPTR[ N0MPP ] ] + ?MP$MPP );
		OUTC( "[" );
		OUTO( .(.MPPTAB[ .NODEPTR[ N0MPP ] ] + ?MP$PPN)<LH> );
		OUTC( "," );
		OUTO( .(.MPPTAB[ .NODEPTR[ N0MPP ] ] + ?MP$PPN)<RH> );
		OUTC( "]" );
		CRLF;

		OUTS( 'THRESHOLD:	' ); OUTD( .NODEPTR[ N0THRESH ] ); CRLF

	    END;
		IF .NODEPTR[ N0NXTND ] EQL 0 THEN
		    BEGIN
			OUTS( 'QUOTA:	' ); OUTD( .NODEPTR[ N0QUOTA ] ); CRLF
		    END
    END;
COMMENT;

! ROUTINE DPORT
! ======= =====

! THIS ROUTINE DISPLAYS ALL INFORMATION ABOUT A PORT

FORWARD	OUTSIX;

GLOBAL ROUTINE DPORT( PORTPTR ) =
    BEGIN
	REGISTER SRCPTR;
	MAP	FORMAT PORTPTR;
	MAP	FORMAT SRCPTR;


	OUTS( 'NAME:' ); OUTSIX( PORTPTR[ PT0NAME ], 6 );
	OUTS( '  UDX:' ); IF .PORTPTR[PT0UDX] EQL 0 THEN OUTM(" ",6) ELSE OUTOR(.PORTPTR[PT0UDX],6);
	OUTS( '?I  ASSOCIATED TERMINAL:' );

	IF (SRCPTR _ .PORTPTR[ PT0SRCPTR ]) NEQ 0 THEN OUTSA( SRCPTR[ S0ID ] )
	    ELSE OUTS( '<NONE>');
	CRLF
    END;
COMMENT;

! ROUTINE OUTSIX
! ======= ======

! THIS ROUTINE PRINTS SIXBIT CHARACTERS FROM THE GIVEN BYTE POINTER

ROUTINE OUTSIX( PTR, COUNT ) =
    BEGIN
	REGISTER	BP;

	BP _ .PTR;

	DECR I FROM .COUNT - 1 TO 0 DO
		OUTC( SCANI( BP ) + #40 );

    END;
COMMENT;

! ROUTINE DPORTS
! ======= ======

! THIS ROUTINE DISPLAYS ALL PORTS

GLOBAL ROUTINE DPORTS =
    BEGIN
	REGISTER
		PORTADDR;
	MAP	FORMAT PORTADDR;

	PORTADDR _ .PORTTAB;

	WHILE .PORTADDR[ PT0NAMEW ] NEQ 0 DO		! UNTIL WE FIND THE END OF THE PORT TABLE
	    BEGIN
		DPORT( .PORTADDR );			! DISPLAY THE PORT
		PORTADDR _ .PORTADDR + PT0SIZE		! STEP TO THE NEXT PORT
	    END;
	CRLF
    END;
END;