*DECK NS$BNPT 
USETEXT COM$NS
USETEXT CYB$NS
USETEXT DEF$NS
USETEXT DIR$NS
USETEXT FERR$NS 
USETEXT FET$NS
USETEXT IOD$NS
USETEXT NCF$NS
USETEXT NCT$NS
USETEXT NPT$NS
      PROC NS$BNPT;          # BUILD CONFIGURED NPU TABLE              #
  
# TITLE NS$BNPT - BUILD CONFIGURED NPU TABLE.      #
  
      BEGIN    # NS$BNPT #
# 
**    NS$BNPT - BUILD NPU TABLE (NPT).
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE IS PART OF THE INITIALIZATION PROCESS FOR NS.
*     ITS FUNCTION IS TO BUILD THE NPU TABLE. 
* 
*     PROC NS$BNPT
* 
*     ENTRY:  
*       NONE. 
* 
*     EXIT: 
*       APPROPRIATE ERROR MESSAGES SENT.
* 
*     METHOD: 
*       SEARCH NCF INDEX RECORD FOR NPU CROSS REFERENCE TABLE RECORD
*       ENTRY.
*       IF FOUND: 
*         ALLOCATE TSB FOR NPT. 
*         FOR EACH NETRY IN NPU CROSS REFERENCE TABLE:  
*           FORMAT A NPT ENTRY
*           INCREMENT NPU TABLE ORDINAL 
*           SEARCH NCB RECORD FOR A MATCH ON NPU NODE NUMBER, 
*             USE THIS NUMBER TO SEARCH NCT TO ACCESS THE 
*             NETWORK NUMBER.  SAVE THIS NETWORK NUMBER AS
*             THE NEIGHBOR NODE NUMBER IN NPT.  SAVE CURRENT
*             NPU TABLE ORDINAL IN NCT. 
*       ELSE
*         SEND ERROR MESSAGE. 
* 
# 
  
      XREF
        BEGIN 
        PROC NS$MSG;         # DISPATCH MESSAGE                        #
        PROC READ;           # READ A RECORD                           #
        PROC RECALL;         # WAIT FOR OPERATION TO FINISH            #
        PROC REQTSB;         # REQUEST TSB                             #
        PROC RETTSB;         # RETURN TSB                              #
        PROC TSBINFO;        # GET TSB ADDRESS                         #
        END 
  
      DEF MIN$NXR$WC # 3 #;  # MINIMUM NPUXREF TABLE SIZE              #
  
      ITEM BUFL U;           # CALCULATED NPUXREF TABLE BUFFER LENGTH  #
      ITEM ERRCODE U;        # ERROR CODE                              #
      ITEM FETTSBADDR U;     # FET TSB ADDRESS                         #
      ITEM I U;              # LOOP INDEX                              #
      ITEM J U;              # LOOP INDEX                              #
      ITEM NCBDIRORD U;      # NCB DIRECTORY ORDINAL                   #
      ITEM NCTTSBADDR U;     # NCT TSB ADDRESS                         #
      ITEM NPTLENGTH U;      # LENGTH OF NPU TABLE                     #
      ITEM NPTTSBADDR U;     # NPU TABLE TSB ADDRESS                   #
      ITEM NXRDIRORD U;      # NPUXREF TABLE NCF DIRECTORY ORDINAL     #
      ITEM NXRTSBADDR U;     # NPUXREF TABLE TSB ADDRESS               #
      ITEM NXRTSBN U;        # NPUXREF TSB NUMBER                      #
      ITEM SUCCESS B;        # LOOP END INDICATOR                      #
      ITEM TEMP U;           # TEMPORARY                               #
      ITEM TSBSIZE U;        # TSB SIZE                                #
      ITEM UPI U;            # LOOP LIMIT                              #
      ITEM UPJ U;            # LOOP LIMIT                              #
  
      DEF L$NCFER1   # 3 #; 
      DEF DM$NCFER1  # DM$LOCAL+DM$ABORT+DM$NAMLOG #; # ROUTE OPTIONS  #
      ARRAY MSG$NCFER1 [0:0] S(L$NCFER1); 
        BEGIN 
        ITEM NCFER1$TXT C(00,00,25) = # MESSAGE TEXT                   #
          ["BAD NCF NPUXREF RECORD."];
        ITEM NCFER1$END U(02,30,30) = [0]; # END OF TEXT               #
        END 
  
      DEF L$NCFER2   # 3 #; 
      DEF DM$NCFER2  # DM$LOCAL+DM$ABORT+DM$NAMLOG #; # ROUTE OPTIONS  #
      ARRAY MSG$NCFER2 [0:0] S(L$NCFER2); 
        BEGIN 
        ITEM NCFER2$TXT C(00,00,27) = # MESSAGE TEXT                   #
          ["NCB ENTRY NOT FOUND IN NCF."];
        ITEM NCFER2$END U(02,42,18) = [0]; # END OF TEXT               #
        END 
  
      CONTROL EJECT;
  
#     BASED ARRAY POINTERS OF SIOFET AND DIR PRESET IN NS$NSI          #
  
      ERRCODE = 0;
      SUCCESS = FALSE;
      UPI = (DIR$WC[0] - 1)/DIR$ENTRYL; 
      FOR I = 1 STEP 1 WHILE I LQ UPI 
        AND NOT SUCCESS 
      DO
        BEGIN                # FIND NPUXREF TABLE DIRECTORY ENTRY      #
        IF DIR$NCFRT[I] EQ DIR$RT$NX
        THEN                 # FOUND                                   #
          BEGIN 
          SUCCESS = TRUE;    # END LOOP                                #
          NXRDIRORD = I;
          END 
        END 
      IF NOT SUCCESS
      THEN                   # NPUXREF TABLE DIRECTORY ENTRY NOT FOUND #
        NS$MSG(MSG$NCFER1,L$NCFER1,DM$NCFER1); # DAYFILE AND ABORT     #
      BUFL = ((DIR$RL[NXRDIRORD] + PRUSIZE)/PRUSIZE)*PRUSIZE + 1; 
      REQTSB(BUFL,NXRTSBADDR,NXRTSBN);  # GET NPUXREF TABLE BUFFER     #
      FETRAN[0] = TRUE;      # RANDOM ACCESS FILE                      #
      FETFST[0] = NXRTSBADDR;  # FIRST                                 #
      FETIN[0] = NXRTSBADDR;
      FETOUT[0] = NXRTSBADDR; 
      FETLMT[0] = NXRTSBADDR + BUFL;  # LIMIT                          #
      FETRR[0] = DIR$RSA[NXRDIRORD];  # RANDOM REQUEST                 #
      READ(SIOFET);          # READ NPUXREF TABLE                      #
      RECALL(SIOFET); 
      P<NXR$NCF> = NXRTSBADDR;  # FORMAT NPUXREF TABLE                 #
      IF FETSTAT[0] NQ RDEOR
        OR NXR$ID[0] NQ NXR$IDENT 
        OR NXR$WC[0] LS MIN$NXR$WC
      THEN                   # BAD NPUXREF TABLE                       #
        NS$MSG(MSG$NCFER1,L$NCFER1,DM$NCFER1); # DAYFILE AND ABORT     #
      TEMP = (NXR$WC[0] - 1)/NXR$ENTRYL;  # NO. OF ENTRIES IN NXR      #
      NPTLENGTH = TEMP*NPT$ENTRYL + NPT$HDRL; 
      REQTSB(NPTLENGTH,NPTTSBADDR,NPTTSBN);  # GET NPU TABLE BUFFER    #
      P<NPT$HEADER> = NPTTSBADDR;  # FORMAT NPU TABLE HEADER           #
      NPT$ID[0] = NPT$IDENT;  # SET TABLE IDENTIFIER                   #
      NPT$EC[0] = TEMP;      # ENTRY COUNT                             #
      P<NPT$ENTRY> = NPTTSBADDR + NPT$HDRL;  # FORMAT NPT ENTRIES      #
      TSBINFO(TSBSIZE,NCTTSBADDR,NCTTSBN);  # GET NCT                  #
      P<NCT$NS> = NCTTSBADDR; 
      UPI = TEMP;            # NO. OF ENTRIES IN NPUXREF               #
      FOR I = 1 STEP 1 UNTIL UPI
      DO
        BEGIN                # BUILD NPU TABLE ENTRIES                 #
        NPT$NPNAME[I] = NXR$NPNAME[I];  # NPU NAME                     #
        NPT$NN[I] = NXR$NPNID[I];  # NODE NUMBER                       #
        NPT$NPUVAR[I] = NXR$NPUVAR[I];  # NPU VARIANT NAME             #
        NPT$F$DFDM[I] = NXR$F$F2[I];  # NPU DEFAULT DUMP FLAG          #
  
        UPJ = (DIR$WC[0] - 1)/DIR$ENTRYL; 
        SUCCESS = FALSE;
        FOR J = 1 STEP 1 WHILE J LQ UPJ 
          AND NOT SUCCESS 
        DO
          BEGIN  # SEARCH NCF OPLD FOR NCB WITH MATCHING NODE NUMBER   #
          IF DIR$NCFRT[J] EQ DIR$RT$NC
            AND DIR$NCFNID[J] EQ NPT$NN[I]
          THEN               # NCB DIRECTORY ENTRY FOUND               #
            BEGIN 
            SUCCESS = TRUE;  # END LOOP                                #
            NCBDIRORD = J;
            END 
          END 
        IF NOT SUCCESS
        THEN                 # NCB DIRECTORY ENTRY NOT FOUND           #
          NS$MSG(MSG$NCFER2,L$NCFER2,DM$NCFER2); # DAYFILE AND ABORT   #
        NPT$NCBSZ[I] = DIR$NCBSZ[NCBDIRORD];
        NPT$NCBRI[I] = DIR$RSA[NCBDIRORD];  # NCB RSA                  #
        FOR J=1 STEP 1 UNTIL NCT$EC[0] DO 
          BEGIN              # FILL IN NEIGHBOR NODE NUMBERS           #
          IF NCT$NNN[J] EQ NPT$NN[I]
          THEN               # THIS IS A NEIGHBOR                      #
            BEGIN 
            NCT$NTORD[J] = I;  # PUT NPT ORDINAL IN NCT ENTRY          #
            IF NPT$NBN1[I] EQ 0 
            THEN             # THERE IS ROOM FOR ANOTHER NEIGHBOR NODE #
              BEGIN 
              NPT$NBRS[I] = NPT$NBRS[I]*LSHIFT8; # SHIFT NEIGHBORS     #
              NPT$NBN6[I] = NCT$NODE[J];  # ADD NEIGHBOR NODE          #
              END 
            END 
          END 
        END 
      RETTSB(NXRTSBN);       # RETURN NPUXREF TABLE TSB                #
      END TERM
