*DECK DB$MDPG 
USETEXT MDBCMTX 
USETEXT MDDEFTX 
USETEXT UTMPTTX 
      PROC DB$MDPG((SEGORD)); 
      BEGIN 
 #
* *   DB$MDPG - GET THE PFN SEGMENT              PAGE  1
* *   BOB MCALLESTER                             DATE  07/30/84 
* 
* DC  PURPOSE 
* 
*     READ THE SPECIFIED DISK SEGMENT INTO MEMORY.
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
# 
      ITEM SEGORD;           # ORDINAL OF ENTRY TO BE LOADED           #
# 
* D   ASSUMPTIONS 
* 
*     NONE
* 
* DC  EXIT CONDITIONS 
* 
*     THE SPECIFIED DISK SEGMENT RESIDES IN CENTRAL MEMORY. 
* 
* DC  CALLING ROUTINES
* 
*     DB$MDDP                DELETE PFN ENTRIES FOR A SCHEMA
*     DB$MDPS                SEARCH FOR A PFN ENTRY 
*     DB$MDWS                WRITE LENGTH CONTROLLED TABLES 
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$MABI;     # INTERNAL ERROR ABORT                    #
      XREF PROC DB$RNRD;     # RANDOM READ                             #
      XREF PROC DB$RNRW;     # RANDOM WRITE                            #
# 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     TLC HEADER IF A NEW DISK SEGMENT IS LOADED. 
* 
*     SWAPLIST IF THE CURRENTLY LOADED SEGMENT IS MOVED TO A NEW
*       DISK LOCATION.
# 
      XREF ARRAY DB$RNFT;;   # FET FOR RANDOM I/O                      #
# 
* DC  DESCRIPTION 
* 
*     IF THE SEGMENT THAT IS REQUESTED, IS ALREADY LOADED THEN RETURN.
* 
*     IF THE RESIDENT SEGMENT HAS BEEN MODIFIED, THEN IT MUST BE
*     WRITTEN BACK TO THE DISK BEFORE READING IN THE NEW ONE. 
*     IF POSSIBLE, THE RESIDENT SEGMENT IS WRITTEN BACK TO THE DISK 
*     AREA THAT IT PREVIOUSLY OCCUPIED. 
* 
*     IF IT HAS OUT GROWN THE OLD SPACE, IT IS WRITTEN AT THE END OF
*     THE SWAP FILE.  IN THAT CASE, IT IS ASSIGNED THE MAXIMUM TABLE
*     SPACE SO THAT IT WILL NOT OUTGROW IT AGAIN. 
 #
  
# 
*     LOCAL VARIABLES 
# 
      ITEM FROMLOC;          # TABLE LOCATION FOR I/O                  #
      ITEM LENGTH;           # LENGTH FOR RANDOM I/O                   #
      ITEM PRUNUM;           # PRU NUMBER FOR RANDOM I/O               #
      ITEM PRUSIZE;          # NEW SIZE AS NUMBER OF PRU-S             #
      ITEM SAVEWORD;         # A PLACE TO SAVE A WORD                  #
      ITEM XA;               # INDUCTION VARIABLE                      #
      ITEM XB;               # INDUCTION VARIABLE                      #
  
  
  
#     B E G I N   D B $ M D P G   E X E C U T A B L E   C O D E .      #
  
  
  
      P<TLC> = B<42,18>PFUNCBBP;
      IF SEGORD NQ TLCDSOR[0]      # IF THE SEGMENT IS NOT RESIDENT    #
      THEN                         # READ IT IN.                       #
        BEGIN 
        FROMLOC = P<TLC> + TLCHLEN[0] + TLCDSBW[0]; 
        IF TLCDSMF[0]              # IF THE MODIFIED FLAG IS SET       #
        THEN                       # REWRITE THE RESIDENT SEGMENT      #
                                   # BEFORE READING THE NEW ONE.       #
          BEGIN 
                                   # SEARCH FOR THE SEGMENT CONTROL    #
                                   # ENTRY IN THE SWAPLIST.            #
          XA = -1;
          PRUNUM = TLCSPRU[TLCDSOR[0]]; 
          FOR XB = SWPLISTL -1 STEP -1 UNTIL 0
          DO
            BEGIN 
            IF SWLPRU[XB] EQ PRUNUM 
            THEN
              BEGIN 
              XA = XB;
              XB = 0; 
              END 
            END 
          IF XA EQ -1 
            OR SWLPLOC[XA] NQ LOC(PFUNCBBP) 
          THEN                     # COULD NOT FIND THE SWAPLIST ENTRY #
            BEGIN 
            DB$MABI("DB$MDPG 1");  # NO RETURN                         #
  
            END 
                                   # XA IS THE INDEX TO THE SWAPLIST   #
  
          TLCSLEN[TLCDSOR[0]] = TLCDSWL[0]; 
          LENGTH = TLCDSWL[0];
                                   # ASSURE THAT THERE IS DISK SPACE   #
                                   # FOR THE CURRENT SEGMENT           #
          PRUSIZE = (TLCDSWL[0] +64) /64; 
          IF PRUSIZE GR SWLPRUL[XA] 
          THEN                     # THE PRU SIZE MUST BE INCREASED    #
            BEGIN 
                                   # IF IT IS THE LAST SWAPLIST ENTRY  #
                                   # OR THERE IS EXPANSION ROOM        #
                                   # AVAILABLE AT THIS ENTRY           #
            IF XA EQ SWPLISTL -1
              OR PRUSIZE LQ SWLPRU[XA+1] - SWLPRU[XA] 
            THEN
              BEGIN                # INCREASE THE ENTRY IN PLACE       #
              SWLPRUL[XA] = PRUSIZE;
              END 
            ELSE
              BEGIN                # MOVE THE ALLOCATION DESCRIPTOR    #
                                   # TO THE END OF THE LIST,           #
                                   # ALLOCATING AT END OF FILE.        #
              SAVEWORD = SWLWORD[XA]; 
              XB = SWPLISTL -2; 
              FOR XA = XA STEP 1 UNTIL XB 
              DO
                BEGIN 
                SWLWORD[XA] = SWLWORD[XA+1];
                END 
              XA = SWPLISTL -1; 
              SWLWORD[XA] = SAVEWORD; 
              SWLPRU[XA] = SWLPRU[XB] + SWLPRUL[XB];
              TLCSPRU[TLCDSOR[0]] = SWLPRU[XA]; 
                                   # WRITE THE MAXIMUM LENGTH          #
              LENGTH = TLCTMXL[0] - TLCDSBW[0]; 
              SWLPRUL[XA] = (LENGTH +64) / 64;
              END 
            END 
          PRUNUM = TLCSPRU[TLCDSOR[0]]; 
          TLCDSMF[0] = FALSE; 
          DB$RNRW(LOC(DB$RNFT),FROMLOC,LENGTH,PRUNUM);
          END 
                                   # READ IN THE NEW SEGMENT           #
        TLCDSOR[0] = SEGORD;
        LENGTH = TLCSLEN[SEGORD]; 
        TLCDSWL[0] = LENGTH;
        PRUNUM = TLCSPRU[SEGORD]; 
        DB$RNRD(LOC(DB$RNFT),FROMLOC,LENGTH,PRUNUM);
        END 
      END 
      TERM
