*DECK FCSNODB 
USETEXT TEXTFCS 
      PROC FCSNODB (CODE, ID);
*CALL COPYRITE
# TITLE FCSNODB - OUTPUT DATA BLOCK.                                   #
  
      BEGIN                            # FCSNODB                       #
  
# 
**    FCSNODB - OUTPUT DATA BLOCK.
* 
*     C. J. RAMSAY                     87/11/03 
* 
*     THIS PROCEDURE IS CALLED TO SEND A DATA BLOCK TO FTPI.
*     THE BLOCK IS EITHER SENT IMMEDIATELY TO THE NETWORK OR QUEUED 
*     INTERNALLY DEPENDING ON THE NUMBER OF OUTSTANDING DATA BLOCKS.
* 
*     PROC FCSNODB (CODE, ID) 
* 
*     ENTRY    CODE      = FUNCTION CODE OF DATA BLOCK. 
*              ID        = CONNECTION IDENTIFIER. 
*              OUTLEN    = LENGTH OF DATA BLOCK IN OCTETS.
*              ACN$ACN   = CONNECTION NUMBER. 
*              FTPDEBUG  = FTP DEBUG MODE.
*              MBOX      = MBT INDEX FOR OUTPUT FILE. 
* 
*     EXIT     DATA BLOCK SENT OR QUEUED. 
*              P<ABH>    = PTR TO OUTPUT DATA BLOCK ABH.
*              P<APDT>   = PTR TO OUTPUT DATA BLOCK (*OUTBUF*). 
* 
*     NOTES    THE DATA BLOCK MAY NOT BE TRANSFERRED TO THE NETWORK 
*              UPON EXIT OF THIS PROCEDURE. THE WORKLIST MAY NEED 
*              FLUSHING VIA A *NETWAIT* CALL. 
* 
*     METHOD   SET UP COMMON FIELDS IN THE *ABH* AND DATA BLOCK.
*              IF THE OUTSTANDING BLOCK COUNT IS LESS THAN THE
*              APPLICATION BLOCK LIMIT THEN THE OUTSTANDING BLOCK 
*              COUNT IS INCREMENTED AND THE DATA BLOCK IS SENT. 
*              OTHERWISE THE WAITING BLOCK COUNT IS INCREMENTED 
*              AND THE DATA BLOCK IS QUEUED AT THE END OF THE 
*              WAITING BLOCK QUEUE. DATA BLOCKS IN THIS QUEUE ARE 
*              SENT ON THE RECEIPT OF FC/ACK SUPERVISORY MESSAGES.
* 
# 
  
# 
****  PROC FCSNODB - XREF LIST
# 
      XREF
        BEGIN 
        PROC FCSMATS;                  # ALLOCATE TABLE SPACE          #
        PROC FCSOFTO;                  # FLUSH TERMINAL OUTPUT         #
        PROC FCSOWOF;                  # WRITE TO OUTPUT FILE          #
        PROC MOVE;                     # MOVE A NUMBER OF WORDS DIRECT #
        PROC NETPUT;                   # OUTPUT A MESSAGE              #
        PROC NETUCAS;                  # COPY ASCII STRING             #
        PROC NETUCDA;                  # CONVERT DISPLAY CODE TO ASCII #
        END 
# 
****
# 
      ITEM CODE          I;            # FUNCTION CODE OF DATA BLOCK   #
      ITEM ID            I;            # CONNECTION IDENTIFIER         #
  
      ITEM DIND          I;            # DESTINATION INDEX             #
      ITEM INDEX         I;            # WORD INDEX TO ENTRY IN WBQ    #
      ITEM ESIZE         I;            # SIZE OF WAITING BLOCK ENTRY   #
      ITEM TSIZE         I;            # SIZE OF TEXT IN WAITING BLOCK #
      ITEM CRLF          U = X"0D0A00000000000";
  
      ARRAY DBUGHDR [LOCALID:REMOTEID] S(2);
        BEGIN 
        ITEM DBUG$TEXT   C(00,00,AIPIHDR$) =
       ["--DEBUG--  (L) ",
        "--DEBUG--  (R) "]; 
        END 
      CONTROL EJECT;
# 
*     START MAIN PROCEDURE
# 
      P<APDT>    = LOC(OUTBUF);        # BASE DATA BLOCK POINTER       #
      AIPI$FC[0] = CODE;               # STORE FUNCTION CODE IN BLOCK  #
      AIPI$ID[0] = ID;                 # STORE CONNECTION IDENTIFIER   #
      NETUCAS (CRLF, 0, 2,
               OUTBUF[0], OUTLEN);     # TERMINATE WITH CR + LF        #
  
      P<ABH>    = LOC(DABH);           # BASE BLOCK HEADER POINTER     #
      ABHADR[0] = ACN$ACN[0];          # STORE CONNECTION NUMBER       #
      ABHTLC[0] = OUTLEN;              # STORE TEXT LENGTH             #
      ABHABN[0] = ACN$ABN[0];          # STORE APPLICATION BLOCK NUMBER#
  
      ACN$ABN[0] = ACN$ABN[0] + 1;     # INCREMENT BLOCK NUMBER        #
# 
*     APPLICATION BLOCK LIMIT NOT REACHED. DISPATCH THE DATA BLOCK AND
*     INCREMENT THE OUTSTANDING BLOCK COUNT.
# 
      IF ACN$OBC[0] LS ACN$ABL[0] 
      THEN
        BEGIN                          # BLOCK LIMIT NOT REACHED       #
        NETPUT (DABH, OUTBUF);         # DISPATCH THE DATA BLOCK       #
        ACN$OBC[0] = ACN$OBC[0] + 1;   # INCR. OUTSTANDING BLOCK CNT   #
        END 
# 
*     APPLICATION BLOCK LIMIT REACHED. QUEUE THE DATA BLOCK AT THE END
*     OF THE WAITING BLOCK QUEUE AND INCREMENT THE WAITING BLOCK COUNT. 
# 
      ELSE
        BEGIN                          # BLOCK LIMIT REACHED           #
        TSIZE = ((OUTLEN*10)+70) / 75; # DATA BLOCK LENGTH IN WORDS    #
        ESIZE = TSIZE + TXT$;          # ENTRY SIZE INCLUDES HEADER    #
        INDEX = WBQL;                  # ENTRY INDEX IS CURRENT END    #
        FCSMATS (P<WBQ>, WBQL, ESIZE); # MAKE ROOM FOR THIS ENTRY      #
        WBQ$SIZE[INDEX] = ESIZE;       # STORE ENTRY SIZE              #
        WBQ$ABH[INDEX]  = ABHWORD[0];  # STORE APPLICATION BLOCK HEADER#
        MOVE (TSIZE, OUTBUF,
              WBQ[INDEX + TXT$]);      # MOVE DATA BLOCK INTO QUEUE    #
        ACN$WBC[0] = ACN$WBC[0] + 1;   # INCREMENT WAITING BLOCK CNT   #
        END;
# 
*     IF DEBUG MODE IS ON THEN WRITE ANY FTP COMMANDS TO OUTPUT FILE. 
# 
      IF FTPDBUGM EQ OPTON$ 
      THEN
        BEGIN 
        DIND = 0;                      # INITIALIZE DESTINATION INDEX  #
        NETUCDA (DBUGHDR[ID], 0, AIPIHDR$,
                 OUTBUF, DIND, FALSE); # INSERT --DEBUG--  (X) HEADER  #
        FCSOWOF (OUTBUF[0], OUTLEN);   # WRITE TO OUTPUT FILE          #
        FCSOFTO;                       # FLUSH TERMINAL OUTPUT         #
        END 
  
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # FCSNODB                       #
  
      TERM
