*DECK     CSSRCA
USETEXT TEXTOV
USETEXT TXTAPSS;
USETEXT TXTSUSS;
USETEXT TEXTCS; 
USETEXT TEXTSS; 
USETEXT TXCMDCS;
PROC CSSRCA(ELINDX);
# TITLE CSSRCA - RESOLVE COMMAND ADDRESSES. # 
  
      BEGIN  # CSSRCA # 
  
# 
**    CSSRCA - RESOLVE COMMAND ADDRESSES. 
* 
*     C. BRION          82/02/19. 
*     C. BRION          82/05/06. 
* 
* 
*     THIS PROCEDURE PROCESSES THE VALID COMMANDS THAT HAVE BEEN
*     DETERMINED TO NEED THE COMMAND ELEMENT'S PHYSICAL ADDRESSES 
*     RESOLVED FROM THE APPROPRIATE NCF CROSS REFERENCE TABLE.
*     THE ELEMENTS TO BE RESOLVED ARE EITHER FROM A COMMAND THAT
*     EFFECTS A SINGLE NPU OR TWO NPUS. CURRENTLY ONLY COMMANDS 
*     EFFECTING TRUNKS AND LOGICAL LINKS WILL EFFECT TWO NPUS.
*     THE MULTIPLE SEND COMMAND MAY EFFECT MORE THAN 1 NPU. 
* 
*     PROC CSSRCA 
* 
*     ENTRY:  
*       ELINDX = INDEX INTO THE SYNTAX PARAMETER LIST WHERE THE 
*                COMMAND ELEMENT TO BE RESOLVED RESIDES.
*       WCBUF = WORD COUNT WORD OF ENTRY. 
*       HDRCMD = ONE WORD COMMAND HEADER WORD.
*       PARMS = BODY OF VALID COMMAND THAT CONTAINS THE TEXT OF THE 
*               COMMAND FOLLOWED BY THE SYNTAX PARAMETER LIST.
* 
*     EXIT: 
*       EITHER A ROUTED COMMAND QUEUE ENTRY HAS BEEN QUEUED TO THE
*       ROUTED COMMAND QUEUE OR A TERMINAL TEXT ENTRY INFORMING THE 
*       OPERATOR OF THE COMMAND PROBLEM IS ISSUED.
* 
# 
  
# 
****  PROC CSSRCA XREF LIST 
* 
# 
      XREF
        BEGIN 
        PROC SSTRQE;                     # SS-REMOVE QUEUE ENTRY #
        PROC SSTAQE;                     # SS-ACCEPT QUEUE ENTRY #
        END 
  
# 
****
# 
  
# 
*     PROC CSSRCA DEFS
# 
      DEF CHARA         #1#;             # CHARACTER "A"# 
      DEF CHAR0         #27#;            # CHARACTER "0"# 
  
#     ELMLST - LIST OF POSSIBLE ELEMENT PARAMETER CODE VALUES. #
  
      STATUS ELMLST 
        NPU,                             # FOR NP0 CODE # 
        CPLR,                            # FOR CP0 CODE # 
        LINE,                            # FOR LI0 CODE # 
        VCIR,                            # FOR VC0 CODE # 
        TERM,                            # FOR TE0 CODE # 
        TRUNK,                           # FOR TR0 CODE # 
        LLINK,                           # FOR LL0 CODE # 
        NPUS;                            # FOR NPS CODE # 
  
  
  
# 
*     PROC CSSRCA ITEMS 
# 
  
      ITEM I,J          U;               # LOOP INDUCTION VARS #
      ITEM CFLAG        B;               # CONTROL FLAG # 
      ITEM GOFLAG       B;               # CONT CMD PROCESSING #
      ITEM MATCH        B;               # MATCH INDICATOR #
      ITEM ELINDX       U;               # LOCAL INDEX VARS # 
      ITEM PLXINDX      U;
      ITEM NPUIDX       U;
      ITEM LPLXINDX     U;
      ITEM LININDX      U;
      ITEM DEVINDX      U;
      ITEM LDEVINDX     U;
      ITEM LLINDXF      U;               # LLINK XREF INDX #
      ITEM LLINDX       U;               # LLINK CURRENT INDEX #
      ITEM LTYPE        B;               # LINK TYPE ID # 
      ITEM NOPINDX      U;
      ITEM STRTINDX     U;               # INDEX VARIABLE # 
      ITEM BEGAP        U;               # BEGINNING INDEX VARIABLE # 
                                         # OF ADDRESS LIST PARMS #
      ITEM INDX         U;               # ELEMENT INDEX #
      ITEM OCBORD       U;               # LOCAL OCB ORDINAL #
      ITEM OKFLAG       B;               # VALID COMMAND FLAG # 
  
# 
*     ELMSWT - ELEMENT TYPE SWITCH. 
# 
  
      SWITCH ELMSWT:ELMLST
        ELMNPU:NPU, 
        ELMCPLR:CPLR, 
        ELMLINE:LINE, 
        ELMVCIR:VCIR, 
        ELMTRM:TERM,
        ELMTRK:TRUNK, 
        ELMLLK:LLINK, 
        ELMNPUS:NPUS; 
  
  
# 
*     MESSAGE ARRAYS FOR TERMINAL TEXT ENTRIES TO OPERATORS.
# 
  
# 
*     NODEF - MESSAGE FOR UNDEFINED ELEMENT.
# 
  
      ARRAY NODEF [00:00] S(3); 
        BEGIN 
        ITEM NOD$TXT1   C(00,00,07);     # ELEMNET TYPE # 
        ITEM NOD$NAME   C(00,42,07);     # ELEMENT NAME # 
        ITEM NOD$TXT2   C(01,24,12) = [",NOT DEFINED"]; 
        ITEM NOD$ZERO   U(02,36,24) = [0];
        END 
  
# 
*     NONPUS - MESSAGE INDICATING NO NPUS UNDER THE OPERATORS CONTROL 
# 
      ARRAY NONPUS [00:00] S(3);
        BEGIN 
        ITEM NN$TXT1    C(00,00,20) = ["NO NPUS UNDER YOUR C"]; 
        ITEM NN$TXT2    C(02,00,06) = ["ONTROL"]; 
        ITEM NN$ZBYT    U(02,36,24) = [0];
        END 
  
# 
*     NOSUP - MESSAGE FOR UNSUPERVISED ELEMENT. 
# 
  
      ARRAY NOSUP [00:00] S(4); 
        BEGIN 
        ITEM NOS$TXT1   C(00,00,07);     # ELEMENT TYPE # 
        ITEM NOS$NAME   C(00,42,07);     # ELEMENT NAME # 
        ITEM NOS$TXT2   C(01,24,15) = [",NOT SUPERVISED"];
        ITEM NOS$ZERO   U(02,54,06) = [0];
        ITEM NOS$ZER1   U(03,00,60) = [0];
        END 
  
# 
*     NOSUP2 - MESSAGE SENT WHEN NO NPUS ARE BEING SUPERVISED.
# 
      ARRAY NOSUP2 [00:00] S(3);
        BEGIN 
        ITEM NS2$TXT1   C(00,00,28) = ["NO NPUS ARE BEING SUPERVISED"]; 
        ITEM NS2$ZBYT   U(02,48,12) = [0];
        END 
  
# 
*     NOCTRL - MESSAGE FOR LACK OF NEEDED CONTROL MESSAGE.
# 
  
      ARRAY NOCTRL [00:00] S(4);
        BEGIN 
        ITEM NOC$TXT1   C(00,00,07);     # ELEMENT TYPE # 
        ITEM NOC$NAME   C(00,42,07);     # ELEMENT NAME # 
        ITEM NOC$TXT2   C(01,24,23) = [",NOT UNDER YOUR CONTROL"];
        ITEM NOC$ZERO   U(03,42,18) = [0];
        END 
  
# 
*     RESCMD - MESSAGE INDICATING RESERVED COMMAND, FOR NOPS ONLY 
# 
      ARRAY RESCMD [00:00] S(5);
        BEGIN 
        ITEM RC$TXT1    C(00,00,20) = ["COMMAND RESTRICTED T"]; 
        ITEM RC$TXT2    C(02,00,20) = ["O NETWORK OPERATORS "]; 
        ITEM RC$ZBYT    I(04,00,60) = [0];
        END 
  
# 
*     NPADDR - NPU ADDRESS ARRAY. 
* 
*     THIS ARRAY HOLDS THE NPU NODE NUMBERS, PORT NUMBERS, ELEMENT
*     ORDINAL VALUES, ELEMENT HOST NODE NUMBERS AND INDICATORS FOR
*     COMMAND CONSTRUCTION STATUS FOR EACH COMMAND SEQUENCE.
# 
  
      ARRAY NPADDR [00:01] S(1);
        BEGIN 
        ITEM NP$NODE    U(00,00,08);
        ITEM NP$ORD     U(00,08,12);
        ITEM NP$HID     U(00,20,08);
        ITEM NP$PORT    U(00,28,08);
        ITEM NP$NORIN   B(00,36,01);
        END 
  
# 
*     CMDPAK - LOCAL COMMAND PACKET.
* 
*     THIS ARRAY HOLDS THE INFORMATION OF THE COMMAND ELEMENTS, THE 
*     COMMAND ELEMENT LOCATION IN THE COMMAND SYNTAX PARAMETER LIST,
*     THE TEXT FOR THE COMMAND ELEMENT TYPE AND THE COMMAND ELEMENT 
*     IDENTIFIER. 
# 
  
      ARRAY CMDPAK [00:00] S(1);
        BEGIN 
        ITEM CMD$WORD   U(00,00,60);     # FULL WORD REF #
        ITEM CMD$ELTYPE C(00,00,07);     # ELEMENT TYPE TEXT #
        ITEM CMD$ELINDX U(00,42,08);     # ELEMENT INDEX IN SYNTAX #
        ITEM CMD$ELMID  S:ELMLST (00,50,08); # INTERNAL ELEMENT ID #
        ITEM CMD$NOP    B(00,58,01);     # NOP KEYWORD PRESENT FLAG # 
        END 
  
# 
*     ELNAME - LOCAL ELEMENT NAME 
* 
*     THIS ARRAY HOLDS THE ARCHETYPE SVC NAME(FROM THE COMMAND
*     PARAMETER LIST).  FLAG EL$SVCF IS SET TRUE TO ALLOW A MATCH 
*     FROM THE DEVICE XREF TABLE. 
# 
      ARRAY ELNAME [00:00] S(1);
        BEGIN 
        ITEM EL$WORD    U(00,00,60);     # FULL WORD REF #
        ITEM EL$SVCF    B(00,00,01);     # SVC ROOT FLAG #
        ITEM EL$SVCNAM  C(00,00,05);     # ARCHETYPE SVC NAME # 
        END 
  
  
  
  
# 
*     MAIN PROC CSSRCA START
# 
  
# 
*     INITIALIZE THE LOCAL VARIABLES
# 
  
      OCBORD = HDR$OPORD[0];             # OCB ORDINAL FROM HEADER #
      BEGAP = HDR$SPCNT[0] + HDR$TXWCNT[0];  # BEG INDEX LOC OF THE # 
                                         # ADDRESS PARM LIST #
      WCB$WORD[1] = 0;
      ABHWORD[1] = 0; 
      WCB$SMID[1] = SMID"TTEXT";         # TERMINAL TEXT ID # 
      WCB$WC[1] = 6;                     # TTEXT ENTRY SIZE # 
      WCB$IAF[1] = TRUE;                 # INPUT ALLOWED TRUE # 
      ABHADR[1] = OCBORD;                # TTEXT OCB ORDINAL #
      ABHTLC[1] = 40;                    # TTEXT CHAR LENGTH #
      STRTINDX = HDR$TXWCNT[0] + 1;      # SET 1ST ELM INDEX LOC #
      CMD$WORD[0] = 0;                   # INITIALIZE CMD PACKET #
      CMD$ELINDX[0] = ELINDX; 
      IF PAR$PCODE[STRTINDX] EQ "NOP"    # IF NOP KEYWORD PRESENT # 
      THEN
        CMD$NOP[0] = TRUE;               # SET CMD PACKET INDICATOR # 
  
# 
*     USING THE PASSED PARAMETER ELINDX, CHECK THE VALUE OF THE 
*     ELEMENT IN THE SYNTAX PARAMETER LIST AND SET THE INTERNAL 
*     ELEMENT IDENTIFIER OF THE COMMAND PACKET. 
# 
  
      INDX = CMD$ELINDX[0]; 
  
      IF PAR$PCODE[INDX] EQ "NP0"           # NPU ELEMENT # 
      THEN
        CMD$ELMID[0] = ELMLST"NPU"; 
  
      ELSE IF PAR$PCODE[INDX] EQ "CP0"      # COUPLER ELEMENT # 
      THEN
        CMD$ELMID[0] = ELMLST"CPLR";
  
      ELSE IF PAR$PCODE[INDX] EQ "LI0"      # LINE ELEMENT #
      THEN
        CMD$ELMID[0] = ELMLST"LINE";
  
      ELSE IF PAR$PCODE[INDX] EQ "VC0"      # CIRCUIT ELEMENT # 
      THEN
        CMD$ELMID[0] = ELMLST"VCIR";
  
      ELSE IF PAR$PCODE[INDX] EQ "TE0"      # TERMINAL ELEMENT #
      THEN
        CMD$ELMID[0] = ELMLST"TERM";
  
      ELSE IF PAR$PCODE[INDX] EQ "TR0"      # TRUNK ELEMENT # 
      THEN
        CMD$ELMID[0] =  ELMLST"TRUNK";
  
      ELSE IF PAR$PCODE[INDX] EQ "LL0"      # LLINK ELEMENT # 
      THEN
        CMD$ELMID[0] = ELMLST"LLINK"; 
  
      ELSE IF PAR$PCODE[INDX] EQ "NPS" # MULT NPU ELEMENT # 
           OR PAR$PCODE[INDX] EQ "AU0"
      THEN
        CMD$ELMID[0] = ELMLST"NPUS";
  
      ELSE IF PAR$PCODE[INDX] EQ "HO0"
      THEN
        CMD$ELMID[0] = ELMLST"TERM";
  
# 
*     THE TYPE OF ELEMENT IS KNOWN. MUST NOW SEARCH THE APPROPRIATE 
*     XREF TABLE TO VERIFY THAT THE ELEMENT IS KNOWN TO CS. 
*     EACH CASE WILL ATTEMPT TO LOCATE A MATCH IN THE XREF TABLE AND
*     IF A MATCH IS FOUND, SET THE LOCAL COMMAND ADDRESS INFORMATION
*     FOR THE NECESSARY ELEMENTS. 
*     A COMMAND MAY NECESSITATE THE ADDRESS INFORMATION FOR DUAL NPUS.
*     A BRANCH IS MADE DEPENDING ON WHETHER A SINGLE OR DUAL SET OF 
*     ADDRESS INFORMATION IS NEEDED.
# 
  
      GOTO ELMSWT[CMD$ELMID[0]];
  
  
  
ELMNPU:                                  # NPU ELEMENT #
  
      CMD$ELTYPE[0] = "NPU:   ";         # SET ELEMENT TYPE TEXT #
      NPU$NAME[CSNPCNT] = PAR$ELNAME[INDX]; 
      NPU$NID[CSNPCNT] = X"FF";          # INSURE SEARCH MATCH #
  
      FOR NPUIDX = 0 STEP 1 WHILE 
          PAR$ELNAME[INDX] NQ NPU$NAME[NPUIDX]
      DO
        BEGIN 
        END 
  
      IF NPU$NID[NPUIDX] NQ X"FF"        # MATCH FOUND #
      THEN
        BEGIN 
        NP$NODE[0] = NPU$NID[NPUIDX]; 
        GOTO ELMSINGL;
        END 
      ELSE                               # NO MATCH # 
        GOTO NOMATCH; 
  
  
  
  
  
ELMCPLR:                                 # COUPLER ELEMENT #
  
      CMD$ELTYPE[0] = "CPLR:  ";         # SET ELM TYPE TEXT #
  
      # SET THE MAX INDEX FOR THE PHYSICAL LINK XREF TABLE #
  
      LPLXINDX = (PLXREFL / 2) -1 ; 
  
      PLX$CNPU[LPLXINDX] = X"FF";        # SET PL XREF TABLE ENTRY #
                                         # AT END TO INSURE MATCH # 
      PLX$NAME[LPLXINDX] = PAR$ELNAME[INDX];
  
      # 
      * VERIFY THAT THE COUPLER ELEMENT IS FOUND AND THAT IT IS A 
      * COUPLER LINK TYPE FOR A MATCH TO OCCUR. 
      # 
  
      FOR PLXINDX = 0 STEP 1 WHILE
        PAR$ELNAME[INDX] NQ PLX$NAME[PLXINDX] 
      DO
        BEGIN 
        END 
  
      IF PLX$CNPU[PLXINDX] NQ X"FF" AND 
         NOT PLX$TYPE[PLXINDX]
      THEN
        BEGIN 
        NP$NODE[0] = PLX$CNPU[PLXINDX]; 
        NP$NODE[1] = PLX$HNID[PLXINDX]; 
        GOTO ELMSINGL;
        END 
      ELSE                               # NO MATCH IN XREF # 
        GOTO NOMATCH; 
  
  
  
  
  
  
ELMLINE:                                 # LINE ELEMENT # 
  
      CMD$ELTYPE[0] = "LINE:  ";         # SET ELEMENT TEXT # 
  
      # 
      * PRESET THE LAST LINE XREF TABLE ENTRY TO INSURE SEARCH MATCH
      # 
  
      LIX$NAME[LIXL - 1] = PAR$ELNAME[INDX];
      LIX$PORT[LIXL - 1] = X"FF"; 
  
      # 
      * SEARCH LINE XREF TABLE FOR MATCH ON NAME
      # 
  
      FOR LININDX = 0 STEP 1 WHILE
        PAR$ELNAME[INDX] NQ LIX$NAME[LININDX] 
      DO
        BEGIN 
        IF DEX$SVCF[DEVINDX]
        THEN
          BEGIN 
          PAR$SVCFLG[INDX] = TRUE;       # SET PARAMETER SVC FLAG      #
                                         # EXIT LOOP IF MATCH FOUND    #
          IF PAR$SVCNAM[INDX] EQ DEX$CNAME[DEVINDX] 
          THEN
            BEGIN 
            J = 0;                       # J IS SVC ORDINAL SUM        #
            FOR I = 0 STEP 1 UNTIL 1
            DO                           # CHECK FOR VALID SVC ORDINAL #
              BEGIN 
              IF (C<I>PAR$SVCORD[INDX] GQ "A" 
                  AND C<I>PAR$SVCORD[INDX] LQ "F")
                  OR (C<I>PAR$SVCORD[INDX] GQ "0" 
                  AND C<I>PAR$SVCORD[INDX] LQ "9")
              THEN
                BEGIN 
                J = J*16 + B<I*6,6>PAR$SVCORD[INDX];
                IF C<I>PAR$SVCORD[INDX] LQ "F"
                THEN
                  BEGIN 
                  J = J - CHARA + 10;    # HEX DIGIT: SUBTRACT "A"     #
                  END 
                ELSE
                  BEGIN 
                  J = J - CHAR0;         # DECIMAL DIGIT: SUBTRACT "0" #
                  END 
                END 
              END 
  
            IF J LQ DEX$NSVC[DEVINDX] 
            THEN
              BEGIN                      # SVC ORDINAL WITHIN RANGE    #
              GOTO FOUNDV;
              END 
            END 
            PAR$SVCFLG[INDX] = FALSE; 
          END 
        END 
  
FOUNDV: 
  
      IF LIX$PORT[LININDX] NQ X"FF"      # MATCH FOUND #
      THEN
        BEGIN 
        NP$NODE[0] = LIX$NID[LININDX];
        NP$PORT[0] = LIX$PORT[LININDX];  # SET PORT VARIABLE #
        GOTO ELMSINGL;
        END 
      ELSE                               # NO MATCH IN XREF # 
        GOTO NOMATCH; 
  
  
  
  
  
  
ELMVCIR:                                 # SVC ELEMENT #
  
      CMD$ELTYPE[0] = "SVC:   ";         # SET ELEMENT TEXT            #
  
      # 
      * PRESET THE LAST SVC XREF TABLE ENTRY TO INSURE SEARCH MATCH 
      # 
  
      EL$SVCNAM[0] = PAR$VCNAME[INDX];  # MOVE ARCHETYPE SVC NAME      #
      EL$SVCF[0] = TRUE;                 # SVC ROOT FLAG               #
      LDEVINDX = DEXL - 1;               # SET LAST ENTRY INDEX        #
      DEX$CNAME[LDEVINDX] = EL$SVCNAM[0]; 
      DEX$PORT[LDEVINDX] = X"FF"; 
  
      # 
      *SEARCH FOR MATCHING NAME ON SVC ENTRY
      # 
  
      FOR DEVINDX = 0 STEP 1 WHILE
          (EL$SVCNAM[0] NQ DEX$CNAME[DEVINDX])
      DO
        BEGIN 
        END 
  
      IF DEX$PORT[DEVINDX] NQ X"FF"      # MATCH FOUND                 #
      THEN
        BEGIN 
        NP$NODE[0] = DEX$NID[DEVINDX];
        NP$PORT[0] = DEX$PORT[DEVINDX]; 
        GOTO ELMSINGL;
        END 
      ELSE
        GOTO NOMATCH; 
  
  
  
  
  
  
ELMTRM:                                  # TERMINAL ELEMENT # 
      IF HDR$VERB[0] EQ "SE0" 
      THEN
        BEGIN 
  
        IF PAR$PCODE[INDX] EQ "HO0" 
        THEN
          BEGIN 
          HDR$VERB[0] = "SE1";
          GOTO ROUTEOK; 
          END 
        ELSE
          BEGIN 
          FOR I=HOPORD$ STEP 1 WHILE PAR$ELNAME[INDX] NQ OC$TNAM[I] AND 
                                     I LQ MAXACN$ 
          DO
            BEGIN 
            END 
          IF I LQ MAXACN$ 
          THEN
            BEGIN 
            HDR$VERB[0] = "SE1";
            GOTO ROUTEOK; 
            END 
          END 
        END 
  
      CMD$ELTYPE[0] = "TERM:  ";
  
      # 
      * PRESET LAST DEVICE XREF TABLE ENTRY TO INSURE MATCH.
      # 
  
      LDEVINDX = DEXL - 1 ;              # SET LAST ENTRY INDEX # 
      DEX$NAME[LDEVINDX] = PAR$ELNAME[INDX];
      DEX$PORT[LDEVINDX] = X"FF"; 
  
      # 
      * SEARCH FOR MATCHING NAME ON DEVICE ENTRY. 
      # 
  
      FOR DEVINDX = 0 STEP 1 WHILE
        PAR$ELNAME[INDX] NQ DEX$NAME[DEVINDX] 
      DO
        BEGIN 
        END 
  
      IF DEX$PORT[DEVINDX] NQ X"FF"      # MATCH FOUND #
      THEN
        BEGIN 
        NP$NODE[0] = DEX$NID[DEVINDX];
        NP$PORT[0] = DEX$PORT[DEVINDX]; 
        GOTO ELMSINGL;
        END 
      ELSE                               # NO MATCH IN XREF # 
        GOTO NOMATCH; 
  
  
  
  
  
  
ELMTRK:                                  # TRUNK ELEMENT #
  
      CMD$ELTYPE[0] = "TRUNK: ";
  
      LPLXINDX = (PLXREFL / 2) - 1;            # SET LAST PLINK INDX# 
  
      # 
      * SET LAST ENTRY TO INSURE MATCH ON SEARCH OF PLXREF TABLE
      # 
  
  
      PLX$TN1[LPLXINDX] = X"FF";
      PLX$NAME[LPLXINDX] = PAR$ELNAME[INDX];
  
      # 
      * SEARCH THE PHYSICAL LINK XREF FOR TRUNK NAME MATCH
      # 
  
      FOR PLXINDX = 0 STEP 1 WHILE
          PAR$ELNAME[INDX] NQ PLX$NAME[PLXINDX] 
      DO
        BEGIN 
        END 
  
      IF PLX$TN1[PLXINDX] NQ X"FF"       # IF MATCH AND TRUNK LINK #
         AND PLX$TYPE[PLXINDX]
      THEN
        BEGIN 
        NP$NODE[0] = PLX$TN1[PLXINDX];   # SET LOCAL NODE AND PORT #
        NP$PORT[0] = PLX$TP1[PLXINDX];   # VALUES FOR LATER # 
        NP$NODE[1] = PLX$TN2[PLXINDX];
        NP$PORT[1] = PLX$TP2[PLXINDX];
        GOTO ELMDUAL; 
        END 
      ELSE                               # NO MATCH IN XREF # 
        GOTO NOMATCH; 
  
  
  
  
  
ELMLLK:                                  # LLINK ELEMENT #
  
      CMD$ELTYPE[0] = "LLINK: ";
  
      LLINDXF = (LLXREFL / 2) - 1;             # SET LAST LLINK ENTRY # 
  
      # 
      * SET LAST ENTRY IN LLINK XREF TABLE TO INSURE MATCH
      # 
  
  
      LLX$HID1[LLINDXF] = X"FF";
      LLX$NAME[LLINDXF] = PAR$ELNAME[INDX]; 
  
      # 
      * SEARCH THE LLINK XREF TABLE FOR LLINK NAME MATCH
      # 
  
      FOR LLINDX = 0 STEP 1 WHILE 
        PAR$ELNAME[INDX] NQ LLX$NAME[LLINDX]
      DO
        BEGIN 
        END 
  
      IF LLX$HID1[LLINDX] NQ X"FF"       # IF MATCH FOUND # 
      THEN
        BEGIN 
        NP$NODE[0] = LLX$NID1[LLINDX];   # SET LOCAL NODE PAIR #
        NP$NODE[1] = LLX$NID2[LLINDX];
        NP$HID[0] = LLX$HID1[LLINDX];    # SET HOST IDS # 
        NP$HID[1] = LLX$HID2[LLINDX]; 
        LTYPE = LLX$TYPE[LLINDX];        # SET LOCAL LLINK TYPE # 
        GOTO ELMDUAL; 
        END 
      ELSE                               # NO MATCH IN XREF # 
        GOTO NOMATCH; 
  
ELMNPUS:  
  
# 
*     IF THIS IS A NOP COMMAND, THEN SEARCH THE NPUCB-S TO SEE IF 
*     THIS OPERATOR CONTROLS ANY NPU-S.  IF SO, THEN SEND THE 
*     COMMAND TO RCQ, OTHERWISE IF THIS COMMAND IS A CONTROL COM- 
*     MAND AND THE OPERATOR IS NOT A DOP, THEN SEND THE COMMAND 
*     TO RCQ, OTHERWISE SEND AN ERROR MESSAGE.
# 
      IF CMD$NOP[0] 
      THEN
        BEGIN 
        IF OC$TYPE[OCBORD] EQ OPTYP"HOP"
        THEN
          BEGIN 
          GOTO ROUTEOK; 
          END 
  
        CFLAG = FALSE;
        FOR I=0 STEP 1 WHILE I LS CSNPCNT 
        DO
          BEGIN 
          IF NPU$CNOP[I] EQ OCBORD AND
             (NPU$STAT[I] EQ SUPSTAT"SUP" 
             OR (OC$TYPE[OCBORD] EQ OPTYP"NOP"
             AND (NPU$STAT[I] EQ SUPSTAT"NCFMIS" OR 
                  NPU$STAT[I] EQ SUPSTAT"LEVMIS"))) 
          THEN
            BEGIN 
            CFLAG = TRUE; 
            END 
          END 
  
        IF CFLAG
        THEN
          BEGIN 
          GOTO ROUTEOK; 
          END 
  
        ELSE
          BEGIN 
          IF HDR$VERB[0] EQ "CO0" AND 
             OC$TYPE[OCBORD] NQ OPTYP"DOP"
          THEN
            BEGIN 
            GOTO ROUTEOK; 
            END 
  
          ELSE IF HDR$VERB[0] EQ "LO0"
          THEN
            BEGIN 
            FOR I=0 STEP 1 WHILE I LS CSNPCNT 
            DO
              BEGIN 
              IF (NPU$STAT[I] EQ SUPSTAT"NCFMIS" OR 
                  NPU$STAT[I] EQ SUPSTAT"LEVMIS") 
              THEN
                BEGIN 
                CFLAG = TRUE; 
                END 
              END 
  
            IF CFLAG
            THEN
              BEGIN 
              GOTO ROUTEOK; 
              END 
            END 
  
          IF OC$TYPE[OCBORD] NQ OPTYP"NOP"
          THEN
            BEGIN 
            WCB$WC[1] = 7;
            SSTAQE(P<CNQ>,WCBUF[1],ABH[1],RESCMD);
            END 
          ELSE
            BEGIN 
            WCB$WC[1] = 5;
            SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NONPUS);
            END 
          END 
        GOTO ENDEXIT; 
        END 
  
# 
*     THIS COMMAND IS NOT A NOP COMMAND, SEND IT TO RCQ.
# 
      ELSE
        BEGIN 
        CFLAG = FALSE;
        FOR I=0 STEP 1 WHILE I LS CSNPCNT 
        DO
          BEGIN 
          IF NPU$STAT[I] EQ SUPSTAT"SUP"
          THEN
            BEGIN 
            CFLAG = TRUE; 
            END 
          END 
        IF CFLAG
        THEN
          BEGIN 
          GOTO ROUTEOK; 
          END 
        ELSE
          BEGIN 
          WCB$WC[1] = 5;
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOSUP2);
          GOTO ENDEXIT; 
          END 
        END 
  
NOMATCH:                                 # NO MATCH IN XREF # 
  
      # 
      * IF NO MATCH FOUND FROM XREF SEARCH, THEN A TERMINAL TEXT
      * TO THE OPERATOR TO INFORM OF THE ERRONEOUS ELEMENT NAME 
      * NEEDS TO BE SENT. 
      # 
  
      NOD$TXT1[0] = CMD$ELTYPE[0];       # SET ELEMENT TYPE TEXT #
      NOD$NAME[0] = PAR$ELNAME[INDX];    # SET ELEMENT NAME # 
      WCB$WC[1] = 5;                     # SET ENTRY SIZE # 
      ABHTLC[1] = 30;                    # SET MESSAGE CHAR LENGTH #
      SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NODEF); 
      GOTO ENDEXIT; 
  
  
  
  
  
ELMDUAL:                                 # DUAL ELEMENT COMMAND # 
  
  
      # 
      * THE ELEMENT WAS DEFINED IN THE XREF TABLE AND EFFECTS TWO 
      * NPUS. 
      # 
  
      NP$NORIN[0] = FALSE;               # INIT THE NPUCB ORDINAL # 
      NP$NORIN[1] = FALSE;               # PRESENT FLAG # 
      NP$ORD[0] = CSNPCNT + 1;
      NP$ORD[1] = CSNPCNT + 1;
  
  
      # 
      * RESOLVE THE NPUCB ORDINALS FOR THE INDICATED NPU NODES. 
      # 
  
      FOR I = 0 STEP 1 UNTIL 1
      DO
        BEGIN 
  
        FOR J = 0 STEP 1 WHILE NP$NODE[I] NQ NPU$NID[J] 
        DO
          BEGIN 
          END 
  
        NP$ORD[I] = J;                   # ALWAYS FOUND, SET ORDINAL #
  
# 
*     CHECK TO VERIFY THAT THE ORDINALS DO NOT REPEAT. IF SO, THEN
*     THE SAME NPU IS THE ORIGINATING AND THE TERMINATING NODE OF 
*     THE LOGICAL LINK IN WHICH CASE, AVOID APPENDING TWO IDENTICAL 
*     NPU ORDINAL (NOR) VALUES TO THE ADDRESS PARAMETER LIST. 
# 
  
        IF NP$ORD[0] NQ NP$ORD[1] 
        THEN
          BEGIN 
  
  
  
      # 
      * FOR EACH NPU NODE ID DEFINED FOR THE COMMAND, SEE IF SUPER- 
      * VISED.
      # 
  
  
        IF NPU$STAT[NP$ORD[I]] EQ SUPSTAT"SUP"
        THEN
          BEGIN 
  
      # 
      * NPU IS SUPERVISED.
      * CHECK TO SEE IF CONTROL NEEDED BY CHECKING FOR THE NOP KEYWORD
      * IN THE COMMAND. 
      * IF CONTROL NEEDED THEN THE ORIGIN OPERATOR OF COMMAND MUST BE 
      * EITHER THE CONTROLLING NOP OR THE HOP.
      * OTHERWISE, CONTROL NOT NEEDED QUALIFIES THE COMMAND.
      # 
  
          GOFLAG = FALSE; 
          IF NOT CMD$NOP[0] 
          THEN
            GOFLAG = TRUE;
          ELSE IF (CMD$NOP[0] AND OCBORD EQ HOPORD$)
          THEN
            GOFLAG = TRUE;
          ELSE IF (CMD$NOP[0] AND OC$TYPE[OCBORD] EQ OPTYP"NOP" 
                  AND OCBORD EQ NPU$CNOP[NP$ORD[I]])
          THEN
            GOFLAG = TRUE;
  
          IF GOFLAG 
          THEN
            BEGIN 
            PAR$PCODE[BEGAP] = "NOR"; 
            PAR$ORD[BEGAP] = NP$ORD[I]; 
            BEGAP = BEGAP + 1;
            NP$NORIN[I] = TRUE; 
            HDR$APCNT[0] = HDR$APCNT[0] + 1;  # BUMP NUM  ADDR PARMS #
            END 
  
          END # IF NPU SUPERVISED # 
  
  
  
  
      # 
      * IF TRUNK ELEMENT, ADD THE TRUNK LINE ADDRESS TO THE ADDRESS 
      * PARAMETER LIST IF A NPUCB ORDINAL WAS ADDED TO THE ADDRESS
      * PARAMETER LIST. 
      # 
  
        IF NP$NORIN[I]
        THEN
  
          BEGIN 
          IF CMD$ELMID[0] EQ ELMLST"TRUNK"
          THEN
  
            BEGIN 
            PAR$PCODE[BEGAP] = "TLA"; 
            PAR$ELADDR[BEGAP] = NP$PORT[I]; 
            END 
  
          ELSE
  
  
      # 
      * MUST BE LLINK ELEMENT. ADD LLINK ADDRESS TO ADDRESS PARAMETER 
      * LIST IF AND ONLY IF A NPUCB ORDINAL WAS ADDED.
      # 
  
            BEGIN 
            PAR$PCODE[BEGAP] = "LLA"; 
            IF LTYPE
            THEN
              PAR$LLTYPE[BEGAP] = TRUE; 
             ELSE 
              PAR$LLTYPE[BEGAP] = FALSE;
  
            PAR$LLNID1[BEGAP] = NP$HID[0];
            PAR$LLNID2[BEGAP] = NP$HID[1];
            END 
  
          BEGAP = BEGAP + 1;
          HDR$APCNT[0] = HDR$APCNT[0] + 1;
  
          END 
  
      END # IF NP$ORD NQ #
  
        END # FOR I LOOP #
  
  
      # 
      * IF A NPUCB ORDINAL NOT ADDED THEN SEND TERMINAL TEXT MESSAGE
      * TO OPERATOR. LACK OF CONTROL IF NOP NEEDS CONTROL AND DOES
      * NOT HAVE IT OR LACK OF SUPERVISION OTHERWISE. 
      # 
  
      IF NOT NP$NORIN[0] AND NOT NP$NORIN[1]
      THEN
        BEGIN 
        IF OC$TYPE[OCBORD] NQ OPTYP"HOP"
        THEN
          BEGIN 
          IF CMD$NOP[0] AND 
             (OCBORD NQ NPU$CNOP[0] OR OCBORD NQ NPU$CNOP[1]) 
          THEN
            BEGIN 
            NOC$TXT1[0] = CMD$ELTYPE[0];    # SET ELM TYPE IN MSG # 
            NOC$NAME[0] = PAR$ELNAME[ELINDX]; # SET ELM NAME IN MSG # 
            SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOCTRL[0]); 
            END 
          END 
        ELSE
          BEGIN 
          NOS$TXT1[0] = CMD$ELTYPE[0];
          NOS$NAME[0] = PAR$ELNAME[ELINDX]; 
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOSUP[0]);
          END 
  
        GOTO ENDEXIT; 
        END 
  
      ELSE                               # NPUCB ORDINAL ADDED OK # 
        GOTO ROUTEOK; 
ELMSINGL:                                # SINGLE ELEMENT COMMAND # 
  
      # 
      * RESOLVE THE NPUCB ORDINAL VALUE FOR THE INDICATED NPU NODE
      # 
  
      FOR I = 0 STEP 1 WHILE NP$NODE[0] NQ NPU$NID[I] 
      DO
        BEGIN 
        END 
  
      NP$ORD[0] = I;                     # ALWAYS FOUND, SET ORDINAL# 
  
  
      # 
      * CHECK IF NPU IS SUPERVISED. IF NOT, SEND MESSAGE TO OPERATOR
      # 
  
  
      IF NPU$STAT[NP$ORD[0]] EQ SUPSTAT"SUPLOST"
      THEN
        BEGIN 
        NOS$TXT1[0] = CMD$ELTYPE[0];     # SET MESSAGE ELEMENT TYPE # 
        NOS$NAME[0] = PAR$ELNAME[INDX];  # SET MSG ELEMENT NAME # 
        SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOSUP); 
        GOTO ENDEXIT; 
        END 
  
      # 
      * NPU IS NOT UNSUPERVISED BUT MAY BE MISMATCHED. IF MISMATCHED, 
      * THEN ONLY A LOAD COMMAND IS ALLOWED FROM THE HOP. 
      # 
  
      IF (NPU$STAT[NP$ORD[0]] EQ SUPSTAT"NCFMIS" OR 
          NPU$STAT[NP$ORD[0]] EQ SUPSTAT"LEVMIS") 
      THEN
        BEGIN 
  
        IF (HDR$VERB[0] EQ "LO0" AND OC$TYPE[OCBORD] EQ OPTYP"HOP") 
        THEN
          BEGIN 
  
     #
            * LOAD COMMAND FROM HOP. ADD THE NPUCB ORDINAL TO THE 
            * VALID COMMAND AS A ADDRESS PARAMETER WORD AND INCREMENT 
            * THE ADDRESS PARAMETER LIST COUNT OF THE COMMAND HEADER
            * WORD. 
            # 
  
          PAR$PCODE[BEGAP] = "NOR"; 
          PAR$ORD[BEGAP] = NP$ORD[0]; 
          HDR$APCNT[0] = HDR$APCNT[0] + 1 ; 
          END 
  
        ELSE
          BEGIN 
  
            # 
            * INVALID COMMAND FROM AN OPERATOR FOR THIS NPU. SEND A 
            * TERMINAL TEXT MESSAGE TO INFORM OF NPU UNSUPERVISED.
            # 
  
          NOS$TXT1[0] = CMD$ELTYPE[0];    # SET MSG ELEMENT TYPE #
          NOS$NAME[0] = PAR$ELNAME[ELINDX]; 
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOSUP); 
          GOTO ENDEXIT; 
          END 
  
        END 
  
      ELSE  # NPU IS SUPERVISED NORMALLY #
        BEGIN 
  
      # 
      * THE NPU IS SUPERVISED. THE COMMAND MAY REQUIRE THAT 
      * THE OPERATOR HAVE CONTROL. DETERMINE WHETHER CONTROL IS NEEDED. 
      # 
  
        OKFLAG = FALSE;      # SET FLAG TO INVALID COMMAND             #
  
        IF CMD$NOP[0] 
        THEN                 # IF THIS IS STRICTLY A NOP COMMAND       #
          BEGIN 
  
          IF OCBORD EQ HOPORD$
          THEN
            BEGIN 
            OKFLAG = TRUE;
            END 
  
          ELSE IF NPU$CNOP[NP$ORD[0]] EQ OCBORD 
          THEN               # IF OPERATOR IS THE CONTROLLING NOP      #
            BEGIN 
            OKFLAG = TRUE;   # SET VALID COMMAND FLAG                  #
            END 
  
          ELSE               # OPERATOR IS NOT A CONTROLLING NOP       #
            BEGIN 
  
            IF HDR$VERB[0] EQ "SE0" AND 
               CMD$ELMID[0] EQ ELMLST"TERM" 
            THEN             # IF THIS CMD IS A SEND TO A TERM         #
              BEGIN 
  
              FOR I=MINACN$ STEP 1 UNTIL MAXACN$
              DO             # SEARCH THE OCB-S FOR THE TERM NAME      #
                BEGIN 
  
                IF (OC$TNAM[I] EQ PAR$ELNAME[INDX]
                   OR (PAR$SVCFLG[INDX] 
                   AND OC$SVCNAM[I] EQ PAR$SVCNAM[INDX])) 
                   AND OC$STATE[I]
                THEN         # IF FOUND AND OCB IS ACTIVE              #
                  BEGIN 
                  OKFLAG = TRUE;
                  END 
                END 
              END 
            ELSE IF HDR$VERB[0] EQ "CO0" AND
                    OC$TYPE[OCBORD] NQ OPTYP"DOP" 
            THEN
              BEGIN 
              OKFLAG = TRUE;
              END 
            END 
          END 
  
        ELSE                 # THIS IS NOT A NOP COMMAND               #
          BEGIN 
          OKFLAG = TRUE;
          END 
  
  
          # 
          * IF EVERYTHING OK, ADD ADDRESS PARAMETERS TO VALID COMMAND 
          * AND SEND ROUTED COMMAND TO COMMAND DISPATCHER VIA THE ROUTED
          * COMMAND QUEUE.
          # 
  
        IF OKFLAG 
        THEN
          BEGIN 
  
          PAR$PCODE[BEGAP] = "NOR";        # ADD NPU ORDINAL #
          PAR$ORD[BEGAP] = NP$ORD[0]; 
          BEGAP = BEGAP + 1 ;              # TO NEXT ADDR PARM WORD # 
          HDR$APCNT[0] = HDR$APCNT[0] + 1; # UP NUM ADDR PARMS #
  
          # 
          * CHECK IF LINE, CIRCUIT OR TERMINAL KEYWORD WAS PRESENT. 
          * IF SO, ADD THE TRUNK/LINE ADDRESS PARAMETER WORD. 
          # 
  
          IF CMD$ELMID EQ ELMLST"LINE"
            OR CMD$ELMID EQ ELMLST"VCIR"
            OR CMD$ELMID EQ ELMLST"TERM"
          THEN
            BEGIN 
  
            PAR$PCODE[BEGAP] = "TLA"; 
            PAR$ELADDR[BEGAP] = NP$PORT[0]; 
            HDR$APCNT[0] = HDR$APCNT[0] + 1; # UP NUM ADDR PARMS #
  
            END 
  
   #
          * CHECK IF COUPLER KEYWORD WAS PRESENT. IF SO, ADD THE COUPLER
          * ADDRESS KEYWORD TO THE ADDRESS PARAMETER LIST.
          # 
  
          IF CMD$ELMID[0] EQ ELMLST"CPLR" 
          THEN
            BEGIN 
            PAR$PCODE[BEGAP] = "CPA"; 
            PAR$ELADDR[BEGAP] = NP$NODE[1]; 
            HDR$APCNT[0] = HDR$APCNT[0] + 1;
            END 
          END 
# 
        * ELEMENT IS NOT UNDER THE OPERATOR-S CONTROL, SEND A MSG 
        * INDICATING SO.
# 
        ELSE
          BEGIN 
  
          NOC$TXT1[0] = CMD$ELTYPE[0];   #SET ELEMENT TYPE TEXT # 
          NOC$NAME[0] = PAR$ELNAME[INDX]; 
          WCB$WC[1] = 6;
          ABHTLC[1] = 40; 
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOCTRL);
          GOTO ENDEXIT; 
  
          END 
  
   #
          * INCREMENT THE COMMAND HEADER WORD ADDRESS PARAMETER COUNT.
          # 
  
        GOTO ROUTEOK; 
  
        END # IF NCFMIS # 
  
  
  
  
  
  
ROUTEOK:  
  
      # 
      * SEND THE ROUTED COMMAND TO THE COMMAND DISPATCHER.
      # 
  
      WCB$WC[1] = WCB$WC[0] + HDR$APCNT[0]; # ADJUST ENTRY SIZE # 
      IF PAR$SVCFLG[INDX] 
      THEN
        BEGIN      # IF SVCNAME, RESTORE PARM TO ORIGINAL STATE # 
        PAR$SVCFLG[INDX] = FALSE; 
        END 
      SSTAQE(P<RCQ>,WCBUF[1],HDRCMD[0],PARMS[0]); 
  
  
  
  
  
  
ENDEXIT:  
  
      END #CSSRCA#
  
 TERM 
