*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, SIZ); # MAKE ROOM # MOVE (WBC, WBQ[WORD], OTQ[OORD]); SSTRTS (P, 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, 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, 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 = LOC(SPMSG1[0]); # LOCATION OF COMMAND TEXT # SSTAQE (P, 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, 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, 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, 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, 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,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, WCBUF[0], ABH[0], PAGEMSG); ACN$PCHAR[HOPORD$] = HOPPC[0]; END XMITHQ; # XMIT QUEUED HOP DATA (IF ANY) # END END END # NVFCUHS # TERM