*DECK     CSSASD
USETEXT TEXTCS; 
USETEXT TEXTSS; 
USETEXT TXCMDCS;
USETEXT TXTAPSS;
USETEXT TXTSUSS;
USETEXT TXTSMCS;
PROC CSSASD;
# TITLE CSSASD - ACTION SEND COMMAND #
  
      BEGIN 
  
# 
**    CSSASD - ACTION SEND COMMAND. 
* 
*     C. BRION               82/05/24.
* 
*     THIS PROCEDURE PROCESSES THE SEND COMMAND.
* 
*     PROC CSSASD 
* 
*     ENTRY 
*       1. HDRCMD[0] = COMMAND HEADER WORD. 
*       2. PARMS[0] = COMMAND BLOCK CONTAINING THE ORIGINAL TYPEIN, 
*                       SYNTAX PARMETER LIST, AND ADDRESS LIST. 
* 
*     EXIT
*       1. IF BROADCAST ALREADY IN PROGRESS -- SEND TERMINAL TEXT TO
*            THE CONNECTION TRAFFIC QUEUE INDICATING SO.
*       2. IF UNABLE TO SEND TO DESTINATION -- SEND TERMINAL TEXT TO
*            CONNECTION TRAFFIC QUEUE INDICATING SO.
*       3. IF O.K. -- 
*            A. COMMAND TEXT SENT TO EVENT QUEUE. 
*            B. MSG SENT TO OUTGOING TRAFFIC QUEUE. 
# 
  
# 
****  PROC CSSASD XREF LIST.
# 
  
      XREF
        BEGIN 
        PROC CSSAMS;                     # ACTION MULTIPLE SEND COMMAND#
        PROC MOVE;                       # MACREL-MOVE MEMORY # 
        PROC MOVEI;                      # MACREL-MOVE INDIRECT # 
        PROC SSTAQE;                     # SS-ACCEPT QUEUE ENTRY #
        PROC SSBEBF;                     # SS-EXTRACT BIT FIELD # 
        PROC SSBSBF;                     # SS-STORE BIT FIELD # 
        PROC SSBSBW;                     # SS-SET BIT IN WORD # 
        FUNC SSDCDA;                     # SS-DISPLAY TO ASCII #
        END 
# 
****
# 
  
      DEF  BADNOR$           #99#;       # INVALID NPU ORDINAL INDEX# 
      DEF  US$               #X"1F"#;    # HEX NUM FOR -US- CHAR       #
      ITEM ELMINDX           U;          # ELEMENT INDEX INTO PARMS # 
      ITEM LLAINDX           U;          # LLINK ADDRESS PARMS INDEX# 
      ITEM BEGAPIX           U;          # START ADDR LIST INDEX #
      ITEM BEGSYIX           U;          # START SYNTAX LIST INDEX #
      ITEM FINAPIX           U;          # LAST ADDR LIST INDEX # 
      ITEM DONE              B;          # FINISH INDICATOR # 
      ITEM NORNUM            U;          # NUMBER NPU ORDINALS #
      ITEM NOR1INDX          U;          # NOR 1 INDEX LOCAL VAR #
      ITEM NOR2INDX          U;          # NOR 2 INDEX LOCAL VAR #
      ITEM NORD1             U;          # NOR 1 LOCAL VAR #
      ITEM NORD2             U;          # NOR 2 LOCAL VAR #
      ITEM NPUORD            U;          # NPU ORDINAL #
      ITEM NORINDX           U;          # ACTIVE NOR INDEX # 
      ITEM DORD              U;          # MOVE VARIABLES # 
      ITEM DBIT              U; 
      ITEM AORD              U; 
      ITEM ABIT              U; 
      ITEM SCHAR             U; 
      ITEM I,Y               U;          # LOOP VARS #
      ITEM DVAR              U; 
  
  
# 
*     FLG$WORD - BASED ARRAY THAT POINTS TO THE SEND PENDING BIT
*     MAP IN THE NPUCB-S. 
# 
      BASED ARRAY FLG$WORD [00:00] S(NPCBSZ$);
        BEGIN 
        ITEM FW$WORD    I(00,00,60);
        END 
  
  
# 
*     NOBRCAST - MESSAGE FOR INVALID LLINK ELEMENT BROADCAST. 
# 
  
      ARRAY NOBRCAST [00:00] S(5);
        BEGIN 
        ITEM NOB$TXT1   C(00,00,20) = ["CANNOT BROADCAST TO "]; 
        ITEM NOB$TXT2   C(02,00,22) = ["HOST-HOST LOGICAL LINK"]; 
        ITEM NOB$ZERO   U(04,12,48) = [0];
        END 
  
# 
*     NODENOSUP - MESSAGE FOR UNSUPERVISED TERMINAL NODE. 
# 
  
      ARRAY NODENOSUP [00:00] S(5); 
        BEGIN 
        ITEM NOD$TXT1   C(00,00,23) =["TERMINAL NODE OF LLINK "]; 
        ITEM NOD$LLNAM  C(02,18,07);     #LLINK NAME# 
        ITEM NOD$TXT2   C(03,00,15) = [" NOT SUPERVISED"];
        ITEM NOD$ZERO   U(04,30,30) = [0];
        END 
  
  
# 
*     FROMNOP - MESSAGE ARRAY FOR FROM NOP.. PREFIX . 
# 
  
      ARRAY FROMNOP [00:00] S(1); 
        BEGIN 
        ITEM FRO$TXT    C(00,00,10) = ["FROM NOP.."]; 
        END 
  
  
  
  
  
  
  
# 
*     INITIALIZE INDICES, ENTRY WORDS.
# 
  
      WCB$WORD[1] = 0;
      ABHWORD[1] = 0; 
      ELMINDX = HDR$TXWCNT[0] + 2;
      BEGAPIX = HDR$TXWCNT[0] + HDR$SPCNT[0]; 
# 
*     DETERMINE IF MULTIPLE SEND COMMAND.  IF SO CALL PROC *CSSAMS*.
# 
  
      IF PAR$PCODE[ELMINDX] EQ "NPS"
      THEN
        BEGIN 
        CSSAMS; 
        GOTO ENDEXIT; 
        END 
  
  
# 
*     DETERMINE THE NPU ORDINAL FOR THE DESTINATION TO SEND THIS
*     MESSAGE.
# 
  
      FOR I = BEGAPIX STEP 1 WHILE PAR$PCODE[I] NQ "NOR"
      DO
        BEGIN 
        END 
  
      NORINDX = I;
      NPUORD = PAR$ORD[NORINDX];
  
  
# 
*     CHECK IF SEND ON LLINK. IF SO, CHECK IF ATTEMPT ON HOST TO HOST 
*     LLINK. IF SO, NOT ALLOWED. SEND ERROR MESSAGE TO OPERATOR.
# 
  
      IF PAR$PCODE[ELMINDX] EQ "LL0"
      THEN
        BEGIN 
        LLAINDX = HDR$TXWCNT[0] + HDR$SPCNT[0]+ 1;
        IF PAR$LLTYPE[LLAINDX]
        THEN
          BEGIN 
          WCB$SMID[1] = SMID"TTEXT";
          WCB$IAF[1] =TRUE; 
          ABHADR[1] = HDR$OPORD[0]; 
          WCB$WC[1] = 7;
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NOBRCAST[0]); 
          GOTO ENDEXIT; 
          END 
  
# 
*     NOT A HOST TO HOST LLINK, CONTINUE BY REFINING WHICH NPU ORDINAL
*     TO USE TO SEND THE BRAODCAST TO.
# 
        FINAPIX = BEGAPIX + HDR$APCNT[0] - 1; 
        DONE = FALSE; 
        NORNUM = 0; 
        NOR1INDX = 0; 
        NOR2INDX = 0; 
  
# 
*     SEARCH THE ADDRESS PARAMETER LIST OF PARMS FOR THE NPU ORDINALS 
*     (NOR). MAXIMUM NORS IS TWO. 
# 
  
        FOR I = BEGAPIX STEP 1 WHILE NOT DONE 
          AND I LQ FINAPIX
        DO
          BEGIN 
          IF PAR$PCODE[I] EQ "NOR"
          THEN
            BEGIN 
            IF NORNUM EQ 0
            THEN
              BEGIN 
              NORNUM = 1; 
              NOR1INDX = I; 
              NORD1 = PAR$ORD[I]; 
              END 
            ELSE
              BEGIN 
              DONE = TRUE;
              NORNUM = 2; 
              NOR2INDX = I; 
              NORD2 = PAR$ORD[I]; 
              END 
            END 
          END 
  
# 
*     THE NPU ORDINALS FOR THE COMMAND HAVE BEEN FOUND. 
*     DETERMINE WHICH IS TO BE USED. THE NPU ORDINAL OF THE NPU WITH
*     THE SAME NODE ID AS THE TERMINAL NODE ID OF THE LLINK ADDRESS 
*     PARAMETER OF THE COMMAND SHOULD BE USED.
# 
  
        NPUORD = BADNOR$; 
        IF NPU$NID[NORD1] NQ PAR$LLNID2[NOR1INDX + 1] 
        THEN
          BEGIN 
          PAR$PCODE[NOR1INDX] = "  ";    # REMOVE NOR # 
          PAR$PCODE[NOR1INDX + 1] = "   "; # REMOVE LLA # 
  
# 
*     FIRST NPU ORDINAL NOT THE ONE. CHECK FOR SECOND.
# 
  
          IF NORNUM EQ 2
          THEN
            BEGIN 
            IF NPU$NID[NORD2] EQ PAR$LLNID2[NOR2INDX + 1] 
            THEN
              NPUORD= NORD2;
            END 
          END 
        ELSE
          NPUORD = NORD1;                # FIRST NPU ORDINAL OK # 
  
# 
*     IF GOOD NPU NOT FOUND, SEND NO SUPERVISED TERMINAL NODE 
*     MESSAGE TO OPERATOR.
# 
  
        IF NPUORD EQ BADNOR$
        THEN
          BEGIN 
          WCB$IAF[1] = TRUE;
          WCB$SMID[1] = SMID"TTEXT";
          WCB$WC[1] = 7;
          ABHADR[1] = HDR$OPORD[0]; 
          SSTAQE(P<CNQ>,WCBUF[1],ABH[1],NODENOSUP[0]);
          GOTO ENDEXIT; 
          END 
  
        END 
  
# 
*     SET UP BROADCAST SM ENTRY AND  SM BODY. 
# 
  
      PFCSFC[1] = 0;
      PFC[1] = MSG; 
  
# 
*     DETERMINE WHICH SM (SFC) BY EXAMINATION OF WHICH ELEMENT WAS
*     SPECIFIED IN THE COMMAND. EACH ELEMENT TYPE WARRANTS DIFFERENT
*     SM SETUP AND CHARACTER TRANSLATION/MOVE ORDINALS TO MOVE THE
*     BROADCAST TEXT INTO THE SM. 
# 
  
      IF PAR$PCODE[ELMINDX] EQ "LI0"   # SEND,LI= # 
      THEN
        BEGIN 
        SFC[1] = LI;
        MSGP[1] = PAR$ELADDR[NORINDX + 1]; # SET PORT NUMBER #
        ABHTLC[1] = 4;
        AORD = 0; 
        ABIT = 32;
        WCB$SMID[1] = SMID"MSGLI";
        END 
  
      ELSE IF PAR$PCODE[ELMINDX] EQ "LL0"  # SEND,LL= # 
      THEN
        BEGIN 
        SFC[1] = LL;
        MSGN1[1] = PAR$LLNID1[NORINDX + 1]; 
        MSGN2[1] = PAR$LLNID2[NORINDX + 1]; # LLINK NODE NUMBERS #
        ABHTLC[1] = 4;
        AORD = 0; 
        ABIT = 32;
        WCB$SMID[1] = SMID"MSGLL";
        END 
  
      ELSE IF PAR$PCODE[ELMINDX] EQ "NP0"  #SEND,NP= #
      THEN
        BEGIN 
        SFC[1] = NP;
        ABHTLC[1] = 2;
        AORD = 0; 
        ABIT = 16;
        WCB$SMID[1] = SMID"MSGNP";
        END 
  
      ELSE                             # SEND, TE= #
        BEGIN 
        SFC[1] = TE;
# 
*     CONVERT TERMINAL NAME AND MOVE INTO MSG/TE SM . 
# 
  
        DORD = ELMINDX; 
        DBIT = 0; 
        AORD = 1; 
        ABIT = 4; 
  
        FOR Y = 1 STEP 1 UNTIL 7
        DO
          BEGIN 
          SSBEBF(PARMS[0],DORD,DBIT,6,SCHAR); 
          SCHAR = SSDCDA(SCHAR);
          SSBSBF(CSSM[1],AORD,ABIT,8,SCHAR);
          END 
  
        MSGP[1] = PAR$ELADDR[NORINDX + 1];
        ABHTLC[1] = 15; 
        AORD = 2; 
        ABIT = 0; 
        WCB$SMID[1] = SMID"MSGTE";
        END 
  
  
# 
*     MOVE THE FROM NOP.. PREFIX INTO SM AREA.
# 
  
      DORD = 0; 
      DBIT = 0; 
  
      FOR I = 1 STEP 1 UNTIL 10 
      DO
        BEGIN 
        SSBEBF(FROMNOP[0],DORD,DBIT,6,SCHAR); 
        SCHAR = SSDCDA(SCHAR);
        SSBSBF(CSSM[1],AORD,ABIT,8,SCHAR);
        END 
  
# 
*     MOVE MESSAGE TEXT FROM COMMAND PARMS AREA TO SM BODY AFTER
*     DISPLAY CODE TO ASCII CONVERSION. 
# 
  
# 
*     DETERMINE BEGINNING INDEX FOR MSG TEXT IN COMMAND PARMS ARRAY.
# 
  
      BEGSYIX = HDR$TXWCNT[0] + 1;
      FOR I = BEGSYIX STEP 1 WHILE PAR$PCODE[I] NQ "MS0"
      DO
        BEGIN 
        END 
  
      DORD = I+1; 
      DBIT = 0; 
  
      FOR Y = 1 STEP 1 UNTIL PAR$MSGCL[I] 
      DO
        BEGIN 
        SSBEBF(PARMS[0],DORD,DBIT,6,SCHAR); 
        SCHAR = SSDCDA(SCHAR);
        SSBSBF(CSSM[1],AORD,ABIT,8,SCHAR);
        END 
  
# 
*     FINISH OUTGOING SM SETUP. 
# 
  
  
      SCHAR = US$;
      SSBSBF(CSSM[1],AORD,ABIT,8,SCHAR);
  
      ABHTLC[1] = ABHTLC[1] + PAR$MSGCL[I] + 11;
      WCB$WC[1] =((ABHTLC[1] * 8)/60) + 3;
  
# 
*     SAVE THE SM IN THE OPERATOR CONTROL BLOCK.
# 
  
      OC$WC[HDR$OPORD[0]] = WCB$WC[1] - 2;
      OC$TLC[HDR$OPORD[0]] = ABHTLC[1]; 
  
      MOVEI(OC$WC[HDR$OPORD[0]],LOC(CSSM[1]),LOC(OC$SM[HDR$OPORD[0]])); 
  
# 
*     SET UP THE REST OF THE ABH WORD AND ENTRIES IN THE NPUCB AND
*     OCB.
# 
  
      ABHABT[1] = APPSUP; 
      ABHBT[1] = APPSUP;
      ABHDN[1] = NPU$NID[NPUORD]; 
      ABHSN[1] = NPU$HID[NPUORD]; 
      ABHACT[1] = ACTCSNP$; 
      P<FLG$WORD> = LOC(NPU$SDFLGS[NPUORD]);
      SSBSBW(FLG$WORD,HDR$OPORD[0]);
      OC$NCNT[HDR$OPORD[0]] = 1;
      OC$VERB[HDR$OPORD[0]] = HDR$VERB[0];
  
# 
*     CHECK IF THERE IS A CURRENT SEND IN PROGRESS. 
*     IF NOT, SET THE NPUCB AND OCB TO REFLECT SEND ACTIVE. 
*     INCREMENT THE NUMBER OF SEND NPUS EQUAL TO ONE. 
# 
  
      IF NPU$OPSD[NPUORD] EQ 0
      THEN
        BEGIN 
        OC$CNPU[HDR$OPORD[0]] = NPUORD; 
        NPU$OPSD[NPUORD] = HDR$OPORD[0];
  
  
# 
*     SEND SM.
# 
  
        SSTAQE(P<OTQ>,WCBUF[1],ABH[1],CSSM[1]); 
  
  
  
        END  # IF OPSD EQ 0 # 
  
  
# 
*     MUST ENTER COMMAND TEXT INTO NETWORK LOG FILE VIA A CMDTXT SUPER- 
*     VISION EVENT TO THE EVENT PROCESSOR.
# 
  
      WCB$WORD[1] = 0;
      ABHWORD[1] = 0; 
      P<MSCMD> = LOC(CMD$TEXT[0]);     # POINT ARRAY FOR MOVE # 
      CMD$TNAM[0] = OC$TNAM[HDR$OPORD[0]]; # OP TERM NAME # 
      MOVE(HDR$TXWCNT[0],PARMS[0],MSCMD[0]);
      WCB$SMID[1] = SMID"CMDTXT"; 
      WCB$WC[1] = HDR$TXWCNT[0] + 4;
      SSTAQE(P<EVQ>,WCBUF[1],ABH[1],CMDLINE[0]);
  
  
ENDEXIT:  
      DVAR = 1; 
  
      END  # CSSASD # 
 TERM 
