*DECK DB$MDRD 
USETEXT UTMPTTX 
USETEXT MDDEFTX 
USETEXT MDBCMTX 
  PROC DB$MDRD; 
    BEGIN 
 #
* *   DB$MDRD - READ EXISTING MD ENTRIES         PAGE  1
  *   M. D. SAXE                                 DATE  04/07/76 
* *   J. G. SERPA - MDU 2.3 ENHANCEMENTS         DATE  07/28/80 
* *   R. L. MCALLESTER - TABLE SEGMENTATION      DATE  03/30/84 
  
  DC  PURPOSE 
  
      READ MD ENTRIES FROM THE OLD MD INTO CORE.
  
  DC  ENTRY CONDITIONS
  
      THE OLD MD FILE MUST HAVE BEEN PREVIOUSLY OPENED. 
  
  DC  EXIT CONDITIONS 
  
      TABLES PERTAINING TO A SCHEMA ARE IN CORE.
  
  DC  CALLING ROUTINES
  
      DB$MDTR - TRANSFER OLD MD ENTRIES TO THE NEW MD 
  
  DC  CALLED ROUTINES 
  
 #
      XREF
        BEGIN 
 #                                                                     #
        PROC DB$DIAG;        # ISSUES DIAGNOSTICS                      #
        PROC DB$ERMD;        # CRM ERROR EXIT FOR THE NEW MD           #
        PROC DB$EROD;        # CRM ERROR EXIT FOR THE OLD MD           #
        PROC DB$FTMD;        # FIT FOR THE NEW MD                      #
        PROC DB$FTOD;        # FIT FOR THE OLD MD                      #
        PROC DB$UALC;        # ALLOCATES SPACE IN MANAGED MEMORY       #
        PROC DB$UAWS;        # ADJUST WORK SPACE IN MANAGED MEMORY     #
        PROC DB$WGET;        # PERFORMS GETS ON WORD ADDRESSABLE FILES #
        PROC DB$WPUT;        # WRITES TO THE NEW MD FILE               #
 #                                                                     #
        END 
  
      BASED ARRAY MDSCENTRY [0] S;
        BEGIN 
*CALL MDSCDDCLS 
        END 
  
      BASED ARRAY ARDIR [0] S;
        BEGIN 
*CALL MDARDDCLS 
        END 
  
      BASED ARRAY ARINFO [0] S; 
        BEGIN 
*CALL MDARIDCLS 
        END 
  
      BASED ARRAY DBPROC [0] S; 
        BEGIN 
*CALL MDDPDDCLS 
        END 
  
      BASED ARRAY CSTSSTBL [0] S; 
        BEGIN 
*CALL MDSBDDCLS 
        END 
  
*CALL MD20CDCLS 
# 
*     LOCAL VARIABLES 
# 
      ITEM OFFSET;           # TABLE OFFSET FOR PARTIAL READ, USED FOR #
                             # TABLE LENGTH CONTROLLED (TLC) TABLES    #
      ITEM REMLNG;           # REMAINING LENGTH OF TABLE BEING READ    #
  
  
  
#     B E G I N   D B $ M D R D   E X E C U T A B L E   C O D E .      #
  
 #
  
  DC  DESCRIPTION 
  
*     READ THE SCHEMA INFORMATION TABLE INTO THE WSA IN COMMON. 
 #
      P<MDSCENTRY> = SCDRBP + 1;
      GETWA = MDSCWASC[SCHDIRP];
      GETLNG = MDSCSISZ[SCHDIRP];      # LENGTH OF SCHEMA INFO TABLE   #
      P<GETENTRY> = LOC(MDSCINFO);
      DBGET;
  
 #
*     READ THE KEY INFORMATION TABLE INTO MANAGED MEMORY. 
 #
      P<MDSCENTRY> = SCDRBP + 1;
      GETWA = MDSCKITWA[SCHDIRP];      # WA OF KEY INFO TABLE          #
      GETLNG = MDSCKITSZ[SCHDIRP];     # LENGTH IN WORDS OF KIT        #
      IF KEYINFOBP EQ 0            # NO CMM BLOCK HAS BEEN ALLOCATED   #
      THEN
        BEGIN                      # ALLOCATE CMM BLOCK FOR KIT        #
        DB$UALC(LOC(KEYINFOBP),GETLNG,0); 
        END 
      ELSE
        BEGIN                      # ADJUST CMM BLOCK                  #
        DB$UAWS(LOC(KEYINFOBP),GETLNG); 
        END 
  
      P<GETENTRY> = KEYINFOBP + 1;     # POSITION TO READ THE KIT      #
      DBGET;                           # READ IT                       #
 #
*     READ THE AREA DIRECTORY AND INFORMATION TABLE INTO MANAGED MEMORY.
 #
      P<MDSCENTRY> = SCDRBP + 1 ; 
      GETWA = MDSCWAAD[SCHDIRP];
      GETLNG = MDSCADSZ[SCHDIRP]; 
# IF NO BLOCK HAS BEEN ALLOCATED FOR AREA DIRECTORY                    #
      IF ARDIRBP EQ 0 THEN
        DB$UALC(LOC(ARDIRBP),GETLNG,0); 
# OTHERWISE ADJUST WORK SPACE                                          #
      ELSE DB$UAWS(LOC(ARDIRBP),GETLNG-1);
      P<GETENTRY> = ARDIRBP + 1;
      DBGET;
      P<MDSCENTRY> = SCDRBP + 1;
      GETLNG = MDSCAISZ[SCHDIRP]; 
# IF NO BLOCK HAS BEEN ALLOCATED FOR AREA DIRECTORY                    #
      IF ARINFOBP EQ 0 THEN 
        DB$UALC(LOC(ARINFOBP),GETLNG,0);
# OTHERWISE ADJUST WORK SPACE                                          #
      ELSE DB$UAWS(LOC(ARINFOBP),GETLNG); 
      P<GETENTRY> = ARINFOBP + 1; 
      DBGET;
      P<MDSCENTRY> = SCDRBP + 1;
 #
*     READ THE DATA BASE PROCEDURE LIST TABLE INTO MANAGED MEMORY.
 #
      GETWA = MDSCWADP[SCHDIRP];
      GETLNG = MDSCDPSZ[SCHDIRP]; 
  
#  IF NO WORK BLOCK HAS BEEN ALLOCATED FOR DBP TABLE                   #
  
      IF DBPROCBP EQ 0 THEN 
        DB$UALC(LOC(DBPROCBP),DFMDDPCW,0);
  
#  IF A DBP TABLE EXISTS THEN                                          #
  
      IF GETLNG - DFMDDPCW GR 0 THEN
        BEGIN 
  
#  ADJUST WORK SPACE FOR DBP TABLE MANAGED MEMORY BLOCK                #
  
        DB$UAWS(LOC(DBPROCBP),GETLNG-DFMDDPCW); 
  
#  GET BACK THE DBP TABLE SIZE                                         #
  
        P<GETENTRY> = DBPROCBP + 1 ;
        DBGET;
        END 
 #
*     READ IN CHECKSUM LIST FROM OLD MD 
 #
      IF MDCHKSMBP EQ 0 THEN
        DB$UALC (LOC(MDCHKSMBP),0,0); 
      P<MDSCENTRY> = SCDRBP + 1;
      GETWA = MDSCCSLWA[SCHDIRP]; 
      GETLNG = MDSCCSLSZ[SCHDIRP];
      DB$UAWS (LOC(MDCHKSMBP),GETLNG);
      P<GETENTRY> = MDCHKSMBP + 1;
      DBGET;
 #
      READ THE SUB-SCHEMA DIRECTORY INTO MANAGED MEMORY 
 #
      P<MDSCENTRY> = SCDRBP + 1 ; 
      GETWA = MDSCWASB[SCHDIRP];
      GETLNG = MDSCSSSZ[SCHDIRP]; 
# IF NO BLOCK HAS BEEN ALLOCATED FOR SUB-SCHEMA DIRECTORY              #
      IF CSTDIRBP EQ 0 THEN 
        DB$UALC(LOC(CSTDIRBP),GETLNG,0);
# OTHERWISE ADJUST WORK SPACE                                          #
      ELSE DB$UAWS(LOC(CSTDIRBP), GETLNG-DFCSTSSHD);
      P<GETENTRY> = CSTDIRBP + 1; 
      DBGET;
 #
      INITIALIZE THE SUB-SCHEMA COUNTER.
 #
      P<CSTSSTBL> = CSTDIRBP + 1; 
      CSTDCNT = MDSBNBSB[0];
      P<ARDIR> = ARDIRBP + 1; 
      AREACNT = MDADNBAR[0];
 #
*     READ IN THE PERMANENT FILE INFORMATION TABLE (PIT). 
 #
      P<MDSCENTRY> = SCDRBP + 1;       # POSITION SCHEMA DIR TABLE     #
      GETWA = MDSCWAPIT[SCHDIRP];      # WA OF PERM FILE INFO TABLE    #
      GETLNG = MDSCPITSZ[SCHDIRP]      # LENGTH OF PIT                 #
               +  MDSCPITSX[SCHDIRP] * 2**18; 
  
      IF PITBP EQ 0                    # IF THE PIT IS NOT ALLOC       #
      THEN                             # ALLOCATE IT.                  #
        BEGIN 
        DB$UALC(LOC(PITBP), DFTLCHL -1, 0); 
        TLCCT[0] = TRUE;               # TLC CONTROL SWITCH            #
        TLCHLEN[0] = DFTLCHL;          # TLC HEADER LENGTH             #
        TLCUSED[0] = 0;                # NO USED MEMORY, INITIALLY     #
        TLCDSOR[0] = 0;                # DISK SEGMENT ORDINAL          #
        TLCDSMF[0] = FALSE;            # DISK SEGMENT NOT MODIFIED     #
        TLCDSBW[0] = DFPITHDR;         # DISK SEGMENT BEGINNING WORD   #
  
                                       # DISK SEGMENT WORD LENGTH      #
        TLCDSWL[0] = (DFTLCTMAX / (DFMDPITEN *2)) * DFMDPITEN;
  
                                       # BUILD SEGMENT BEGINNING WORD  #
        TLCBSBW[0] = TLCDSWL[0] + DFPITHDR; 
  
                                       # MAXIMUM TABLE LENGTH          #
        TLCTMXL[0] = TLCBSBW[0] + TLCDSWL[0]; 
        END 
  
      REMLNG = GETLNG;
      P<TLC> = B<42,18>PITBP; 
      TLCUSED[0] = 0; 
      TLCPAD[0] = DFTLCPAD; 
      OFFSET = 0;                      # TLC OFFSET FOR FIRST READ     #
      IF GETLNG GR TLCTMXL[0] 
      THEN                             # TABLE IS LARGER THAN MAXIMUM  #
        BEGIN 
        GETLNG = TLCTMXL[0];           # REDUCE READ TO MAXIMUM SIZE   #
        END 
      FOR REMLNG = (REMLNG - GETLNG) STEP -GETLNG UNTIL 0 
      DO
        BEGIN 
        DB$UAWS(LOC(PITBP),GETLNG);    # ALLOCATE TABLE FOR READ SIZE  #
  
                                       # AS THE TABLE SIZE EXPANDS     #
                                       # DB$UAWS WILL DUMP IT TO DISK  #
  
        P<GETENTRY> = LOC(TLC) + TLCHLEN[0] + OFFSET; 
        DBGET;
        GETLNG = TLCTMXL[0] - TLCBSBW[0]; 
        IF GETLNG GR REMLNG 
          AND REMLNG GR 0 
        THEN
          BEGIN 
          GETLNG = REMLNG;
          END 
        OFFSET = TLCBSBW[0];
        END 
      TLCPAD[0] = DFPITPD;             # RESTORE PIT PAD SIZE          #
  
  
 #
*     READ IN THE CONSTRAINT USE TABLE. 
 #
      P<MDSCENTRY> = SCDRBP + 1;       # POSITION SCHEMA DIR TABLE     #
      GETWA = MDSCCUTWA[SCHDIRP];      # WA OF CONSTRAINT USE TABLE    #
      GETLNG = MDSCCUTSZ[SCHDIRP];     # LENGTH OF CONSTRAINT USE TABLE#
      IF CUTBP EQ 0                    # IF CUT NOT YET ALLOCATED      #
      THEN
        BEGIN 
        DB$UALC(LOC(CUTBP),GETLNG,0);  # ALLOCATE CMM BLOCK FOR CUT    #
        END 
      ELSE
        BEGIN 
        DB$UAWS(LOC(CUTBP),GETLNG);    # ADJUST SIZE OF BLOCK FOR CUT  #
        END 
      P<GETENTRY> = CUTBP + 1;         # POSITION TO CUT               #
      DBGET;                           # READ CUT                      #
  
 #
*     READ IN THE VERSION DIRECTORY TABLE.
 #
      P<MDSCENTRY> = SCDRBP + 1;       # POSITION SCHEMA DIR TABLE     #
      GETWA = MDSCWAVD[SCHDIRP];       # WA OF VERSION DIRECTORY TABLE #
      GETLNG = MDSCNOVER[SCHDIRP] * DFMDVDEN;  # LENGTH OF VDT         #
      VERSCNT = GETLNG; 
      IF VERDIRBP EQ 0             # NO CMM BLOCK HAS BEEN ALLOCATED   #
      THEN
        BEGIN                      # ALLOCATE CMM BLOCK FOR VDT        #
        DB$UALC(LOC(VERDIRBP),GETLNG,0);
        END 
      ELSE                         # ADJUST CMM BLOCK                  #
        BEGIN 
        DB$UAWS(LOC(VERDIRBP),GETLNG);
        END 
  
      P<GETENTRY> = VERDIRBP + 1;      # POSITION VDT                  #
      DBGET;                           # READ IN VDT                   #
  
 #
*     READ IN THE VERSION INFORMATION TABLE.
 #
      P<MDSCENTRY> = SCDRBP + 1;       # POSITION SCHEMA DIR TABLE     #
      GETWA = MDSCWAVD[SCHDIRP] + MDSCNOVER[SCHDIRP];   # WA OF VIT    #
      GETLNG = MDSCNOVER[SCHDIRP] * MDSCNBARS[SCHDIRP] * DFMDVIEN;
  
      IF VERINFBP EQ 0                 # IF THE VIT IS NOT ALLOC       #
      THEN                             # ALLOCATE IT.                  #
        BEGIN 
        DB$UALC(LOC(VERINFBP), DFTLCHL -1, 0);
        TLCCT[0] = TRUE;               # TLC CONTROL SWITCH            #
        TLCHLEN[0] = DFTLCHL;          # TLC HEADER LENGTH             #
        TLCUSED[0] = 0;                # NO USED MEMORY, INITIALLY     #
        TLCDSOR[0] = 0;                # DISK SEGMENT ORDINAL          #
        TLCDSMF[0] = FALSE;            # DISK SEGMENT NOT MODIFIED     #
        TLCDSBW[0] = DFVITHDR;         # DISK SEGMENT BEGINNING WORD   #
  
                                       # DISK SEGMENT WORD LENGTH      #
        TLCDSWL[0] = (DFTLCTMAX / (DFMDVIEN *2)) * DFMDVIEN;
  
                                       # BUILD SEGMENT BEGINNING WORD  #
        TLCBSBW[0] = TLCDSWL[0] + DFVITHDR; 
  
                                       # MAXIMUM TABLE LENGTH          #
        TLCTMXL[0] = TLCBSBW[0] + TLCDSWL[0]; 
        END 
  
      REMLNG = GETLNG;
      P<TLC> = B<42,18>VERINFBP;
      TLCUSED[0] = 0; 
      TLCPAD[0] = DFTLCPAD; 
      OFFSET = 0;                      # TLC OFFSET FOR FIRST READ     #
      IF GETLNG GR TLCTMXL[0] 
      THEN                             # TABLE IS LARGER THAN MAXIMUM  #
        BEGIN 
        GETLNG = TLCTMXL[0];           # REDUCE READ TO MAXIMUM SIZE   #
        END 
      FOR REMLNG = (REMLNG - GETLNG) STEP -GETLNG UNTIL 0 
      DO
        BEGIN 
        DB$UAWS(LOC(VERINFBP),GETLNG); # ALLOCATE TABLE FOR READ SIZE  #
  
                                       # AS THE TABLE SIZE EXPANDS     #
                                       # DB$UAWS WILL DUMP IT TO DISK  #
  
        P<GETENTRY> = LOC(TLC) + TLCHLEN[0] + OFFSET; 
        DBGET;
        GETLNG = TLCTMXL[0] - TLCBSBW[0]; 
        IF GETLNG GR REMLNG 
          AND REMLNG GR 0 
        THEN
          BEGIN 
          GETLNG = REMLNG;
          END 
        OFFSET = TLCBSBW[0];
        END 
  
  
    END 
  TERM; 
