*DECK NVFVDCD
USETEXT TEXTNVF
USETEXT TXVCBNV
PROC NVFVDCD(SWTESS);
# TITLE NVFVDCD - DISPATCH CIO DATA. #
BEGIN # NVFVDCD #
#
** NVFVDCD - DISPATCH VCB DATA FROM CIO BUFFER.
*
* A. LIM. 81/11/20.
*
* THIS PROCEDURE DISPATCHES VCB DATA FROM CIO BUFFER TO THE
* APPROPRIATE QUEUE, OR CALL THE APPROPRIATE ROUTINE TO
* PROCESS IT.
*
* PROC NVFVDCD(SWTESS)
*
* ENTRY *AVRT* (ACTIVE-VCB-REQUEST-TABLE) CONTAINS THE ACTIVE
* VCB READ REQUESTS READ BY THE CURRENT READLS FUNCTION.
* *AVCOUNT* CONTAINS THE NUMBER OF ENTRIES IN AVRT.
* *READLIST* IS THE ACTUAL READ LIST USED BY THE CIO
* READLS FUNCTION. *RLCOUNT* CONTAINS THE NUMBER OF
* ENTRIES IN READLIST.
* *AVRT*, *AVCOUNT*, *READLIST*, *RLCOUNT* ARE IN
* COMMON BLOCK *VCBIO* IN *TXVCBNV*.
* *VWT* (IN TEXTNVF) CONTAINS THE VCB WRITE REQUESTS.
* DATA IS AVAILABLE IN THE VCB CIO BUFFER.
*
* EXIT VCB DATA FROM THE VCB CIO BUFFER ARE DISPATCHED TO
* THE APPROPRIATE QUEUE, OR THE APPROPRIATE ROUTINE
* IS CALLED TO PROCESS THE DATA.
* FORMAL RETURN PARAMETER ARRAY SWTESS IS SET AS FOLLOWS:
* - IF ALL VCB RECORDS SPECIFIED IN THE CURRENT READLS
* OPERATION HAVE BEEN PROCESSED, AND
* *VWBT* (VCB-WRITE-BLOCK-TABLE) NOT EMPTY, SWTESS IS
* SET SO THAT PROC NVFVWVF IS CALLED TO WRITE THE
* RECORD BACK TO DISK. ELSE IF *VWBT* EMPTY, SET
* SWTESS TO GO BACK TO THE INITIAL STATE, I.E.
* CALL PROC NVFVRVF TO READ THE VCB FILE AGAIN.
* - IF CIO READLS NOT COMPLETE, AND CIO IDLE, REISSUE
* READLS FUNCTION.
* EITHER CIO READLS NOT COMPLETE AND CIO IDLE, OR
* JUST CIO READLS NOT COMPLETE, SET SWTESS SUCH
* THAT THIS ROUTINE WILL AGAIN BE CALLED WHEN THE
* FET COMPLET BIT IS SET OR THE IN POINTER
* DOES NOT EQUAL TO THE OUT POINTER.
*
* METHOD THIS ROUTINE CONSISTS PRIMARILY OF A LARGE LOOP. EACH
* TIME THROUGH THE LOOP, A REQUEST IN THE AVRT WILL BE
* PROCESSED.
* THE LOOP TERMINATES WHEN ALL ENTRIES IN THE AVRT HAVE
* BEEN PROCESSED OR WHEN THE CIO BUFFER IS EMPTY.
#
*CALL SWTESS
#
**** PROC NVFVDCD - XREF LIST BEGIN.
#
XREF
BEGIN
PROC ABORT; # MACREL- ABORT TASK #
PROC MESSAGE; # MACREL- DAYFILE MESSAGE #
PROC MOVE; # MACREL - MOVE CM WORDS #
PROC NVFUMVD; # NVF - MARK VCB DATA VALID/INVALID #
PROC NVFVFSD; # NVF - FILTER SS DATA BLOCK #
PROC NVFVRVF; # NVF - READ VCB FILE #
PROC NVFVWVF; # NVF - WRITE VCB FILE #
PROC READLS; # MACREL - CIO READLS FUNCTION CALL #
PROC READW; # MACREL - CIO READW FUNCTION CALL #
PROC SSTAQE; # SS - ACCEPT QUEUE ENTRY #
PROC SSTATS; # SS - ALLOCATE STORAGE AT END OF TABLE #
PROC SSTRTS; # SS - REMOVE TABLE SPACE #
END
#
****
#
# ITEM #
ITEM AINDX I = 0; # AVRT INDEX, PRESET TO 0 #
ITEM CURBLK I = -1; # CURRENT DATA BLOCK #
ITEM I,II,J,L I; # INDUCTION VARIABLES #
ITEM K I; # INDEX #
ITEM MATCHE B; # FLAG FOR MATCH ON ENTRY #
ITEM P I; # ACTUAL PARAMETER FOR SSTRTS #
ITEM TEMP I; # FOR UNNEEDED GARBAGE #
ITEM VWTFLAG B; # FLAG FOR TERMINATING VWT SEARCH LOOP #
ITEM WRSAMBLK B; # FLAG FOR WRITTING ON SAME BLOCK #
#
** DUMMY - DUMMY BASED ARRAY.
*
* DUMMY IS A BASED ARRAY USED TO STORE AN ADDRESS INTO THE
* PARAMETER LIST.
#
BASED ARRAY DUMMY[00:00] S(1);;
#
** WCWD - WORD COUNT ARRAY.
*
* WCWD ARRAY IS THE FIRST PORTION OF A MANAGED QUEUE ENTRY. IT
* CONTAINS THE WORD COUNT OF QUEUE ENTRY SIZE + 2 WORDS.
* (ITSELF AND HEADER WORD).
#
ARRAY WCWD[00:00] S(1);
BEGIN
ITEM WC$WORD U(00,00,60); # FULL WORD REFERENCE #
ITEM WC$WC U(00,48,12); # ENTRY SIZE #
END
#
** HDR - HEADER ARRAY.
*
* HDR ARRAY IS THE SECOND PORTION OF A MANAGED QUEUE ENTRY. IT
* CONTAINS THE HEADER INFORMATION OF THE ENTRY.
#
ARRAY HDR[00:00] S(1);
BEGIN
ITEM HDR$WORD U(00,00,60); # FULL WORD REFERENCE #
END
#
* TEMPB- THIS IS A TEMPBORARY BUFFER TO GET THE CONTENT OF
* AN ADDRESS.
#
BASED ARRAY TEMPB[00:00] S(1);
BEGIN
ITEM TEM$LA U(00,42,18); # LIST ADDRESS FOR CIO READLS #
END
#
* RDLSMSG- DAYFILE MESSAGE.
#
ARRAY RDLSMSG[00:00] S(4);
BEGIN
ITEM RDL$MSG C(00,00,31) =
[" NVFVDCD- ERRONEOUS READLS CALL"];
ITEM RDL$ZERO U(03,06,54) = [0];
END
CONTROL EJECT;
P<TEMPB> = VB$LA[0];
FOR I = AINDX STEP 1 WHILE ((VB$IN[0] NQ VB$OUT[0]) OR
(AVR$RPA[I] EQ CURBLK))
AND (I LS AVCOUNT)
DO # LOOP AS LONG AS BUFFER HAS DATA OR READ #
BEGIN # ON CURRENT BLOCK AND AVRT NOT EXHAUSTED #
IF AVR$RPA[I] NQ CURBLK
THEN
BEGIN # TIME TO TRFR A NEW BLK OF DATA INTO WSA #
READW(VCBFET,VCBWSA,VBRECD$,TEMP);
CURBLK = VBW$RPA[1]; # SAVE THE CURRENT BLK NUMBER #
END
IF AVR$RPA[I] EQ VBW$RPA[1]
THEN
BEGIN # AVRT RPA MATCH VCBWSA RPA #
IF AVR$TYPE[I] NQ MARKED$
THEN
BEGIN # A REQUEST THAT HAS NOT BEEN PROCESSED #
IF AVR$TYPE[I] EQ RDWRITE$
THEN
BEGIN # READ FOR A WRITE #
WRSAMBLK = TRUE; # MIGHT BE OTHER WRITE ON SAME BLK #
FOR II = I STEP 1 WHILE II LS AVCOUNT
AND WRSAMBLK
DO # LOOP UNTIL AVRT EXHSTD OR NOT SAME BLK#
BEGIN
IF AVR$TYPE[II] EQ RDWRITE$
THEN
BEGIN
IF AVR$RPA[II] EQ VBW$RPA[1]
THEN
BEGIN # WRITE ON SAME BLK MERGE DATA FR VWT TO WSA#
IF VWTLNGTH NQ 0
THEN
BEGIN
VWTFLAG = FALSE;
FOR J = 0 STEP 1 WHILE J LS VWTLNGTH/VBESIZ$
AND NOT VWTFLAG
DO
BEGIN
IF AVR$ORD[II] EQ VWT$ORD[J]
THEN
BEGIN # MATCH ON VCB ORD #
MOVE(VBESIZ$,VWT[J],VCBWSA[AVR$ENTRY[II]]);
P = J * VBESIZ$;
SSTRTS(P<VWT>,P,VBESIZ$); # REMOVE SPS FR VWT#
NVFUMVD(AVR$ORD[II],VALID$); # MRK DATA VALID#
AVR$TYPE[II] = MARKED$; # MARK NTRY AS PROCD#
VWTFLAG = TRUE; # TERMINATE LOOP #
END
END
$BEGIN
IF NOT VWTFLAG THEN ABORT;
$END
END
ELSE
BEGIN
$BEGIN # VWT EMPTY #
ABORT;
$END
END
END
ELSE
BEGIN
WRSAMBLK = FALSE;
END
END
END
SSTATS(P<VWBT>,VBRECD$); # ALLOC SPS AT END OF VWBT#
K = VWBLNGTH/VBRECD$ - 1; # CALCULATE INDEX #
MOVE(VBRECD$,VCBWSA,VWBT[K]); #MOV BLK FR WSA TO VWBT#
END # READ FOR A WRITE #
ELSE IF AVR$TYPE[I] EQ RDSS$
THEN
BEGIN # READ FOR SERIAL SEARCH #
NVFVFSD; # CALL PROC TO PROCESS THE BLK #
END
ELSE IF AVR$TYPE[I] EQ RDREAD$
THEN
BEGIN # READ FOR READING OF AN ENTRY #
MATCHE = FALSE; # INIT FLAG #
FOR L = 1 STEP 1 WHILE L LQ VBMXENTRY$
AND NOT MATCHE
DO
BEGIN # SEARCH WSA FOR THE ENTRY #
IF AVR$ENTRY[I] EQ VBW$ENTRY[L]
THEN
BEGIN # FOUND #
WC$WC[0] = VBESIZ$ + 2;
HDR$WORD[0] = AVR$WORD[I]; # PUT AVRT ENTRY IN HDR #
P<DUMMY> = AVR$QADDR[I]; # GET DESTINATION Q ADDR #
SSTAQE(DUMMY,WCWD,HDR,VCBWSA[L]); # TRFR ENTRY TO Q #
NVFUMVD(AVR$ORD[I],INVALID$); # MARK DATA INVALID #
MATCHE = TRUE;
END
END
$BEGIN # CANNOT FIND THE ENTRY, IMPOSSIBLE... #
IF NOT MATCHE THEN ABORT;
$END
END # READ FOR READING OF AN ENTRY #
END # AVRT READ TYPE NOT MARKED #
END # AVRT RPA MATCH VCBWSA RPA #
END # FOR I LOOP #
AINDX = I; # SET AVRT INDEX #
#
* SET UP FORMAL RETURN PARAMETER ARRAY SWTESS.
#
IF AINDX EQ AVCOUNT
THEN
BEGIN # AVRT EXHAUSTED, IMPLIES CIO READLS COMPL#
AINDX = 0; # RESET AVRT INDEX #
CURBLK = -1; # RESET CURRENT BLOCK #
IF VWBLNGTH NQ 0
THEN
BEGIN # VWBT NOT EMPTY #
STE$ADDR1[0] = LOC(VCBFET); # WATCH FET COMPLETE BIT #
STE$ADDR2[0] = 0; # AND WATCH ONE LOCATION ONLY#
STE$RTN[0] = LOC(NVFVWVF); # WAKE UP PROC *NVFVWVF* #
STE$INIT1[0] = VB$WORD[0];
STE$CBIT1[0] = FALSE;
STE$INIT2[0] = 0;
END
ELSE
#GO BACK TO INITIAL STATE: READ VCB FILE WHEN VRQ NON-EMPTY #
BEGIN
STE$ADDR1[0] = LOC(INVVRVF); # WATCH INTERRUPT CELL FOR VRQ #
STE$ADDR2[0] = 0;
STE$RTN[0] = LOC(NVFVRVF);
STE$INIT1[0] = 0;
STE$INIT2[0] = 0;
IF NOT VB$CBIT[0]
THEN
BEGIN
STE$ADDR1[0] = LOC(VCBFET);
STE$ADDR2[0] = 0;
STE$RTN[0] = LOC(NVFVRVF);
STE$INIT1[0] = VB$WORD[0];
STE$CBIT1[0] = FALSE;
STE$INIT2[0] = 0;
END
END
END
ELSE
BEGIN # CIO READLS INCOMPLETE #
IF VB$CBIT[0]
THEN
BEGIN # CIO IDLE #
IF TEM$LA[0] EQ 0
THEN
BEGIN # READLS LA IS SET TO TERMINATOR WORD #
MESSAGE(RDLSMSG[0], 0);
ABORT;
END
ELSE
BEGIN
READLS(VCBFET); # REISSUE READLS REQUEST #
END
END
STE$ADDR1[0] = LOC(VCBFET); # WATCH COMPLETE BIT IN FET+0 #
STE$ADDR2[0] = LOC(VB$IN[0]); # AND WATCH FET *IN* POINTER #
STE$RTN[0] = LOC(NVFVDCD); # WAKE UP *NVFVDCD* WHEN ONE CHG#
STE$INIT1[0] = VB$WORD[0]; # SET UP INIT VALUE OF FET + 0 #
STE$CBIT1[0] = FALSE; # WAKE SELF UP AGAIN WHEN CBIT ST#
STE$INIT2[0] = VB$OUT[0];
END
END # NVFVDCD #
TERM