*DECK NP$SEND 
USETEXT AIPDEF
USETEXT NP$GMB
USETEXT NP$MODE 
USETEXT NP$NWL
USETEXT NP$STAT 
PROC NP$SEND; 
*IF DEF,IMS 
 #
*1DC  NP$SEND 
*     1. PROC NAME         AUTHOR               DATE
*        NP$SEND           S.KRULEVITCH         77/05/23
* 
*     2. FUNCTIONAL DESCRIPTION 
*        SENDS A WORKLIST,POSSIBLY WITH A GETSM REQUEST, TO NIP.
* 
*     3. METHOD USED
*        IF THE UPLINE DATA QUEUE FEATURE IS IN USE, AND IF THE 
*        SENDGETMM AND ID$FLAG ARE SET TRUE, BUILD A
*        -GET MULTIPLE MESSAGES- ENTRY AT THE END OF THE WORKLIST.
* 
*        BUILD A -GET SUPERVISORY MESSAGE- ENTRY AT THE END OF THE WL 
*        IF SENDGETSM AND SD$FLAG ARE SET TRUE. 
* 
*        IF THE DOWNLINE MESSAGE BUFFERING FEATURE IS IN USE, AND IF
*        THE DOWNLINE BUFFER IS LESS THAN THE LENGTH OF THE (FIXED-SIZE)
*        NETWORK WORKLIST, COPY THE MESSAGES INTO THE WORKLIST. 
*        OTHERWISE, BUILD A PUTQ ENTRY IN THE NETWORK WORKLIST, 
*        CONTAINING THE ADDRESS OF THE DOWNLINE MESSAGE BUFFER. 
* 
*        CALL NP$XFER TO TRANSFER THE NETWORK WORKLIST TO NIP. IF THE 
*        WORKLIST RESPONSE IS RETURNED TO AIP THEN NP$RESP IS CALLED
*        TO PROCESS THE RESPONSE. 
* 
*     4. ENTRY CONDITIONS 
*        NEXT - INDEX OF NEXT AVAILABLE WORKLIST CELL 
*        SD$FLAG - TRUE IF SM DATA QUEUED IN NIP
*        SPACE$LEFT - NUMBER OF AVAILABLE WORKLIST CELLS
* 
*     5. EXIT CONDITONS 
*        IF A NETGET OR NETGETL WAS JUST ISSUED, THE DATA BLOCK (OR NULL
*        BLOCK) WILL BE FOUND (OR POINTED TO) IN THE WORKLIST.  IF A
*        -GETSM- WAS INCLUDED IN THE WORKLIST, SUPERVISORY MESSAGES 
*        (IF ANY) WILL BE FOUND IN THE SUPERVISORY MESSAGE BUFFER.
* 
*     6. COMDECKS CALLED AND SYMPL TEXTS USED.
*        AIPDEF    NP$CRT    NP$MODE   NP$NWL 
*        NP$STAT
* 
*     7. ROUTINES CALLED
*        NP$RESP - PROCESSES WORKLIST RESPONSE
*        NP$XFER - TRANSFER NWL TO NIP
*        NP$UCV - UPDATE CONTROL VARIABLES
* 
*     8. DAYFILE MESSAGES 
*        NONE 
* 
 #
*ENDIF
   BEGIN
  
*CALL NP$CRT
  
#                                                                     # 
#     ROUTINES CALLED                                                 # 
#                                                                     # 
   XREF BEGIN 
        PROC NP$RESP;                   # PROCESSES NIP RESPONSE       #
        PROC NP$SN;                     # UPDATE AIP STATISTICS        #
        PROC NP$UCV;                    # UPDATE CONTROL VARIABLES     #
        PROC NP$XFER;                   # TRANSFER NWL TO NIP          #
        END #XREFS# 
#                                                                     # 
#     LOCAL DECLARATIONS                                              # 
#                                                                     # 
      DEF TIL       #STEP 1 UNTIL#; 
      ITEM
        I               I,
        LEN             I;              #TEMPORARY VARIABLE           # 
      BASED ARRAY MEM[0]; 
        BEGIN 
        ITEM MEMWORD    I;              # FULL WORD ACCESS             #
        END 
  
#**********************************************************************#
#                                                                     # 
#     NP$SEND EXECUTION BEGINS HERE                                   # 
#                                                                     # 
# 
      ONLY CREATE GETMM WORKLIST ENTRY IF THE AIP MULTIPLE UPLINE DATA
      MESSAGE QUEUING FEATURE IS IN USE AND NIP HAS DATA MESSAGES AND 
      EITHER THE WORKLIST BUFFER IS NOT EMPTY OR A WORKLIST REQUEST 
      WILL BE SENT ANYWAY TO GET SUPERVISORY MESSAGES.
# 
      IF (GMBUSE                 ) AND
         (SENDGETMM              ) AND
         (ID$FLAG NQ 0           ) AND
         (  (HDR$N[NHDR] NQ 0) OR 
            (DEFER$GSM       )   )
  
      THEN
        BEGIN 
#                                                                      #
#       THE SHORTEST DATA MESSAGE IS TWO WORDS LONG.  A GETMM          #
#       REQUEST IS BUILT ONLY IF THERE IS AT LEAST TWO WORDS IN        #
#       THE AIP UPLINE DATA BUFFER.                                    #
#                                                                      #
#       STEP 1: CALCULATE LEN = EMPTY SPACE IN AIP DATA BUFFER         #
  
        IF (GMBHEAD LS GMBFOOT) AND 
           (GMBLAST LQ GMBFOOT) 
        THEN
          BEGIN 
          IF GMBHEAD GQ 4 
          THEN
            GMBFOOT = 1;
          END #BOUNDARY CONDITION#
        IF GMBHEAD GR GMBFOOT 
        THEN
          BEGIN 
          LEN = GMBHEAD - GMBFOOT - 1;
          END 
        ELSE
          LEN = GMBLAST - GMBFOOT + 1;
#                                                                      #
#       STEP 2: BUILD GETMM ENTRY IF LEN IS LARGE ENOUGH               #
        IF LEN GQ 2 
        THEN                            # UPLINE DATA BUF LARGE ENOUGH #
          BEGIN 
  
*IF,DEF,STAT
          NP$SN(TYPE"GMM");             # INCREMENT NO OF GMM WKLST BLT#
*ENDIF
  
          N$GMMAWL[0] = 1;              # FLAG GMM AWL TO PROCESS      #
          NWL[NEXT]=0;                  # CLEAR AND BUILD OP WORD      #
          NWL$ID[NEXT]=AWLID; 
          BS = OPABHSIZ;                # NWL ENTRY SIZE               #
          NWL$TA[NEXT]=LOC(GMBWRD[GMBFOOT]);
          NWL$OP[NEXT]=OP$GMM;          # GETMM OPCODE                 #
          GMM$NFW[NEXT+1] = LEN;        # SIZE OF AIP DATA BUFFER      #
          GMM$ACN[NEXT+1] = GMBCN;      # CON NO FOR AIP DATA BUFFER   #
          GMM$ALN[NEXT+1] = GMBLN;      # LIST NO FOR AIP DATA BUFFER  #
          NP$UCV;                       # UPDATE NWL CONTROL VARIABLES #
          END 
        END #SENDGETMM# 
  
      IF SENDGETSM AND (SD$FLAG NQ 0)   # IF SM QUEUED IN NIP          #
      THEN
        BEGIN 
#                                                                     # 
#       THE SHORTEST SUPERVISORY MESSAGE IS TWO WORDS LONG. A GETSM   # 
#       REQUEST IS BUILT ONLY IF THERE IS AT LEAST TWO WORDS IN THE   # 
#       SMB (SUPERVISORY MESSAGE BUFFER).                             # 
#                                                                     # 
#       STEP 1: CALCULATE LEN = EMPTY SPACE IN SMB                    # 
        IF HEAD LS FOOT AND (LAST-FOOT+1) LS NEXTSMLEN
        THEN
          BEGIN 
          IF (HEAD-FIRST) GQ NEXTSMLEN
          THEN
            FOOT = FIRST; 
          END #BOUNDARY CONDITION#
        IF HEAD GR FOOT 
        THEN
          LEN = HEAD - FOOT;
        ELSE
          LEN = LAST - FOOT + 1;
#                                                                     # 
#       STEP 3: BUILD NP$GSM ENTRY IF LEN IS LARGE ENOUGH              #
        IF LEN GQ NEXTSMLEN 
        AND LEN GQ OPABHSIZ 
        THEN
          BEGIN 
*IF,DEF,STAT
          NP$SN(TYPE"GSM");             # INCREMENT NO OF GSM WKLST BLT#
*ENDIF
  
          N$GSMAWL[0] = 1;  # FLAG GSM AWL TO PROCESS                  #
          NWL[NEXT]=0;                  # CLEAR AND BUILD OP WORD      #
          NWL$ID[NEXT]=AWLID; 
          BS = OPABHSIZ;                # NWL ENTRY SIZE               #
          NWL$TA[NEXT]=LOC(GSM[FOOT]);
          NWL$OP[NEXT]=OP$GSM;
          NWL[NEXT+1]=LEN;              # CLEAR AND SEND SMB SPACE SIZE#
          NP$UCV;                       # UPDATE NWL CONTROL VARIABLES #
          END 
        END #SENDGETSM# 
#                                                                     # 
#     ISSUE NWL WORKLIST TO NIP IF NWL ENTRY EXISTS                   # 
#                                                                     # 
      IF HDR$N[NHDR] NQ 0 
      THEN
        BEGIN 
        IF DOWNUSE                      # DOWNLINE BUFFERING IN USE    #
        THEN
          BEGIN 
          P<WORKLIST> = LOC(NWLBUF);    # ADDR OF FIXED WORKLIST       #
          IF NOT RESEND                 # NOT RESENDING SAME WORKLIST  #
          THEN
            BEGIN 
            P<MEM> = LOC$APBUF;         # SAVE LOC OF APP BUFFER       #
            LEN = HDR$W[NHDR] - 1;      # LENGTH (WORDS) OF TEXT IN BUF#
            NEXT = NNTR;                # INITIALIZE POINTERS FOR WL   #
            SPACE$LEFT = LWL; 
            IF LEN LQ SPACE$LEFT
            THEN                        # TEXT IN BUFFER CAN FIT IN WL #
              BEGIN 
              FOR I = 0 STEP 1 UNTIL (LEN - 1)
              DO                        # COPY TEXT FROM APP BUFF INTO #
                BEGIN                   # FIXED-SIZE NETWORK WORKLIST  #
                NWL[NEXT + I] = MEMWORD[I]; 
                END 
              END 
            ELSE                        # TEXT IN BUF TOO LONG FOR WL  #
              BEGIN                     # BUILD PUTQ ENTRY             #
              NP$SN(TYPE"PUTQ");        # INCREMENT NO OF PUTQ WL BUILT#
  
              PUTQ[NEXT] = 0;           # CLEAR AND BUILD OP WORD      #
              PQ$ID[NEXT] = AWLID;
              PQ$OP[NEXT] = OP$PUTQ;    # PUTQ OPCODE                  #
              PQ$TA[NEXT] = LOC$APBUF;  # ADDR OF TEXT AREA BUFFER     #
              PQ$N[NEXT+1] = HDR$N[NHDR];  # NO. OF WL ENTRIES IN BUF  #
              PQ$W[NEXT+1] = LEN;       # NO. OF WORDS IN TEXT AREA BUF#
# 
              THE HEADER FIELDS CONTAIN THE LENGTH AND NUMBER OF WORDS
              OF THE DOWNLINE BUFFER.  CLEAR THESE FIELDS, AS THEY
              SHOULD NOW REFLECT THE LENGTH/NO. OF ENTRIES OF THE FIXED 
              WORKLIST.  THE FIXED WORKLIST ONLY CONTAINS ONE 2-WORD
              PUTQ ENTRY.  THE HEADER FIELDS WILL BE RESET IN NP$UCV. 
# 
              HDR$N[NHDR] = 0;
              HDR$W[NHDR] = 1;
              BS = OPABHSIZ;
              NP$UCV;                   # UPDATE NWL CONTROL VARIABLES #
  
              END 
            END 
          END 
  
        NP$XFER(LOC(NWL[NCTL]));
        IF NOT DEFER$PRO
        THEN                            # IF NOT IN PARALLEL MODE      #
          NP$RESP;                      # PROCESS RESPONSE AWL         #
        END 
  
      RETURN; 
   END #NP$SEND#
TERM
