*DECK DB$SWI
USETEXT CDGDFTX 
      FUNC DB$SWI((PRU)); 
      BEGIN 
 #
* *   DB$SWI--SWAP IN TABLE                      PAGE  1
* *   C O GIMBER                                 07/13/76 
* *   R L MCALLESTER                             02/15/85 
* 
* DC  PURPOSE 
* 
*     SWAP IN TABLE GIVEN THE PRU NUMBER IN SWAP FILE.
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMTERS 
# 
      ITEM PRU;              # PRU NUMBER OF TABLE TO SWAP IN          #
# 
* DC  EXIT CONDITIONS 
* 
*     RETURNS FIRST WORD ADDRESS OF TABLE SWAPPED IN. 
* 
* DC  CALLING ROUTINES
* 
*     DB$SWPI                SWAP IN TABLES FOR USER
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$FLOP;           # GENERATE FLOW POINT               #
      XREF PROC DB$MFA;            # ALLOCATE MANAGED ARRAY            #
      XREF PROC DB$MFF;            # FREE MANAGED BLOCK                #
      XREF PROC DB$PUNT;           # CDCS ABORT PROCESSOR              #
      XREF PROC DB$RNFI;           # RANDOM FILE INITIALIZATION        #
      XREF PROC DB$RNRD;           # RANDOM READ INTO WSA              #
      XREF PROC DB$RNRW;           # RANDOM WRITE FROM WSA             #
# 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$RNFT;          # CDCS SWAP FILE FET                #
        BEGIN 
        ITEM FETLFN  C(00,00,07);  # LOCAL FILE NAME                   #
        ITEM FETEP   B(01,15,01);  # ERROR PROCESSING BIT              #
        END 
# 
*     EXTERNALLY DEFINED LOCAL VARIABLES
# 
      XDEF ITEM SWPTC  I = 0;      # COUNT OF ENTRIES IN SWAP TABLE    #
  
      DEF DFSSL #300#;             # LENGTH OF SWAP SEGMENT TABLE      #
  
      XDEF ARRAY SWPSEGT [DFSSL];  # SWAP SEGMENT TABLE                #
        BEGIN 
*CALL SWPTDCLS
        END 
# 
*     CDCS COMMON 
* 
 #
# 
*     LOCAL VARIABLES.
# 
      ITEM FETLOC I = 0;           # LOCATION OF FET                   #
      ITEM PRUL   I;               # LENGTH EXPRESSED IN PRU'S         #
      ITEM PRUN   I;               # PRU NUMBER OF TABLE TO SWAP OUT   #
      ITEM STXI   I;               # INDEX INTO SWAP TABLE FOR DB$SWI  #
      ITEM STXO   I;               # INDEX INTO SWAP TABLE FOR DB$SWO  #
      ITEM STXX   I;               # SECONDARY INDEX INTO SWAP SEGMENT #
      ITEM WL     I;               # WORD LENGTH OF TABLE              #
      ITEM WSA    I;               # ADDRESS OF WORKING STORAGE        #
  
  
  
  
  
#     B E G I N   D B $ S W I   E X E C U T A B L E   C O D E .        #
  
  
 #
* 
* DC  DESCRIPTION 
* 
*     SEARCH SWAP TABLE FOR THE SPECIFIED PRU NUMBER. 
*     IF NOT FOUND ABORT CDCS.
*     READ TABLE INTO CORE
*     AND IF IT IS NOT A "READ ONLY" REQUEST, 
*         CLEAR SWAP TABLE ENTRY. 
 #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP ("SWI");
      CONTROL ENDIF;
  
                                   # SEARCH FOR THE PRU NUMBER         #
      FOR STXI = 1 STEP 1 UNTIL SWPTC 
      DO
        BEGIN 
        IF PRU EQ SWPN[STXI]
        THEN                       # THE ENTRY IS FOUND                #
          BEGIN 
          WL = SWL[STXI];          # GET THE WORD LENGTH FROM THE ENTRY#
          DB$MFA(WL,WSA);          # ALLOCATE THE MEMORY BLOCK         #
  
                             # IT IS POSSIBLE THAT DB$SWO IS CALLED TO #
                             # RELEASE CM SPACE DURING THE PROCESSING  #
                             # OF THE DB$MFA CALL.                     #
                             # THIS COULD RESULT IN THE CURRENT ENTRY  #
                             # BEING MOVED TO MAKE SPACE FOR A NEW     #
                             # ENTRY.                                  #
                             # DB$SWO WILL ADJUST STXI IF THIS OCCURS. #
  
                                   # RESTORE THE CMM BLOCK CONTENTS    #
          DB$RNRD(FETLOC,WSA,WL,PRU); 
  
                                   # SQUEEZE OUT THE SWAP TABLE ENTRY  #
          FOR STXX = STXI STEP 1 UNTIL SWPTC
          DO
            BEGIN 
            SWWORD[STXX] = SWWORD[STXX+1];
            END 
  
          SWPTC = SWPTC-1;         # REDUCE THE SWAP TABLE ENTRY COUNT #
          DB$SWI = WSA;            # RETURN THE CMM BLOCK ADDRESS      #
          RETURN; 
  
          END 
        END 
  
      DB$PUNT("DB$SWI");           # THE ENTRY WAS NOT FOUND.  ABORT.  #
  
  
  
#**********************************************************************#
#                                                                      #
#     E M B E D D E D   P R O C E D U R E   -   D B $ S W O .          #
#                                                                      #
#**********************************************************************#
  
      XDEF FUNC DB$SWO; 
      FUNC DB$SWO((FWA),(LENGTH));
      BEGIN 
 #
**    DB$SWO--SWAP OUT TABLE                     PAGE  1
* *   C O GIMBER                                 07/13/76 
* *   R L MCALLESTER                             02/15/85 
* 
* DC  DESCRIPTION 
* 
*     SWAP OUT CDCS TABLE GIVEN FWA AND LENGTH. 
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
# 
      ITEM FWA;                        # FWA OF TABLE                  #
      ITEM LENGTH;                     # LENGTH OF TABLE               #
# 
* DC  EXIT CONDITIONS 
* 
*     RETURNS -PRU OF TABLE IF SWAPPED OUT. 
*     RETURNS FWA OF TABLE IF SWAP TABLE FULL.
* 
* DC  CALLING ROUTINE 
* 
*     DB$SWPO--SWAP OUT TABLES FOR USER.
* 
* DC  DESCRIPTION 
* 
 #
  
  
  
#     B E G I N   D B $ S W O   E X E C U T A B L E   C O D E .        #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP ("SWO");
      CONTROL ENDIF;
  
      IF FETLOC EQ 0
      THEN                         # FIRST CALL                        #
        BEGIN 
        FETLOC = LOC(DB$RNFT);
                                   # INITIALIZE THE SWAP FILE          #
        FETLFN[0] = "ZZZZZCS";
        FETEP[0] = FALSE; 
        DB$RNFI(FETLOC);
                                   # INITIALIZE THE SWAP SEGMENT TABLE #
        SWWORD[0] = 0;
        SWL[0] = 1; 
        SWPL[0] = 1;
        SWWORD[1] = O"377777";
        END 
  
 #
*     IF SWAP OUT TABLE FULL THEN RETURN FWA PASSED.
 #
      IF SWPTC EQ DFSSL-1 
      THEN
        BEGIN 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP ("SWO-NO"); 
        CONTROL ENDIF;
  
        DB$SWO = FWA; 
        RETURN; 
  
        END 
 #
*     SEARCH SWAP OUT TABLE 
*       IF A LARGE ENOUGH BLOCK IS FOUND THEN SWAP OUT THE CMM BLOCK. 
 #
      SWPTC = SWPTC+1;             # ADD ONE TO SWAP TABLE ENTRY COUNT #
      PRUL = (LENGTH /64) +1;      # LENGTH IN PRU'S FOR SWAP FILE     #
  
      FOR STXO = 1 STEP 1 UNTIL SWPTC 
      DO
        BEGIN 
        IF PRUL LQ SWPN[STXO] - SWPN[STXO-1] - SWPL[STXO-1] 
        THEN
          BEGIN                    # FOUND SPACE ON THE SWAP FILE      #
  
                                   # MAKE SPACE FOR THE NEW ENTRY      #
                                   # IN THE SWAP TABLE                 #
          FOR STXX = SWPTC STEP -1 UNTIL STXO 
          DO
            BEGIN 
            SWWORD[STXX+1] = SWWORD[STXX];
            END 
  
          IF STXO LQ STXI          # JUST IN CASE A SWAP-IN IS IN      #
          THEN                     # PROGRESS, ADJUST STXI.            #
            BEGIN 
            STXI = STXI +1; 
            END 
                                   # CREATE THE NEW SWAP TABLE ENTRY   #
          PRUN = SWPN[STXO-1] + SWPL[STXO-1]; 
          SWPN[STXO] = PRUN;
          SWPL[STXO] = PRUL;
          SWL [STXO] = LENGTH;
                                   # WRITE OUT THE CMM BLOCK CONTENTS  #
          DB$RNRW(FETLOC,FWA,LENGTH,PRUN);
          DB$MFF(FWA);             # RELEASE THE CMM BLOCK             #
          DB$SWO = -PRUN; 
          RETURN; 
  
          END 
        END 
 #
*     IF LARGE ENOUGH BLOCK NOT FOUND THEN INTERNAL ERROR.
 #
      DB$PUNT("DB$SWO");
      END                              # DB$SWO # 
  
      END                              # DB$SWI # 
      TERM
