*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 = 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,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,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 = 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