*DECK NS$BNCT 
USETEXT COM$NS
USETEXT DEF$NS
USETEXT DIR$NS
USETEXT FERR$NS 
USETEXT FET$NS
USETEXT IOD$NS
USETEXT NCF$NS
USETEXT NCT$NS
      PROC NS$BNCT;          # BUILD NODE CONNECTION TABLE             #
  
# TITLE NS$BNCT - BUILD NODE CONNECTION TABLE.                         #
  
      BEGIN    # NS$BNCT #
# 
**    NS$BNCT - BUILD NODE CONNECTION TABLE (NCT).
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE IS PART OF THE INITIALIZATION PROCESS FOR NS.
*     ITS FUNCTION IS TO BUILD THE NODE CONNECTION TABLE. 
* 
*     PROC NS$BNCT
* 
*     ENTRY:  
*       NONE. 
* 
*     EXIT: 
*       ERROR MESSAGE(S) SENT IF ERROR IS DETECTED. 
* 
*     METHOD: 
*       SEARCH NCF INDEX RECORD FOR PHYSICAL LINK CROSS REFERENCE 
*       ENTRY TABLE RECORD. 
*       IF FOUND: 
*         FOR EACH ENTRY IN PHYSICAL LINK CROSS REFERENCE TABLE:  
*           INCREMENT NCT ENTRY COUNT.
*           IF ENTRY IS A COUPLER ENTRY, MAKE A HOST NODE ENTRY IN
*             NCT.
*           ELSE
*             MAKE TWO NPU NODE ENTRIES IN NCT. 
*             INCREMENT NCT ENTRY COUNT.
*       ELSE
*         SEND ERROR MESSAGES.
* 
# 
  
      XREF
        BEGIN 
        PROC EXREDUC;        # REDUCE TSB SIZE                         #
        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$PHL$WC # 3 #;  # MINIMUM PHYLINK TABLE WORD COUNT        #
  
      ITEM BUFL U;           # CALCULATED PHYLINK TABLE BUFFER LENGTH  #
      ITEM ERRCODE U;        # ERROR CODE                              #
      ITEM FETTSBADDR U;     # FET TSB ADDRESS                         #
      ITEM I U;              # LOOP INDEX                              #
      ITEM NCTORD U;         # NCT ORDINAL                             #
      ITEM NCTTSBADDR U;     # NCT TSB ADDRESS                         #
      ITEM ORD U;            # NCT ORDINAL                             #
      ITEM PHLDIRORD U;      # NCF DIRECTORY ORDINAL OF PHYLINK TABLE  #
      ITEM PHLTSBADDR U;     # PHYLINK TABLE TSB ADDRESS               #
      ITEM PHLTSBN U;        # PHYLINK TABLE TSB NUMBER                #
      ITEM SUCCESS B;        # LOOP END INDICATOR                      #
      ITEM TSBSIZE U;        # TSB SIZE                                #
      ITEM UP U;             # LOOP LIMIT                              #
  
      DEF L$NCFERR   # 3 #; 
      DEF DM$NCFERR  # DM$LOCAL+DM$ABORT+DM$NAMLOG #; # ROUTE OPTIONS  #
      ARRAY MSG$NCFERR [0:0] S(L$NCFERR); 
        BEGIN 
        ITEM NCFERR$TXT C(00,00,23) = # MESSAGE TEXT                   #
          ["BAD NCF PHYLINK RECORD."];
        ITEM NCFERR$END U(02,18,42) = [0]; # END OF TEXT               #
        END 
  
      CONTROL EJECT;
  
#     BASED ARRAY POINTERS OF SIOFET AND DIR PRESET IN NS$NSI          #
  
      ERRCODE = 0;
      SUCCESS = FALSE;
      UP = (DIR$WC[0] - 1)/DIR$ENTRYL;  # NUMBER OF ENTRIES IN DIR     #
      FOR I = 1 STEP 1 WHILE I LQ UP
        AND NOT SUCCESS 
      DO
        BEGIN                # FIND PHYLINK DIRECTORY ENTRY            #
        IF DIR$NCFRT[I] EQ DIR$RT$PH
        THEN                 # FOUND                                   #
          BEGIN 
          SUCCESS = TRUE;    # END LOOP                                #
          PHLDIRORD = I;
          END 
        END 
      IF NOT SUCCESS
      THEN                   # PHYLINK DIRECTORY ENTRY NOT FOUND       #
        NS$MSG(MSG$NCFERR,L$NCFERR,DM$NCFERR); # DAYFILE AND ABORT     #
      BUFL = ((DIR$RL[PHLDIRORD] + PRUSIZE)/PRUSIZE)*PRUSIZE + 1; 
      REQTSB(BUFL,PHLTSBADDR,PHLTSBN);  # GET PHYLINK TABLE BUFFER     #
      FETRAN[0] = TRUE;  # NCF IS A RANDOM ACCESS FILE                 #
      FETFST[0] = PHLTSBADDR;  # FIRST                                 #
      FETIN[0] = PHLTSBADDR;
      FETOUT[0] = PHLTSBADDR; 
      FETLMT[0] = PHLTSBADDR + BUFL;  # LIMIT                          #
      FETRR[0] = DIR$RSA[PHLDIRORD];  # RANDOM REQUEST                 #
      READ(SIOFET);          # READ PHYLINK RECORD FROM NCF            #
      RECALL(SIOFET); 
      P<PHL$NCF> = PHLTSBADDR;  # FORMAT PHYLINK TABLE                 #
      IF FETSTAT[0] NQ RDEOR
        OR PHL$ID[0] NQ PHL$IDENT 
        OR PHL$WC[0] LS MIN$PHL$WC
      THEN                   # BAD PHYLINK RECORD                      #
        NS$MSG(MSG$NCFERR,L$NCFERR,DM$NCFERR); # DAYFILE AND ABORT     #
      REQTSB(DIR$RL[PHLDIRORD],NCTTSBADDR,NCTTSBN);  # GET NCT BUFFER  #
      P<NCT$NS> = NCTTSBADDR;  # FORMAT NCT                            #
      NCT$ID[0] = NCT$IDENT;
      NCTORD = 0;            # INITIALIZE                              #
      UP = (PHL$WC[0] - 1)/PHL$ENTRYL;  # NO. OF ENTRIES               #
      FOR I = 1 STEP 1 UNTIL UP 
      DO
        BEGIN                # BUILD EACH NCT ENTRY                    #
        NCT$LISTFP[NCTORD] = NCTORD + 1;  # SET FORWARD LIST POINTER   #
        NCTORD = NCTORD + 1;
        IF NOT PHL$F$LTRK[I]
        THEN                 # ITS A COUPLER PHYLINK TABLE ENTRY       #
          BEGIN 
          NCT$NODE[NCTORD] = PHL$PLP1[I];  # COUPLER NODE NUMBER       #
          NCT$NNN[NCTORD] = PHL$PLNID1[I];  # NPU NODE NUMBER          #
          END 
        ELSE                 # ITS A TRUNK PHYLINK TABLE ENTRY         #
          BEGIN 
          ORD = NCTORD;  # CURRENT NCT ORDINAL                         #
          NCT$NODE[ORD] = PHL$PLNID1[I];  # NPU NODE NUMBER            #
          NCT$PN[ORD] = PHL$PLP1[I];  # PORT NUMBER                    #
          NCT$NNN[ORD] = PHL$PLNID2[I];  # NEIGHBOR NODE NUMBER        #
          NCT$LISTBP[ORD] = NCTORD - 1;  # NCT BACKWARD PTR            #
          NCT$LISTFP[ORD] = NCTORD + 1;  # NCT FORWARD PTR             #
          NCTORD = NCTORD + 1;
          NCT$NODE[NCTORD] = PHL$PLNID2[I];  # NPU NODE NUMBER         #
          NCT$PN[NCTORD] = PHL$PLP2[I];  # PORT NUMBER                 #
          NCT$NNN[NCTORD] = PHL$PLNID1[I];  # NEIGHBOR NODE NUMBER     #
          END 
        NCT$LISTBP[NCTORD] = NCTORD - 1;  # SET BACKWARD LIST POINTER  #
        END 
      NCT$LISTFP[NCTORD] = 0;          # SET FORWARD PTR OF LAST NCT   #
      NCT$LISTTP[0] = NCTORD;  # LIST TAIL POINTER                     #
      NCT$EC[0] = NCTORD;    # ENTRY COUNT                             #
      BUFL = DIR$RL[PHLDIRORD] - (NCTORD*NCT$ENTRYL + NCT$HDRL);
      EXREDUC(BUFL,NCTTSBN,0,NCTTSBADDR); 
      RETTSB(PHLTSBN);       # RETURN PHYLINK TABLE BUFFER             #
      END TERM
