*DECK     NVFCPUT 
USETEXT          TEXTSS 
USETEXT          TXTAPSS
USETEXT          TEXTNVF
USETEXT          TXTANVF
PROC  NVFCPUT;
# TITLE NVFCPUT - PREPARE USER TEXT.   #
  
      BEGIN # NVFCPUT # 
# 
**    NVFCPUT - PREPARE USER TEXT.
* 
*     S. H. FISCHER.         81/12/04.
* 
*     THIS PROCEDURE PROCESSES TEXT LINES (TERMINAL TEXT) AND 
*     SYNCHRONOUS SUPERVISORY MESSAGES EMANATING FROM THE INNER(I)
*     LAYER AND DESTINED FOR A USER.  ITS MAIN FUNCTION IS TO FORMAT
*     THE TEXT INTO A NETWORK BLOCK AND EITHER ISSUE IT, QUEUE IT OR
*     DISCARD IT AS APPROPRIATE.
* 
*     PROC NVFCPUT
* 
*     ENTRY    WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION
*                         TRAFFIC QUEUE (*CTQ*) ENTRY (CONTAINS THE 
*                         INPUT ALLOWED FLAG).
*             ABHBUF[0] = APPLICATION BLOCK HEADER FOR THE TEXT OR SM 
*                         (BASED ARRAY *ABH* IN *TXTAPSS* POINTS HERE). 
*             MSGBUF[0] = DISPLAY CODED TEXT LINE OR SM BODY (BASED 
*                         ARRAY *APSM* IN *TXTAPSS* POINTS HERE).  THE
*                         POSSIBLE PFC/SFC VALUES FOR THE SYNCHRONOUS 
*                         SMS ARE:  CTRL/DEF AND CTRL/RTC.
* 
*     EXIT    ONE OR MORE OF THE FOLLOWING DEPENDING UPON THE STATE OF
*             THE CONNECTION, WHETHER APPLICATION BLOCK LIMIT HAS BEEN
*             REACHED, AND WHETHER THE CONNECTION HAS BEEN INITIALIZED: 
*             - A NETWORK DATA BLOCK FOR THE TEXT HAS BEEN PLACED IN
*               THE OUTGOING TRAFFIC QUEUE (*OTQ*). 
*             - AN ENTRY FOR THE SYNCHRONOUS SM HAS BEEN PLACED IN THE
*               OUTGOING TRAFFIC QUEUE (*OTQ*). 
*             - THE TEXT OR SM HAS BEEN PLACED IN THE WAITING BLOCK 
*               QUEUE (*WBQ*) PENDING RECEIPT OF A BLOCK ACKNOWLEDGEMENT
*               OR A FLOW CONTROL INITIALIZED SM FOR THE CONNECTION.
*             - THE TEXT OR SYNCHRONOUS SM HAS BEEN DISCARDED.
* 
*     NOTE    PROCESSING IS IN ACCORDANCE WITH THE NVF/USER C-LAYER 
*             STATE DIAGRAM.
# 
  
  
  
  
# 
****  PROC NVFCPUT - XREF LIST. 
# 
      XREF
        BEGIN 
        PROC ABORT;          # ABORT PROGRAM                           #
        PROC MESSAGE;        # SEND MESSAGE TO DAYFILE                 #
        PROC MOVE;           # MOVE BLOCK OF MEMORY                    #
        PROC NVFCFCE;        # FIND CONNECTION ENTRY                   #
        PROC SSTAQE;         # ACCEPT QUEUE ENTRY                      #
        PROC SSTETS;         # ENLARGE TABLE SPACE                     #
        END 
# 
****
# 
  
  
  
  
      ITEM J          I;     # SCRATCH #
      ITEM I          I;     # LOOP VARIABLE                           #
      ITEM NEWACN     B;     # TRUE IF ACN NOT FOUND IN ACN LIST       #
      ITEM AE         I;     # ORD OF MATCHED ACN LIST ENTRY           #
      ITEM ACNN       I;     # ACN OF ENTRY                            #
      ITEM ROUT       I;     # ORDINAL OF ENTRY LOCATED IN WBQ         #
  
  
  
  
#     ADJUST BLOCK TYPE TO OUTPUT RANGE.                               #
  
  
  
      ABHABT[0] = ABHABT[0] - 6;       # (APPTTX$ - APPBLK) = 6        #
  
      ACNN = ABHADR[0]; 
  
      NVFCFCE( ACNN, AE, NEWACN );
  
  
  
  
$BEGIN
      IF NEWACN 
      THEN
        BEGIN 
        MESSAGE( " ACN LOST - NVFCPUT", 0 );
        ABORT;
        END 
$END
      IF NEWACN 
      THEN
        BEGIN 
        RETURN;  # IGNORE ENTRY # 
        END 
  
  
  
  
# 
*     MAP MSG BLOCK IN BRKCMD STATE TO ACTIVE STATE.
# 
      IF ACN$STATE[AE] EQ ACNST"BRKCMD" 
        AND ABHABT[0] EQ APMSG
      THEN
        BEGIN 
        ABHABT[0] = APPBLK; 
        ACN$STATE[AE] = ACNST"ACTIVE";
        END 
  
  
  
  
# 
*     DETERMINE IF THE CONNECTION IS IN A STATE TO KEEP THE BLOCK.
* 
# 
  
  
      IF ACN$STATE[AE] EQ ACNST"ACTIVE" 
        OR ACN$STATE[AE] EQ ACNST"CLEARI" 
        OR ACN$STATE[AE] EQ ACNST"BRKCMD" 
      THEN
        BEGIN 
  
  
  
  
# 
*       IF THE CONNECTION HAS BEEN INITIALIZED AND OUTSTANDING BLOCK
*       LIMIT HAS NOT BEEN REACHED THEN THE BLOCK CAN BE SENT 
*       IMMEDIATELY. OTHERWISE THE BLOCK MUST BE QUEUED.
# 
  
        IF ACN$INIT[AE] 
          AND ACN$BLCNT[AE] LS ACN$ABL[AE]
        THEN
          BEGIN  # CAN SEND BLOCK IMMEDIATELY # 
          ABHABN[0] = ACN$ABN[AE];
          ACN$ABN[AE] = ACN$ABN[AE] + 1;
          ACN$BLCNT[AE] = ACN$BLCNT[AE] + 1;
          SSTAQE( P<OTQ>, WCBUF, ABHBUF, MSGBUF );
          END 
        ELSE
          BEGIN  # MUST QUEUE BLOCK # 
  
  
  
  
# 
*         CMD BLOCKS CAN ONLY BE ADDED AT THE END OF THE QUEUE, 
*         BLK AND MSG BLOCKS CAN BE APPENDED TO THE LAST BLOCK
*         IF IT IS A BLK BLOCK. SEARCH ONLY IF THERE IS A EXISTING
*         BLOCK.
# 
  
          IF ABHABT[0] NQ APPCMD
            AND ACN$WBCNT[AE] NQ 0
          THEN
            BEGIN # MUST SEARCH QUEUE FOR LAST BLOCK #
            J = 0;
            FOR I =0 STEP WBQ$ESIZE[I]
              WHILE J LS ACN$WBCNT[AE]
            DO
              BEGIN 
              IF WBQ$ABHACN[I] EQ ACNN
              THEN
                BEGIN 
                J = J + 1;
                ROUT = I; 
                END 
              END 
  
  
  
  
# 
*           IF THE LAST BLOCK IS A BLK BLOCK THEN APPEND TO THE NEW 
*           BLOCK IF IT CAN HOLD BOTH BLOCKS AND THE CHARACTER TYPE 
*           AND FORMAT EFFECTORS MATCH. CHANGE TYPE TO MSG IF ADDED 
*           TEXT WAS FROM MSG BLOCK.
# 
  
            IF WBQ$ABT[ROUT] EQ APPBLK
              AND WBQ$NCP[ROUT] EQ ABHNCP[0]
              AND WBQ$ACT[ROUT] EQ ABHACT[0]
              AND WBQ$NFE[ROUT] EQ ABHNFE[0]
              AND (WBQ$TLC[ROUT] + ABHTLC[0]) LQ ACN$DBZ[AE]
            THEN
              BEGIN          # CAN APPEND TO THE BLOCK                 #
              J = WCB$WC[0] -2;        # WORDS TO ADD                  #
              SSTETS( P<WBQ>, I, J ); 
              MOVE( J, MSGBUF[0], WBQ[I] ); 
              WBQ$ESIZE[ROUT] = WBQ$ESIZE[ROUT] + J;
              WBQ$TLC[ROUT] = WBQ$TLC[ROUT] + ABHTLC[0];
              WBQ$ABT[ROUT] = ABHABT[0];
              RETURN; 
  
              END 
            END 
#                MUST ADD BLOCK TO END OF WBQ.                         #
          SSTAQE( P<WBQ>, WCBUF, ABHBUF, MSGBUF );
          ACN$WBCNT[AE] = ACN$WBCNT[AE] + 1 ; 
          END 
        END 
  
#     ALL OTHER STATES JUST DISCARD THE BLOCK.                         #
  
      END # NVFCPUT # 
      TERM
