*DECK     NVFVPSR 
USETEXT    TEXTNVF
USETEXT    TEXTSS 
USETEXT    TXCMDNV
USETEXT    TXVCBNV
  
PROC NVFVPSR(SWTESS); 
#     TITLE NVFVPSR - PROCESS SERIAL-SEARCH REQUEST.                   #
  
      BEGIN    # NVFVPSR #
# 
**    NVFVPSR - PROCESS SERIAL-SEARCH REQUEST.
* 
*     A. LIM.    82/04/14.
*     C. BRION   83/04/29.
* 
*     THIS PROCEDURE-S MAIN FUNCTION IS TO PROCESS SERIAL-SEARCH
*     REQUEST(S). (PRESENT DESIGN IS THERE IS ONLY ONE REQUEST
*     OUTSTANDING AT ONE TIME)  IT RECORDS THE REQUEST WITH ADDITIONAL
*     INFORMATIONS INTO COMMON TABLE *AVST*.  THEN IT CALLS INTERNAL
*     PROC TO SET UP TO READ *MAXSSRD$* OR LESS NUMBER OF VCB BLOCKS, 
*     AND GOES TO IDLE TO BE WAKEN UP BY AN INTERRUPT SET BY
*     *NVFVFSD* ROUTINE TO READ MORE BLOCKS, OR INITIALLY WAKEN 
*     UP BY DATA BEING PUT INTO *VSQ*.
* 
*     PROC NVFVPSR(SWTESS)
* 
*     ENTRY    THE VCB SERIAL-SEARCH REQUEST(S) IN VCB-SERIAL-SEARCH
*              -REQUEST-QUEUE *VSQ*.
* 
*     EXIT     ACTIVE-VCB-SERIAL-SEARCH-REQUEST TABLE *AVST* IS BUILT.
*              *MAXSSRD$* OR LESS NUMBER OF VCB READ REQUESTS MADE
*              IN VCB-READ-REQUEST QUEUE *VRQ*. 
*              FORMAL RETURN PARAMETER ARRAY IS SET TO WAKE SELF UP 
*              TO MAKE REQUESTS IN *VRQ* TO READ MORE VCB BLOCKS, OR
*              TO WAKE SELF UP WHEN MORE DATA IS PUT INTO *VSQ*.
* 
*     METHOD   *SSTRQE* IS CALLED TO REMOVE AN ENTRY FROM *VSQ*, THEN 
*              BUILD AN ENTRY IN THE *AVST* FROM THIS ENTRY.
*              *NVFVSRR* IS CALLED TO SET UP TO READ *MAXSSRD$* OR
*              LESS VCB BLOCKS. 
*              FORMAL RETURN PARAMETER ARRAY IS SET SUCH THAT TO
*              WAKE SELF UP AFER *NVFVFSD* HAS DONE FILTERING 
*              ALL THE REQUESTED BLOCKS AND MADE ENTRIES IN 
*              VCB-SERIAL-SEARCH-DATA-QUEUE *VCBSSQ*. 
*              WHEN DONE PROCESSING ALL ENTRIES IN *VSQ*, 
*              FORMAL RETURN PARAMETER ARRAY IS SET SUCH THAT 
*              TO WAKE SELF UP WHEN A NEW REQUEST IS MADE INTO
*              *VSQ*. 
# 
  
  
# 
****  PROC NVFVPSR XREF LIST
# 
      XREF
        BEGIN 
        PROC NVFUROS;        # RETURN VCB ORDINAL STATUS               #
        PROC SSTAQE;         # SS- ACCEPT A QUEUE ENTRY                #
        PROC SSTRQE;         # SS- REMOVE A QUEUE ENTRY                #
        END 
# 
****
# 
  
*CALL SWTESS
  
  
  
      ITEM EFLAG      B;     # ERROR FLAG FROM SET UP READ REQUEST     #
      ITEM I          I;     # LOOP INDUCTION VARIABLE                 #
      ITEM N          I;     # INDEX TO 2ND HALF OF MSGBUF             #
  
  
CONTROL EJECT;
  
      N = (NMSGBUF$ + 1)/2;         # INDEX TO 2ND HALF OF MSGBUF      #
      P<TVSQ> = LOC(MSGBUF[0]);     # POINT TVSQ TO 1ST HALF OF MSGBUF #
      P<TVCBSSQ> = LOC(MSGBUF[N]);  # AND TVCBSSQ TO 2NF HALF OF MSGBUF#
      WCB$WORD[1] = 0;                 # CLEAR WC WORD 1               #
      ABH$WORD[1] = 0;                 # CLEAR ABH WORD 1              #
      FOR I = N STEP 1 UNTIL NMSGBUF$ 
      DO
        BEGIN                # CLEAR 2ND HALF OF MSGBUF                #
        MSG$WORD[I] = 0;
        END 
  
# 
*     IF HOP/BRK OR HOP/END OCCURRED, CLEAR INTERRUPT CELL *INVPSR* 
*     IN CASE IT IS INVOKED BY *NVFVFSD*.  SEND A VCB-SS-DATA ENTRY 
*     WITH END FLAG AND ERROR RESPONSE FLAG SET TO *VCBSSQ*.  EXIT
*     WITH FORMAL PARAMETER SET TO WAKE SELF UP WHEN DATA IN PUT
*     INTO *VSQ*. 
# 
      TSS$APENDF[0] = AVS$APENDF[0];   # SET LAST APPL FLAG # 
      IF ABORTCMDF
      THEN
        BEGIN 
        INVPSR = 0;                    # CLEAR INTERRUPT CELL          #
        WCB$WC[1] = VSSQSIZ$ + 2; 
        TSS$VENDF[0] = TRUE;           # SET VCB SS END FLAG           #
        TSS$EC[0] = SSEC"ABRT";        # SET THE ERROR CODE            #
        SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
  
        FOR I=0 WHILE VSQL NQ 0 
        DO                             # EMPTY OUT THE SS REQUEST QUEUE#
          BEGIN 
          SSTRQE(P<VSQ>,WCBUF[0],ABHBUF[0],MSGBUF[0]);
          END 
  
        INVVPSR = 0;                   # CLEAR INTERRUPT CELL          #
        STE$ADDR1[0] = LOC(INVVPSR);   # WATCH INTERRUPT FOR VSQ       #
        STE$ADDR2[0] = 0;              #   AND ONE CELL ONLY           #
        STE$RTN[0] = LOC(NVFVPSR);     # INVOKE NVFVPSR WHEN VSQ NQ 0  #
        STE$INIT1[0] = 0; 
        STE$INIT2[0] = 0; 
        RETURN;                        # EXIT                          #
        END 
  
  
# 
*     IF INVOKED BY *NVFVFSD* (INVPSR NQ 0), THEN SET UP TO READ MORE 
*     BLOCKS, IF THERE IS MORE TO READ. 
# 
  
      IF INVPSR NQ 0
      THEN
        BEGIN 
        INVPSR = 0;                    # CLEAR INTERRUPT               #
        IF AVS$VCBLK[0] - 1 EQ MAXSEC$
        THEN
          BEGIN              # LAST BLK READ ALREADY LAST BLK IN FILE  #
          IF AVS$MTCHF[0] 
          THEN
            BEGIN            # DONE READING AND MATCH FOUND-- DONE     #
            SSBUSYF = FALSE; # CLEAR SS-BUSY FLAG                      #
            TSS$VENDF[0] = TRUE;
            WCB$WC[1] = VSSQSIZ$ + 2; 
            SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
            END 
          ELSE
            BEGIN            # DONE READING VCB FILE, BUT NO MATCH     #
            TSS$EC[0] = SSEC"NOMATCH";
            SSBUSYF = FALSE;
            WCB$WC[1] = VSSQSIZ$ + 2; 
            TSS$VENDF[0] = TRUE;       #   WITH END FLAG AND           #
            SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
            END 
          END 
        ELSE
          BEGIN              # MORE VCB BLOCKS TO READ                 #
          IF (AVS$SGLEF[0] AND AVS$MTCHF[0])
          THEN
            BEGIN            # SEARCH FOR SINGLE ENTRY AND MATCH--DONE #
            SSBUSYF = FALSE; # CLEAR SS-BUSY FLAG                      #
            TSS$VENDF[0] = TRUE;
            WCB$WC[1] = VSSQSIZ$ + 2; 
            SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
            END 
          ELSE
            BEGIN            # NEED TO SEARCH FURTHER                  #
            NVFVSRR;         # CALL TO SET UP MORE READ REQUEST        #
            IF EFLAG
            THEN
              BEGIN          # NONE OF THE BLOCKS LEFT ASSIGNED        #
              IF AVS$MTCHF[0] 
              THEN
                BEGIN        # AT LEAST ONE MATCH FOUND                #
                SSBUSYF = FALSE;
                TSS$VENDF[0] = TRUE;
                WCB$WC[1] = VSSQSIZ$ + 2; 
                SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
                END 
              ELSE
                BEGIN        # NO MATCH FOUND YET--BAD                 #
                TSS$EC[0] = SSEC"NOMATCH";
                SSBUSYF = FALSE;
                WCB$WC[1] = VSSQSIZ$+2;     # SEND ENTRY TO VCBSSQ     #
                TSS$VENDF[0] = TRUE;        #   WITH END FLAG          #
                SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]); 
                END 
              END 
            ELSE
              BEGIN          # SET UP TO READ IS GOOD                  #
              # WAKE SELF UP WHEN NVFVFSD DONE WITH ALL BLOCK READ     #
              STE$ADDR1[0] = LOC(INVPSR); 
              STE$ADDR2[0] = 0; 
              STE$RTN[0] = LOC(NVFVPSR);
              STE$INIT1[0] = 0; 
              STE$INIT2[0] = 0; 
              RETURN;        # EXIT    #
              END 
            END 
          END 
        END 
  
  
# 
*     HERE TO PROCESS A NEW REQUEST IN *VSQ*
# 
  
      FOR I = 0 WHILE VSQL NQ 0 
      DO
        BEGIN 
        SSTRQE(P<VSQ>,WCBUF[0],ABHBUF[0],MSGBUF[0]);  # GET AN ENTRY   #
        AVS$WORD0[0] = 0;              # CLEAR AVST                    #
        AVS$WORD1[0] = 0; 
        AVS$WORD2[0] = 0; 
        AVS$VCBLK[0] = 1;              # RESET VCB BLOCK = 1           #
        AVS$WORDP[0] = TVS$WORDP[0];   # GET DATA FROM VSQ             #
        AVS$SGLEF[0] = TVS$SGLEF[0];
        AVS$VALUE[0] = TVS$VALUE[0];
        AVS$MASK[0] = TVS$MASK[0];
        AVS$APENDF[0] = TVS$APENDF[0];   # SET LAST APPL FLAG # 
        NVFVSRR;             # CALL TO SET UP TO READ BLOCKS           #
        TSS$APENDF[0] = AVS$APENDF[0];   # SET LAST APPL FLAG # 
        IF EFLAG
        THEN
         BEGIN               # NO BLOCKS IN THE WHOLE VCB FILE ASSIGNED#
         TSS$EC[0] = SSEC"NOMATCH"; 
         WCB$WC[1] = VSSQSIZ$+2;       # SEND AN ENTRY TO VCBSSQ       #
         TSS$VENDF[0] = TRUE;          #   WITH END FLAG               #
         SSTAQE(P<VCBSSQ>,WCBUF[1],ABHBUF[1],MSGBUF[N]);
         END
        ELSE
         BEGIN               # ALREADY SET UP TO READ BLOCKS           #
         SSBUSYF = TRUE;     # SET SS-BUSY FLAG                        #
         # SET UP TO WAKE SELF UP BY NVFVFSD WHEN DONE FILTERING       #
         STE$ADDR1[0] = LOC(INVPSR);
         STE$ADDR2[0] = 0;
         STE$RTN[0] = LOC(NVFVPSR); 
         STE$INIT1[0] = 0;
         STE$INIT2[0] = 0;
         RETURN;             # EXIT    #
         END
        END 
  
  
# 
*     RESTART PROC WHEN *VSQ* HAS DATA. 
# 
  
      INVVPSR = 0;           # INSURE INTERRUPT CELL IS CLEAR          #
      STE$ADDR1[0] = LOC(INVVPSR);
      STE$ADDR2[0] = 0; 
      STE$RTN[0] = LOC(NVFVPSR);
      STE$INIT1[0] = 0; 
      STE$INIT2[0] = 0; 
      RETURN;                # EXIT                                    #
  
  
CONTROL EJECT;
  
PROC NVFVSRR; 
#     TITLE NVFVSRR - SET UP VCB-READ REQUEST.                         #
  
      BEGIN    # NVFVSRR #
# 
**    NVFVSRR - SET UP VCB-READ REQUEST.
* 
*     A. LIM.    82/04/18.
* 
*     THIS PROCEDURE IS INTERNAL TO *NVFVPSR* AND IS CALLED ONLY
*     BY *NVFVPSR*.  IT-S MAIN FUNCTION TO SET UP *MAXSSRD$* OR 
*     LESS NUMBER OF VCB BLOCK READ REQUEST IN *VRQ*. 
* 
*     PROC NVFVSRR
* 
*     ENTRY    NEXT VCB BLOCK TO READ IN *AVST*.
* 
*     EXIT     EFLAG = TRUE - ERROR, FROM NEXT BLOCK TO READ TO END 
*                             OF VCB FILE, THERE IS NO BLOCKS ASSIGNED. 
*                    = FALSE - *MAXSSRD$* OR LESS BLOCKS READ REQUESTS
*                              MADE IN *VQR*. 
* 
*     METHOD   *NVFUROS* IS CALLED TO RETURN THE STATUS(ASSIGNED/ 
*              UNASSIGNED) OF A VCB ORDINAL.  ANY ONE VCB ORDINAL 
*              WITHIN A BLOCK IS ASSIGNED IS GOOD ENOUGH TO JUSTIFY 
*              THAT BLOCK IS ASSIGNED.  THEN A READ REQUEST WILL BE 
*              MADE IN THE *VRQ*. 
*              IT LOOPS TILL *MAXSSRD$* OR END OF FILE IS REACHED.
# 
  
  
      ITEM DUMBUF     U;     # DUMMY BUFFER FOR BODY OF VCB READ REQ   #
      ITEM FOUND      B;     # LOOP EXIT VARIABLE                      #
      ITEM I          I;     # LOOP INDUCTION VARIABLE                 #
      ITEM J          I;     # LOOP INDUCTION VARIABLE                 #
      ITEM STATS      B;     # VCB ORD STATUS, T=UNASSIGNED, F=ASSIGNED#
      ITEM VCBORD     U;     # VCB ORDINAL                             #
  
  
  
  
  
      EFLAG = FALSE;         # CLEAR THE ERROR FLAG                    #
      P<TVRQ> = LOC(ABHBUF[1]);   # POINT VRQ ENTRY TEMPLATE AT ABHBUF #
      FOR I = AVS$VCBLK[0] STEP 1 WHILE     I LQ MAXSEC$
                                        AND AVS$RSSCNT[0] LS MAXSSRD$ 
      DO
        BEGIN                # LOOP TIL BLK LIMIT OR MAX-SS-READ LIMIT #
        VCBORD = (I-1)*2**3 + 1;       # CALCUL. FIRST VCB ORD IN BLK  #
        FOUND = FALSE;                 # INIT LOOP EXIT VAR            #
        FOR J = 1 STEP 1 WHILE     J LQ VBMXENTRY$
                               AND NOT FOUND
        DO
          BEGIN              # LOOP TIL ALL ENTRIES IN BLK OR FOUND    #
          NVFUROS(VCBORD,STATS);       # CALL FOR STATUS OF ORD        #
          IF NOT STATS
          THEN
            BEGIN            # AT LEAST ONE ORDINAL IN BLK IS ASSIGNED #
            FOUND = TRUE;    # EXIT THE LOOP                           #
            END 
          VCBORD = VCBORD + 1;
          END 
        IF FOUND
        THEN
          BEGIN              # THIS BLOCK IS ASSIGNED                  #
          AVS$RSSCNT[0] = AVS$RSSCNT[0] + 1;  # INCREMENT READ-SS-CNT  #
          # BUILD A VCB READ REQUEST FOR SERIAL SEARCH                 #
          WCB$WORD[1] = 0;   # CLEAR WC WORD 1                         #
          ABH$WORD[1] = 0;   # CLEAR ABH WORD 1                        #
          WCB$WC[1] = 2;
          TVR$TYPE[0] = RDSS$;
          TVR$ORD[0] = VCBORD - 1;
          SSTAQE(P<VRQ>,WCBUF[1],TVRQ,DUMBUF);
          END 
        END 
      AVS$VCBLK[0] = I;      # NEXT BLOCK TO READ                      #
      IF AVS$RSSCNT[0] EQ 0 
      THEN
        BEGIN                # NO READ REQUESTS MADE AT ALL--BAD       #
        EFLAG = TRUE;        # SET ERROR FLAG                          #
        END 
  
      END    # NVFVSRR #
  
      END    # NVFVPSR #
  
TERM
