*DECK DB$SEK
USETEXT CDCSCTX 
      PROC DB$SEK;
      BEGIN 
 #
* *   DB$SEK -- CRM RANDOM SEEK PROCESSOR        PAGE  1
* *   C O GIMBER                                 11/29/76 
* 
* DC  PURPOSE 
* 
*     DO CRM RANDOM SEEK ON A FILE WHILE ALLOWING TASK
*     INTERRUPTION FOR I/O. 
* 
* DC  ENTRY CONDITIONS
* 
*     P<RSARBLK> IS SET.
*     ALL APPROPRIATE FIT FIELDS ARE SET. 
* 
* DC  EXIT CONDITIONS 
* 
*     P<RSARBLK> IS SET.
*     NORMAL EXIT 
*       CRM SEEK IS COMPLETE OR SHORT SEEK HAS BEEN DONE DFSEEKLIMIT
*       TIMES.
*     ABNORMAL EXIT 
*       EXIT THRU ERROR ROUTINE SPECIFIED IN FIT. 
*       EXIT TO DB$ERR IF THE FILE IS NOT IN "UP" OR "IDLING" STATUS. 
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$ERR;      #CDCS ERROR PROCESSOR# 
      XREF PROC DB$FLOP;     #IDENTIFY FLOW POINT                      #
      XREF PROC DB$FSET;     #SELECT AND SET A FIT                     #
      XREF PROC DB$POP;      #POP FROM STACK# 
      XREF PROC DB$PUSH;     #PUSH INTO STACK#
      XREF PROC DB$SCHD;     #CDCS SCHEDULER# 
      XREF PROC SEEKF;       #CRM SHORT SEEK# 
# 
* DC  NON-LOCAL VARIABLES 
* 
*     CDCS COMMON.
 #
# 
*     LOCAL VARIABLES 
# 
      BASED ARRAY FIT;
*CALL FITDCLS 
      ITEM INDEX;            #SCRATCH ITEM# 
      XREF ARRAY DB$RA0;
        ITEM COMPLETE B(0,59,1);   #THE COMPLETE BIT IN THE FET#
      CONTROL NOLIST;        # *CALL FIATDCLS                          #
*CALL FIATDCLS
      CONTROL LIST; 
  
  
  
#     B E G I N   D B $ S E K   E X E C U T A B L E   C O D E .        #
  
  
 #
* 
* DC  DESCRIPTION 
* 
*     PUSH ENTRY POINT. 
 #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("SEK"); 
      CONTROL ENDIF;
  
      DB$PUSH(DB$SEK);
      P<OFT> = RSAROFIT[0]; 
      DB$FSET;                     # SELECT AND SET A FIT              #
 #
*     LOOP DOING SHORT SEEKS UNTIL COMPLETE OR DFSEEKLIMIT TIMES. 
*       ABORT REQUEST IF AREA IS DOWN.
 #
      RSARSEKCNT[0] = DFSEEKLIMIT;
      FOR INDEX=INDEX WHILE RSARSEKCNT[0] GR 0 DO 
        BEGIN 
        IF OFSTATUS[0] NQ S"UP" AND 
                       OFSTATUS[0] NQ S"IDLING" THEN
            BEGIN 
            DB$ERR(10); 
            END 
        IF FPCFPOS[0]        # IF ANOTHER USER HAS USED THIS FIT       #
        THEN                 # RESET THE FIAT SO AAM WILL REINITIATE   #
          BEGIN              # THE SEEK                                #
          P<FIAT> = UFFITFIAT[0]; 
          FISEEK1[0] = 0; 
          FIPOSK1[0] = 0; 
          FIALTPOS[0] = TRUE; 
          FIXFER[0] = FALSE;
          FISKLAST[0] = FALSE;
          FPCFPOS[0] = FALSE; 
  
          CONTROL IFGR DFFLOP,0;
            ITEM SEKRFLO C(10) = "SEK-R00   ";
            B<36,6>SEKRFLO = B<3,3>RSARSEKCNT[0] + O"33"; 
            DB$FLOP(SEKRFLO); 
          CONTROL ENDIF;
  
          END 
        P<FIT> = LOC(UFFIT[0]); 
        SEEKF(FIT,DB$RA0);
 #
*       RECALL THE TASK UNTIL THE SEEK OCCURS WITHOUT A DELAY.
*       THIS GUARANTEES THAT THE BLOCK IS IN MEMORY.
 #
        IF COMPLETE [UFFITBZF[0]] 
          AND FITEOR[0] 
        THEN
          BEGIN 
          RSARSEKCNT[0] = 0;
          UFFITMKL[0] = FPFITMKL[0];  # RESTORE THE MKL                #
          END 
        ELSE
          BEGIN 
          DB$SCHD(-LOC(OFFITBZF[0]), DFWAITIO);  # INDIRECT THRU BZF   #
  
          CONTROL IFGR DFFLOP,0;
            ITEM SEKFLOP C(10) = "SEK-C00   ";
            B<36,6>SEKFLOP = B<3,3>RSARSEKCNT[0] + O"33"; 
            DB$FLOP(SEKFLOP); 
          CONTROL ENDIF;
  
          RSARSEKCNT[0] = RSARSEKCNT[0] -1; 
          DB$FSET;                 # SELECT AND SET A FIT              #
          END 
        END  #SEEK LOOP#
 #
*     POP ENTRY POINT.
*     RETURN. 
 #
      DB$POP(DB$SEK); 
      RETURN; 
      END  #DB$SEK# 
      TERM; 
