*DECK CSTRND
USETEXT TEXTCS
USETEXT TXTCTCS
PROC CSTRND (SWTESS);
# TITLE CSTRND - RECEIVE NCF DATA. #
BEGIN # CSTRND #
#
** CSTRND - RECEIVE NCF DATA.
*
* D. G. DEPEW. 81/09/24.
*
* THIS PROCEDURE DEBLOCKS LINE RECORDS FROM THE NCF CIO BUFFER AND
* COMBINES THEM WITH THE CORRESPONDING NCF READ REQUESTS QUEUE
* ENTRIES TO CREATE NCF DATA QUEUE ENTRIES.
*
* PROC CSTRND (SWTESS)
*
* ENTRY THE NCF DATA QUEUE MAY CONTAIN EITHER OF THE FOLLOWING:
* - ZERO (I.E., IT MAY BE EMPTY) OR MORE COMPLETE ENTRIES.
* - ZERO OR MORE COMPLETE ENTRIES FOLLOWED BY A PARTIALLY
* COMPLETED ENTRY. A PARTIALLY COMPLETED ENTRY IS ONE
* WHICH AS YET CONTAINS ONLY A PROTION OR ITS LINE
* RECORD.
* THE NCF READ REQUESTS QUEUE CONTAINS ENTRIES CORRESPONDING
* TO THOSE LINE RECORDS FOR WHICH DEBLOCKING HAS NOT YET
* BEGUN.
* ITEM *RLCOUNT* (IN TXTCTCS) CONTAINS THE NUMBER OF LINE
* RECORDS BEING READ BY THE CURRENT READLS FUNCTION (AND
* THENCE THE NUMBER OF RESULTING NCF DATA QUEUE ENTRIES).
* ITEM *RLIORD* (IN TXTCTCS) POINTS TO THE READ LIST INDEX
* ENTRY CORRESPONDING TO ONE OF THE FOLLOWING:
* - THE LINE RECORD CURRENTLY BEING DEBLOCKED IF THE LAST
* ENTRY IN THE NCF DATA QUEUE IS INCOMPLETE.
* - THE LINE RECORD FOR WHICH DEBLOCKING WILL BEGIN IF THE
* LAST ENTRY IN THE NCF DATA QUEUE IS COMPLETE OR THE
* QUEUE IS EMPTY.
* DATA IS AVAILABLE IN THE NCF CIO BUFFER.
*
* EXIT LINE RECORD DATA AND/OR NEW ENTRIES HAVE BEEN ADDED TO THE
* NCF DATA QUEUE AS DESCRIBED BELOW UNDER *METHOD*.
* NCF READ REQUESTS QUEUE ENTRIES, CORRESPONDING TO THOSE
* NEW ENTRIES (EITHER COMPLETE OR INCOMPLETE) THAT HAVE
* BEEN ADDED TO THE NCF DATA QUEUE THIS TIME (IF ANY),
* HAVE BEEN DELETED.
* FORMAL RETURN PARAMETER ARRAY SWTESS IS SET AS FOLLOWS:
* - IF ALL LINE RECORDS SPECIFIED IN THE CURRENT READLS
* OPERATION HAVE BEEN COMPLETELY PROCESSED, SWTESS IS
* SET SO THAT PROC CSTSNR IS CALLED WHEN AN ENTRY IS
* MADE IN THE CONFIGURE TERMINAL REQUEST QUEUE.
* - IF ALL LINE RECORDS SPECIFIED IN THE CURRENT READLS
* OPERATION HAVE NOT BEEN PROCESSED AND THE NCF CIO
* BUFFER IS EMPTY, SWTESS IS SET SUCH THAT THIS ROUTINE
* WILL AGAIN BE CALLED WHEN THE FET COMPLETE BIT IS SET
* OR THE IN POINTER DOES NOT EQUAL THE OUT POINTER.
* IF WE ARE WAITING FOR DATA TO BE PLACED IN THE BUFFER AND
* THE I/O HAS STOPPED, THE READLS FUNCTION IS REISSUED.
*
* METHOD THIS ROUTINE CONSISTS PRIMARILY OF A LARGE LOOP. EACH
* TIME THROUGH THE LOOP ONE OF THE FOLLOWING OCCURS:
* - A NEW, SKELETON ENTRY IS ADDED TO THE NCF DATA QUEUE.
* THIS ENTRY CONSISTS OF THE CNF/TE/R SM (FROM THE NCF
* READ REQUESTS QUEUE) PLUS THE FIRST TWO WORDS OF THE
* LINE RECORD. (WORD TWO OF A LINE RECORD CONTAINS ITS
* LENGTH, WHICH IS USED TO DETERMINE THE SIZE OF THE
* NCF DATA QUEUE ENTRY.) THE NCF READ REQUESTS QUEUE
* ENTRY IS DELETED.
* - LINE RECORD DATA IS ADDED TO AN INCOMPLETE NCF DATA
* QUEUE ENTRY, BUT BECAUSE OF INSUFFICIENT DATA
* AVAILABILITY, THE ENTRY CANNOT BE COMPLETED.
* - LINE RECORD DATA IS ADDED TO AN INCOMPLETE NCF DATA
* QUEUE ENTRY, COMPLETING IT EXACTLY.
* THE LOOP TERMINATES WHEN ALL LINE RECORDS SPECIFIED IN THE
* READLS FUNCTION HAVE BEEN PROCESSED OR WHEN THE CIO BUFFER
* IS EMPTY. THIS ROUTINE CAN STOP AN INDEFINITE NUMBER OF
* TIMES TO WAIT FOR I/O.
#
*CALL SWTESS
#
**** PROC CSTRND - XREF LIST BEGIN.
#
XREF
BEGIN
PROC CSTSNR; #START NCF READ REQUESTS #
PROC MOVE; #MOVE STORAGE DIRECT ADDRESSING (MACREL) #
PROC READLS; #ISSUE CIO READLS FUNCTION (MACREL) #
PROC READW; #READ WORDS FROM CIO BUFFER (MACREL) #
PROC SSFCBS; #DETERMINE AVAIL DATA AND SPACE IN BUFFER #
PROC SSSAWR; #ACCEPT WORKLIST REQUEST #
PROC SSTATS; #ALLOCATE STORAGE AT END OF TABLE #
PROC SSTRTS; #REMOVE STORAGE ANYWHERE IN TABLE #
END
#
****
#
ITEM I; #LOOP INDUCTION VARIABLE #
ITEM QORD; #CALCULATED ORD LAST ENTRY OF NCF DATA Q #
ITEM RORD; #NDQ ORD TO RD INTO OR CORRES NRQ NTRY ORD#
ITEM NEED; #AMT OF DATA NEEDED TO COMPLETE NDQ ENTRY #
ITEM AVAIL; #AMT OF DATA AVAILABLE IN NCF CIO BUFFER #
ITEM WC; #SIZ NEW NDQ NTRY OR AMT FILLED IN SO FAR #
ITEM SIZ; #SIZ OF CORRESPONDING NCF READ Q ENTRY #
ITEM TEMP; #FOR UNNEEDED GARBAGE #
ARRAY LINEHDR [00:00] S(LRHDRL$); #LINE RECORD HEADER WSA #
ITEM LH$LRLEN U(01,48,12); #LINE REC LENGTH EXCLUDING ID WD #
IF NDQL NQ 0
THEN # AT LEAST ONE ENTRY IN NDQ (MAY BE INC) #
FOR QORD=0 STEP NDQ$ESIZE[QORD]
WHILE (QORD + NDQ$ESIZE[QORD]) LS NDQL
DO # FIND FIRST WD OF LAST NCF DATA Q ENTRY #
BEGIN END
FOR I=0 WHILE NF$IN[0] NQ NF$OUT[0]
AND RLIORD LS RLCOUNT
DO # LOOP UNTIL BUF EMPTY OR ALL LINRECS READ#
IF NDQL NQ 0
AND NOT NDQ$CFLAG[QORD]
THEN # NDQ NOT EMPTY AND LAST ENTRY INCOMPLETE #
BEGIN # CONTINUE ENTRY IN PROGRESS #
WC = NDQ$TCSIZE[QORD] + NDQ$LRSIZE[QORD]; # TOT DATA SO FAR #
NEED = NDQ$ESIZE[QORD] - WC;
SSFCBS (NCFFET, TEMP, AVAIL); # FIND OUT WHAT'S AVAILABLE #
IF AVAIL GQ NEED
THEN # THE LAST ENTRY CAN BE COMPLETED NOW #
BEGIN
AVAIL = NEED; # WILL ADD EXACT AMOUNT TO COMPLETE ENTRY #
NDQ$CFLAG[QORD] = TRUE; # SET ENTRY COMPLETE #
SSSAWR(CSWDF"CTDNQ") ; # CONFIGUE OR RE-CONFIGUE TERM#
RLIORD = RLIORD + 1; # NEXT READLIST INDEX ENTRY #
END
RORD = QORD + WC; # ORD TO WHICH DATA WILL BE READ #
READW (NCFFET, NDQ[RORD], AVAIL, TEMP); # XFER DATA TO NTRY #
NDQ$LRSIZE[QORD] = NDQ$LRSIZE[QORD] + AVAIL; # AMT RD SO FAR#
END
ELSE # NDQ EMPTY OR LAST ENTRY COMPLETE #
BEGIN # CREATE A NEW SKELETON NCF DATA Q ENTRY #
QORD = NDQL; # WHERE NEW NDQ ENTRY WILL BE #
FOR RORD=0 STEP NRQ$ESIZE[RORD]
WHILE NRQ$LRIORD[RORD] NQ RLI$LRIORD [RLIORD]
DO # FND NRQ NTRY CORRESPONDING TO NXT LINREC#
BEGIN END
READW (NCFFET, LINEHDR, LRHDRL$, TEMP); # GET NXT LINREC HDR#
SIZ = NRQ$ESIZE[RORD];
WC = SIZ + LH$LRLEN[0] + 1; # TOTAL SIZE NEW NCF DATA Q NTRY#
SSTATS (P<NDQ>, WC); # ADD NEW ENTRY SPACE TO NCF DATA Q #
MOVE (SIZ, NRQ[RORD], NDQ[QORD]); # START NEW NDQ ENTRY #
SSTRTS (P<NRQ>, RORD, SIZ); # DELETE NCF READ QUEUE ENTRY #
NDQ$CFLAG[QORD] = FALSE;
NDQ$LRSIZE[QORD] = LRHDRL$; # AMT OF LINREC IN NTRY SO FAR #
NDQ$TCSIZE[QORD] = SIZ; # CNF/TE/R SIZ SAME AS NRQ NTRY SIZ #
NDQ$ESIZE[QORD] = WC; # INITIALIZE WITH FINAL ENTRY SIZE #
RORD = QORD + SIZ; # BEGINNING ORDINAL OF LINE RECORD #
MOVE (LRHDRL$, LINEHDR, NDQ[RORD]); # SKELETON NDQ NTRY DONE#
END
# SET UP FORMAL RETURN PARAMETER ARRAY SWTESS. #
IF RLIORD EQ RLCOUNT
AND NF$CBIT[0]
THEN # ALL LINE RECORDS HAVE BEEN DEBLOCKED #
BEGIN
# WE WANT PROC CSTSNR TO BE CALLED WHENEVER AN ENTRY IS PLACED IN #
# THE CONFIGURE TERMINAL REQUEST QUEUE (CTQ) AND IF THERE IS #
# ALREADY AN ENTRY IN THE CTQ, WE WANT CSTSNR CALLED IMMEDIATELY. #
# AT THIS POINT, HOWEVER, THE INTERRUPT CELL FOR PROC CSTSNR (ITEM #
# *ICSTSNR* - WATCHED BY THE STATUS WORKLIST ENTRY PROCESSOR AND #
# INCREMENTED WHENEVER AN ENTRY IS PLACED IN THE CTQ) HAS SOME NON-#
# ZERO VALUE THAT MAY OR MAY NOT ACCURATELY REFLECT THE PRESENSE #
# OF AN ENTRY IN THE CTQ (*ICSTSNR* MAY BE NON-ZERO SOLELY AS A #
# RESULT OF PREVIOUS ENTRIES THAT HAVE ALL BEEN PROCESSED). IF WE #
# SIMPLY CLEAR *ICSTSNR*, RECOLLECTION OF ANY ENTRIES THAT MIGHT #
# ALREADY BE IN THE CTQ WILL BE LOST AND THEY WONT GET PROCESSED #
# UNTIL ANOTHER ENTRY IS PLACED IN THE CTQ (COULD BE A LONG TIME). #
# WHAT WE WANT TO DO IS SET *ICSTSNR* TO ZERO IF THE CTQ IS EMPTY, #
# OR SET IT NON-ZERO (ACTUAL VALUE OF NO CONSEQUENCE) IF THERE IS #
# AT LEAST ONE ENTRY IN THE CTQ. HENCE, THE FOLLOWING CODE LINE. #
ICSTSNR = CTQL; # REFLECTS PRESENSE OF CNF/TE/R Q ENTRIES #
STE$ADDR1[0] = LOC (ICSTSNR); # WATCH INTERRUPT CELL #
STE$ADDR2[0] = 0; # WATCH ONE CELL ONLY #
STE$RTN[0] = LOC (CSTSNR); # PROCESSOR OF CNF/TE/R QUEUE #
STE$INIT1[0] = 0; # CALL WHEN NONZERO ENTRIES IN CNF/TE/R Q #
STE$INIT2[0] = 0;
END
ELSE # WE MUST WAIT FOR I/O #
BEGIN
STE$ADDR1[0] = LOC (NCFFET); # WATCH FIRST WORD OF NCF FET #
STE$ADDR2[0] = LOC (NF$IN[0]); # WATCH FET IN POINTER #
STE$RTN[0] = LOC (CSTRND); # RECALL THIS ROUTINE #
STE$INIT1[0] = NF$WORD[0]; # SET UP INIT VALUE OF FET 1ST WD #
STE$CBIT1[0] = FALSE; # RECALL WHEN FET COMP BIT IS SET #
STE$INIT2[0] = NF$OUT[0]; # RECALL WHEN *IN* NQ *OUT* #
IF NF$CBIT[0]
THEN # I/O HAS STOPPED #
READLS (NCFFET); # RESTART CURRENT READLS OPERATION #
END
END # CSTRND #
TERM