*DECK NS$N00
USETEXT COM$NS
USETEXT DEF$NS
USETEXT ERR$NS
USETEXT LTSB$NS 
USETEXT NAT$NS
USETEXT NCT$NS
USETEXT NDCB$NS 
USETEXT NPT$NS
USETEXT NST$NS
USETEXT PFC$NS
USETEXT PIC$NS
USETEXT SMB$NS
USETEXT SMD$NS
  
PROC NS$N00(ERRCODE);        # PROCESS NPU LOAD REQUEST                #
  
# TITLE NS$N00 - PROCESS NPU LOAD REQUEST.                             #
  
      BEGIN    # NS$N00 # 
# 
**    NS$N00 - PROCESS NPU LOAD REQUEST.
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE PROCESS NPU LOAD REQUEST.
* 
*     PROC NS$N00(ERRCODE)
* 
*     ENTRY:  
*       NPU-TABLE ORDINAL.
* 
*     EXIT: 
*       ERRCODE - IF SPCB IS MISSING. 
* 
*     METHOD: 
*       IF NOT IN GRADUAL SHUTDOWN MODE:  
*         PERFORM NPU ACTIVITY INITIALIZATION.
*         UPDATE NCT TABLE ENTRY. 
*         SET NPU-PRIMARY-STATE TO "LOADING NPU". 
*         EXTRACT NPU-VARIANT FROM NPT TABLE ENTRY. 
*         FIND LOAD PARTITION TO LOCATE PICB. 
*         IF ERRCODE EQ 0:  
*           ALLOCATE TSB FOR PICB.
*           READ LOGICL RECORD TO READ PICB.
*           ACCESS RECORD-HEADER OF LOAD-PARTITION RECORD.
*           IF RECORD-NAME EQ NPU-VARIANT NAME: 
*             STORE ASSIGNED TSBN FROM PICB IN NAT. 
*             CASE ON LOAD TYPE:  
*             1) SAM BOOTSTRAP LOAD:  
*               IF SPICB EXISTS IN PICB:  
*                 SET XPCB-DIRECTIVE-INDEX TO 
*                 PICB INDEX OF SPCB-HEADER.
*                 VALIDATE SPCB SIZE. 
*                 SET XPCB-END-DIRECTIVE-INDEX TO 
*                 PICB-INDEX OF SPCB END DIRECTIVE. 
*                 SET NPU-PRIMARY-STATE TO "LOADING SAM". 
*                 FORMAT EVENT MESSAGE AND DISPATCH IT. 
*                 START GLOBAL TIMER. 
*                 PROCESS NEXT XPCB DIRECTIVE.
*               ELSE
*                 SET ERRCODE TO "SPCB MISSING".
*             2) LOCAL-NPU OR REMOTE-NPU LOAD:  
*               IF LOAD-TYPE IS REMOTE-NPU LOAD 
*                 SET REMOTE-LOAD-INDICATOR IN NAT. 
*               IF NDCB-ADDRESS NONZERO:  
*                 SET NPU-PRIMARY-STATE TO
*                 "WAITING FOR DUMP NDCB RESPONSE". 
*                 FORMAT EVENT MESSAGE AND DISPATCH IT. 
*                 STORE NDCB-ADDRESS IN XPCB-DIRECTIVE. 
*                 FORMAT OVL/DT/R AND NETPUT IT.
*                 START LOCAL TIMER.
*               ELSE
*                 SET SELF-LOADING-INDICATOR IN NAT.
*                 INITIATE NPU LOAD.
*                 PROCESS NEXT XPCB DIRECTIVE.
*        ELSE 
*          SET ERRCODE. 
* 
# 
  
      ITEM ERRCODE    U;               # ERROR CODE                    #
  
      $BEGIN
      XREF
        BEGIN 
        PROC NS$DBG;         # TRACE PROCEDURE CALL                    #
        END 
      $END
  
      XREF
        BEGIN 
        PROC MOVEOK;         # ALLOW TSB TO MOVE                       #
        PROC NETPUT;         # NETPUT                                  #
        PROC NS$FBH;         # FORMAT SPECIAL ABH                      #
        FUNC NS$FEC U;       # FORMAT ERROR CODE                       #
        PROC NS$FLR;         # FIND LOAD RECORD                        #
        PROC NS$INL;         # INITIATE NPU LOAD                       #
        PROC NS$LSN;         # INCREMENT LOAD SEQUENCE NUMBER          #
        PROC NS$MSG;         # DISPATCH MESSAGE                        #
        PROC NS$NAI;         # INITIALIZE NPU ACTIVITY                 #
        PROC NS$SGT;         # START ACTIVITY TIMER                    #
        PROC NS$SLT;         # START RESPONSE TIMER                    #
        PROC NS$XPD;         # PROCESS NEXT XPCB DIRECTIVE             #
        FUNC NS$XZFN C(10);  # ZERO-FILLED FILE NAME                   #
        PROC READ;           # READ RECORD                             #
        PROC RECALL;         # RECALL                                  #
        PROC REQTSB;         # REQUEST TSB                             #
        PROC RETTSB;         # RELEASE TSB                             #
        PROC TSBINFO;        # LOCATE TSB                              #
        END 
  
      ITEM BACKPTR    U;     # BACK POINTER                            #
      ITEM HEADPTR    U;     # HEAD POINTER                            #
      ITEM LFN        C(7);  # LFN OF NPU LOAD FILE                    #
      ITEM LT         S:LOADTYPE;      # \PU LOAD TYPE                 #
      ITEM NCTORD     U;     # NODE CONNECTION TABLE ORDINAL           #
      ITEM NDCBFWA    U;     # FWA OF NDCB                             #
      ITEM NEXTPTR    U;     # NEXT POINTER                            #
      ITEM NPUVAR     C(6);  # NPU VARIANT NAME                        #
      ITEM PCBCI      I;     # PICB INDEX OF FIRST SPCB DIRECTIVE      #
      ITEM PCBLI      I;     # PICB INDEX FOR LAST SPCB DIRECTIVE      #
      ITEM PCBSIZE    U;     # SPCB SIZE                               #
      ITEM PICBSIZE   U;     # PICB SIZE                               #
      ITEM RI         U;     # RANDOM INDEX                            #
      ITEM TSBFWA     U;     # TSB FWA                                 #
      ITEM TSBN       U;     # TSB NUMBER                              #
      ITEM TSBSIZE    U;     # TSB SIZE                                #
  
      ARRAY PICBFET [1:L$LFET] S(1);
        BEGIN 
        ITEM FETWORD U(0,0,60) = [L$LFET(0)]; 
        END 
  
      DEF L$EM10      # 3 #;
      DEF DM$EM10     # DM$LOCAL+DM$EVENT+DM$NAMLOG #; # ROUTING OPT   #
      ARRAY MSG$EM10 [0:0] S(L$EM10); 
        BEGIN 
        ITEM EM10$TEXT  C(0,0,27) =              # EVENT MESSAGE TEXT  #
          ["NPUNAME, SAM LOAD STARTED."]; 
        ITEM EM10$NPNAM C(0,00,7);               # NPU NAME            #
        ITEM EM10$END   U(02,42,18) = [0];       # END OF TEXT         #
        END 
  
      DEF L$EM20     # 4 #; 
      DEF DM$EM20     # DM$LOCAL+DM$EVENT+DM$NAMLOG #; # ROUTING OPT   #
      ARRAY MSG$EM20 [0:0] S(L$EM20); 
        BEGIN 
        ITEM EM20$TEXT  C(0,0,37) =              # EVENT MESSAGE TEXT  #
          ["NPUNAME, DUMP/LOAD(VARIAN) REQUESTED."];
        ITEM EM20$NPNAM C(0,00,7);               # NPU NAME            #
        ITEM EM20$NPVAR C(1,54,6);               # NPU VARIANT         #
        ITEM EM20$END   U(3,42,18) = [0];        # END OF TEXT         #
        END 
  
      SWITCH LTCASE:LOADTYPE # STATUS SWITCH FOR NPU LOAD TYPE         #
        SAM:LT$SAM,          # SAM LOAD                                #
        LOCAL:LT$LOCAL,      # LOCAL NPU LOAD                          #
        REMOTE:LT$REMOT;     # REMOTE NPU LOAD                         #
  
CONTROL EJECT;
      $BEGIN
      NS$DBG("N00");         # TRACE CALL                              #
      $END
  
      ERRCODE = 0;
  
      IF NOT GRADSHUT 
      THEN                   # NOT IN GRADUAL SHUTDOWN MODE            #
        BEGIN 
        NS$NAI;              # INITIALIZE NPU ACTIVITY                 #
  
        NAT$PN[0] = NPUPO[0];          # SET PORT NUMBER OF TRUNK      #
        NAT$SPN[0] = NPUSP[0];         # SET SUBPORT NUMBER OF TRUNK   #
        NCTORD = NAT$NCTORD[0];        # NODE CONNECTION TABLE ORDINAL #
        NCT$F$ACT[NCTORD] = TRUE;      # SET NEIGHBOR NPU ACTIVE FLAG  #
  
        HEADPTR = NCT$LISTHP[0];       # HEAD PTR OF LIST              #
        IF HEADPTR NQ NCTORD
        THEN                 # NCT ENTRY NOT AT HEAD OF LIST           #
          BEGIN              # LINK NCT ENTRY TO HEAD OF LIST          #
          NEXTPTR = NCT$LISTFP[NCTORD]; 
          BACKPTR = NCT$LISTBP[NCTORD]; 
          NCT$LISTFP[BACKPTR] = NEXTPTR;
          NCT$LISTBP[NEXTPTR] = BACKPTR;
          NCT$LISTHP[0] = NCTORD; 
          NCT$LISTBP[HEADPTR] = NCTORD; 
          NCT$LISTFP[NCTORD] = HEADPTR; 
          NCT$LISTBP[NCTORD] = 0; 
          END 
  
        NAT$PSTATE[0] = S"NPS$LNPU";   # PRIMARY STATE = LOADING NPU   #
        NPUVAR = NPT$NPUVAR[NTORD];    # NPU VARIANT NAME              #
  
        NS$FLR(NPUVAR,RI,PICBSIZE,ERRCODE); # LOCATE PICB RECORD       #
  
        IF PICBSIZE LS PRUSIZE
        THEN # CIO BUFFER MUST BE AT LEAST ONE PRU LONG                #
          PICBSIZE = PRUSIZE; 
        IF ERRCODE EQ 0 
        THEN                 # PICB RECORD FOUND                       #
          BEGIN 
          REQTSB(PICBSIZE+1,TSBFWA,TSBN); # REQUEST TSB FOR PICB       #
  
          P<LTSB$FET> = LOC(PICBFET);  # FORMAT FET FOR PICB READ      #
          IF NPT$ALFWD[NTORD] NQ 0
          THEN # ALTERNATE CCP LOAD FILE                               #
            LFN = NPT$ALFPFN[NTORD];
          ELSE # DEFAULT CCP LOAD FILE                                 #
            LFN = LFN$NLF;
          LFET$LFN[0] = NS$XZFN(LFN); # SET LFN                        #
          LFET$FM[0] = TRUE;
          LFET$COMP[0] = TRUE;
          LFET$RAN[0] = TRUE; 
          LFET$LEN[0] = L$LFET - 5; 
          LFET$FIRST[0] = TSBFWA; 
          LFET$IN[0] = TSBFWA;
          LFET$OUT[0] = TSBFWA; 
          LFET$LIMIT[0] = TSBFWA + PICBSIZE + 1;
          LFET$RR[0] = RI;
  
          READ(LTSB$FET);              # READ PICB RECORD              #
          RECALL(LTSB$FET);            # WAIT TILL I/O COMPLETES       #
  
          P<PICB> = TSBFWA;            # FWA OF PICB                   #
          IF PICB$RNAME[0] EQ NPUVAR
          THEN               # VALID PICB RECORD                       #
            BEGIN 
            NAT$PITSBN[0] = TSBN;      # STORE PICB TSB NO IN NAT      #
            PICB$HDRW1[0] = 0;         # CLEAR HEADER WORD             #
            PICB$ID[0] = PICB$IDENT;   # REFORMAT PICB HEADER WORD     #
            PICB$BS[0] = PICBSIZE + 1;
            PICB$VAR[0] = NPUVAR; 
# 
            CASE ON LOAD TYPE 
# 
            LT = NPULT[0];             # NPU LOAD TYPE                 #
            GOTO LTCASE[LT];
  
SAM:                         # SAM BOOTSTRAP LOAD                      #
            PCBSIZE = PICB$LSPCB[PICB$HDRL];     # SPCB SIZE           #
            PCBCI = PICB$HDRL + PICB$PARWL +     # CURRENT PICB INDEX  #
                    PICB$LDPCB[PICB$HDRL] + 
                    PICB$LLPCB[PICB$HDRL];
            PCBLI = PCBCI + PCBSIZE - 1;         # LAST PICB INDEX     #
            NAT$PSTATE[0] = S"NPS$LSAM";         # SET PRIMARY STATE   #
  
            IF PCBSIZE NQ 0 
              AND PICB$PCBID[PCBCI] EQ ID$SPCB
              AND PCBLI LQ PICBSIZE 
              AND PICB$CODE[PCBLI] EQ DIRCODE"ENDPCB" 
            THEN             # VALID SPCB EXISTS                       #
              BEGIN          # START SAM LOAD PROCEDURE                #
              NAT$PDIRI[0] = PCBCI;    # SET CURRENT PICB INDEX        #
              NAT$PENDI[0] = PCBLI;    # SET LAST PICB INDEX           #
              EM10$NPNAM[0] = NPNAM;   # SET NPU NAME                  #
              NS$MSG(MSG$EM10,L$EM10,DM$EM10);   # DISPATCH EVENT MSG  #
  
              NS$LSN; # ASSIGN LSN FOR LOADING SAM                     #
  
              NS$XPD(ERRCODE);         # PROCESS NEXT XPCB DIRECTIVE   #
  
              NS$SGT;        # START ACTIVITY TIMER                    #
              END 
  
            ELSE             # BAD SPCB                                #
              BEGIN 
              ERRCODE = NS$FEC(EC"ERR$FILE",FEC"ERR$SPCB"); 
              END 
  
            GOTO N00EXIT; 
  
REMOTE:                      # REMOTE NPU LOAD                         #
            NAT$F$RMTL[0] = TRUE;      # SET REMOTE LOAD FLAG          #
  
LOCAL:                       # LOCAL NPU LOAD                          #
            NDCBFWA = PICB$NDCBA[PICB$HDRL];     # FWA OF NDCB         #
  
            IF NDCBFWA NQ 0 
            THEN             # HOST LOADING/CONFIGURING NPU            #
              BEGIN 
              NAT$PSTATE[0] = S"NPS$DNDCB";      # SET PRIMARY STATE   #
  
              EM20$NPNAM[0] = NPNAM;   # SET NPU NAME                  #
              EM20$NPVAR[0] = NPUVAR;            # SET NPU VARIANT     #
              NS$MSG(MSG$EM20,L$EM20,DM$EM20);   # DISPATCH EVENT MSG  #
  
              NAT$NDCBA[0] = NDCBFWA;            # SAVE NDCB ADDRESS   #
              MOVEOK(NPT$NSTTSB[NTORD]);         # ALLOW NST TO MOVE   #
  
              NS$LSN; # ASSIGN LSN FOR DUMPING NDCB                    #
  
              NS$FBH(LNPUDTDR,TRUE);   # FORMAT ABH FOR NETWORK SM     #
              PFCSFC[0] = NPUDT;                 # PFC/SFC             #
              NPUPO[0] = NAT$PN[0];              # PORT NO             #
              NPUSP[0] = NAT$SPN[0];             # SUBPORT NO          #
              NPUCC[0] = CMDCODE"CC$DUMP";       # DUMP COMMAND CODE   #
              NPULS[0] = NAT$LSN[0];             # LOAD SEQUENCE NO    #
              NPUBA1[0] = B<36,4>NDCBFWA;        # DUMP BEGINNING ADDR #
              NPUBA2[0] = B<40,20>NDCBFWA;
              NPUEA[0] = NDCBFWA+NDCB$SIZE-1;    # DUMP ENDING ADDR    #
              NETPUT(ABH$WORD,SMB$BUFFER); # SEND NPU/DT/R (DUMP NDCB) #
  
              NS$SLT;        # START RESPONSE TIMER                    #
              END 
  
            ELSE             # SELF LOADING/HOST CONFIGURING NPU       #
              BEGIN 
              NAT$F$SEFL[0] = TRUE;    # SET SELF-LOADING FLAG         #
              NS$INL(ERRCODE);         # INITIATE NPU LOAD             #
  
              IF ERRCODE EQ 0 
              THEN
                NS$XPD(ERRCODE);       # PROCESS NEXT XPCB DIRECTIVE   #
              END 
  
N00EXIT:  
            MOVEOK(TSBN);    # ALLOW PICB TSB TO MOVE                  #
            END 
  
          ELSE               # BAD PICB RECORD                         #
            BEGIN 
            RETTSB(TSBN);    # RETURN BAD PICB TSB                     #
            ERRCODE = NS$FEC(EC"ERR$FILE",FEC"ERR$PICB"); 
            END 
  
          END 
  
        ELSE                 # CANNOT LOCATE PICB                      #
          BEGIN 
          ERRCODE = NS$FEC(EC"ERR$FILE",FEC"ERR$PICBNF"); 
          END 
  
        END 
  
      RETURN; 
      END   # NS$N00 #
      TERM
