*DECK     NVFCPHT 
USETEXT TEXTNVF 
USETEXT TEXTSS
USETEXT TXTAPSS 
PROC NVFCPHT; 
# TITLE NVFCPHT - PREPARE HOP TEXT.   # 
  
      BEGIN  # NVFCPHT #
# 
**    NVFCPHT - PREPARE HOP TEXT. 
* 
*     D. G. DEPEW.           82/02/25.
* 
*     THIS PROCEDURE PROCESSES TEXT LINES (TERMINAL TEXT) FROM THE
*     I-LAYER DESTINED FOR THE HOP.  ITS FUNCTION IS TO FORMAT THE TEXT 
*     INTO A HOP/DIS SM AND EITHER ISSUE IT, QUEUE IT OR DISCARD IT 
*     AS APPROPRIATE. 
* 
*     PROC NVFCPHT
* 
*     ENTRY    WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION
*                         TRAFFIC QUEUE (*CTQ*) ENTRY (CONTAINS THE 
*                         INPUT ALLOWED AND HOP ALERT FLAGS). 
*             ABHBUF[0] = APPLICATION BLOCK (EVENT) HEADER FOR THE TEXT 
*                         (BASED ARRAY *ABH* IN *TXTAPSS* POINTS HERE). 
*             MSGBUF[0] = DISPLAY CODED TEXT LINE (BASED ARRAY *APSM* 
*                         IN *TXTAPSS* POINTS HERE).
* 
*     EXIT    ONE OR MORE OF THE FOLLOWING IN ACCORDANCE WITH THE STATE 
*             OF THE HOP PSEUDO ACN AND WHETHER PAGE WAIT IS IN EFFECT: 
*              - A HOP/DIS SM FOR THE TEXT HAS BEEN PLACED IN THE 
*                OUTGOING TRAFFIC QUEUE (*OTQ*).
*              - THE TEXT HAS BEEN PLACED IN THE WAITING BLOCK QUEUE
*                (*WBQ*) IN HOP/DIS FORMAT PENDING PAGE TURN. 
*              - THE TEXT HAS BEEN DISCARDED. 
*              - A HOP/END SM HAS BEEN FORMATTED AND PLACED IN THE
*                PROTOCOL EVENT QUEUE (*PEQ*).
# 
  
# 
****  PROC NVFCPHT - XREF LIST. 
# 
      XREF
        BEGIN 
        PROC MOVE;           # MOVE STORAGE DIRECT ADDRESSING (MACREL) #
        PROC SSTAQE;         # ACCEPT QUEUE ENTRY                      #
        PROC SSTETS;         # ENLARGE TABLE SPACE ANYWHERE IN TABLE   #
        END 
  
*CALL HMSGNVF 
  
# 
****
# 
  
  
      DEF ODWC$     #4#;     # *OUTPUT DISCARDED* FAKE Q NTRY WD COUNT #
      DEF RWC$      #3#;     # *READY..* FAKE QUEUE ENTRY WORD COUNT   #
      DEF MTLW$     #2#;     # *MORE DATA..* TEXT LENGTH IN WORDS      #
  
  
      ARRAY READY [00:00] S(1); 
        BEGIN 
        ITEM R$WD0      U(00,00,60);
        ITEM R$TEXT     C(00,00,07) = ["READY.."];
        ITEM R$ZERO     U(00,42,18) = [0];
        END 
  
      ARRAY MORDATA [00:00] S(2); 
        BEGIN 
        ITEM M$WD0      U(00,00,60);
        ITEM M$WD1      U(01,00,60);
        ITEM M$TEXT     C(00,00,11) = ["MORE DATA.."];
        ITEM M$ZERO     U(01,06,54) = [0];
        END 
  
      ARRAY DISCARD [00:00] S(2); 
        BEGIN 
        ITEM D$WD0      U(00,00,60);
        ITEM D$WD1      U(01,00,60);
        ITEM D$TEXT     C(00,00,16) = ["OUTPUT DISCARDED"]; 
        ITEM D$ZERO     U(01,36,24) = [0];
        END 
  
  
  
  
CONTROL EJECT;
  
PROC SENDLINE;
  
      BEGIN  # SENDLINE # 
# 
*     SENDLINE - SEND SINGLE LINE OF TEXT TO THE HOP. 
* 
*     THIS EMBEDDED PROC EITHER OUTPUTS OR ENQUEUES A SINGLE LINE OF
*     HOP TEXT DEPENDING UPON WHETHER PAGE WAIT IS IN EFFECT. 
* 
*     PROC SENDLINE 
* 
*     ENTRY   1. THE TEXT IS DEFINED BY *WCBUF[0]*, *ABHBUF[0]* AND 
*                *MSGBUF[0]* AS DESCRIBED ABOVE.
*             2. THE STATE OF THE HOP PSEUDO ACN IS SUCH THAT IT IS OK
*                TO ISSUE HOP/DIS SM'S. 
*             3. THE TEXT LENGTH IS ALWAYS A MULTIPLE OF 10 CHARACTERS. 
* 
*     EXIT    1. IF PAGE WAIT IS NOT IN EFFECT (PAGING TURNED OFF OR
*                LESS THAN 31 LINES ARE CURRENTLY BEING DISPLAYED), A 
*                HOP/DIS SM HAS BEEN PLACED IN THE *OTQ*. 
*             2. IF PAGE WAIT IS IN EFFECT (PAGING TURNED ON AND EITHER 
*                31 OR 32 LINES ARE CURRENTLY BEING DISPLAYED), THE 
*                TEXT HAS BEEN PLACED IN THE *WBQ* AS FOLLOWS:  
*                - IF, UPON ENTRY, THERE WAS AN EXISTING *WBQ* ENTRY
*                  FOR THE HOP AND THAT ENTRY CONTAINED FEWER THAN 31 
*                  LINES, THE TEXT WAS ADDED TO THE END OF THAT ENTRY.
*                - IF, UPON ENTRY, THERE WAS NO *WBQ* ENTRY FOR THE HOP 
*                  OR THAT ENTRY CONTAINED 31 OR 32 LINES, A NEW ENTRY
*                  WAS CREATED. 
* 
*     NOTES   1. HOP ENTRIES IN THE *WBQ* ARE IN HOP/DIS FORMAT AND MAY 
*                BE MOVED TO THE *OTQ* WITHOUT MODIFICATION, EXCEPT FOR 
*                THE ADDITION OF THE EXTRA WORD REQUIRED BY NIP.
*             2. WHEN PAGING IS TURNED ON, THE 32ND LINE OF THE DISPLAY 
*                IS RESERVED FOR THE *MORE DATA..* MESSAGE. 
# 
  
      ITEM I;                # LOOP INDUCTION VARIABLE                 #
      ITEM TLW;              # TEXT LENGTH IN WORDS                    #
      ITEM WBC;              # WAITING BLOCK COUNT                     #
      ITEM TORD;             # ORDINAL WHERE TEXT IS ADDED IN *WBQ*    #
      ITEM WORD;             # WAITING BLOCK QUEUE ENTRY ORDINAL       #
  
      BASED ARRAY TEXTLOC [00:00] S(1); 
        ITEM TL$WORD    U(00,00,60);
  
  
  
# 
*     WE BEGIN BY INITIALIZING SOME ITEMS AND POINTERS PURSUANT TO
*     FORMATTING THE HOP/DIS SM.
# 
      PFCSFC[1] = HOPDIS; 
      P<TEXTLOC> = LOC (SPMSG1[1]);    # WHERE TEXT WILL BE MOVED TO   #
      TLW = WCB$WC[0] - 2;
  
  
# 
*     IF PAGE WAIT IS NOT IN EFFECT, SIMPLY FORMAT THE HOP/DIS SM, SHIP 
*     IT, INCREMENT THE COUNT OF LINES BEING DISPLAYED, AND GET OUT.
*     PROVIDE FOR THE EXTRA WORD IN THE HOP/DIS SM REQUIRED BY NIP. 
# 
      IF NOT ACN$PWAIT[HOPORD$] 
        OR ACN$BLCNT[HOPORD$] LS ACN$PL[HOPORD$]
      THEN                             # WE ARE NOT AT A PAGE BOUNDARY #
        BEGIN 
        ABHTLC[1] = TLW + 2;           # HOP/DIS TLC IN ABH            #
        WCB$WORD[1] = TLW + 4;         # HOP/DIS ENTRY SIZE IN *OTQ*   #
        HOPI[1] = WCB$IAF[0];                    # INPUT ALLOWED FLAG  #
        MOVE (TLW, MSGBUF[0], TEXTLOC[0]);            # TEXT           #
        TL$WORD[TLW] = 0;                             # EXTRA WORD     #
        SSTAQE (P<OTQ>, WCBUF[1], ABH[1], APSM[1]); 
        ACN$BLCNT[HOPORD$] = ACN$BLCNT[HOPORD$] + 1;  # LINE COUNT     #
        RETURN; 
        END 
  
  
# 
*     PAGE WAIT IS IN EFFECT.  IF THERE ARE CURRENTLY 31 LINES BEING
*     DISPLAYED, *MORE DATA..* IS SENT AS THE LAST LINE OF THE PAGE.
# 
      IF ACN$BLCNT[HOPORD$] EQ ACN$PL[HOPORD$]
      THEN                             # MUST SEND *MORE DATA..*       #
        BEGIN 
        ABHTLC[1] = 4;                 # *MORE DATA..* TLC IN ABH      #
        WCB$WORD[1] = 6;               # *MORE DATA..* ESIZE IN *OTQ*  #
        HOPI[1] = FALSE;               # INPUT NOT NECESSARILY ALLOWED #
        SPMSG1[1] = M$WD0[0];                         # TEXT           #
        SPMSG2[1] = M$WD1[0]; 
        SPMSG3[1] = 0;                                # EXTRA WORD     #
        SSTAQE (P<OTQ>, WCBUF[1], ABH[1], APSM[1]); 
        ACN$BLCNT[HOPORD$] = ACN$PL[HOPORD$] + 1;     # LINE COUNT     #
        END 
  
  
# 
*     THE TEXT MUST BE ENQUEUED IN THE *WBQ*.  THE FIRST TASK IS TO 
*     LOCATE THE LAST HOP ENTRY IN THE *WBQ* (IF THERE IS ONE). 
*     IF A HOP *WBQ* ENTRY IS EXTANT, ITS ORDINAL MUST, OF COURSE, BE 
*     LESS THAN THE TOTAL LENGTH OF THE *WBQ*.  THE SEARCH TECHNIQUE IS 
*     SET UP SUCH THAT IF THERE IS NO HOP *WBQ* ENTRY, THE ORDINAL
*     RETURNED EQUALS THE *WBQ* LENGTH. 
# 
      WBC = ACN$WBCNT[HOPORD$];        # NUMBER HOP ENTRIES IN *WBQ*   #
      WORD = WBQLNGTH;
      FOR I=0  STEP WBQ$ESIZE[I]
        WHILE WBC NQ 0
      DO                               # FIND LAST ENTRY               #
        IF WBQ$ABHACN[I] EQ 0 
          AND WBQ$CRSACN[I] EQ 0
        THEN                           # MUST BE HOP/DIS ASYNCH SM     #
          BEGIN 
          WBC = WBC - 1;
          WORD = I;                    # SAVE ORDINAL                  #
          END 
  
  
# 
*     IF THERE IS AN EXISTING *WBQ* ENTRY AND IT CONTAINS EXACTLY 31
*     LINES OF TEXT, THE *MORE DATA..* MESSAGE MUST BE ADDED TO THE END 
*     OF THAT ENTRY.  THIS WILL RESULT IN A NEW HOP *WBQ* ENTRY BEING 
*     CREATED FOR THE NEW LINE OF TEXT FURTHER BELOW. 
# 
      IF WORD LS WBQLNGTH 
        AND WBQ$LICNT[WORD] EQ ACN$PL[HOPORD$]
      THEN                             # 31 LINE ENTRY EXISTS          #
        BEGIN 
        TORD = WORD + WBQ$ESIZE[WORD];      # WHERE MSG WILL BE ADDED  #
        SSTETS (P<WBQ>, TORD, MTLW$);                 # MAKE ROOM      #
        WBQ$WORD[TORD] = M$WD0[0];                    # TEXT           #
        WBQ$WORD[TORD+1] = M$WD1[0];
        WBQ$TLC[WORD] = WBQ$TLC[WORD] + MTLW$;        # TLC IN ABH     #
        WBQ$ESIZE[WORD] = WBQ$ESIZE[WORD] + MTLW$;    # ENTRY SIZE     #
        WBQ$LICNT[WORD] = HOPTPL$;                    # LINE COUNT     #
        END 
  
  
# 
*     FINALLY, THE NEW LINE OF TEXT CAN BE ENQUEUED.  IF A HOP *WBQ*
*     ENTRY IS EXTANT AND IT CONTAINS FEWER THAN 31 LINES OF TEXT, THE
*     NEW LINE CAN (MUST) BE ADDED TO THE EXISTING ENTRY.  OTHERWISE, 
*     CREATE A NEW ENTRY. 
# 
      IF WORD LS WBQLNGTH 
        AND WBQ$LICNT[WORD] LS ACN$PL[HOPORD$]
      THEN                             # CAN ADD TEXT TO EXISTING NTRY #
        BEGIN 
        TORD = WORD + WBQ$ESIZE[WORD];      # WHERE TEXT WILL BE ADDED #
        SSTETS (P<WBQ>, TORD, TLW);                   # MAKE ROOM      #
        MOVE (TLW, MSGBUF[0], WBQ[TORD]);             # TEXT           #
        WBQ$TLC[WORD] = WBQ$TLC[WORD] + TLW;          # TLC IN ABH     #
        WBQ$ESIZE[WORD] = WBQ$ESIZE[WORD] + TLW;      # ENTRY SIZE     #
        WBQ$LICNT[WORD] = WBQ$LICNT[WORD] + 1;        # LINE COUNT     #
        IF WCB$IAF[0] 
        THEN                 # INPUT IS ALLOWED WITH THIS LINE OF TEXT #
          WBQ$HIAF[WORD] = TRUE;  # ENSURE SAME FOR ENTIRE Q'D HOP/DIS #
        END 
  
      ELSE                   # CREATE NEW *WBQ* ENTRY                  #
        BEGIN 
        ABHTLC[1] = TLW + 1;           # HOP/DIS TLC IN ABH            #
        WCB$WORD[1] = TLW + 3;         # HOP/DIS ENTRY SIZE IN *WBQ*   #
        WCB$FLAGS[1] = 1;              # INITIAL LINE COUNT            #
        HOPI[1] = WCB$IAF[0];          # INPUT ALLOWED FLAG            #
        MOVE (TLW, MSGBUF[0], TEXTLOC[0]);            # TEXT           #
        SSTAQE (P<WBQ>, WCBUF[1], ABH[1], APSM[1]); 
        ACN$WBCNT[HOPORD$] = ACN$WBCNT[HOPORD$] + 1;  # WAITING BLOCKS #
        END 
  
      END  # SENDLINE # 
  
  
  
  
  
CONTROL EJECT;
# 
*     MAIN ROUTINE BEGINS HERE. 
* 
*     WE BEGIN BY INITIALIZING SOME FIELDS IN THE OUTGOING ABH AND SM 
*     BODY AREAS.  THEN WE TAKE A MAIN BRANCH DEPENDING ON WHETHER
*     INPUT IS ALLOWED AFTER THIS TEXT IS OUTPUT TO THE HOP.
# 
  
      ABHWORD[1] = 0; 
      ABHABT[1] = APPCMD; 
      ABHACT[1] = CT60TRANS;
      SPMSG0[1] = 0;
  
  
  
      IF WCB$IAF[0] 
      THEN                   # COMMAND COMPLETE, INPUT ALLOWED         #
        BEGIN 
  
  
# 
*       IF THE HOP HAS A COMMAND IN PROGRESS, THE TEXT IS PROCESSED 
*       NORMALLY.  IF HE HAD ENTERED A BREAK, THE TEXT IS DISCARDED 
*       AND THE MESSAGE *OUTPUT DISCARDED* IS SENT.  THE STATE OF THE 
*       HOP PSEUDO ACN IS RESET TO ALLOW SUBSEQUENT COMMANDS. 
# 
        IF ACN$HOPST[HOPORD$] EQ S"COMMAND" 
          OR ACN$HOPST[HOPORD$] EQ S"BREAK" 
        THEN                           # COMMAND OR BREAK IN PROGRESS  #
          BEGIN 
          IF ACN$HOPST[HOPORD$] EQ S"BREAK" 
          THEN                         # BREAK IN PROGRESS             #
            BEGIN                      # SET TEXT = *OUTPUT DISCARDED* #
            SPMSG0[0] = D$WD0[0]; 
            SPMSG1[0] = D$WD1[0]; 
            WCB$WC[0] = ODWC$;
            END 
          ACN$HOPST[HOPORD$] = S"ACTIVE"; 
  
  
# 
*         WE NOW DO THE ACTUAL PROCESSING OF THE TEXT.  THE I-LAYER 
*         NEVER GENERATES *READY..*.  THIS IS GENERATED BY THE C-LAYER
*         (HEREIN) AS A RESULT OF THE INPUT ALLOWED FLAG BEING SET. 
*         THE TEXT MUST BE OUTPUT FIRST WITH INPUT NOT ALLOWED FOLLOWED 
*         BY *READY..* WITH INPUT ALLOWED.  THE RESPONSE TO MANY
*         COMMANDS CONSISTS SOLELY OF *READY..* (NULL TEXT).
# 
          IF WCB$WC[0] GR 2 
          THEN                         # THERE IS TEXT                 #
            BEGIN 
            WCB$IAF[0] = FALSE; 
            SENDLINE;                  # SO SHIP IT                    #
            WCB$IAF[0] = TRUE;
            END 
          SPMSG0[0] = R$WD0[0];        # SET TEXT = *READY..*          #
          WCB$WC[0] = RWC$; 
          SENDLINE;                    # AND SHIP IT                   #
# 
*         SEND THE FIRST PAGE OF THE HELP TEXT TO THE RIGHT K-DISPLAY.
# 
          WCB$SMID[1] = HOPDIS; 
          WCB$WC[1] = RKPAGESZ$ + 1;
          ABHWORD[1] = 0; 
          ABHABT[1] = APPCMD; 
          ABHACT[1] = CT60TRANS;
          ABHTLC[1] = RKPAGESZ$;
          CURPAGE = PAGE1$; 
  
          SSTAQE(P<OTQ>,WCBUF[1],ABH[1],RKPAGE[CURPAGE]); 
          END 
  
        ELSE                 # NEITHER BREAK NOR COMMAND IN PROGRESS   #
          BEGIN 
  
  
# 
*         FOR ALL OTHER STATES OF THE HOP PSUEDO ACN WE DISCARD THE 
*         TEXT AND SEND A HOP/END PROTOCOL EVENT TO THE INNER LAYER.
# 
          WCB$WORD[1] = 2;             # MIN QUEUE ENTRY SIZE          #
          WCB$SMID[1] = HPESTAT"HOPEND";
          SSTAQE (P<PEQ>, WCBUF[1], ABH[1], APSM[1]); 
          END 
  
        END                  # INPUT ALLOWED = YES                     #
  
  
  
      ELSE                   # INPUT NOT ALLOWED AS RESULT THIS TEXT   #
        BEGIN 
  
  
# 
*       IF THE HOP IS IDLE OR HAS A COMMAND IN PROGRESS, PROCESS THE
*       TEXT NORMALLY (TEXT COULD BE THE RESULT OF AN UNSOLICITED EVENT 
*       REPORT OR A COMMAND).  IF THE K-DISPLAY IS NOT CURRENTLY
*       ASSIGNED TO NVF, AND THE HOP HAS NOT ENTERED AN *IG=NVF*
*       COMMAND, AND THIS MESSAGE WARRANTS AN ALERT, SEND A HOP/ALT SM
*       TO NAM.  FOR ALL OTHER CONDITIONS, SIMPLY DISCARD THE TEXT. 
# 
        IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
          OR ACN$HOPST[HOPORD$] EQ S"COMMAND" 
        THEN                           # ALL IS WELL, FORWARD THE TEXT #
          SENDLINE; 
  
        ELSE IF ACN$HOPST[HOPORD$] EQ S"INACT"
          OR ACN$HOPST[HOPORD$] EQ S"ENDED" 
          OR ACN$HOPST[HOPORD$] EQ S"STARTEND"
        THEN                           # K-DIS NOT NOW ASSIGNED TO NVF #
          IF WCB$HAF[0] 
            AND NOT ACN$IGNOR[HOPORD$]
          THEN                         # MUST SEND HOP/ALT SM TO NIP   #
            BEGIN 
            WCB$WORD[1] = 3;
            ABHTLC[1] = LHOPALT;
            PFCSFC[1] = HOPALT; 
            SSTAQE (P<OTQ>, WCBUF[1], ABH[1],APSM[1]);
            END 
  
        END                  # INPUT ALLOWED = NO                      #
  
      END  # NVFCPHT #
  
      TERM
