*DECK     NVFVRVF 
USETEXT  TEXTNVF
USETEXT  TEXTSS 
USETEXT  TXVCBNV
  
PROC NVFVRVF(SWTESS); 
# TITLE NVFVRVF - READ VCB (VALIDATION CONTROL BLOCK) FILE.            #
  
      BEGIN  # NVFVRVF #
# 
**    NVFVRVF - READ VCB FILE.
* 
*     A. LIM.    81/11/02.
* 
*     THIS PROCEDURE READS THE VCB FILE UPON REQUEST. 
* 
*     PROC NVFVRVF(SWTESS)
* 
*     ENTRY   THE VCB-READ-REQUEST-QUEUE (VRQ) CONTAINS ONE OR MORE 
*               VCB-READ-REQUEST(S).  DURING INITIALIZATION, WHEN 
*               PROC IS FIRST CALLED, THE VRQ IS EMPTY. 
*             THE ACTIVE-VCB-READ-REQUEST-TABLE (AVRT) AND THE
*               READLIST ARE EMPTY. 
* 
*     EXIT    ENTRIES ARE MADE IN AVRT, AND AVRT IS SORTED INTO 
*               ASCENDING ORDER BY THE ENTIRE ENTRY.
*             NON-DUPLICATED PRUS ARE COPIED FROM AVRT TO READLIST. 
*             ITEM *AVCOUNT* REFLECTS THE ACTUAL NUMBER OF ENTRIES
*               IN AVRT, WHILE ITEM *RLCOUNT* REFLECTS THE NUMBER 
*               OF PRUS BEING READ BY THE CURRENT READLS FUNCTION.
*             FORMAL ARRAY SWTESS IS SET SO THAT PROC *NVFVDCD* IS
*               IS CALLED WHEN THE VCB FET COMPLETE BIT IS SET OR 
*               THE *IN* POINTER CHANGES. 
*             FOR THE INITIALIZATION CALL, FORMAL ARRAY SWTESS IS 
*               SET SUCH THAT THIS PROC WILL AGAIN BE CALLED WHEN 
*               AN ENTRY IS MADE IN THE VRQ.
# 
  
#     SWTESS - STATUS WORKLIST MONITOR ARRAY.                          #
*CALL SWTESS
  
  
  
  
  
# 
****  PROC NVFVRVF - XREF LIST BEGIN. 
# 
      XREF
        BEGIN 
        PROC ABORT;          # MACREL - ABORT TASK                     #
        PROC MESSAGE;        # MACREL - SEND MESSAGE                   #
        PROC MOVE;           # MACREL - MOVE CM WORDS                  #
        PROC NVFVDCD;        # NVF - DISPATCH CIO DATA                 #
        PROC READLS;         # MACREL - ISSUE CIO READLS FUNCTION      #
        PROC SSTATS;         # SS - ALLOCATE TABLE SPACE               #
        PROC SSTRQE;         # SS - REMOVE QUEUE ENTRY                 #
        PROC XSST;           # MACREL - SHELL SORT TABLE INTO ASCENDING#
        END 
# 
****
# 
  
  
  
      ITEM CURREQ     I;     # CURRENT VCB REQUEST                     #
      ITEM I,J,L      I;     # INDUCTION VARIABLES                     #
      ITEM K          I;     # INDEX IN VWT                            #
  
  
# 
*     DAYFILE MESSAGE ARRAY.
# 
  
      ARRAY VBMSG[00:00] S(3);
        BEGIN 
        ITEM VM$MSG     C(00,00,23) = ["DUPLICATED VCB REQUEST."];
        ITEM VM$ZERO    U(02,18,42) = [0];
        END 
  
CONTROL EJECT;
  
      P<TVRQ> = LOC(ABHBUF); # PLACE TEMPLATE ON WORD ONE OF VRQ ENTRY #
      AVCOUNT = 0;           # INIT COUNT OF ENTRIES IN AVRT           #
      RLCOUNT = 0;           # INIT COUNT OF PRUS TO BE READ           #
  
# 
*     BUILD AVRT FROM VRQ 
# 
  
      FOR I = 0 STEP 1 WHILE VRQLNGTH NQ 0
        AND AVCOUNT LS RLMAX$ 
      DO                     # LOOP UNTIL VRQ EMPTY OR AVRT FULL       #
        BEGIN                # FOR I LOOP                              #
        SSTRQE(P<VRQ>,WCBUF,ABHBUF,MSGBUF); # REMOVE 1 ENTRY FROM VRQ  #
        IF TVR$TYPE[0] EQ RDWRITE$
        THEN
          BEGIN              # READ FOR A WRITE                        #
          K = VWTLNGTH/VBESIZ$;   # CALCU INDEX TO INSERT ENTRY TO VWT #
          SSTATS(P<VWT>, VBESIZ$);         # ALLOC SPACE AT END OF VWT #
          MOVE(VBESIZ$, MSGBUF, VWT[K]);   # MOVE ENTRY TO VWT         #
          END 
        AVR$ORD[AVCOUNT] = TVR$ORD[0];     # MAKE ENTRY IN AVRT        #
        AVR$TYPE[AVCOUNT] = TVR$TYPE[0];
        AVR$QADDR[AVCOUNT] = TVR$QADDR[0];
        AVCOUNT = AVCOUNT + 1;
        END                  # FOR I LOOP                              #
  
# 
*     SORT AVRT.
# 
  
      IF AVCOUNT NQ 0 
      THEN
        BEGIN                # AVRT NOT EMPTY-  AT LEAST ONE ENTRY     #
        XSST(AVRT, AVCOUNT); # SHELL SORT IT                           #
  
        $BEGIN
# 
*     CHECK AVRT FOR TWO ADJACENT DUPLICATED REQUESTS.  ISSUE DAYFILE 
*     MESSAGE AND ABORT NVF.
# 
  
        CURREQ = AVR$REQ[0]; # SET CURRENT REQUEST TO 1ST REQ IN AVRT  #
        FOR L = 1 STEP 1 UNTIL AVCOUNT - 1
        DO
          BEGIN              # FOR L LOOP                              #
          IF AVR$REQ[L] EQ CURREQ 
          THEN
            BEGIN 
            MESSAGE(VBMSG[0],DFILE$);  # SEND MESSAGE TO SYSTEM DAYFILE#
            ABORT;                     #   AND ABORT NVF               #
            END 
          ELSE
            BEGIN 
            CURREQ = AVR$REQ[L];
            END 
          END                # FOR L LOOP                              #
  
        $END
  
# 
*     AVRT LOOKS GOOD.  PREPARE READLS FUNCTION BY PUTTING
*     NON-DUPLICATED RELATIVE PRU-ADDRESS FROM AVRT TO READLIST, AND
*     THEN ISSUE THE READLS.
# 
  
        RL$RPA[RLCOUNT] = AVR$RPA[0] + 1; # MAKE 1ST ENTRY IN READLIST #
        FOR J = 1 STEP 1 UNTIL AVCOUNT - 1
        DO
          BEGIN                        # FOR J LOOP                    #
          IF AVR$RPA[J] + 1 NQ RL$RPA[RLCOUNT]
          THEN
            BEGIN                      # NON-DUPLICATED PRU            #
            RLCOUNT = RLCOUNT + 1;
            RL$RPA[RLCOUNT] = AVR$RPA[J] + 1;  # MAKE ENTRY IN READLIST#
            END 
          END                          # FOR J LOOP                    #
        RLCOUNT = RLCOUNT + 1; # ACTUAL NO OF ENTRIES IN READLIST      #
        RL$RPA[RLCOUNT] = 0;           # MAKE THE TERMINATOR WORD      #
        VB$LA[0] = LOC(READLIST);      # STORE READLIST ADDR IN FET    #
        READLS(VCBFET);                # ISSUE READLS FUNCTION         #
  
#     SET UP FORMAL RETURN PARAMETER ARRAY SWTESS.                     #
  
        STE$ADDR1[0] = LOC(VCBFET);      # WATCH COMP BIT IN FET+0     #
        STE$ADDR2[0] = LOC(VB$IN[0]);    # WATCH FET *IN* POINTER      #
        STE$RTN[0] = LOC(NVFVDCD);       # RTN TO DISPATCH CIO DATA    #
        STE$INIT1[0] = VB$WORD[0];       # SET UP INIT VALUE OF FET+0  #
        STE$CBIT1[0] = FALSE;            # CALL NVFVDCD WHEN C-BIT SET# 
        STE$INIT2[0] = VB$OUT[0];        #   OR WHEN *IN* NQ *OUT*     #
        END 
      ELSE
        BEGIN                            # THIS IS INITIALIZATION CALL# 
        INVVRVF = 0;                     # INSURE INTERRUPT CEL IS CLR# 
        STE$ADDR1[0] = LOC(INVVRVF);     # WATCH INTERRUPT CELL        #
        STE$ADDR2[0] = 0;                #   AND WATCH ONE CELL ONLY   #
        STE$RTN[0] = LOC(NVFVRVF);       # RECALL THIS PROC            #
        STE$INIT1[0] = 0;                #   WHEN VRQ NON-EMPTY        #
        STE$INIT2[0] = 0; 
        END 
  
      END  # NVFVRVF #
  
      TERM
