*DECK CSCPNT USETEXT TEXTCS USETEXT TEXTSS USETEXT TXTAPSS PROC CSCPNT; # TITLE CSCPNT - PREPARE NOP TEXT. # BEGIN # CSCPNT # # ** CSCPNT - PREPARE NOP TEXT. * * D. G. DEPEW. 82/05/18. * * THIS PROCEDURE PROCESSES TEXT LINES (TERMINAL TEXT) FROM THE * I-LAYER DESTINED FOR A NOP. ITS FUNCTION IS TO FORMAT THE TEXT * INTO A NETWORK BLOCK AND EITHER ISSUE IT, QUEUE IT OR DISCARD IT * AS APPROPRIATE. * * PROC CSCPNT * * ENTRY WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION * TRAFFIC QUEUE (*CNQ*) ENTRY (CONTAINS THE * INPUT ALLOWED FLAG). * 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 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*). * - THE TEXT 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 HAS BEEN DISCARDED. * - AN FC/RST/SM HAS BEEN PLACED IN THE *OTQ* FOLLOWED BY * A NETWORK *MSG* DATA BLOCK CONSISTING OF THE MESSAGES * *OUTPUT DISCARDED* FOLLOWED BY *READY..*. * - A CON/CB SM HAS BEEN FORMATTED AND PLACED IN THE * PROTOCOL EVENT QUEUE (*PEQ*). * * NOTES 1. TO INSURE PROPER CURSOR POSITIONING AT A NOP TERMINAL * UNDER ALL CIRCUMSTANCES, CS USES THE POST PRINT FORMAT * EFFECTOR *.* (PERIOD). HOWEVER, THE I-LAYER GENERATES * TEXT IN ONE FORMAT, IRRESPECTIVE OF FOR WHOM THE TEXT * IS DESTINED (HOP OR A NOP), AND THIS EXCLUDES FORMAT * EFFECTORS. HENCE, THIS ROUTINE MUST RIGHT SHIFT EACH * TEXT MESSAGE ONE CHARACTER AND INSERT THE FORMAT * EFFECTOR IN THE LEADING CHARACTER POSITION. * 2. PROCESSING IS IN ACCORDANCE WITH THE CS/NOP C-LAYER * STATE DIAGRAM. # # **** PROC CSCPNT - XREF LIST. # XREF BEGIN PROC MOVE; # MOVE STORAGE DIRECT ADDRESSING # PROC SSBSBF; # STORE BITFIELD # PROC SSTAQE; # ACCEPT QUEUE ENTRY # PROC SSTETS; # ENLARGE TABLE SPACE (ANYWHERE IN TABLE) # END # **** # DEF ODTLW$ #2#; # *OUTPUT DISCARDED* TEXT LENGTH IN WORDS # DEF RTLW$ #1#; # *READY..* TEXT LENGTH IN WORDS # ITEM I; # LOOP INDUCTION VARIABLE # ITEM NACN; # NOP ACN = ORDINAL OF ACN LIST ENTRY # ITEM TLW; # LENGTH OF TEXT IN CM WORDS # # ITEMS BELOW ARE USED TO SHIFT TEXT RT ONE CHAR FOR FE INSERTION. # ITEM SWP; # STORE WORD POSITION # ITEM SBP; # STORE BIT POSITION (WITHIN *SWP*) # # * MESSAGE ARRAYS WITH LEADING ZEROES AS FORMAT EFFECTORS. # ARRAY DISCARD [00:00] S(ODTLW$); BEGIN ITEM D$WD0 U(00,00,60); ITEM D$WD1 U(01,00,60); ITEM D$TEXT C(00,00,17) = [".OUTPUT DISCARDED"]; ITEM D$LT U(01,42,18) = [0]; END ARRAY READY [00:00] S(RTLW$); BEGIN ITEM R$WD0 U(00,00,60); ITEM R$TEXT C(00,00,08) = [".READY.."]; ITEM R$LT U(00,48,12) = [0]; END CONTROL EJECT; PROC SENDATA; BEGIN # SENDATA # # * SENDATA - SEND NETWORK DATA BLOCK TO A NOP. * * THIS EMBEDDED PROC EITHER OUTPUTS OR ENQUEUES A SINGLE BLOCK OF * NOP TEXT DEPENDING UPON WHETHER THE NOP'S CONNECTION IS CURRENTLY * AT APPLICATION BLOCK LIMIT, AND WHETHER THE CONNECTION HAS BEEN * INITIALIZED. * * PROC SENDATA * * ENTRY TLW = LENGTH OF TEXT IN CM WORDS. * WCBUF[0] = AS ABOVE IN MAIN PROC DESCRIPTION. * ABHBUF[1] = PARTIALLY COMPLETED APPLICATION BLOCK HEADER * FOR THE TEXT. THE APPLICATION BLOCK TYPE HAS * BEEN FILLED IN. * APSM[1] = THE TEXT IN NETWORK BLOCK FORMAT WITH FORMAT * EFFECTORS IN PLACE (2ND HALF OF *MSGBUF*). * THE STATE OF THE NOP'S CONNECTION IS SUCH THAT IT IS OK * TO ISSUE NETWORK DATA BLOCKS. * * EXIT 1. IF THE NOP"S CONNECTION HAS BEEN INITIALIZED (FC/INIT * RECEIVED) AND IT IS NOT AT APPLICATION BLOCK LIMIT, * THE BLOCK HAS BEEN PLACED IN THE OUTGOING TRAFFIC * QUEUE (*OTQ*). * 2. IF THE NOP"S CONNECTION HAS NOT BEEN INITIALIZED OR IT * IS AT APPLICATION BLOCK LIMIT, THE BLOCK HAS BEEN * PLACED IN THE WAITING BLOCK QUEUE (*WBQ*) AS FOLLOWS: * - IF, UPON ENTRY, THERE WAS AN EXISTING *WBQ* ENTRY * FOR THIS NOP AND IF THE TEXT LENGTH OF THAT ENTRY * PLUS THE TEXT LENGTH OF THE NEW BLOCK DID NOT EXCEED * THE RECOMMENDED BLOCK SIZE FOR THE CONNECTION (*DBZ* * IN CON/REQ/SM), THE NEW BLOCK WAS ADDED TO THE END * OF THAT EXISTING *WBQ* ENTRY. * - IF, UPON ENTRY, THERE WAS NO *WBQ* ENTRY FOR THIS * NOP OR IF THE TEXT LENGTH OF THAT ENTRY PLUS THE * TEXT LENGTH OF THE NEW BLOCK EXCEEDED THE * RECOMMENDED BLOCK SIZE, A NEW *WBQ* ENTRY FOR THIS * NOP WAS CREATED. * * NOTE NOP ENTRIES IN THE *WBQ* ARE IN NETWORK DATA BLOCK FORMAT * AND MAY BE MOVED TO THE *OTQ* WITHOUT MODIFICATION. # ITEM AORD; # ORDINAL WHERE BLOCK IS INSERTED IN *WBQ*# ITEM WBC; # WAITING BLOCK COUNT # ITEM WORD; # WAITING BLOCK QUEUE ENTRY ORDINAL # # * FIRST COMPLETE THE APPLICATION BLOCK HEADER FOR THE OUTGOING TEXT, * EXCEPT FOR THE BLOCK NUMBER. ALSO, SET THE QUEUE ENTRY SIZE. # ABHADR[1] = NACN; ABHACT[1] = CT6DISPLAY; ABHTLC[1] = TLW * 10; WCB$WORD[1] = TLW + 2; # * CHECK FOR CONNECTION INITIALIZED AND APPLICATION BLOCK LIMIT AND * TAKE THE APPROPRIATE ACTION (AS HAS BEEN DESCRIBED). # IF ACN$INIT[NACN] AND ACN$BLCNT[NACN] LS ACN$ABL[NACN] THEN # CAN SEND BLOCK IMMEDIATELY # BEGIN ABHABN[1] = ACN$ABN[NACN]; # ABH COMPLETE # ACN$ABN[NACN] = ACN$ABN[NACN] + 1; # NEXT BLOCK NUMBER # ACN$BLCNT[NACN] = ACN$BLCNT[NACN] + 1; # OUTSTANDING BLOCKS # SSTAQE (P, WCBUF[1], ABHBUF[1], MSGBUF[MSBFAPL]); END ELSE # MUST ENQUEUE BLOCK IN *WBQ* # BEGIN # * THE FIRST TASK IS TO LOCATE THE LAST *WBQ* ENTRY FOR THIS NOP * (IF THERE IS ONE). THE SEARCH TECHNIQUE EMPLOYED RESULTS IN * *AORD* POINTING TO THE NEXT *WBQ* ENTRY AFTER THE DESIRED ENTRY. * THIS IS THE CORRECT ORDINAL AT WHICH TO ADD THE NEW BLOCK TO * THE EXISTING *WBQ* ENTRY, IF THAT IS APPROPRIATE. # WBC = 0; WORD = 0; FOR AORD=0 STEP WBQ$ESIZE[AORD] WHILE WBC LS ACN$WBCNT[NACN] DO # FIND LAST ENTRY FOR THIS NOP # IF WBQ$ABHACN[AORD] EQ NACN THEN # THIS ENTRY FOR THIS NOP # BEGIN WBC = WBC + 1; WORD = AORD; # SAVE ORDINAL # END # * IF A *WBQ* ENTRY EXISTS FOR THIS NOP AND IF THE NEW BLOCK CAN * BE APPENDED TO THIS ENTRY WITHOUT EXCEEDING THE RECOMMENDED * BLOCK SIZE, THEN ADD THE NEW BLOCK TO THE EXISTING *WBQ* ENTRY. * OTHERWISE, CREATE A NEW *WBQ* ENTRY. # IF WBC NQ 0 AND (WBQ$TLC[WORD] + ABHTLC[1]) LQ ACN$DBZ[NACN] AND WBQ$ABT[WORD] EQ APPBLK THEN # CAN APPEND TO EXISTING ENTRY # BEGIN SSTETS (P, AORD, TLW); # MAKE ROOM # MOVE (TLW, MSGBUF[MSBFAPL], WBQ[AORD]); # TEXT # WBQ$ESIZE[WORD] = WBQ$ESIZE[WORD] + TLW; # ENTRY SIZE # WBQ$TLC[WORD] = WBQ$TLC[WORD] + ABHTLC[1]; # TEXT LENGTH # IF WCB$IAF[0] THEN # INPUT ALLOWED AFTER THIS TEXT # WBQ$ABT[WORD] = APMSG; # ENSURE SAME FOR QUEUED BLOCK # END ELSE # MUST CREATE NEW *WBQ* ENTRY # BEGIN ABHABN[1] = ACN$ABN[NACN]; # ABH COMPLETE # ACN$ABN[NACN] = ACN$ABN[NACN] + 1; # NEXT BLOCK NUMBER # ACN$WBCNT[NACN] = WBC + 1; # WAITING BLOCKS # SSTAQE (P , WCBUF[1], ABHBUF[1], MSGBUF[MSBFAPL]); END END # ENQUEUING IN *WBQ* # END # SENDATA # CONTROL EJECT; # * MAIN ROUTINE BEGINS HERE. * * WE BEGIN BY INITIALIZING IMPORTANT LOCAL VARIABLES AS WELL AS THE * APPLICATION BLOCK HEADER FOR THE OUTBOUND TEXT. NEXT, THE TEXT * IS RIGHT SHIFTED ONE CHARACTER POSITION AND THE POST PRINT FORMAT * EFFECTOR (*.*) IS INSERTED. AFTER THE SHIFT, WE INSURE THERE ARE * SUFFICIENT ZERO BITS PRESENT TO CONSTITUTE A VALID LINE * TERMINATOR. # NACN = ABHADR[0]; TLW = WCB$WC[0] - 2; ABHWORD[1] = 0; IF TLW NQ 0 THEN # THERE IS TEXT - INSERT FORMAT EFFECTOR # BEGIN MSG$WORD[MSBFAPL] = O"57" *2**54; # POST PRINT FORMAT EFFECT # SWP = MSBFAPL; # SECOND HALF OF *MSGBUF* # SBP = 6; # ONE CHARACTER TO THE RIGHT # FOR I=0 STEP 1 UNTIL TLW-1 DO # RT SHIFT TEXT STRING ONE CHAR # SSBSBF (MSGBUF[0], SWP, SBP, 60, MSG$WORD[I]); IF MSG$ZERO[SWP-1] NQ 0 THEN # TOO FEW ZERO BITS FOR SHIFTED ZERO BYTE # BEGIN MSG$WORD[SWP] = 0; # MAKE 66 BIT LINE TERMINATOR # TLW = TLW + 1; END END # FORMAT EFFECTOR INSERTION # # * NOW TAKE A MAIN BRANCH DEPENDING UPON WHETHER INPUT IS ALLOWED ON * THIS CONNECTION AFTER THIS TEXT HAS BEEN OUTPUT. # IF WCB$IAF[0] THEN # COMMAND COMPLETE, INPUT ALLOWED # BEGIN ABHABT[1] = APMSG; # * IF THIS NOP HAS A COMMAND IN PROGRESS, THE TEXT IS PROCESSED * NORMALLY. IF HE HAD ENTERED A USER BREAK, THE TEXT IS IGNORED * AND AN FC/RST/SM IS SENT FOLLOWED BY THE *OUTPUT DISCARDED* * MESSAGE. THE STATE OF THE ACN IS RESET TO ALLOW SUBSEQUENT * COMMANDS. # IF ACN$NOPST[NACN] EQ S"COMMAND" OR ACN$NOPST[NACN] EQ S"BREAK" THEN # COMMAND OR BREAK IN PROGRESS # BEGIN IF ACN$NOPST[NACN] EQ S"BREAK" THEN # BREAK IN PROGRESS # BEGIN SPMSG0[1] = D$WD0[0]; # SET TEXT = *OUTPUT DISCARDED* # SPMSG1[1] = D$WD1[0]; TLW = ODTLW$; ACN$NOPST[NACN] = S"CLEARI"; END ELSE BEGIN ACN$NOPST[NACN] = S"ACTIVE"; END # * NOW PROCESS 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 RESPONSE TO MANY COMMANDS * CONSISTS SOLELY OF *READY..* (NULL TEXT). # MSG$WORD[MSBFAPL + TLW] = R$WD0[0]; # APPEND *READY..* # TLW = TLW + 1; SENDATA; END ELSE IF ACN$NOPST[NACN] EQ S"BROKEN" THEN BEGIN # CONECTION BROKEN IN PROGRESS # # * WITH THIS TEXT THE I-LAYER HAS INDICATED ITS QUIESCENCE FOR * THIS NOP. HENCE, IT IS NOW APPROPRIATE TO SEND THE CON/CB TO * THE I-LAYER FOR FINAL CLEANUP. THE TEXT GETS DISCARDED. # WCB$WORD[0] = 2; # MIN QUEUE ENTRY SIZE # WCB$SMID[0] = SMID"CONCB"; SSTAQE (P, WCBUF[0], ABHBUF[0], MSGBUF[0]); END END # INPUT ALLOWED = YES # ELSE # INPUT NOT ALLOWED AS RESULT THIS TEXT # BEGIN ABHABT[1] = APPBLK; # * IF THE STATE OF THE NOP"S CONNECTION IS APPROPRIATE, PROCESS * THE TEXT NORMALLY. OTHERWISE, DISCARD IT. # IF ACN$NOPST[NACN] EQ S"ACTIVE" OR ACN$NOPST[NACN] EQ S"COMMAND" OR ABHBRK[0] EQ 1 THEN # OK TO SEND TEXT # BEGIN ABHBRK[0] = 0; SENDATA; END END # INPUT ALLOWED = NO # END # CSCPNT # TERM