*DECK XF
USETEXT CCTTEXT 
      PROC   XF;
          BEGIN 
          XREF PROC CBLIST; 
          XREF FUNC DEC C(10);
          XREF ITEM CC$PW    I;    # LISTING WIDTH..LIVES IN CBLIST # 
          XREF PROC SMSORT; 
          XREF PROC SMKEY;
          XREF PROC SMOPT;
          XREF PROC SMOWN;
          XREF PROC SMEND;
          XREF PROC SMRTN;
  
          XDEF PROC PUTR; 
          XDEF PROC GETR; 
 #
                 XF DEBUG PARAMETERS: 
  
          CALL XFORMATTER,X,X,X,X.  (WHERE "X" MAY BE "Y" OR "N").
  
          THE PARAMTERS, IN ORDER, ARE: 
          (1)    XRVBLD, PTRBLD, AND DNXREF GENERAL DUMPS.
          (2)    URPTR DUMPS. 
          (3)    SORTS GENERAL DUMPS....CAUTION, MAY CREATE LOTS OF 
                             OUTPUT.....
          (4)    FORCES USE OF THE EXTERNAL SORT RATHER THAN IN-CORE ONE
  
 #
              $BEGIN
              XREF  PROC     OUTPUT;
              XREF  PROC     DISPLAY; 
              ITEM  XDMP     B = FALSE;     # TYPE 1 DUMPS #
              ITEM  UDMP     B = FALSE;     # TYPE 2 DUMPS #
              ITEM  SDMP     B = FALSE;     # TYPE 3 DUMPS #
              ITEM  DMPS     B = FALSE;     # FLOW TRACE..BONUS WITH
                                   ANY OF THE OTHERS... # 
  
              COMMON PARAMS;
                  BEGIN 
                  ARRAY  PARAMT [0:7];
                      ITEM   PARAMC  C(0,0,10); 
                  END 
              $END
          XREF ITEM LISTTYP  C(20); 
          XREF ITEM LISTHED  C(90); 
          DEF     DEFPGHED   #4#;   # CBLIST NEW HEADER FUNCTION #
          DEF INCOREMAX #500#;   # MAXIMUM TAGS FOR IN-CORE SORT #
          ITEM    FORCEXT    B = FALSE;     # TYPE 4 ACTION # 
          ITEM    ASTART     I; 
          ITEM    ASIZE      I; 
          ITEM    BSTART     I; 
          ITEM    BSIZE      I; 
          ITEM   NAMETPTR  I; 
          ITEM   NBRWORDS  I; 
          ITEM   REALPNT   I; 
          ITEM   REALDNT   I; 
          ITEM   W1        C(10); 
          ITEM   W2        C(10); 
          ITEM   W3        C(10); 
          ITEM    STACK      I; 
          ITEM    TST        I;    # PARAMETERS FOR EXTERNAL SORT # 
          ITEM    TSZ        I; 
          ITEM    INCR       I; 
          ITEM    INDX       I; 
          ITEM    WA         U; 
  
          BASED ARRAY ZPARM; ITEM Z;
          P<ZPARM> = 0;       #  TERMINATES SM PARM LISTS # 
  
 #  ARRAY OF SPECIAL REGISTER NAMES # 
          ARRAY SPECREGNMS [0:11] P(2); 
              BEGIN 
              ITEM SREGWD1  C(0,0,10) = [ 
                  "LINE-COUNT", 
                  "LINAGE-COU", 
                  "PAGE-COUNT", 
                  "DEBUG-ITEM", 
                  "DEBUG-LINE", 
                  "DEBUG-NAME", 
                  "DEBUG-SUB-", 
                  "DEBUG-SUB-", 
                  "DEBUG-SUB-", 
                  "DEBUG-CONT", 
                  "DEBUG-NUME", 
                  "HASHED-VAL"];
              ITEM SREGWD2   C(1,0,10) = [
                  "ER        ", 
                  "NTER      ", 
                  "ER        ", 
                  "          ", 
                  "          ", 
                  "          ", 
                  "1         ", 
                  "2         ", 
                  "3         ", 
                  "ENT       ", 
                  "RIC-CONTEN", 
                  "UE        "];
              END 
    #  THESE VARIABLES ARE USED TO INDICATE THE POSITION OF LISTS 
*      IN THE WORK AREA (WORKS). GENERALLY USED TO PASS PARAMETERS.   # 
  
          ITEM    LOWER      I; 
          ITEM    UPPER      I; 
    # LOWER/UPPER ARE THE MIN/MAX VALUES USED TO INDEX INTO DNT OR PNT
*      VALUES ARE FROM CCTDNTLEN AND CCTPNTLEN.                       # 
  
          ITEM    NO         I;    # LOOP COUNTER # 
          ITEM    TLINE      I;    # PAGE-HEADING POINTER # 
          ITEM    XFFOOT     C(10) = "          ";
  
  
          ITEM CODE;
    # CODE IS USED TO INDICATE WHETHER THE DATA-NAMES OR PROCEDURE-NAMES
*        ARE BEING PROCESSED.(DNXR OR PNXR ).THE PNT OR DNT ARE ACCESSED
*        ACCORDING TO THIS MARKER. ALSO USED IN XRVBLD TO SET UP THE XRV
*                                                                     # 
           DEF    PNXR       #1#; 
           DEF    DNXR       #2#; 
# 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
  
          COMMON SCRATCH VARIABLE AREA (WORKING-STORAGE)
  
              THESE VARIABLES MAY BE USED WITHIN THE MAJOR PROCS FREELY,
                  BUT DON-T EXPECT ANYTHING TO BE SAVED BETWEEN PROCS.. 
              ALSO, DON-T USE THESE IN THE "MINOR" PROCS (COMPARE, SWOP,
                  ETC.).
  
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
# 
  
          ITEM    I          I; 
          ITEM    J          I; 
          ITEM    K          I; 
          ITEM    L          I; 
          ITEM    X          I; 
*CALL TABLNAMES 
*CALL AWRT
*CALL DNT 
*CALL PNT 
*CALL NAMET 
*CALL INT1
*CALL WORKTABS
*CALL GETSET
*CALL DNATVALS
*CALL TABLEDF 
          CONTROL EJECT;
          PROC SORT1; 
  
          BEGIN 
          SMSORT(10,ZPARM); 
          SMOPT("NODAY",ZPARM); 
          SMKEY(1,1,10,0,"INTEGER",ZPARM);
          SMOWN(1,PUTR,3,GETR,ZPARM); 
          SMEND(ZPARM); 
  
          END 
  
          CONTROL EJECT;
          PROC SORT2; 
  
          BEGIN 
          SMSORT(50,ZPARM); 
          SMOPT("NODAY",ZPARM); 
          SMKEY(11,1,30,0,"DISPLAY",ZPARM); 
          SMKEY(41,1,10,0,"INTEGER",ZPARM); 
          SMOWN(1,PUTR,3,GETR,ZPARM); 
          SMEND(ZPARM); 
  
          END;
  
          CONTROL EJECT;
          PROC PUTR(RECA, RLA); 
  
          BEGIN 
          ARRAY RECA [0:4]; 
              ITEM SIXTYBITS I(0,0,60); 
          ITEM RLA I; 
  
          ARRAY SORTRECORD [0:4]; 
              ITEM COMPUTERWORD I(0,0,60);
          ITEM SORTLENGTH I;
  
          READT(SORTRECORD,SORTLENGTH); 
          IF SORTLENGTH LS 0 THEN 
              SMRTN(3,ZPARM); 
          IF SORTLENGTH EQ 1 THEN 
              SORTLENGTH = 10;
          ELSE
              SORTLENGTH = 50;       # CONVERT TO CHARS FOR SM #
          SMRTN(0,SORTRECORD,SORTLENGTH,ZPARM); 
  
          END 
  
          CONTROL EJECT;
          PROC GETR(RECA, RLA); 
  
          BEGIN 
          ARRAY RECA [0:4]; 
              ITEM SIXTYBITS I(0,0,60); 
          ITEM RLA I; 
          ITEM NEWNUM I;
  
          IF RLA EQ 50 THEN 
              NEWNUM = 5; 
          ELSE
              NEWNUM = 1;       # CONVERT TO WORDS FOR WRITET # 
          WRITET(RECA, NEWNUM); 
          SMRTN(1,ZPARM); 
  
          END 
  
          CONTROL EJECT;
          PROC GETNAME(INDEX);
 # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *        GETNAME - GETS A NAME FROM THE NAME TABLE AND PUTS IT INTO
 *            W1, W2 AND W3 
 *           INDEX IS THE INDEX OF THE PNT OR DNT ENTRY 
 *           CODE MUST BE SET TO PNXR OR DNXR 
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #
  
              BEGIN 
              ITEM INDEX I; 
  
              IF CODE EQ PNXR 
              THEN
                  BEGIN 
                  REALPNT = VIRTUAL(PNT$,INDEX);
                  NAMETPTR = PNTNAMETPTR[REALPNT];
                  NBRWORDS = PNTNBRWORDS[REALPNT];
                  END 
              ELSE
                  BEGIN 
                  REALDNT = VIRTUAL(DNT$,INDEX);
                  IF DNTSREG[REALDNT] 
                  THEN
                      BEGIN  # SPECIAL REGISTER - GET NAME FROM TABLE # 
                      W1 = SREGWD1 [DNTSREGVAL[REALDNT]]; 
                      W2 = SREGWD2 [DNTSREGVAL[REALDNT]]; 
                      IF DNTSREGVAL[REALDNT] EQ S"DBG$NUM$CONT" 
                      THEN
                          W3 = "NT";
                      ELSE
                          W3 = "          ";
                      RETURN; 
                      END 
                  ELSE
                      BEGIN 
                      NAMETPTR = DNTNAMETPTR[REALDNT];
                      NBRWORDS = DNTNBRWORDS[REALDNT];
                      END 
                  END 
              W1 = GETQUICK(NAMET$CHARS,NAMET$,NAMETPTR); 
              IF NBRWORDS GR 1
              THEN
                  BEGIN 
                  W2 = GETQUICK(NAMET$CHARS,NAMET$,NAMETPTR + 1); 
                  IF NBRWORDS GR 2
                  THEN
                      W3 = GETQUICK(NAMET$CHARS,NAMET$,NAMETPTR + 2); 
                  ELSE
                      W3 = "          ";
                  END 
              ELSE
                  BEGIN 
                  W2 = "          ";
                  W3 = "          ";
                  END 
              RETURN; 
              END 
          CONTROL EJECT;
          PROC  XRVBLD (  ASTART,ASIZE,BSTART,BSIZE   , CODE ); 
              BEGIN 
              DEF PNXRV      #1#;  # MARKER VALUE IN AWRT TO INDICATE 
                                        PROCEDURE-NAMES # 
              DEF DNXRV      #2#;  # AS ABOVE, FOR DATA-NAMES # 
              DEF SPREG      #3#;  # SPECIAL-REGISTER MARKER IN AWRT #
              DEF PNORDN     #4#;  # REFERENCE INDICATOR...INT ENTRY
                                        HOLDS THE NEEDED INFORMATION #
              DEF AWRESVD    #5#;  # THE AWRT HOLDS THE PNT/DNT 
                                        INDEX # 
              ARRAY XRV [0];
                  BEGIN 
                  ITEM XFXRVADR U(0,0,44); #ADR OF PNT/DNT ENTRY# 
                  ITEM XFXRVLINE U(0,44,16); #LINE NO. FROM AWRT# 
                  ITEM XRVITEM I(0,0,60); 
                  END 
              ITEM ASTART;   #START OF AWRT ENTRIES                    #
              ITEM ASIZE;    #LENGTH OF AWRT                           #
              ITEM BSTART;   #LOWER LIMIT OF XRV                       #
              ITEM BSIZE;    #LENGTH OF XRV                            #
              ITEM CODE;     #TYPE OF REF BEING SEARCHED FOR           #
              ITEM PTRA;     #PTR TO ITEM IN AWRT                      #
              ITEM PTRB;     #PTR TO ITEM IN O/P VECTOR.               #
              ITEM WORK  U;      #TEMP. STORE FOR DNT/PNT ADDRESS.     #
              ITEM AWEND;    #INDEX OF LAST ITEM IN AWRT               #
              ITEM AWCODE;   #ENTRY TYPE BEING SOUGHT IN AWRT.ACTUAL
                              *VALUE, NOT FORMAL PARAM. # 
              ITEM INTPTR;   #POINTER TO INT ENTRY FOR
                              *AWRT ENTRY. N.B. QUAILFIERS             #
              ITEM XACODE,XINCODE;
  
  
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(6, "XRVBLD", DEC(ASTART), DEC(ASIZE),
                      DEC(BSTART), DEC(BSIZE), DEC(CODE));
              IF  XDMP  THEN
                  OUTPUT(4, "PTRB", "ADDR", "LINE", "PTRA");
              $END
  
  
              PTRB = BSTART;
              AWEND   =ASIZE-1+ASTART;
              AWCODE = CODE;
              INTPTR=1; 
              FOR  PTRA = ASTART STEP 1  UNTIL  AWEND  DO 
                  BEGIN 
                  IF   GETFIELD(AWRTQUALIF,AWRT$,PTRA)  EQ 0  THEN
                      BEGIN  #THIS ENTRY IS NOT A QUALIFIER            #
                      IF GETQUICK(IN$CODE,INT$,INTPTR) EQ 1 THEN
                          GOTO NOTFOUND;    #THIS ENTRY IS NOT DECLARED#
                      XACODE=GETQUICK(AWRTCODE,AWRT$,PTRA); 
    #     FETCH THE TYPE-CODE FROM AWRT                                #
  
                      IF   XACODE   EQ AWCODE THEN
                          BEGIN   #MOVE DETAILS INTO XRV               #
                          WORK =  GETQUICK(IN$NAME,INT$,INTPTR);
                          GOTO  FOUND;
                          END 
                      ELSE   #THE CODES DONT MATCH, BUT CHECK FOR 4,5  #
                          BEGIN 
                          IF AWCODE EQ PNXRV  THEN
                              GOTO PNSCAN;
    #        IF THE REQUIRED ITEMS ARE PNT REFS., 
*            THE AWRT TYPE CANNOT BE 3 OR 5 . 
*            IE. SPECIAL-REG OR ALREADY RESOLVED REF.                 # 
                          IF XACODE EQ SPREG THEN 
                              BEGIN 
                              WORK = GETQUICK(IN$NAME,INT$,INTPTR); 
                              GOTO FOUND; 
                              END 
    #        LOOK FOR AWRTCODE 5 FOR DNT POINTER                       #
                          IF  XACODE   EQ AWRESVD   THEN
                              BEGIN   #THE AWRT POINTS TO THE DNT      #
                              WORK =  GETQUICK(AWRTIMMED,AWRT$,PTRA); 
                              GOTO  FOUND;
                              END 
PNSCAN:                     #LOOK FOR AWRTCODE = 4 FOR PNT OR DNT 
                              *                   ENTRIES              #
                            IF  XACODE  EQ PNORDN  THEN 
                              BEGIN 
                              XINCODE = GETQUICK(IN$PROCNAME,INT$,INTPTR
                                );
    #        XINCODE= 0 FOR DN-REFS, 1 FOR PN-REFS.                    #
                              IF(AWCODE EQ PNXRV AND  XINCODE  EQ 1) OR 
                                (AWCODE EQ DNXRV AND  XINCODE   EQ 0) 
                                THEN   #THE AWRT TYPE 4 IS FOR THE
                              *CORRECT DNT/PNT ENTRY                   #
                                  BEGIN 
                                  WORK = GETQUICK(IN$NAME,INT$,INTPTR); 
                                  GOTO FOUND; 
                                  END 
                              END 
                          END 
                      GOTO NOTFOUND;
FOUND:  
                      XFXRVADR[0] = WORK; 
                      XFXRVLINE[0] = GETQUICK(AWRTLINE,AWRT$,PTRA); 
                      $BEGIN
                      IF  XDMP  THEN
                          OUTPUT(4, DEC(PTRB), DEC(XFXRVADR[0]),
                              DEC(XFXRVLINE[0]), DEC(PTRA));
                      $END
                      SETFIELD(WORK1WORD,WORK1$,PTRB,XRVITEM);
                      PTRB = PTRB +1; 
NOTFOUND: 
                      INTPTR = INTPTR + 1;
                      END 
                  END 
              BSIZE = PTRB-BSTART;
              END 
          CONTROL EJECT;
          PROC PTRBLD( ASTART,ASIZE,BSTART,BSIZE);
           DEF    PNXR       #1#;  # MARKER VALUE FOR PNT USE # 
  # 
              THIS PROC SCANS THE VECTOR BUILT BY XRVBLD AFTER IT HAS 
                  BEEN SORTED.  ANOTHER VECTOR IS BUILT WHICH POINTS
                  TO THE FIRST APPEARANCE OF A DNT/PNT ADDRESS
                  IN THE SCANNED VECTOR.  IT ALSO POINTS TO THE 
                  ACTUAL DNT/PNT ADDRESS AND ALSO HOLDS THE FIRST 
                  10 CHARACTERS OF THE NAME (EACH ENTRY IS 2 WORDS LONG)
  # 
              BEGIN 
              ARRAY AA [0]; 
                  BEGIN 
                  ITEM PDADDR U(0,0,44); #ADDR OF PNT/DNT#
                  ITEM LINE U(0,44,16); #LINE NO. OF USAGE# 
                  ITEM AAITEM I(0,0,60);
                  END 
              ARRAY BB [0]; 
                  BEGIN 
                  ITEM FADDR U(0,0,44); #ADDR OF PNT/DNT# 
                  ITEM AINDEX U(0,44,16); #POINTER TO ENTRY IN AA#
                  ITEM BBITEM I(0,0,60);
                  ITEM FIRST10CH U(0,0,60);   #FIRST 10 CHARS OF NAME  #
                  END 
              ITEM  INPTR    I; 
              ITEM  OUTPTR   I; 
              ITEM  LOOP     I; 
              ITEM  LIMIT    I; 
              ITEM  BS       I; 
              ITEM  ASTART   I;    # INPUT VECTOR BASE ADDR # 
              ITEM  BSTART   I;    # OUTPUT VECTOR BASE ADDR #
              ITEM  ASIZE    I;    # INPUT VECTOR SIZE #
              ITEM  BSIZE    I;    # OUTPUT VECTOR SIZE # 
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(5, "PTRBLD", DEC(ASTART), DEC(ASIZE),
                      DEC(BSTART), DEC(BSIZE)); 
              IF  XDMP AND NOT SDMP  THEN        # NOT ALREADY DUMPED # 
                  BEGIN 
                  OUTPUT(3,"INDEX","POINTER","LINE"); 
                  FOR LIMIT = ASTART STEP 1 UNTIL ASTART+ASIZE-1  DO
                      BEGIN 
                      INPTR = GETQUICK(WORK1WORD,WORK1$,LIMIT); 
                      OUTPTR = B<0,44>INPTR;
                      LOOP = B<44,16>INPTR; 
                      OUTPUT(3,DEC(LIMIT),DEC(OUTPTR),DEC(LOOP)); 
                      END 
                  END 
              $END
              BS=0; 
              X = 0;
              LOOP = ASIZE; 
              INPTR = ASTART; 
              OUTPTR = BSTART;
              FOR LIMIT = 1 STEP 1 UNTIL LOOP DO   #SCAN UNTIL THE
                              *                           PNT/DNT ADDR #
                  BEGIN      #            CHANGES. THEN BUILD AN ENTRY #
                             #            IN THE O/P VECTOR .          #
                  AAITEM = GETQUICK (WORK1WORD,WORK1$,INPTR); 
                  IF  X NQ  PDADDR[0] THEN
                      BEGIN 
                      X = PDADDR[0];
                      FADDR[0] =  X;   #ADDR OF PNT/DNT ENTRY          #
                      AINDEX[0] = INPTR;    #ADDR OF ENTRY IN LINE LIST#
                      SETFIELD(WORK1WORD,WORK1$,OUTPTR,BBITEM); 
                      OUTPTR=OUTPTR+1;
                      IF CODE EQ PNXR THEN   #SET THE FIRST 10 CHARS IN 
                              *                           O/P.         #
                          NAMETPTR = GETQUICK(PNTNAMETPTR,PNT$,X);
                      ELSE
                          NAMETPTR = GETQUICK(DNTNAMETPTR,DNT$,X);
                      BS=BS+1;
                      IF NAMETPTR EQ 0
                      THEN   # MUST BE A SPECIAL REGISTER # 
                          FIRST10CH = SREGWD1[GETQUICK(DNTSREGVAL,
                            DNT$,X)]; 
                      ELSE
                          FIRST10CH = GETQUICK(NAMET$CHARS,NAMET$,
                            NAMETPTR);
                      SETFIELD(WORK1WORD,WORK1$,OUTPTR,BBITEM); 
                      OUTPTR = OUTPTR + 1;
  
                      END 
                  INPTR  =  INPTR + 1;
                  END 
              BSIZE =  BS;
              $BEGIN
              IF  XDMP  THEN
                  BEGIN 
                  BS = BS + BS; 
                  FOR LIMIT = BSTART STEP 2 UNTIL BSTART + BS - 1  DO 
                      BEGIN 
                      AAITEM = GETQUICK(WORK1WORD, WORK1$, LIMIT);
                      X = LIMIT + 1;
                      BBITEM = GETQUICK(WORK1WORD, WORK1$, X);
                      OUTPUT(3,DEC(LIMIT),DEC(PDADDR[0]),DEC(LINE[0])); 
                      OUTPUT(2, DEC(X), FIRST10CH [0]); 
                      END 
                  END 
              $END
  
              END            #OF PTRBLD                                #
          CONTROL EJECT;
          PROC   URPTR(ASTART,ASIZE,BSTART,BSIZE,LOWER,UPPER);
    #THIS PROCEDURE IS USED TO BUILD A LIST OF UNREFERENCED DATA-NAMES
*  OR PROCEDURE NAMES .  THIS IS DONE BY EXAMINING THE LIST OF DNT/PNT
*  POINTERS PRODUCED BY PROC PTRBLD .(NOTE THAT  PTRBLD MUST HAVE BEEN
*  CALLED AGAIN , AFTER  OSORT2 , AS THE ORIGIONAL VECTOR HAS BEEN
*  SORTED ).
*                                                                     # 
              BEGIN 
              ARRAY AA [0]; 
                  BEGIN 
                  ITEM PDADDR U(0,0,44); #ADDR OF USED PNT/DNT# 
                  ITEM FILL U(0,44,16); 
                  ITEM AAITEM I(0,0,60);
                  END 
              ARRAY BB [0]; 
  
                  BEGIN 
                  ITEM UNUSED U(0,0,44); #ADDR OF AN UNUSED PNT/DNT#
                  ITEM UFILL U(0,44,16);
                  ITEM BBITEM I(0,0,60);
                  ITEM FIRST10CH U(0,0,60);    #FIRST THIRD OF NAME    #
                  END 
              ITEM  ASTART   I;    # INPUT LIST BASE ADDR # 
              ITEM  BSTART   I;    # OUTPUT LIST BASE ADDR #
              ITEM  ASIZE    I;    # LIST SIZE #
              ITEM  BSIZE    I;    # LIST SIZE #
              ITEM  LOWER    I;    # BASE OF PNT/DNT #
              ITEM  UPPER    I;    # TOP OF DNT/PNT # 
              ITEM  BSZ      I; 
              ITEM  LOW      I; 
              ITEM  UP       I; 
              ITEM  AMAX     I; 
              ITEM  SAVNAM   I; 
              BASED ARRAY  SNAM[0]; 
                  BEGIN 
                  ITEM NAME10 C(0,0,10);
                  END 
              DEF PNXR       #1#;  # MARKER VALUE FOR PNT SEARCH #
              P<SNAM>= LOC(SAVNAM); 
    # 
*                                                                     # 
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(7,"URPTR",DEC(ASTART),DEC(ASIZE),DEC(BSTART),
                      DEC(BSIZE), DEC(LOWER), DEC(UPPER));
              $END
              J = ASTART; 
              AMAX = ASTART + ASIZE+ASIZE-3;
              AAITEM = GETQUICK(WORK1WORD,WORK1$,J);
              X=PDADDR[0];
              K = BSTART; 
              BSZ = 0;
              LOW = LOWER;
              UP = UPPER; 
              FOR  I=LOW STEP 1 UNTIL UP DO 
                  BEGIN 
                  IF I  NQ  X   THEN
                      BEGIN 
                      IF PNXR EQ CODE THEN
                          NAMETPTR = GETQUICK(PNTNAMETPTR,PNT$,I);
                      ELSE
                          BEGIN 
                          REALDNT = VIRTUAL(DNT$,I);
                          NAMETPTR = DNTNAMETPTR[REALDNT];
                          L = DNTLINE[REALDNT]; 
                          IF  L EQ 0  THEN TEST; # IGNORE SPC REGS #
                          L = DNTLEVEL[REALDNT];
                          END 
                      IF NAMETPTR EQ 0 THEN 
                          TEST; 
                      SAVNAM = GETQUICK(NAMET$CHARS,NAMET$,NAMETPTR); 
                      UNUSED[0] = I;
                      BSZ = BSZ +1;   # I IS AN UNUSED ADDRESS         #
                      SETFIELD (WORK1WORD,WORK1$,K,BBITEM); 
                      L=K+1;
                      SETFIELD(WORK1WORD,WORK1$,L,SAVNAM);
                      K=K+2;
                      END 
                  ELSE
  
                      IF  J LQ  AMAX THEN   #I WAS USED , RESET X IF J I
                              *                              VALID     #
                          BEGIN 
                          J = J + 2;    #STILL WITHIN INPUT VECTOR     #
                          AAITEM = GETQUICK(WORK1WORD,WORK1$,J);
                          X=PDADDR[0];
                          END 
                  END 
              BSIZE = BSZ;
              $BEGIN
              IF  UDMP  THEN
                  BEGIN 
                  BSZ = BSZ + BSZ;
                  FOR I = BSTART STEP 2 UNTIL BSTART + BSZ - 1 DO 
                      BEGIN 
                      AAITEM = GETQUICK(WORK1WORD, WORK1$, I);
                      J = I + 1;
                      BBITEM = GETQUICK(WORK1WORD, WORK1$, J);
                      OUTPUT(3, DEC(I), DEC(PDADDR[0]), DEC(FILL[0]));
                      OUTPUT(2, DEC(J), FIRST10CH [0]); 
                      END 
                  END 
              $END
              END            #OF URPTRBLD                              #
          CONTROL EJECT;
          PROC  QSORT1(START,SIZE,STACK); 
              BEGIN 
 #
                             THIS IS A SYMPL VERSION OF QUICKSORT AS
                      DESCRIBED IN KNUTH, VOL 3, PP 116-117.
 #
              ITEM    START  I;    # START OF INPUT STRING #
              ITEM    SIZE   I;    # SIZE OF INPUT STRING # 
              ITEM    STACK  I;    # BASE OF STACK AREA # 
              ITEM    SP     I;    # STACK POINTER #
  
              DEF     M      #9#;  # SIZE OF SUBSTRING TO SORTED BY 
                                       STRAIGHT INSERTION # 
  
              # LOCAL STORAGE # 
              #       L              SUBSTRING LOWER BOUNDS # 
              ITEM    R      I;    # SUBSTRING UPPER BOUNDS # 
              #       I              TRIAL LOWER BOUNDS # 
              #       J              TRIAL UPPER BOUNDS # 
              #       K              TRIAL ELEMENT #
              ITEM    KI     I;    # K[I] ELEMENT # 
              ITEM    KJ     I;    # ETC...#
  
              ARRAY STACKITEM [0];
                  BEGIN 
                  ITEM    SIT    U(0,0,30); 
                  ITEM    SIB    U(0,30,30);
                  ITEM    SI     U(0,0,60); 
                  END 
              $BEGIN
                  PROC DMPPTR(NAM,P1,V1,P2,V2); 
                  BEGIN 
                  ITEM    NAM    C(10); 
                  ITEM    V1     I; 
                  ITEM    P1     I; 
                  ITEM    V2     I; 
                  ITEM    P2     I; 
                  ITEM    V1T    I;    # TOP OF V1 #
                  ITEM    V1B    I;    # BOTTOM OF V1 # 
                  ITEM    V2T    I;    # ETC. . . # 
                  ITEM    V2B    I; 
  
                  V1T = B<0,44>V1;
                  V1B = B<44,16>V1; 
                  V2T = B<0,44>V2;
                  V2B = B<44,16>V2; 
                  OUTPUT(7, NAM, DEC(P1), DEC(V1T), DEC(V1B), DEC(P2),
                      DEC(V2T), DEC(V2B));
                  END            # DMPPTR # 
              $END
  
 Q1:                         # INITIALIZE # 
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(4,"QSORT1",DEC(START),DEC(SIZE),DEC(STACK)); 
              $END
              IF  SIZE LQ M  THEN  GOTO Q9;      # USE STRAIGHT INSERT# 
              SP = STACK;        # SET STACK EMPTY #
              L = START;
              R = START + SIZE - 1; 
          SETFIELD(WORK1WORD,WORK1$,R+1,O"37777777777777777777"); 
 #     SET INFINITE ENTRY AT END AND 0 ENTRY AT FRONT                  #
          SETFIELD(WORK1WORD,WORK1$,L-1,0); 
  
 Q2:                         # BEGIN NEW STAGE #
              I = L;
              J = R + 1;
              K = GETQUICK(WORK1WORD,WORK1$,L); 
                  $BEGIN
                  IF  SDMP  THEN
                      OUTPUT(5, "Q2", DEC(L), DEC(I), DEC(J), DEC(R));
                  $END
  
 Q3:                         # COMPARE KI : K # 
              FOR  I = I + 1 STEP 1 WHILE I LQ J  DO
                  BEGIN 
                  KI = GETQUICK(WORK1WORD,WORK1$,I);
                  IF  KI GQ K  THEN  GOTO Q4; 
                  END 
  
 Q4:                         # COMPARE K : KJ # 
                  $BEGIN
                  IF  SDMP  THEN DMPPTR("Q4", L,K,I,KI);
                  $END
              FOR  J = J - 1 STEP -1 WHILE J GQ I - 1  DO 
                  BEGIN 
                  KJ = GETQUICK(WORK1WORD,WORK1$,J);
                  IF  K GQ KJ  THEN  GOTO Q5; 
                  END 
  
 Q5:                         # TEST I : J # 
                  $BEGIN
                  IF  SDMP  THEN DMPPTR("Q5", L,K,J,KJ);
                  $END
              IF  J LQ I  THEN
                  BEGIN 
                  SETFIELD(WORK1WORD,WORK1$,L,KJ);
                  SETFIELD(WORK1WORD,WORK1$,J,K); 
                  KJ == K;
                      $BEGIN
                      IF  SDMP  THEN  DMPPTR("Q5SWOP",L,K,J,KJ);
                      $END
                  GOTO Q7;
                  END 
  
 Q6:                         # EXCHANGE # 
              SETFIELD(WORK1WORD,WORK1$,I,KJ);
              SETFIELD(WORK1WORD,WORK1$,J,KI);
              KI == KJ; 
                  $BEGIN
                  IF  SDMP  THEN DMPPTR("Q6",I,KI,J,KJ);
                  $END
              GOTO Q3;
  
 Q7:                         # PUT IN STACK # 
                  $BEGIN
                  IF  SDMP  THEN
                      OUTPUT(6,"Q7",DEC(L),DEC(I),DEC(J),DEC(R),DEC(M));
                  $END
              IF  R - J GQ J - L AND J - L GR M  THEN 
                  BEGIN 
                  SIT[0] = J + 1; 
                  SIB[0] = R; 
                  SP = SP + 1;
                  SETFIELD(WORK1WORD,WORK1$,SP,SI[0]);
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4, "STACKED1",DEC(SP),DEC(SIT[0]), 
                             DEC(SIB[0]));
                      $END
                  R = J - 1;
                  GOTO Q2;
                  END 
  
              IF  J - L GR R - J AND R - J GR M  THEN 
                  BEGIN 
                  SIT[0] = L; 
                  SIB[0] = J - 1; 
                  SP = SP + 1;
                  SETFIELD(WORK1WORD,WORK1$,SP,SI[0]);
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4, "STACKED2",DEC(SP),DEC(SIT[0]), 
                             DEC(SIB[0]));
                      $END
                  L = J + 1;
                  GOTO Q2;
                  END 
  
              IF  R - J GR M AND M GQ J - L  THEN 
                  BEGIN 
                  L = J + 1;
                      $BEGIN
                      IF  SDMP  THEN OUTPUT(2,"RESET L", DEC(L)); 
                      $END
                  GOTO Q2;
                  END 
  
              IF  J - L GR M AND M GQ R - J  THEN 
                  BEGIN 
                  R = J - 1;
                      $BEGIN
                      IF  SDMP  THEN OUTPUT(2,"RESET R",DEC(R));
                      $END
                  GOTO Q2;
                  END 
  
 Q8:                         # TAKE OFF STACK # 
              IF  SP GR STACK  THEN 
                  BEGIN 
                  SI[0] = GETQUICK(WORK1WORD, WORK1$,SP); 
                  SP = SP - 1;
                  L = SIT[0]; 
                  R = SIB[0]; 
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4,"UNSTACKED",DEC(SP),DEC(L),DEC(R));
                      $END
                  GOTO Q2;
                  END 
  
 Q9:                         # STRAIGHT INSERTION SORT #
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                      OUTPUT(1,"Q9"); 
                      OUTPUT(3,"INDEX","POINTER","LINE"); 
                      FOR  L = START STEP 1 UNTIL START+SIZE-1  DO
                          BEGIN 
                          K = GETQUICK(WORK1WORD,WORK1$,L); 
                         I = B<0,44>K;
                         J = B<44,16>K; 
                          OUTPUT(3,DEC(L),DEC(I),DEC(J)); 
                          END 
                      END 
                  $END
  
              FOR J = START + 1 STEP 1 UNTIL START + SIZE - 1  DO 
                  BEGIN 
                  I = J - 1;
                  KI = GETQUICK(WORK1WORD,WORK1$,I);
                  K  = GETQUICK(WORK1WORD,WORK1$,J);
 Q9S3:  
                  IF  K GQ KI  THEN  GOTO Q9S5; 
 Q9S4:  
                  SETFIELD(WORK1WORD,WORK1$,I+1,KI);
                  I = I - 1;
                  IF  I GR START - 1  THEN
                      BEGIN 
                      KI = GETQUICK(WORK1WORD,WORK1$,I);
                      GOTO Q9S3;
                      END 
 Q9S5:                       # K INTO K[I+1] #
                  IF  I+1 NQ J  THEN   # DONT REPLACE YOURSELF #
                      SETFIELD(WORK1WORD,WORK1$,I+1,K); 
  
                  END 
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                      OUTPUT(1,"Q9END");
                      OUTPUT(3,"INDEX","POINTER","LINE"); 
                      FOR  L = START STEP 1 UNTIL START+SIZE-1  DO
                          BEGIN 
                          K = GETQUICK(WORK1WORD,WORK1$,L); 
                         I = B<0,44>K;
                         J = B<44,16>K; 
                          OUTPUT(3,DEC(L),DEC(I),DEC(J)); 
                          END 
                      END 
                  $END
              END                # QSORT1 # 
          CONTROL EJECT;
          PROC QSORT2(ASTART,ASIZE,BBASE ); 
    #THIS PROCEDURE IS USED TO SORT A SET OF POINTERS FROM THE XRV
*   ACCORDING TO THE VALUE OF THE ASSOCIATED PNT/DNT ENTRY .
*                                                                     # 
  
  
              BEGIN 
              ITEM    ASTART I;    # START OF STRING ADDRESS #
              ITEM    ASIZE  I;    # SIZE OF STRING TO SORT # 
              ITEM    BBASE  I;    # START ADDR OF WORK STACK # 
              ITEM    SP     I;    # STACK POINTER #
  
              DEF     M      #9#;  # SIZE OF SUBSTRING TO SORT BY 
                                       STRAIGHT INSERTION # 
  
              # LOCAL STORAGE # 
              #       BASICLY THE SAME AS QSORT1... 
                             I, J, K, AND L ARE USED THE SAME # 
              ITEM    R      I;    # SUBSTRING UPPER BOUNDS # 
              ITEM    K1     I; 
              ITEM    K2     I; 
              ITEM    KI1    I; 
              ITEM    KI2    I; 
              ITEM    GREATER B = FALSE;    # INDICATOR FOR "COMPARE" # 
              ITEM    EQUAL   B = FALSE;
              ARRAY STACKITEM[0]; 
                  BEGIN 
                  ITEM SIT   U(0,0,30); 
                  ITEM SIB   U(0,30,30);
                  ITEM SI    U(0,0,60); 
              END 
  
  
              PROC SWOP(A,B); 
                  BEGIN 
                  ITEM A     I; 
                  ITEM B     I; 
                  ITEM SWOP1 I; 
                  ITEM SWOP2 I; 
                  ITEM SWA   I; 
                  ITEM SWB   I; 
  
                  SWOP1 = A * 2 + ASTART;   # COMPUTE ACTUAL ADDR      #
                  SWOP2 = B * 2 + ASTART; 
  
                  SWA =GETQUICK(WORK1WORD,WORK1$,SWOP1);
                  SWB = GETQUICK(WORK1WORD,WORK1$,SWOP2); 
                  SETFIELD(WORK1WORD,WORK1$,SWOP1,SWB); 
                  SETFIELD(WORK1WORD,WORK1$,SWOP2,SWA); 
                  SWOP1=SWOP1+1;
                  SWOP2=SWOP2+1;
                  SWA =GETQUICK(WORK1WORD,WORK1$,SWOP1);
                  SWB = GETQUICK(WORK1WORD,WORK1$,SWOP2); 
                  SETFIELD(WORK1WORD,WORK1$,SWOP1,SWB); 
                  SETFIELD(WORK1WORD,WORK1$,SWOP2,SWA); 
                  END 
  
  
  
  
              PROC COMPARE(INDA,INDB);
              ITEM   INDA    I; 
              ITEM   INDB    I;    # INDEXES TO COMPARE # 
              ITEM   LOW     I; 
              ITEM   IND     I; 
              ITEM   REM     I; 
              ITEM   ANAME   C(10); 
                  ITEM   ANAME3  C(10); 
              ITEM   BNAME   C(10); 
              ITEM   IA      I; 
              ITEM   IB      I; 
              ITEM   CHAR    I; 
              DEF    PNXR    #1#; 
              ITEM   ACHAR   U; 
              ITEM   BCHAR   U; 
              ITEM   NAMETA  I; 
              ITEM   NAMETB  I; 
              ITEM   LENA    I; 
              ITEM   LENB    I; 
              ARRAY  TRANTABLE[5];
                  ITEM TABLE U = [
                      O"77020304050607107777",   # 00 - 07 #
                      O"11121314151617207777",   # 10 - 17 #
                      O"21222324252627307777",   # 20 - 27 #
                      O"31323334353637407777",   # 30 - 37 #
                      O"41424344457701777777"];  # 40 - 47 #
              ARRAY AN [0]; 
                  BEGIN 
                  ITEM AN03  U(0,0,24); 
                  ITEM AN46  U(0,24,18);
                  ITEM AN79  U(0,42,18);
                ITEM PDADDR U(0,0,44);
                  ITEM ANITEM I(0,0,60);
                  END 
              ARRAY BN [0]; 
                  BEGIN 
                  ITEM BN03 U(0,0,24);
                  ITEM BN46 U(0,24,18); 
                  ITEM BN79 U(0,42,18); 
                  ITEM BNITEM I(0,0,60);
                  END 
                  BEGIN 
                  EQUAL= FALSE; 
                  GREATER = FALSE;
                  IA = INDA *2 + ASTART;         # GET REAL ADDRESS # 
                  IB = INDB *2 + ASTART;
                  CHAR = IA+1;
                  ANAME = C<0,10>GETQUICK(WORK1WORD,WORK1$,CHAR); 
                  CHAR = IB+1;
                  BNAME = C<0,10>GETQUICK(WORK1WORD,WORK1$,CHAR); 
                  IF  ANAME EQ BNAME  THEN
                      BEGIN  #                          A1=B1          #
                      ANITEM = GETQUICK(WORK1WORD,WORK1$,IA); 
                      IA=PDADDR[0]; 
                      ANITEM = GETQUICK(WORK1WORD,WORK1$,IB); 
                      IB=PDADDR[0]; 
                      GETNAME(IA);
                      ANAME = W2; 
                      ANAME3 = W3;
                      GETNAME(IB);
                      IF ANAME EQ W2
                      THEN
                          BEGIN 
                          IF ANAME3 EQ W3 
                          THEN
                              GOTO EQNAMES; 
                          ELSE
                              BEGIN 
                              ANAME = ANAME3; 
                              BNAME = W3; 
                              END 
                          END 
                      ELSE
                          BNAME = W2; 
                      END 
 #    NAMES NOT EQUAL # 
                  ANITEM = ANAME; 
                  BNITEM = BNAME; 
    #COMPARE THE STRINGS ANAME,BNAME AND COLLATE                       #
                  IF AN03[0] NQ BN03[0] THEN
                      BEGIN 
                      LOW = 0;   #START COLLATING AT CHAR 0            #
                      GOTO COLLATE; 
                      END 
                  IF AN46[0] NQ BN46[0] THEN
                      BEGIN 
                      LOW = 4;
                      GOTO COLLATE; 
                      END 
                  LOW = 7;
COLLATE:                    #AT THIS POINT WE KNOW APPROX WHERE THE 
                              *DIFFERENCE LIES ,WITHIN AT MOST 4 CHARS #
                    FOR CHAR = LOW*6 STEP 6 UNTIL 54  DO
                      BEGIN 
                      IND=B<CHAR,3>ANAME; 
                      REM=B<CHAR+3,3>ANAME; 
                      ACHAR=C<REM,1>TABLE[IND]; 
  
                      IND=B<CHAR,3>BNAME; 
                      REM=B<CHAR+3,3>BNAME; 
                      BCHAR=C<REM,1>TABLE[IND]; 
  
                      IF ACHAR EQ BCHAR THEN
                          TEST; 
                      IF ACHAR GR BCHAR THEN
                          BEGIN 
                          GREATER=TRUE; 
                          RETURN; 
                          END 
                      RETURN; 
                      END 
 EQNAMES: 
                  IF CODE EQ PNXR 
                  THEN
                      BEGIN 
                      ANAME = GETQUICK(PNTLINE,PNT$,IA);
                      BNAME = GETQUICK(PNTLINE,PNT$,IB);
                      END 
                  ELSE
                      BEGIN 
                      ANAME = GETQUICK(DNTLINE,DNT$,IA);
                      BNAME = GETQUICK(DNTLINE,DNT$,IB);
                      END 
                  IF ANAME GR BNAME 
                  THEN
                      GREATER = TRUE; 
                  IF ANAME EQ BNAME 
                  THEN
                      EQUAL = TRUE;   # LINES SAME SO EQUAL # 
  
                  END        #COMPARE                                  #
  
                  $BEGIN
                  PROC DMPPTR (NAM,A,B);
                      BEGIN 
                      ITEM A       I; 
                      ITEM B       I; 
                      ITEM NAM     C(10); 
                      ITEM AN      I; 
                      ITEM AV1     I; 
                      ITEM AV2     I; 
                      ITEM BN      I; 
                      ITEM BV1     I; 
                      ITEM BV2     I; 
                      ITEM I       I; 
                      ITEM J       I; 
  
                      I = A * 2 + ASTART;   # GET REAL ADDRESS #
                      J = B * 2 + ASTART; 
                      AN = GETQUICK(WORK1WORD,WORK1$,I);
                      BN = GETQUICK(WORK1WORD,WORK1$,J);
                    AV1 = B<0,44>AN;
                    AV2 = B<44,16>AN; 
                    BV1 = B<0,44>BN;
                    BV2 = B<44,16>BN; 
                      I = I + 1;
                      J = J + 1;
                      AN = GETQUICK(WORK1WORD,WORK1$,I);
                      BN = GETQUICK(WORK1WORD,WORK1$,J);
                      OUTPUT(9, NAM, DEC(A),AN,DEC(AV1),DEC(AV2), 
                          DEC(B),BN,DEC(BV1),DEC(BV2)); 
                      END 
                  $END
  
  
  
 #
          A VERSION OF QUICKSORT FROM KNUTH, VOL 3, PP 116-117. 
  
          SINCE EACH ENTRY CONTAINS 2 WORDS, WE SORT USING INDEXES
              RATHER THAN ACTUAL TABLE ADDRESSES.  THE ROUTINES "SWOP", 
              "COMPARE", AND "DMPPTR" BIAS THE INDEXES INTO ADDRESSES-
              (BUT WE DON"T HAVE TO WORRY ABOUT THAT...)
 #
  
              $BEGIN
              IF DMPS 
              THEN
                  OUTPUT (4,"QSORT2",DEC(ASTART),DEC(ASIZE),
 #     SET LAST + 1 TO INFINITE AND FIRST - 1 TO LOWEST                #
                  DEC(BBASE));
              $END
  
              SP = BBASE;          # SET STACK EMPTY #
              SETFIELD (WORK1WORD,WORK1$,ASTART-1,
                  O"47474747474747474747");   # = SIGN LOWEST # 
                  # BINARY ZERO HIGHEST # 
              SETFIELD (WORK1WORD,WORK1$,ASTART+1+ASIZE*2,0); 
              IF  ASIZE LQ M  THEN  GOTO Q9;     # SMALL SORT..INSERT  #
              L = 0;
              R = ASIZE - 1;
Q2:                                # BEGIN NEW STAGE #
              I = L;
              J = R + 1;           # IMPLIED: K = K[L] #
                  $BEGIN
                  IF  SDMP  THEN   DMPPTR("Q2", I,J); 
                  $END
Q3:                                # COMPARE K[I] : K # 
              FOR  I = I + 1 STEP 1 WHILE I LQ J  DO
                  BEGIN 
                  COMPARE(I,L); 
                  IF  GREATER OR EQUAL  THEN  GOTO Q4;
                  END 
Q4:                                # COMPARE K : K[J] # 
                  $BEGIN
                  IF  SDMP  THEN  DMPPTR("Q4",I,L); 
                  $END
              FOR  J = J - 1 STEP -1 WHILE J GQ I-1  DO 
                  BEGIN 
                  COMPARE(L,J); 
                  IF  GREATER OR EQUAL  THEN GOTO Q5; 
                  END 
Q5:                                # TEST I : J # 
                  $BEGIN
                  IF  SDMP  THEN  DMPPTR("Q5",L,J); 
                  $END
              IF  J LQ I  THEN
                  BEGIN 
                  SWOP(L,J);
                      $BEGIN
                      IF  SDMP  THEN DMPPTR("Q5SWOP",L,J);
                      $END
                  GOTO Q7;
                  END 
Q6:                                # EXCHANGE # 
              SWOP(I,J);
                  $BEGIN
                  IF  SDMP  THEN  DMPPTR("Q6",I,J); 
                  $END
              GOTO Q3;
Q7:                                # PUT ON STACK # 
                  $BEGIN
                  IF  SDMP  THEN
                      OUTPUT(6,"Q7",DEC(L),DEC(I),DEC(J),DEC(R),DEC(M));
                  $END
              IF  R - J GQ J - L AND J - L GR M  THEN 
                  BEGIN 
                  SIT[0] = J + 1; 
                  SIB[0] = R; 
                  SP = SP + 1;
                  SETFIELD(WORK1WORD,WORK1$,SP,SI[0]);
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4, "STACKED1",DEC(SP),DEC(SIT[0]), 
                             DEC(SIB[0]));
                      $END
                  R = J - 1;
                  GOTO Q2;
                  END 
  
              IF  J - L GR R - J AND R - J GR M  THEN 
                  BEGIN 
                  SIT[0] = L; 
                  SIB[0] = J - 1; 
                  SP = SP + 1;
                  SETFIELD(WORK1WORD,WORK1$,SP,SI[0]);
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4, "STACKED2",DEC(SP),DEC(SIT[0]), 
                             DEC(SIB[0]));
                      $END
                  L = J + 1;
                  GOTO Q2;
                  END 
  
              IF  R - J GR M AND M GQ J - L  THEN 
                  BEGIN 
                  L = J + 1;
                      $BEGIN
                      IF  SDMP  THEN OUTPUT(2,"RESET L", DEC(L)); 
                      $END
                  GOTO Q2;
                  END 
  
              IF  J - L GR M AND M GQ R - J  THEN 
                  BEGIN 
                  R = J - 1;
                      $BEGIN
                      IF  SDMP  THEN OUTPUT(2,"RESET R",DEC(R));
                      $END
                  GOTO Q2;
                  END 
  
 Q8:                         # TAKE OFF STACK # 
              IF  SP GR BBASE  THEN 
                  BEGIN 
                  SI[0] = GETQUICK(WORK1WORD, WORK1$,SP); 
                  SP = SP - 1;
                  L = SIT[0]; 
                  R = SIB[0]; 
                      $BEGIN
                      IF  SDMP  THEN
                          OUTPUT(4,"UNSTACKED",DEC(SP),DEC(L),DEC(R));
                      $END
                  GOTO Q2;
                  END 
  
 Q9:                               # STRAIGHT INSERTION SORT #
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                      OUTPUT(1,"Q9"); 
                      OUTPUT(4,"INDEX","NAME","POINTER","LINE");
                      FOR  L = ASTART STEP 2 UNTIL ASTART+(ASIZE*2)-1 DO
                          BEGIN 
                          I = L + 1;
                          K = GETQUICK(WORK1WORD,WORK1$,L); 
                          J = GETQUICK(WORK1WORD,WORK1$,I); 
                         I = B<0,44>K;
                         K = B<44,16>K; 
                          OUTPUT(4,DEC(L),J,DEC(I),DEC(K)); 
                          END 
                      END 
                  $END
  
              SP = BBASE; 
              K = (SP - ASTART ) / 2;  # DE-INDEX IT #
              FOR  R = 1 STEP 1 UNTIL ASIZE-1  DO 
                  BEGIN 
                  L = R - 1;
                  J = R * 2 + ASTART;       # BUILD ACTUAL ADDRESS #
                  I = J - 2;
                  KI1 = GETQUICK(WORK1WORD,WORK1$,I); 
                  KI2 = GETQUICK(WORK1WORD,WORK1$,I+1); 
                  K1 = GETQUICK(WORK1WORD,WORK1$,J);
                  K2 = GETQUICK(WORK1WORD,WORK1$,J+1);
Q9S3: 
                  COMPARE(R,L); 
                  IF  GREATER OR EQUAL  THEN  GOTO Q9S5;
                  SETFIELD(WORK1WORD,WORK1$,SP,K1); 
                  SETFIELD(WORK1WORD,WORK1$,SP+1,K2); 
Q9S4: 
                  SETFIELD(WORK1WORD,WORK1$,I+2,KI1); 
                  SETFIELD(WORK1WORD,WORK1$,I+3,KI2); 
                  L = L - 1;
                  I = I - 2;
                  IF  L GQ 0  THEN
                      BEGIN 
                      KI1 = GETQUICK(WORK1WORD,WORK1$,I); 
                      KI2 = GETQUICK(WORK1WORD,WORK1$,I+1); 
                      COMPARE(K,L); 
                      IF  NOT GREATER AND NOT EQUAL  THEN GOTO Q9S4;
                      END 
Q9S5: 
                  IF  I + 2 NQ J  THEN
                      BEGIN 
                      SETFIELD(WORK1WORD,WORK1$,I+2,K1);
                      SETFIELD(WORK1WORD,WORK1$,I+3,K2);
                      END 
                  END              # OF Q9 #
  
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                      OUTPUT(1,"Q9END");
                      OUTPUT(4,"INDEX","NAME","POINTER","LINE");
                      FOR  L = ASTART STEP 2 UNTIL ASTART+(ASIZE*2)-1 DO
                          BEGIN 
                          I = L + 1;
                          K = GETQUICK(WORK1WORD,WORK1$,L); 
                          J = GETQUICK(WORK1WORD,WORK1$,I); 
                          I = B<0,44>K; 
                          K = B<44,16>K;
                          OUTPUT(4,DEC(L),J,DEC(I),DEC(K)); 
                          END 
                      END 
                  $END
              END            #OF QSORT2                                #
          CONTROL EJECT;
          PROC   DNXREF(ASTART,ASIZE ); 
              BEGIN 
  
    #THIS PROC PRINTS THE REFERENCED DATA NAMES ,USING THE VECTOR BUILT 
* BY  PTRBLD  AFTER IT HAS BEEN SORTED
*                                                                     # 
              ITEM  ASTART;  #ADDR OF FIRST ENTRY                      #
              ITEM  ASIZE;   #LENGTH OF TABLE                          #
              ITEM  COL      I; 
              ARRAY APTR [0]; 
                  BEGIN 
                  ITEM DNTADR U(0,0,44); #ADDR OF DNT ENTRY#
                  ITEM FIRSTUSE U(0,44,16); #POINTER TO FIRST ENTRY 
                              *                             IN SORTED 
                              *      XRV                               #
                  ITEM APTRITEM I(0,0,60);
                  ITEM FIRST10CH U(0,0,60); 
                  END 
              ARRAY XRV [0];
                  BEGIN 
                  ITEM XRVDNT U(0,0,44); #ADDR OF ITEM IN AWRT# 
                  ITEM XRVLINE U(0,44,16); #LINE NO. OF NAME USAGE# 
                  ITEM XRVITEM I(0,0,60); 
                  END 
              DEF DNAMPOS    #0#;  # DNAMPOS _ REFSIZE
                                     ARE USED FOR PAGE LAYOUT... #
              DEF DNAMLNT    #30#; # MAX NAME LENGTH #
              DEF LINEPOS    #31#;
              DEF COLPOS     #37#;
              DEF REFPOS     #50#; # NORMAL STARTING COL FOR REFS # 
              DEF MINPW      #70#; # MIN PW FOR NAOMAL LIST FORMAT #
              DEF OPGAPLNTH  #3#; 
              DEF LINENOLNT  #5#; 
              DEF COLLNT     #2#; 
              DEF REFSIZE    #6#; 
  
              DEF SSPACE     #1#; 
              DEF PLINELNTH  #132#; # NOMINAL LINE LENGTH # 
              ITEM   OPLINE   C(PLINELNTH); 
              ITEM CURNAM   U;      #DNT ADR OF CURRENT NAME           #
              ITEM XRVIND;   #   INDEX INTO XRV                        #
              ITEM NOOFNAMES; 
              BASED ARRAY CLEARLINE[0]; 
                  BEGIN 
                  ITEM OUTLINE I(0,0,60); 
                  END 
              ITEM  REFCOL;  #START COL. FOR REFS ON PAGE.             #
              ITEM TENSPACES C(10)="          ";
              DEF PNXR       #1#;  # PNT FLAG # 
              ITEM NAMELOOP  I;   #CONTROL COUNTER FOR NAMELIST        #
  
  
  
              PROC NEWLINE; 
    #PROC TO SPACE FILL REST OF LINE, 
*   PRINT THE CURRENT LINE ,THEN CLEAR THE LINE.                      # 
                  BEGIN 
                  C<REFCOL,PLINELNTH - REFCOL >OPLINE = TENSPACES;
                  CBLIST(SSPACE,OPLINE,CC$PW);
                  FOR REFCOL = 0 STEP 10 UNTIL PLINELNTH DO 
                      C<REFCOL,10>OPLINE = TENSPACES; 
                  REFCOL =COL;
                  END 
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(3, "DNXREF", DEC(ASTART), DEC(ASIZE)); 
              IF  XDMP  THEN
                  WORKOUT;
              $END
              IF  CC$PW LS MINPW  THEN
                  COL = REFPOS - REFSIZE;        # SET FOR NARROW LIST #
              ELSE
                  COL = REFPOS;                  # SET NORMAL LIST #
              P<CLEARLINE>=LOC(OPLINE); 
              I = PLINELNTH/ 10 - 1;
              FOR J =0 STEP 1 UNTIL I  DO 
                  OUTLINE[J] = TENSPACES; 
    # 
*                                                                     # 
              NOOFNAMES =  ASIZE-1; 
              CURNAM =  0;
              I= ASTART;
              FOR NAMELOOP = 0  STEP 1 UNTIL NOOFNAMES DO 
                  BEGIN 
                  APTRITEM = GETQUICK (WORK1WORD,WORK1$,I); 
                  CURNAM =  DNTADR[0];    #ADR OF DNT ENTRY            #
                  XRVIND =  FIRSTUSE[0];   #INDEX TO START OF REF LIST #
                  I=I+1;
                  APTRITEM = GETQUICK (WORK1WORD,WORK1$,I); 
                  OUTLINE[0]=FIRST10CH[0];    #FIRST THIRD OF NAME     #
                  IF CODE EQ PNXR THEN
                      BEGIN 
                      REALPNT = VIRTUAL(PNT$,CURNAM); 
                      K = PNTCOLUMN[REALPNT]; 
                      J = PNTLINE[REALPNT]; 
                      END 
                  ELSE
                      BEGIN 
                      REALDNT = VIRTUAL(DNT$,CURNAM); 
                      K = DNTCOLUMN[REALDNT]; 
                      J = DNTLINE[REALDNT]; 
                      END 
  
                  GETNAME(CURNAM);   # GET NAME FROM NAME TABLE # 
                  OUTLINE[1] = W2;
                  OUTLINE[2] = W3;   # MOVE NAME TO PRINT # 
                  IF J EQ 0 
                  THEN
    #      IF THE LINE NO. OF THE DECLARATION IS ZERO,THE 
*          DATA-NAME IS FOR A "SPECIAL-"REGISTER" .                   # 
                      C<LINEPOS,9>OPLINE = " SPECIAL "; 
                  ELSE
                      BEGIN 
                      C<LINEPOS,LINENOLNT>OPLINE = DEC(J);
                      IF K EQ 0 
                      THEN  #  THIS IS A DDL ITEM # 
                          C<COLPOS,3>OPLINE = "DDL";
                      ELSE
                          C<COLPOS,COLLNT>OPLINE = DEC(K);
                      END 
                  REFCOL = COL; 
NEXTREF:  
                        XRVITEM = GETQUICK (WORK1WORD,WORK1$,XRVIND); 
                  IF  CURNAM EQ XRVDNT[0] THEN
                      BEGIN  #MOVE THE USAGE LINE NOS. TO THE PRINT LINE
                              *#
                      IF  (REFCOL + REFSIZE) GR CC$PW  THEN 
                          NEWLINE;
                      C<REFCOL,REFSIZE>OPLINE = DEC(XRVLINE[0]);
                      REFCOL = REFCOL + REFSIZE;
                      XRVIND = XRVIND + 1;
                      GOTO  NEXTREF;
                      END 
                  NEWLINE;
                  I=I+1;
                  END 
              END            #OF DNXREF                                #
          CONTROL EJECT;
          PROC UDNXREF(ASTART,ASIZE); 
  
    #REPORT THE UNUSED DATA-NAMES . 
*                                                                     # 
              BEGIN 
              ARRAY AA[0];
                  BEGIN 
                  ITEM PDADDR U(0,0,44); #POINTS TO UNUSED PNT/DNT# 
                  ITEM FILL U(0,44,16); 
                  ITEM AAITEM I(0,0,60);
                  ITEM FIRST10CH U(0,0,60); 
                  END 
              ITEM  ASTART,ASIZE;    #FORMAL PARAMETERS                #
              ITEM COLDECL;  #COL NO OF DECLERATION                    #
              ITEM    MAX    I; 
              ITEM    LBASE  I; 
              ITEM OLINE; 
              DEF COL        #40#;
              ITEM    OPLINE C(COL);
              BASED ARRAY OUTNM[0]; 
                  ITEM OUTITEM; 
              DEF PNXR       #1#; 
  
              ITEM SPACES C(10)="          "; 
              DEF LINEPOS    #31#;
              DEF LLNTH      #6#; 
              DEF COLPOS     #37#;
              DEF COLLNTH    #3#; 
              DEF ENTWDS     #4#; 
              BASED ARRAY OUTLINE[0]; 
                  ITEM LINE C(10);
              DEF SSPACE     #1#; 
              $BEGIN
              IF  DMPS  THEN
                  OUTPUT(3, "UDNXREF", DEC(ASTART), DEC(ASIZE));
              IF  XDMP  THEN
                  WORKOUT;
              $END
              J = ASTART; 
              MAX = ASIZE;
              LBASE = LOC(OPLINE);
              P<OUTLINE> = LBASE; 
              P<OUTNM> = LBASE; 
              FOR I =  1   STEP 1  UNTIL MAX  DO
                  BEGIN 
                  AAITEM = GETQUICK (WORK1WORD,WORK1$,J); 
                  J=J+1;
                  X =  PDADDR[0]; 
                  IF CODE EQ  PNXR THEN 
                      OLINE = GETQUICK(PNTLINE,PNT$,X); 
                  ELSE
                      OLINE = GETQUICK(DNTLINE,DNT$,X); 
                  IF OLINE EQ 0 THEN
                      GOTO  SPECIAL;   # IGNORE UNUSED SP.REGS.        #
                  OPLINE = SPACES;
                  C<LINEPOS,LLNTH>OPLINE= DEC(OLINE); 
                  AAITEM = GETQUICK (WORK1WORD,WORK1$,J); 
                  OUTITEM[0]=FIRST10CH[0];
                  IF PNXR EQ CODE THEN
                      BEGIN 
                      COLDECL = GETQUICK(PNTCOLUMN,PNT$,X); 
                      END 
                  ELSE
                      BEGIN 
                      COLDECL = GETQUICK(DNTCOLUMN,DNT$,X); 
                      END 
                  GETNAME(X);  # GET NAME FROM NAME TABLE # 
                  OUTITEM[1] = W2;   # MOVE NAME TO PRINT # 
                  OUTITEM[2] = W3;
                  IF COLDECL EQ 0 
                    THEN
                      C<COLPOS,3>OPLINE = "DDL";
                  ELSE
                      C<COLPOS,COLLNTH>OPLINE  = DEC(COLDECL);
                  CBLIST(SSPACE,OPLINE,COL);
SPECIAL:  
                    J=J+1;
                  END 
              END            #OF URDNXREF                              #
          CONTROL EJECT;
          PROC READT(REC,LNTH); 
              BEGIN 
              ITEM    LNTH   I; 
              ARRAY  REC [0:4]; 
                  ITEM RWD   I(0,0,60); 
  
              IF  INDX GQ TSZ  THEN 
                  BEGIN 
                  LNTH = -1;
                  INDX = TST;      # RESET #
                  RETURN;    # ALL DONE # 
                  END 
              RWD[0] = GETQUICK(WORK1WORD,WORK1$,INDX); 
             I = B<0,44>RWD[0]; 
              IF  INCR EQ 1  THEN 
                  LNTH = 1; 
              ELSE
                  BEGIN 
                  J = INDX + 1; 
                  RWD[1] = GETQUICK(WORK1WORD,WORK1$,J);
                  IF  CODE EQ DNXR  THEN
                      BEGIN 
                      RWD[4] = GETQUICK(DNTLINE,DNT$,I);
                      END 
                  ELSE
                      BEGIN 
                      RWD[4] = GETQUICK(PNTLINE,PNT$,I);
                      END 
                  GETNAME(I);   # GET NAME FROM NAME TABLE #
                  RWD[2] = W2;  # MOVE NAME TO PRINT #
                  RWD[3] = W3;
                  LNTH = 5; 
                  END 
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                      J = LNTH + 3; 
                     K = B<44,16>RWD[0];
                      OUTPUT(J,"SENT",DEC(INDX),DEC(I),DEC(K),RWD[1], 
                          RWD[2],RWD[3],DEC(RWD[4])); 
                      END 
                  $END
              INDX = INDX + INCR; 
              RETURN; 
              END     #READT# 
          CONTROL EJECT;
          PROC WRITET(REC,LNTH);
              BEGIN 
              ARRAY REC [0:4];
                  ITEM RWD   I(0,0,60); 
              ITEM    LNTH   I; 
  
              SETFIELD(WORK1WORD,WORK1$,INDX,RWD[0]); 
              IF  LNTH GR 1  THEN 
                  BEGIN 
                  I = INDX + 1; 
                  SETFIELD(WORK1WORD,WORK1$,I,RWD[1]);
                  END 
                  $BEGIN
                  IF  SDMP  THEN
                      BEGIN 
                     I = B<0,44>RWD[0]; 
                     J = B<44,16>RWD[0];
                      IF  LNTH EQ 1  THEN 
                          K = 4;
                      ELSE
                          K = 5;
                      OUTPUT(K,"RCVD.",DEC(INDX),DEC(I),DEC(J),RWD[1]); 
                      END 
                  $END
              INDX = INDX + INCR; 
              RETURN; 
              END     #WRITET#
          CONTROL EJECT;
          PROC WORKOUT; 
              $BEGIN
              ITEM I; 
              ITEM XST,XMAX;
              BASED ARRAY WORKS [0];
                  BEGIN 
                 ITEM WK1 U(0,29,15); 
                 ITEM WK2 U(0,44,16); 
                  END 
              P<WORKS>=LOC(WA); 
              OUTPUT(7,DEC(ASTART),DEC(ASIZE),
                DEC(BSTART),DEC(BSIZE),DEC(STACK),DEC(LOWER),DEC(UPPER) 
                );
              XMAX = ASTART + ASIZE ; 
              FOR I=ASTART STEP 1 UNTIL XMAX DO 
                  BEGIN 
                  WA = GETQUICK(WORK1WORD,WORK1$,I);
                  OUTPUT(3,DEC(I),DEC(WK1[0]),DEC(WK2[0]) );
                  END 
              XMAX = BSTART + BSIZE;
              FOR I=BSTART STEP 1 UNTIL XMAX DO 
                  BEGIN 
                  WA = GETQUICK(WORK1WORD,WORK1$,I);
                  OUTPUT(3,DEC(I),DEC(WK1[0]),DEC(WK2[0]) );
                  END 
              $END
  
           DEF    DEFSUB     #5#;  #DEFSUB....DEFFOOT ARE USED TO 
                                    CALL CBLIST # 
           DEF    EJECT      #3#; 
           DEF    DEFSUBFOOT #7#; 
           DEF    DEFFOOT    #6#; 
  
          PROC SUBHEAD(N);
    #A TRIVIAL S/R USED TO INTERFACE WITH CBLIST TO SET UP NEW
*  PAGE HEADINGS AND FOOTINGS ,ACCORDING TO A SINGLE PARAMETER.       # 
              BEGIN 
              ITEM N; 
              ARRAY HEADS[3] S(7);
                  BEGIN 
                  ITEM SHEAD C(0,0,70)= 
                    ["  REFERENCED DATA-NAMES        LINE COLUMN
   REFERENCE(S)  ", 
                    "  UNREFERENCED DATA-NAMES      LINE COLUMN 
                ",
                    "  REFERENCED PROCEDURE-NAMES   LINE COLUMN 
  REFERENCE(S)  ",
                    "  UNREFERENCED PROCEDURE-NAMES LINE COLUMN 
                "]; 
                  END 
              CBLIST(DEFSUB,SHEAD[N],70); 
              CBLIST(EJECT);
              CBLIST(DEFSUBFOOT,SHEAD[N],70); 
              END 
  
          CONTROL EJECT;
    # 
*                EXECUTABLE CODE STARTS HERE
*                                                                     # 
          IF NOT CCTXREFLIST[0] THEN
              RETURN; 
          $BEGIN
          IF  CCTCHKOUT NQ 0  THEN # DEBUG MODE ON #
              BEGIN 
                  I = 0;
                  J = 0;
                  K = 6;
                  FOR L = 6 STEP 1 UNTIL 18 DO
                      BEGIN 
                      IF C<K,1>PARAMC[I] EQ "," 
                      THEN
                          J = J + 1;   #NEW PARAM, BUMP PARAM NBR#
                      ELSE
                          BEGIN 
                          IF C<K,1>PARAMC[I] EQ "Y" 
                          THEN
                              BEGIN    # AN OPTION IS SELECTED - SET IT#
                              IF J EQ 0 THEN XDMP = TRUE; 
                              ELSE
                                  IF J EQ 1 THEN UDMP = TRUE; 
                                  ELSE
                                      IF J EQ 2 THEN SDMP = TRUE; 
                                      ELSE FORCEXT = TRUE;
                              END 
                          END 
                  K = K + 1 ; 
                  IF L EQ 9 
                  THEN
                      BEGIN 
                      K = 0;
                      I = I + 1;   # NEW WORD#
                      END 
                  END 
              IF  XDMP OR UDMP OR SDMP OR FORCEXT  THEN 
                  DMPS = TRUE;
              IF DMPS  THEN 
                  OUTPUT(1, "BEGIN XF");
              END 
          $END
          LISTTYP = "CROSS REFERENCE FOR "; 
          CBLIST(DEFPGHED, LISTHED, 110); 
          CBLIST(DEFSUBFOOT,XFFOOT,10);   #CLEAR PREVIOUS FOOTINGS     #
          CBLIST(DEFFOOT,XFFOOT,10);
  
          TLINE=0;
          CODE=DNXR;
    #       USE DNT ON FIRST PASS                                      #
          UPPER = CCTDNTLEN;
          LOWER =1; 
          FOR NO = 1 STEP 1 UNTIL 2 DO
              BEGIN 
              ASTART=1; 
              ASIZE=CCTAWRTLEN; 
              BSTART=1; 
              BSIZE=0;
          $BEGIN
          IF  DMPS  THEN
              OUTPUT(3, "PASS = ", DEC(NO), DEC(UPPER));
          $END
              WORK1WORD[VIRTUAL(WORK1$,1)] = 0;   # CREATE DUMMY ENTRY #
              XRVBLD(ASTART,ASIZE,BSTART,BSIZE,CODE); 
    #           GO THROUGH THE AWRT (ASTART FOR ASIZE) AND BUILD
*               AN XRV(CROSS-REF-VECTOR) (BSTART,ETC) .               # 
  
  
# 
          SORT THE XRV ACCORDING TO DNT/PNT POINTER AND LINE NR 
              PUTTING REFS TO THE SAME NAME TOGETHER... 
# 
  
              IF  NOT TTABALLINCOR[WORK1$] OR FORCEXT  THEN 
                  BEGIN 
                  INDX = BSTART;
                  TST = BSTART; 
                  TSZ = BSIZE + BSTART - 1; 
                  INCR = 1; 
                      $BEGIN
                      IF  DMPS  THEN
                          OUTPUT(5,"SORT1",DEC(INDX),DEC(TST),DEC(TSZ), 
                              DEC(INCR)); 
                      $END
                  SORT1;
                  END 
              ELSE
                  BEGIN 
                  STACK = BSIZE + BSTART + 1;  # SORT NEEDS 1 EXTRA WD #
                  QSORT1(BSTART,BSIZE,STACK); 
                  END 
  
              ASTART = BSIZE+ BSTART; 
    #          FORCE SPACE BETWEEN LISTS                               #
              ASTART = ASTART + 2;  # SORT NEEDS ONE ENTRY AT FRONT # 
  
    #          SCAN THE SORTED XRV (ETC) AND BUILD A LIST 
*             OF POINTERS (ETC) WHICH POINT TO THE FIRST USE
*             OF A DNT/PNT INDEX IN THE SORTED XRV.                   # 
  
              PTRBLD(BSTART,BSIZE,ASTART,ASIZE);
  
# 
          SORT THE LIST ACCORDING TO THE ACTUAL ITEM NAME + LINE NR.
              THE SORTED LIST POINTS BACK TO THE ORIGINAL XRV (NOW
              SORTED).
# 
              IF NOT TTABALLINCOR [WORK1$]
              OR ASIZE GR INCOREMAX 
              OR FORCEXT
              THEN
                  BEGIN 
                  INDX = ASTART;
                  TST = ASTART; 
                  TSZ = ASIZE *2 + ASTART - 1;
                  INCR = 2; 
                      $BEGIN
                      IF  DMPS  THEN
                          OUTPUT(5,"SORT2",DEC(INDX),DEC(TST),DEC(TSZ), 
                              DEC(INCR)); 
                      $END
                  SORT2;     # GO CALL SMERGE # 
                  END 
              ELSE
                  BEGIN 
                  STACK = 2 + ASTART + ASIZE * 2;  # EXTRA ENTRY #
                  QSORT2(ASTART,ASIZE,STACK);    # DO IT IN CORE #
                  END 
  
              SUBHEAD(TLINE); 
              TLINE=TLINE+1;
  
    #         SCAN DOWN THE SECOND SORTED LIST AND PRINT THE NAMES,ETC
*            TOGETHER WITH THE REF. LINE NUMBERS IN THE FIRST SORTED
*           LIST.                                                     # 
  
              DNXREF(ASTART,ASIZE); 
  
  
    #        DISCARD THE SECOND SORTED LIST AND RECREATE IT IN ITS
*            UNSORTED FORM.  I.E. A LIST WHOSE ELEMENTS ARE DNT/PNT 
*            ADDRESSES IN ASCENDING ORDER .                           # 
  
              PTRBLD(BSTART,BSIZE,ASTART,ASIZE);
  
              BSTART = 2 + ASTART + ASIZE * 2;  # EXTRA ENTRY FOR SORT #
  
    #       FROM THE LIST OF USED PNT/DNT ADDRESSES (,ETC)
*           BUILD A LIST(ETC) OF DNT/PNT ADDRESSES WHICH DO NOT 
*           APPEAR IN THE USED LIST. I.E. THE UNUSED DATA-NAMES PROC- 
*           EDURE-NAMES.                                              # 
  
              URPTR(ASTART,ASIZE,BSTART,BSIZE,LOWER,UPPER); 
  
  
# 
          SORT THE UNUSED NAMES LIST
# 
              IF NOT TTABALLINCOR [WORK1$]
              OR BSIZE GR INCOREMAX 
              OR FORCEXT
              THEN
                  BEGIN 
                  INDX = BSTART;
                  TST = BSTART; 
                  TSZ = BSIZE *2 + BSTART - 1;
                  INCR = 2; 
                      $BEGIN
                      IF  DMPS  THEN
                          OUTPUT(5,"SORT2",DEC(INDX),DEC(TST),DEC(TSZ), 
                              DEC(INCR)); 
                      $END
                  SORT2;     # GO CALL SORT/MERGE # 
                  END 
              ELSE
                  BEGIN 
                  STACK = 2 + BSTART + BSIZE * 2;  # EXTRA ENTRY #
                  QSORT2(BSTART,BSIZE,STACK);    # DO IT IN CORE #
                  END 
  
              SUBHEAD(TLINE); 
              TLINE=TLINE+1;
  
              UDNXREF(BSTART,BSIZE);
    #         PRINT OUT THE UNUSED DATA-NAMES , PROCEDURE-NAMES.       #
              CODE = PNXR;
    #         SET UP FOR SECOND PASS(PROCEDURE-NAMES).                 #
              UPPER =  CCTPNTLEN; 
              END 
          CBLIST(9);         #CLOSE TO GET RID OF FOOTINGS             #
          RETURN;            #GO HOME                                  #
          END                #OF XF                                    #
      TERM
