*DECK DB$SR16 
USETEXT UTMPTTX 
USETEXT MD10CTX 
USETEXT MDBCMTX 
USETEXT CUGBATX 
  PROC DB$SR16; 
    BEGIN 
  
 #
* *   DB$SR16 - INITIALIZE FOR INITIAL MOD RUN   PAGE  1
* *   M. D. SAXE                                 DATE  03/24/76 
  *   A. W. LO                                   DATE  05/08/77 
* *   J. G. SERPA                                DATE  07/24/80 
* *   KIM H. NGUYEN                              DATE  11/09/84 
  
  DC  PURPOSE 
  
      SET UP THE MASTER DIRECTORY CONTROL WORDS, SCHEMA DIRECTORY TABLE,
      AND THE PFN TABLE FOR AN INITIAL MODIFICATION RUN.
  
  DC  ENTRY CONDITIONS
  
      NONE. 
  
  DC  EXIT CONDITIONS 
  
      THE FOLLOWING TABLES HAVE BEEN READ INTO CMM BLOCKS:  
        MASTER DIRECTORY CONTROL WORDS, 
        SCHEMA DIRECTORY, 
        PFN TABLE,
  
  DC  CALLING ROUTINES
  
      DB$STD - SYNTAX TABLE DRIVER. 
  
  DC  CALLED ROUTINES 
  
 #
      XREF
        BEGIN 
  
          FUNC DB$MPOE;      # PUSH CMM OVERFLOW ACTION SUBROUTINE     #
          FUNC DB$STAT;      # CHECK IF FILE IS AT CONTROL POINT       #
  
          PROC DB$EROD;      # ERROR PROC FOR OLD MD CRM ERRORS        #
          PROC DB$FTOD;      # FIT FOR THE OLD MASTER DIRECTORY        #
          PROC DB$MVG;       # GROW A VARIABLE BLOCK                   #
          PROC DB$MV1A;      # CREATE A VARIABLE BLOCK                 #
          PROC DB$MABT;      # ABORT MDU AFTER ISSUING DIAGNOSTIC      #
          PROC DB$NO;        # RETURNS TO THE NO SIDE OF THE SYNTAX TBL#
          PROC DB$OVCM;      # CMM OVERFLOW ACTION SUBROUTINE          #
          PROC DB$UALB;      # ALLOCATE MANY BLOCKS                    #
          PROC DB$UALC;      # ALLOCATES BLOCKS OF CORE IN MANAGED MEM #
          PROC DB$UAWS;      # INCREASES THE BLOCKS OF CORE IN MNG MEM #
          PROC DB$WGET;      # READS WORD ADDRESSABLE FILES            #
          PROC DB$WOPN;      # OPENS WORD ADDRESSABLE FILES            #
  
      ARRAY DB$VRDT [0:0] S(3);    # MDU VERSION AND DATE              #
            BEGIN 
            ITEM DBVRPROD  C(0,00,03); # MDU EXTERNAL PRODUCT VERSION  #
            ITEM DBVRDATE  C(0,24,05); # MDU DATE OF INSTALLATION      #
            ITEM DBVTDATE  C(1,00,10); # TODAYS DATE YY/MM/DD          #
            ITEM DBVCTIME  C(2,06,05); # CURRENT TIME HH.MM            #
            END 
  
          ITEM DB$JDTE C(10);          # TODAYS JULIAN DATE            #
  
        END 
# 
  DC  NON-LOCAL VARIABLES MODIFIED
  
      ALL CELLS IN (1,0) COMMON.
  
# 
  
*CALL MDABTDCLS 
      BASED ARRAY PFNTBLE S(1); 
        BEGIN 
*CALL MDPFNDCLS 
        END 
  
      BASED ARRAY MDSCENTRY [0:0] S(1);  # SCHEMA DIRECTORY TABLE      #
        BEGIN 
*CALL MDSCDDCLS 
        END 
  
      BASED ARRAY KEYINFOT [0:0] S(1);;  # KEY INFORMATION TABLE       #
  
      BASED ARRAY MDCUT [0:0] S(1);;  # CONSTRAINT USE TABLE           #
  
  
#     LOCAL ITEMS                                                      #
  
      ITEM GETLNG;           # LENGTH OF CURRENT READ                  #
      ITEM I;                # SCRATCH CELL.                           #
      ITEM OFFSET;           # OFFSET FOR READ WITHIN THE TABLE        #
      ITEM REMLNG;           # REMAINING LENGTH OF TABLE BEING READ    #
      ITEM WORDAD;           # WORD ADDRESS IN MD FOR READ             #
      DEF DFSDLIMIT #10#;    # MAXIMUM NUMBER OF SCHEMA DIR ALLOWED    #
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   A L L O C              #
#                                                                      #
#**********************************************************************#
  
      PROC ALLOC; 
        BEGIN 
# 
*     DESCRIPTION 
* 
*     "ALLOC" CALLS "DB$UAWS" TO ALLOCATE MEMORY FOR THE PFN TABLE. 
*     IT ALSO BUILDS THE INDEX TABLE IF ONE IS REQUIRED.
*     DB$UAWS WILL CREATE DISK SEGMENTS WHENEVER THE MAXIMUM CAPACITY 
*     CENTRAL MEMORY TABLE IS EXCEEDED. 
* 
*     THE SEQUENCE OF CALLS TO ALLOC IS - 
* 
*     IF THE SIZE OF THE PFN TABLE TO BE LOADED IS WITHIN THE MAXIMUM 
*     TABLE SIZE, THERE IS ONLY ONE CALL. 
*     ALL OF THE REQUIRED MEMORY IS ALLOCATED.
*     NO DISK SEGMENT OR INDEX TABLE IS CREATED.
* 
*     IF THE REQUIREMENT EXCEEDS THE MAXIMUM TABLE SIZE, THEN 
*     THE FIRST CALL REQUESTS EXACTLY THE MAXIMUM.
*         NOTE THAT THE MAXIMUM SIZE IS THE SIZE OF TWO DISK SEGMENTS 
*         AND THAT DISK SEGMENT SIZES ARE ALWAYS CALCULATED TO BE AN
*         EXACT MULTIPLE OF THE SIZE OF THE PFN ENTRIES.
*     THE ALLOCATED TABLE SPACE IS THEN FILLED FROM THE MASTER
*     DIRECTORY.
* 
*     THEN A SECOND CALL IS MADE TO ALLOCATE THE SPACE OF A SINGLE
*     DISK SEGMENT. 
*     THE SECOND CALL CAUSES DB$UAWS TO WRITE THE CONTENTS OF THE TABLE 
*     AS TWO DISK SEGMENTS. 
*     IT COPIES THE SECOND OF THESE TWO SEGMENTS INTO THE FIRST HALF OF 
*     THE TABLE AND REALLOCATES THE SECOND HALF TO USED TO BUILD A NEW
*     SEGMENT.
* 
*     EACH SUCCESSIVE CALL WILL CREATE AND ALLOCATE ANOTHER SEGMENT.
* 
*     AN INDEX ENTRY IS CREATED FOR EACH OF THE SEGMENTS EXCEPT THE 
*     FIRST ONE.
# 
  
  
  
#     B E G I N   " A L L O C "   E X E C U T A B L E   C O D E .      #
  
  
        DB$UAWS(LOC(PFUNCBBP),GETLNG);  # ALLOCATE TABLE FOR READ SIZE #
  
                                       # AS THE TABLE SIZE EXPANDS     #
                                       # DB$UAWS WILL DUMP IT TO DISK  #
  
        IF (TLCHLEN[0] -DFTLCHL -1) *DFPFUNENT GR PFXL
        THEN                           # THERE IS A NEW DISK SEGMENT   #
          BEGIN 
          IF PFXL EQ 0                 # IF THERE IS NO INDEX          #
          THEN                         # CREATE ONE.                   #
            BEGIN 
            PFXA = DFTLCPAD * DFPFUNENT;
            DB$MV1A(PFXA,P<PFX>); 
            END 
          PFXL = PFXL + DFPFUNENT;     # INCREASE INDEX LENGTH.        #
          IF PFXL GR PFXA              # IF IT IS NEEDED               #
          THEN                         # ALLOCATE MORE INDEX SPACE.    #
            BEGIN 
            DB$MVG(P<PFX>,DFTLCPAD * DFPFUNENT);
            PFXA = PFXA +(DFTLCPAD * DFPFUNENT);
            END 
                                       # RESTORE PFN TABLE POINTER     #
          P<TLC> = B<42,18>PFUNCBBP;
          P<PFNTBLE> = LOC(TLC) + TLCHLEN[0] + DFMDPFNHD; 
  
                                       # INSERT THE NEW INDEX ENTRY    #
          PXPFW1[PFXL - DFPFUNENT] = MDPFN1WRD[0];
          PXPFW2[PFXL - DFPFUNENT] = MDPFN2WRD[0];
          PXPFW3[PFXL - DFPFUNENT] = MDPFN3WRD[0];
          END 
        END 
#**********************************************************************#
#     E N D   O F   I N T E R N A L   P R O C E D U R E   A L L O C    #
#**********************************************************************#
  
  
  
  
#     B E G I N   D B $ D S 1 6   E X E C U T A B L E   C O D E .      #
  
  
 #
  
  DC  DESCRIPTION 
  
      TEST IF THE OLD MASTER DIRECTORY FILE IS AT THE CONTROL POINT.
      IF IT IS NOT, CALL DB$MABT TO ABORT THE RUN.
 #
      IF DB$STAT(OLMDLFN) EQ 0
      THEN
        BEGIN 
        DB$MABT(DFNOOLMD,OLMDLFN);
        END 
 #
      INITIALIZE BLOCK POINTERS 
 #
      PFUNCBBP = 0; 
      SCDRBP = 0; 
      WRKBUFBP = 0;          # WORK BUFFER BLOCK POINTER WORD # 
 #
      INITIALIZE MDPFINFO 
 #
      P<GETENTRY> = LOC(MDPFWORD[0]); 
      FOR I = 0 STEP 1
        UNTIL FILETYPE"LASTFILE" * DFPFENTLEN - 1 
      DO
        BEGIN 
        GETUNSIG[I] = 0;
        END 
  
      AREANAM = " ";
      ARNMLEN = 0;
      ARNMLNW = 0;
      CCLFLAGS[0] = 0;
      CCLPROCNAME = " ";
      CHARGE = " "; 
      CHARGELEN = 0;
      DENSITY = 0;
      FILENAM = 0;
      JOBFAM = " "; 
      JOBPW = " ";
      JOBUN = " ";
      SBNMLEN = 0;           # SUBSCHEMA NAME LENGTH IN CHARACTERS #
      SCHNAME = " ";
      SCNMLEN = 0;
      SUBNAME = " ";
      TAPEFLAGS[0] = 0; 
      TRACKTYPE = FALSE;
      UNITLIM = 0;
      UPDLIM = 0; 
 #
      INITIALIZE THE SCHEMA INFORMATION TABLE.
 #
      P<GETENTRY> = LOC(MDSCINFO);
      FOR I = 0 STEP 1
        UNTIL DFMDSCINSZ - 1
      DO
        GETUNSIG[I] = 0;
 #
      ZERO OUT MASTER DIRECTORY FILE CONTROL WORDS. 
 #
      P<GETENTRY> = LOC(MDCONWD); 
      FOR I=0 STEP 1 UNTIL DFMDNUMCWM1 DO 
        GETUNSIG[I] = 0;
 #
      INITIALIZE FIRST AVAILABLE WORD IN THE NEW MD 
 #
      PUTWA = DFMDNUMCW + 1;
 #
      INITIALIZE COUNTERS AND OTHER VARIABLES 
 #
      AREACNT = 0;
      CSTDCNT = 0;
      PFUNCNT = 0;
      PROCCNT = 0;
      SCDRCNT = 0;
      DIRATHED = 1; 
      MODERR = 0; 
      NEWSCH = 0; 
      OVACTID = DB$MPOE(DFTRIGLV,DFTRIGWD,DB$OVCM); 
      PCUTNDX = 0;
      SCFATAL = 0;           # ERROR INDICATOR FOR THE CURRENT SCHEMA#
      SCFILE = FALSE;        # SCHEMA FILE CLAUSE SEEN FLAG            #
      SCHDIRP = 0;           # POINTER USED TO INDEX SCHEMA DIRECTORY#
      SCHINCR = 0;           # SCHEMA IN CORE FROM (1,0) SCAN FLAG #
      SCINPRG = 0;           # ID OF THE SCHEMA IN PROGRESS # 
      VERSCNT = 0;
      VERSNAM = " ";
      VERSORD = 0;
      P<SWAPLIST> = 0;       # LIST OF USED PRU'S ON THE SWAP FILE     #
      SWPLISTL = 0;          # LENGTH OF THE SWAP LIST                 #
  
      P<PFX> = 0;            # PFN INDEX TABLE POINTER                 #
      PFXA = 0;              # TABLE SIZE CURRENTLY ALLOCATED          #
      PFXL = 0;              # TABLE LENGTH CURRENTLY IN USE           #
 #
      ALLOCATE CMM BLOCKS FOR AREA DIRECTORY, AREA INFORMATION, 
      CHECKSUM LIST, DBP LIST, SUBSCHEMA/CST, VERSION DIRECTORY,
      VERSION INFORMATION, PERMANENT FILE INFORMATION TABLES. 
 #
  
      DB$UALB;
 #
      OPEN THE OLD MASTER DIRECTORY 
 #
  
      DB$WOPN(DB$FTOD,DB$EROD); 
 #
      READ THE MASTER DIRECTORY CONTROL WORDS INTO MEMORY (RESIDES IN 
      COMMON  - DB$MDBC)
 #
  
      DB$WGET(DB$FTOD,MDCONWD,DFMDNUMCW,1,DB$EROD); 
 #
      ABORT IF THE OLD MASTER DIRECTORY FILE IS NOT A VALID MD FILE.
 #
      IF MDWAPFN[0] + MDSZPFN[0] - 2 GQ MDWALUWD[0] OR
         MDSDWA[0] + MDSDNO[0] * DFMDSCDESIZE - 2  GQ MDWALUWD[0] OR
        MDCWVERS[0] NQ DFMDVERSOL      # PRIOR VERSION NUMBER, OR      #
        AND MDCWVERS[0] NQ DFMDVERS OR # CURRENT MDU VERSION NUMBER    #
         MDCWIDNT[0] NQ DFMDIDNT OR    # MD FILE IDENTIFIER STRING #
          MDCWPROD[0] NQ DFMDPRODOL     # OLD MD PRODUCT NUMBER        #
          AND MDCWPROD[0] NQ DFMDPROD     # MD PRODUCT NUMBER          #
         THEN DB$MABT(DFBADMD,0);      # BAD OLD MD FILE ABORT #
 #
      ALLOCATE SPACE IN MANAGED MEMORY FOR THE SCHEMA DIRECTORIES.
 #
      DB$UALC(LOC(SCDRBP),0,0); 
  
 #
      READ THE SCHEMA DIRECTORY INTO MANAGED MEMORY.
 #
      I = MDSDSIZE[0];
      DB$UAWS(LOC(SCDRBP),I); # ALLOCATE SPACE FOR THE SCHEMA DIRECTORY#
      P<MDSCENTRY> = SCDRBP + 1;
      DB$WGET(DB$FTOD,MDSCENTRY,MDSDSIZE[0],MDSDWA[0],DB$EROD); 
      SCDRCNT = MDSDNO[0]; # STORE THE NUMBER OF SCHEMAS SPECIFIED IN  #
                           # THE MD.                                   #
  
 #
      COMPUTE THE SIZE OF ALL THE SCHEMA DIRECTORIES AND STORE IT INTO
      A COMMON CELL.
 #
  
      SCHDRSZ = MDSDSIZE[0];
  
  
 #
      ALLOCATE SPACE FOR THE PFN TABLE AND READ IT INTO MANAGED MEMORY. 
 #
  
# 
*     ALLOCATE THE PFN/UN COMBO TABLE AND SET ITS TLC PARAMETERS
# 
      DB$UALC(LOC(PFUNCBBP), DFMDPFNHD + DFTLCHL -1, DFTLCPAD); 
      TLCCT[0] = TRUE;             # TABLE LENGTH IS CONTROLLED        #
      TLCXT[0] = TRUE;             # TABLE IS INNDEXED                 #
      TLCHLEN[0] = DFTLCHL;        # TLC HEADER LENGTH                 #
      TLCUSED[0] = DFMDPFNHD;      # PFN TABLE HEADER IS ONLY USE      #
      TLCDSOR[0] = 0;              # NO DISK SEMENT ORDINAL            #
      TLCDSMF[0] = FALSE;          # DISK SEGMENT NOT MODIFIED         #
      TLCDSBW[0] = DFMDPFNHD;      # DISK SEGMENT BEGINNING WORD       #
  
                                   # DISK SEGMENT WORD LENGTH          #
      TLCDSWL[0] = (DFTLCTMAX / (DFPFUNENT *2)) * DFPFUNENT;
  
                                   # BUILD SEGMENT BEGINNING WORD      #
      TLCBSBW[0] = TLCDSWL[0] + DFMDPFNHD;
  
                                   # MAXIMUM TABLE LENGTH              #
      TLCTMXL[0] = TLCBSBW[0] + TLCDSWL[0]; 
# 
*     READ IN THE PFN 
# 
      P<PFNTBLE> = LOC(TLC) + TLCHLEN[0]; 
      GETLNG = MDSZPFN[0];
      REMLNG = MDSZPFN[0];
      OFFSET = 0; 
      WORDAD = MDWAPFN[0];
      TLCUSED[0] = 0; 
      TLCPAD[0] = DFTLCPAD; 
      IF GETLNG GR TLCTMXL[0] 
      THEN                             # TABLE IS LARGER THAN MAXIMUM  #
        BEGIN 
        GETLNG = TLCTMXL[0];           # REDUCE READ TO MAXIMUM SIZE   #
        END 
      ELSE
        BEGIN 
        TLCDSWL[0] = GETLNG - DFMDPFNHD;  # SET DISK SEG WORD LENGTH   #
        END 
      FOR REMLNG = (REMLNG - GETLNG) STEP -GETLNG UNTIL 0 
      DO
        BEGIN 
        ALLOC;                         # GET SPACE FOR MORE INPUT      #
  
                                       # GET ANOTHER SEGMENT LOAD FROM #
                                       # THE MASTER DIRECTORY          #
        P<PFNTBLE> = LOC(TLC) + TLCHLEN[0] + OFFSET;
        DB$WGET(DB$FTOD,PFNTBLE,GETLNG,WORDAD,DB$EROD); 
        WORDAD = WORDAD + GETLNG; 
        OFFSET = TLCBSBW[0];
        GETLNG = TLCTMXL[0] - TLCBSBW[0]; 
        IF GETLNG GR REMLNG 
          AND REMLNG GR 0 
        THEN
          BEGIN 
          GETLNG = REMLNG;
          END 
        END 
      IF PFXL NQ 0           # IF AN INDEX HAS BEEN CREATED            #
      THEN
        BEGIN                # MAKE ADJUSTMENTS FOR COMPATIBILITY WITH #
                             # INDEXED SEQUENTIAL TABLE PROCESSING     #
  
                             # APPEND THE BUILD SEGMENT PORTION TO THE #
                             # RESIDENT DISK SEGMENT.                  #
        TLCDSWL[0] = TLCUSED[0] - DFMDPFNHD;
        IF PFXL NQ 0
        THEN
          BEGIN 
          GETLNG = TLCTMXL[0] - TLCUSED[0]; 
          IF GETLNG EQ 0
          THEN
            BEGIN            # REQUEST ANOTHER FULL DISK SEGMENT.      #
            GETLNG = TLCTMXL[0] - TLCBSBW[0]; 
            END 
          ELSE
            BEGIN            # MARK THIS SEGMENT AS MODIFIED.          #
            TLCDSMF[0] = TRUE;
            END 
          ALLOC;             # ROUND OUT THE ALLOCATION                #
          END 
        END 
      TLCPAD[0] = DFPFUNPD;            # RESTORE PFN PAD SIZE          #
  
 #
      RESET THE BASED ARRAY POINTERS TO THE MANAGED MEMORY BLOCKS.
      CALLS TO CRM MAY HAVE ALTERED THE LOCATIONS OF THE RESERVED 
      BLOCKS IN MANAGED MEMORY
      STORE THE NUMBER OF PFN ENTRIES INTO ITS APPROPRIATE COUNTER. 
 #
      P<TLC> = B<42,18>PFUNCBBP;
      P<PFNTBLE> = P<TLC> + TLCHLEN[0]; 
      PFUNCNT = MDPFCNT[0]; 
  
 #
      STORE DATE AND TIME OF MASTER DIRECTORY FILE MODIFICATION.
 #
      MDCHTIME[0] = DBVCTIME[0];
      MDCHDATE[0] = C<5,5>DB$JDTE;
 #
      SET RUN TYPE TO INDICATE A MOD RUN. 
 #
      RUNTYPE = 1;
      DB$NO;
    END 
  TERM; 
