*DECK     NVFCUHS 
USETEXT TEXTNVF 
USETEXT TEXTSS
USETEXT TXTAPSS 
USETEXT TXTANVF 
USETEXT TXINNVF 
PROC NVFCUHS; 
# TITLE NVFCUHS - UPDATE HOP STATUS.    # 
  
      BEGIN  # NVFCUHS #
# 
**    NVFCUHS - UPDATE HOP STATUS.
* 
*     D. G. DEPEW.           82/03/04.
* 
*     THIS PROCEDURE PERFORMS ALL THE CONNECTION(C) LAYER PROCESSING
*     REQUIRED FOR THE INBOUND, SPECIAL HOP SUPERVISORY MESSAGES. 
* 
*     PROC NVFCUHS
* 
*     ENTRY    WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION
*                         TRAFFIC QUEUE (*CTQ*) ENTRY.
*             ABHBUF[0] = APPLICATION BLOCK HEADER FOR THE SM (BASED
*                         ARRAY *ABH* IN *TXTAPSS* POINTS HERE).
*             MSGBUF[0] = BODY OF THE SM (BASED ARRAY *APSM* IN 
*                         *TXTAPSS* POINTS HERE).  THE POSSIBLE PFC/SFC 
*                         VALUES ARE:  HOP/START, HOP/CMD, HOP/BRK, 
*                         HOP/PAGE, HOP/END, HOP/IG.
* 
*     EXIT    ANY OF THE FOLLOWING IN VARIOUS COMBINATIONS ACCORDING TO 
*             THE SM RECEIVED AND THE STATE OF THE HOP PSEUDO ACN:  
*             - THE HOP PSEUDO ACN STATE HAS BEEN UPDATED.
*             - AN ENTRY HAS BEEN PLACED IN THE PROTOCOL EVENT QUEUE
*               (*PEQ*).
*             - ONE OR MORE HOP ENTRIES IN THE WAITING BLOCK QUEUE
*               (*WBQ*) HAVE BEEN TRANSFERRED TO THE OUTGOING TRAFFIC 
*               QUEUE (*OTQ*).
*             - ALL OUTPUT ENQUEUED FOR THE HOP (IN THE *WBQ*) HAS BEEN 
*               DISCARDED.
*             - AN ENTRY HAS BEEN PLACED IN THE OPERATOR TYPEIN QUEUE 
*               (*OPTQ*). 
*             - HOP PAGING STATUS HAS BEEN UPDATED. 
*             - HOP IGNORE STATUS HAS BEEN UPDATED. 
* 
*     NOTE    THE PROCESSING IS DEFINED BY THE NVF/HOP C-LAYER STATE
*             DIAGRAM.
# 
  
# 
****  PROC NVFCUHS - XREF LIST. 
# 
      XREF
        BEGIN 
        PROC MOVE;           # MOVE STORAGE DIRECT ADDRESSING (MACREL) #
        PROC SSSAWR;         # ACCEPT WORKLIST REQUEST                 #
        PROC SSTAQE;         # ACCEPT QUEUE ENTRY                      #
        PROC SSTATS;         # ALLOCATE TABLE SPACE AT END OF TABLE    #
        PROC SSTRTS;         # REMOVE TABLE SPACE ANYWHERE IN TABLE    #
        END 
  
*CALL HMSGNVF 
  
# 
****
# 
  
  
      ITEM STATE  S:HCNST;   # TEMP CELL FOR STATE OF HOP PSEUDO ACN   #
  
# 
*     FOLLOWING ITEMS ARE USED ONLY BY EMBEDDED PROCS (SOME ARE 
*     SHARED).
# 
  
      ITEM I;                # LOOP INDUCTION VARIABLE                 #
      ITEM COUNT;            # NUMBER OF HOP *WBQ* ENTRIES TO BE MOVED #
      ITEM LICNT;            # COUNT OF DISPLAY LINES IN *WBQ* ENTRY   #
      ITEM OORD;             # OUTGOING TRAFFIC QUEUE ORDINAL          #
      ITEM SIZ;              # *OTQ* ENTRY SIZE                        #
      ITEM WBC;              # *WBQ* ENTRY COUNT OR ENTRY SIZE         #
      ITEM WORD;             # WAITING BLOCK QUEUE ORDINAL             #
  
  
      BASED ARRAY TEXTLOC [00:00] S(1); ; 
  
  
      ARRAY OUTDISC [00:00] S(5); 
        BEGIN 
        ITEM OD$PSFC    U(00,00,16) = [HOPDIS]; 
        ITEM OD$ZERO1   U(00,16,43) = [0];
        ITEM OD$IAF     B(00,59,01) = [TRUE];              # INPUT OK  #
        ITEM OD$TEXT1   C(01,00,16) = ["OUTPUT DISCARDED"]; 
        ITEM OD$ZERO2   U(02,36,24) = [0];
        ITEM OD$TEXT2   C(03,00,07) = ["READY.."];
        ITEM OD$ZERO3   U(03,42,18) = [0];
        ITEM OD$ZERO4   U(04,00,60) = [0];
        END 
  
      ARRAY PAGEMSG [00:00] S(4); 
        BEGIN 
        ITEM PG$PSFC    U(00,00,16) = [HOPDIS]; 
        ITEM PG$ZERO1   U(00,16,44) = [0];                 # NO INPUT  #
        ITEM PG$TEXT    C(01,00,15) = ["PAGE ACCEPTED.."];
        ITEM PG$ZERO2   U(02,30,30) = [0];
        ITEM PG$ZERO3   U(03,00,60) = [0];
        END 
  
      DEF ODTLW$   #5#;      # *OUTPUT DISCARDED* TEXT LENGTH IN WORDS #
      DEF ODQES$   #7#;      # *OUTPUT DISCARDED* QUEUE ENTRY SIZE     #
      DEF PGTLW$   #4#;      # *PAGE ACCEPTED..* TEXT LENGTH IN WORDS  #
      DEF PGQES$   #6#;      # *PAGE ACCEPTED..* QUEUE ENTRY SIZE      #
  
  
  
  
CONTROL EJECT;
  
PROC XMITHQ;
  
      BEGIN  # XMITHQ # 
# 
*     XMITHQ - TRANSMIT HOP QUEUE.
* 
*     THIS EMBEDDED PROC MOVES HOP ENTRIES IN THE WAITING BLOCK QUEUE 
*     (*WBQ*) TO THE OUTGOING TRAFFIC QUEUE (*OTQ*).  THE NUMBER OF 
*     ENTRIES MOVED DEPENDS UPON PAGING STATUS AND WHETHER THERE
*     ACTUALLY IS DATA QUEUED (IN THE *WBQ*) FOR THE HOP. 
* 
*     PROC XMITHQ 
* 
*     ENTRY   1. THE *WBQ* CONTAINS ZERO OR MORE HOP ENTRIES. 
*             2. THE ACN LIST ENTRY FOR THE HOP CONTAINS ALL REQUIRED 
*                INFORMATION - NAMELY, THE COUNT OF HOP ENTRIES IN THE
*                *WBQ* AND THE PAGING STATUS FLAG.
* 
*     EXIT    1. ZERO OR MORE HOP ENTRIES HAVE BEEN REMOVED FROM THE
*                *WBQ* AND PLACED IN THE *OTQ*. 
*             2. THE COUNT OF LINES CURRENTLY BEING DISPLAYED HAS BEEN
*                SET TO THE LINE COUNT OF THE LAST *WBQ* ENTRY MOVED
*                (ZERO IF NO ENTRIES MOVED).
*             3. THE HOP WAITING BLOCK COUNT HAS BEEN UPDATED 
*                APPROPRIATELY. 
* 
*     NOTE    HOP ENTRIES IN THE *WBQ* ARE ALREADY IN CORRECT HOP/DIS 
*             FORMAT EXCEPT FOR THE EXTRA WORD AT THE END, WHICH IS 
*             REQUIRED BY NIP AND MUST BE ADDED.
# 
  
  
  
# 
*     THE FIRST TASK IS TO DETERMINE HOW MANY BLOCKS (HOP *WBQ* ENTRIES)
*     TO MOVE.  IF PAGING IS ON, MOVE ONE BLOCK (AT MOST A SCREENFULL). 
*     IF PAGING IS OFF, MOVE ALL ENQUEUED BLOCKS.  OF COURSE, IF THERE
*     ARE CURRENTLY NO HOP ENTRIES IN THE *WBQ*, NOTHING HAPPENS. 
# 
      WBC = ACN$WBCNT[HOPORD$]; 
      IF ACN$PWAIT[HOPORD$] 
        AND WBC NQ 0
      THEN
        COUNT = 1;
      ELSE
        COUNT = WBC;                        # CAN BE ZERO              #
      ACN$WBCNT[HOPORD$] = WBC - COUNT;     # UPDATED                  #
  
  
# 
*     NOW MOVE THE BLOCKS.  SET THE COUNT OF TEXT LINES CURRENTLY BEING 
*     DISPLAYED TO THE LINE COUNT OF THE LAST BLOCK MOVED (IF ONE). 
*     PROVIDE FOR THE EXTRA WORD REQUIRED IN THE HOP/DIS SM.  IN ORDER
*     TO MOVE A BLOCK, WE MUST FIRST FIND IT. 
# 
      LICNT = 0;                       # INITIALIZE                    #
      WORD = 0; 
  
      FOR I=1  STEP 1  UNTIL COUNT
      DO                               # MOVE *COUNT* BLOCKS, ZERO OK  #
        BEGIN 
        FOR WORD = WORD  STEP WBQ$ESIZE[WORD] 
          WHILE WBQ$ABHACN[WORD] NQ 0 
             OR WBQ$CRSACN[WORD] NQ 0 
        DO                             # FIND HOP ENTRY (HOP/DIS SM)   #
          BEGIN  END
  
        OORD = OTQLNGTH;               # WHERE *OTQ* ENTRY WILL BE     #
        WBC = WBQ$ESIZE[WORD];         # SIZE OF ENTRY TO BE MOVED     #
        SIZ = WBC + 1;                 # SIZE OF HOP/DIS NTRY IN *OTQ* #
        LICNT = WBQ$LICNT[WORD];       # TEXT LINES IN *WBQ* ENTRY     #
        WBQ$ESIZE[WORD] = SIZ;              # UPDATE PRIOR TO MOVE     #
        WBQ$TLC[WORD] = WBQ$TLC[WORD] + 1;
        SSTATS (P<OTQ>, SIZ);               # MAKE ROOM                #
        MOVE (WBC, WBQ[WORD], OTQ[OORD]); 
        SSTRTS (P<WBQ>, WORD, WBC);         # DELETE WAITING BLOCK     #
        OTQ$WORD[OTQLNGTH-1] = 0;           # EXTRA WORD               #
  
        IF OORD EQ 0
        THEN                           # FIRST ENTRY IN *OTQ*          #
          SSSAWR (WWDF"SACNI"); 
        END 
  
      ACN$BLCNT[HOPORD$] = LICNT;      # NUMBER LINES ON SCREEN        #
  
      END  # XMITHQ # 
  
  
  
  
PROC PURGEHQ; 
  
      BEGIN  # PURGEHQ #
# 
*     PURGEHQ - PURGE HOP QUEUE.
* 
*     THIS EMBEDDED PROC REMOVES ALL HOP ENTRIES FROM THE WAITING BLOCK 
*     QUEUE (*WBQ*).
* 
*     PROC PURGEHQ
* 
*     ENTRY   1. THE *WBQ* CONTAINS ZERO OR MORE HOP ENTRIES. 
*             2. THE ACN LIST ENTRY FOR THE HOP CONTAINS ALL REQUIRED 
*                INFORMATION - NAMELY, THE COUNT OF HOP *WBQ* ENTRIES.
* 
*     EXIT    1. ALL HOP ENTRIES IN THE *WBQ* HAVE BEEN DELETED.
*             2. THE COUNTS OF *WBQ* ENTRIES AND LINES CURRENTLY BEING
*                DISPLAYED (BOTH IN THE ACN LIST ENTRY FOR THE HOP) 
*                HAVE BEEN CLEARED. 
# 
  
  
  
# 
*     INITIALIZE AND UPDATE THE ACN LIST ENTRY FOR THE HOP. 
# 
      COUNT = ACN$WBCNT[HOPORD$];      # NUMBER OF BLOCKS TO DELETE    #
      ACN$WBCNT[HOPORD$] = 0; 
      ACN$BLCNT[HOPORD$] = 0;          # START NEW PAGE                #
  
  
# 
*     NOW DELETE THE ENTRIES.  IN ORDER TO DELETE AN ENTRY, WE MUST 
*     FIRST FIND IT.
# 
      WORD = 0; 
      FOR I=1  STEP 1  UNTIL COUNT
      DO                               # DEL *COUNT* ENTRIES, ZERO OK  #
        BEGIN 
        FOR WORD = WORD  STEP WBQ$ESIZE[WORD] 
          WHILE WBQ$ABHACN[WORD] NQ 0 
             OR WBQ$CRSACN[WORD] NQ 0 
        DO                             # FIND HOP ENTRY (HOP/DIS SM)   #
          BEGIN  END
  
        WBC = WBQ$ESIZE[WORD];         # SIZE OF ENTRY TO BE DELETED   #
        SSTRTS (P<WBQ>, WORD, WBC);    # DELETE WAITING BLOCK          #
        END 
  
      END  # PURGEHQ #
  
  
  
  
  
CONTROL EJECT;
# 
*     MAIN ROUTINE BEGINS HERE. 
* 
*     WE EXECUTE WHAT AMOUNTS TO A CASE CONSTRUCT TO PROCESS THE SIX
*     TYPES OF INCOMING HOP SM-S. 
# 
  
  
  
      IF WCB$SMID[0] EQ CTQSTAT"SHSTART"
      THEN                             # K-DISPLAY ASSIGNED TO NVF     #
        BEGIN 
  
  
# 
*       INITIALIZE THE HOP ACN LIST ENTRY.  SEND THE HOP/START TO THE 
*       I-LAYER (AS PROTOCOL EVENT), IF APPROPRIATE.  UPDATE THE STATE. 
# 
        STATE = ACN$HOPST[HOPORD$]; 
        ACN$WORD0[HOPORD$] = 0; 
        ACN$WORD1[HOPORD$] = 0; 
        ACN$ACN[HOPORD$] = 1;          # INSURE NON-MATCH W/REAL ACN'S #
        IF STATE EQ S"INACT"
        THEN                           # SEND HOP/START TO I-LAYER     #
          BEGIN 
          WCB$SMID[0] = HPESTAT"HOPSRT";    # HOP/START ID FOR I-LAYER #
          SSTAQE (P<PEQ>, WCBUF[0], ABH[0], APSM[0]);  # TO I-LAYER    #
          END 
  
        IF STATE EQ S"ENDED"
        THEN
          ACN$HOPST[HOPORD$] = S"RESTART";
        ELSE
          BEGIN 
          ACN$HOPST[HOPORD$] = S"CREATE"; 
          ACN$PL[HOPORD$] = HOPLPL[0] - 1;
          END 
        END 
  
  
  
      ELSE IF WCB$SMID[0] EQ CTQSTAT"SHCMD" 
      THEN                             # HOP ENTERED A COMMAND         #
        BEGIN 
  
  
# 
*       FORWARD THE COMMAND TO THE I-LAYER (AS OPERATOR TYPEIN) FOR 
*       SYNTAX CRACKING AND COMMAND PROCESSING.  ECHO THE COMMAND BACK
*       TO THE K-DISPLAY VIA HOP/DIS SM.  UPDATE THE STATE AND SEND HIM 
*       THE NEXT PAGE OF QUEUED OUTPUT (IF ANY).  NOTE THAT *OPTQ*
*       ENTRIES DO NOT CONTAIN A PFC/SFC WORD.
# 
        WCB$WORD[1] = WCB$WC[0] - 1;   # DEDUCT FOR PFC/SFC WORD       #
        ABHWORD[1] = 0; 
        ABHTLC[1] = HOPDTL[0];         # ACTUAL CHAR COUNT             #
        P<TEXTLOC> = LOC(SPMSG1[0]);   # LOCATION OF COMMAND TEXT      #
        SSTAQE (P<OPTQ>, WCBUF[1], ABH[1], TEXTLOC[0]);  # TO I-LAYER  #
  
        WCB$WORD[0] = WCB$WC[0] + 1;   # EXTRA WORD FOR HOP/DIS SM     #
        ABHTLC[0] = ABHTLC[0] + 1;
        SPMSG0[0] = 0;                 # NO INPUT ALLOWED              #
        PFCSFC[0] = HOPDIS; 
        SSTAQE (P<OTQ>, WCBUF[0], ABH[0], APSM[0]);   # ECHO COMMAND   #
        OTQ$WORD[OTQLNGTH-1] = 0;                     # EXTRA WORD     #
  
        ACN$HOPST[HOPORD$] = S"COMMAND";
        XMITHQ;                        # XMIT QUEUED HOP DATA (IF ANY) #
  
        END 
  
  
  
      ELSE IF WCB$SMID[0] EQ CTQSTAT"SHBRK" 
      THEN                             # HOP ENTERED A BREAK           #
        BEGIN 
  
  
# 
*       RELEASE ALL QUEUED (IN THE *WBQ*) OUTPUT.  IF THE HOP PSEUDO
*       ACN IS IN THE *ACTIVE* STATE, SEND THE *OUTPUT DISCARDED* 
*       MESSAGE FOLLOWED BY *READY..*.  IF A COMMAND IS IN PROGRESS,
*       FORWARD THE BREAK TO THE I-LAYER AS AN OPERATOR TYPEIN (*OPTQ*).
*       UPDATE THE STATE. 
# 
        PURGEHQ;                       # PURGE QUEUED HOP DATA(IF ANY) #
  
        IF ACN$HOPST[HOPORD$] EQ S"CREATE"
        THEN                           # BREAK HISTORY BUFFER OUTPUT   #
          ACN$HOPST[HOPORD$] = S"STARTBRK"; 
  
        ELSE IF ACN$HOPST[HOPORD$] EQ S"ACTIVE" 
        THEN                           # BREAK UNSOLICITED STATUS RPTS #
          BEGIN 
          WCB$WORD[0] = ODQES$; 
          ABHTLC[0] = ODTLW$; 
          SSTAQE (P<OTQ>, WCBUF[0], ABH[0], OUTDISC); 
          ACN$BLCNT[HOPORD$] = 2;      # START NEW PAGE W/ 2 LINES     #
          END 
  
        ELSE IF ACN$HOPST[HOPORD$] EQ S"COMMAND"
        THEN                           # BREAK COMMAND IN PROGRESS     #
          BEGIN 
          WCB$WORD[1] = 2;             # MIN QUEUE ENTRY LENGTH        #
          ABHWORD[1] = 0;              # TLC = 0                       #
          ABHBRK[1] = 1;
          SSTAQE (P<OPTQ>, WCBUF[1], ABH[1], TEXTLOC[0]);  #TO I-LAYER #
          ACN$HOPST[HOPORD$] = S"BREAK";
          END 
  
        ELSE                           # MUST BE BRK HIST AFT RESTART  #
          ACN$HOPST[HOPORD$] = S"RESBREAK"; 
  
        END 
  
  
  
      ELSE IF WCB$SMID[0] EQ CTQSTAT"SHIG"
      THEN                             # HOP WANTS TO IGNORE NVF REPTS #
  
  
# 
*       ALL THAT IS REQUIRED IS TO SET THE APPROPRIATE FLAG IN THE HOP
*       ENTRY OF THE ACN LIST.
# 
        ACN$IGNOR[HOPORD$] = TRUE;
  
  
  
      ELSE IF WCB$SMID[0] EQ CTQSTAT"SHEND" 
      THEN                             # K-DIS NO LONGER ASS'D TO NVF  #
        BEGIN 
  
  
# 
*       RELEASE ALL QUEUED (IN THE *WBQ*) OUTPUT.  IF THE HOP PSEUDO
*       ACN IS IN THE *ACTIVE* STATE, SEND A HOP/END PROTOCOL EVENT TO
*       THE I-LAYER.  IF A COMMAND IS IN PROGRESS, SEND A HOP/END-
*       WARNING PROTOCOL EVENT TO THE I-LAYER (HOP/END WILL BE SENT 
*       WHEN COMMAND IS CLEANED UP).  UPDATE THE HOP PSEUDO ACN STATE.
# 
        PURGEHQ;                       # PURGE QUEUED HOP DATA(IF ANY) #
  
        IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
          OR ACN$HOPST[HOPORD$] EQ S"COMMAND" 
        THEN                           # MUST SEND P.E. TO I-LAYER     #
          BEGIN 
          WCB$WORD[0] = 2;             # MIN QUEUE ENTRY SIZE          #
          ABHTLC[0] = 0;
          IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
          THEN
            WCB$SMID[0] = HPESTAT"HOPEND";
          ELSE
            WCB$SMID[0] = HPESTAT"HOPENDW"; 
          SSTAQE(P<PEQ>, WCBUF[0], ABH[0], APSM[0]);  # TO I-LAYER     #
          END 
  
        IF ACN$HOPST[HOPORD$] EQ S"CREATE"
          OR ACN$HOPST[HOPORD$] EQ S"STARTBRK"
        THEN
          ACN$HOPST[HOPORD$] = S"STARTEND"; 
        ELSE
          ACN$HOPST[HOPORD$] = S"ENDED";
  
        END 
  
  
  
      ELSE                             # MUST BE A PAGING COMMAND SM   #
        BEGIN 
# 
*       IF THE COMMAND IS A PAGING COMMAND FOR THE RIGHT K-DISPLAY, SEND
*       A NEW PAGE OF HELP TEXT TO THE RIGHT K-DISPLAY. 
# 
        IF (HOPPC[0] EQ "(" ) OR
           (HOPPC[0] EQ ")" ) 
        THEN
          BEGIN 
          WCB$SMID[1] = HOPDIS; 
          WCB$WC[1] = RKPAGESZ$ + 1;
          ABHWORD[1] = 0; 
          ABHABT[1] = APPCMD; 
          ABHACT[1] = CT60TRANS;
          ABHTLC[1] = RKPAGESZ$;
# 
*         IF THE COMMAND IS A PAGE FORWARD COMMAND, SEND THE NEXT PAGE
*         OF HELP TEXT. 
# 
          IF HOPPC[0] EQ "("
          THEN
            BEGIN 
            IF CURPAGE EQ LASTPAGE$ 
            THEN
              BEGIN 
              CURPAGE = PAGE1$; 
              END 
            ELSE
              BEGIN 
              CURPAGE = CURPAGE + 1;
              END 
            END 
# 
*         IF THE COMMAND IS A PAGE BACKWARD COMMAND, SEND THE PREVIOUS
*         PAGE OF HELP TEXT.
# 
          ELSE                         # HOPPC = ")"                   #
            BEGIN 
            IF CURPAGE EQ PAGE1$
            THEN
              BEGIN 
              CURPAGE = LASTPAGE$;
              END 
            ELSE
              BEGIN 
              CURPAGE = CURPAGE - 1;
              END 
            END 
  
          SSTAQE(P<OTQ>,WCBUF[1],ABH[1],RKPAGE[CURPAGE]); 
          END 
# 
*       IF THE COMMAND INDICATES A CHANGE IN PAGING STATUS IS DESIRED,
*       SEND THE *PAGE ACCEPTED..* MESSAGE AND REMEMBER THE NEW PAGING
*       STATUS.  THEN SEND THE HOP AS MUCH QUEUED (IN THE *WBQ*) DATA 
*       (IF ANY) AS IS CONSISTENT WITH THE UPDATED PAGING STATUS. 
# 
        ELSE
          BEGIN 
          IF HOPPC[0] NQ ACN$PCHAR[HOPORD$] 
          THEN                         # PAGING STATUS CHANGE          #
            BEGIN 
            WCB$WORD[0] = PGQES$; 
            ABHTLC[0] = PGTLW$; 
            SSTAQE (P<OTQ>, WCBUF[0], ABH[0], PAGEMSG); 
            ACN$PCHAR[HOPORD$] = HOPPC[0];
            END 
  
          XMITHQ;                      # XMIT QUEUED HOP DATA (IF ANY) #
          END 
        END 
  
  
      END  # NVFCUHS #
  
      TERM
