*DECK S$MRGPH 
          PROC  S$MRGPH(SPEC$); 
  
#**       S$MRGPH -  MERGE PHASE                                       #
#                                                                      #
#     CALLING SEQUENCE-                                                #
#         S$MRGPH(SPEC$):                                              #
#                                                                      #
#     GIVEN-                                                           #
#         SPEC$ = USER SPECIFICATION                                   #
#                                                                      #
#     DOES-                                                            #
#         MERGES ACCORDING TO SPEC$.                                   #
#         MERGED RECORDS ARE HANDLED ACCORDING TO SPEC$.               #
  
  
          BEGIN 
*CALL A 
*CALL SPEC$ 
*CALL REC$
*CALL SMT$
*CALL WSAO$ 
          BASED 
*CALL CODE$ 
  
          XREF
              BEGIN 
              ITEM S$LOC      I;
              ITEM S$POS      I;
              ITEM S$ACODE    I;
              ITEM S$LCODE    I;
              ITEM S$IRRL     I;
              ITEM S$LK       I;
              ITEM S$LR       I;
              ITEM S$OREC     I;
              ITEM S$ORSA     I;
              END 
  
          XREF
              BEGIN 
              PROC  S$CMGFS;
              PROC  S$ABORT;           # ABORT WITH INTERNAL ERROR     #
              PROC  S$ABT;             # ABORT WITH USER ERROR         #
              PROC  S$CMALF;           # ALLOCATE FIXED BLOCK          #
              PROC  S$CMFRF;           # FREE FIXED BLOCK              #
              PROC  S$CMOP2;           # LET CMM MEM DOWN              #
              PROC  S$CMSLF;           # SHRINK BLOCK                  #
              PROC  S$DSASM;           # DIS-ASSEMBLE CODE$            #
              PROC  S$EXECU;           # EXECUTE GENERATED CODE        #
              PROC  S$GNOPM;           # GEN ONE-PASS USER MERGE       #
              PROC  S$INFO;            # DISPLAY CONSOLE MESSAGE       #
              PROC  S$LOAD;            # LOAD A CAPSULE                #
              PROC  S$PRTCD;           # PRINT ON FILE CALLED CODE     #
              PROC  S$RTNFL;
              PROC  S$SETCD;           # SET CODE$ FROM A FILE         #
              PROC  S$STREC;           # SET REC$                      #
              PROC  S$ULOAD;           # UNLOAD A CAPSULE              #
              PROC  S$UMDSN;           # USER-MERGE MERGE DESIGN       #
              END 
  
          BASED ARRAY WSA$ [0:0]; 
              ITEM  WSA$WORD     U(0, 0,60);
  
          ITEM LCODE           I;      # LENGTH OF CODE                #
          ITEM LINE        C(60);      # USED FOR S$PRTCD              #
  
          #   CONSOLE OR DAYFILE MESSAGES TO INDICATE SORT STATUS      #
  
          ITEM INITMESS C(40) = "MERGE - INITIALIZATION PHASE"; 
          ITEM MRGMESS C(40) = "MERGE - USER MERGE IN PROCESS"; 
          ITEM MAXFREE         I; 
  
  
          CONTROL DISJOINT; 
  
          CONTROL INERT;
  
CONTROL EJECT;
  
          $BEGIN
  
          FUNC  OCT(VALUE) C(20); 
              ITEM  VALUE        U;    # VALUE TO BE CONVERTED         #
              ITEM  C20          C(20); 
              ITEM  I            I; 
              BEGIN 
              FOR I = 0 STEP 1 UNTIL 19 DO
                  C<I,1>C20 = B<3*I,3>VALUE + O"33";
              OCT = C20;
              END  # OCT #
  
          FUNC  DEC(VALUE) C(10); 
              ITEM  VALUE       I;     # VALUE TO BE CONVERTED         #
              ITEM  C10PLUS     C(20);
              ITEM  I            I; 
              ITEM  N            I; 
              BEGIN 
              C10PLUS = "         0          "; 
              N = VALUE;
              IF N LS 0  THEN 
                  N = -N; 
              IF N GR 999999999 THEN
                  BEGIN 
                  C10PLUS = " *********          "; 
                  I = 0;
                  END 
              ELSE
                  BEGIN 
                  FOR I = 9 WHILE N NQ 0  DO
                      BEGIN 
                      C<I,1>C10PLUS = N - (N/10)*10 + 27; 
                      N = N/10; 
                      I = I - 1;
                      END 
                  END 
              IF VALUE LS 0 THEN
                  C<I,1>C10PLUS = "-";
              DEC = C<I,10>C10PLUS; 
              END  # DEC #
  
CONTROL EJECT;
  
          PROC PRINTWSAO; 
          BEGIN 
          ITEM LINE C(60);
          ITEM C20  C(20);
  
          LINE = " ----- WSAO$ STORAGE ALLOCATION ---"; 
          S$PRTCD(LINE);
  
          LINE = " LTRN=";
          C<7,10>LINE = DEC(WSAO$LTRN); 
          C20 = OCT(WSAO$LTRN); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " ORSA=";
          C<7,10>LINE = DEC(WSAO$ORSA); 
          C20 = OCT(WSAO$ORSA); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " OREC=";
          C<7,10>LINE = DEC(WSAO$OREC); 
          C20 = OCT(WSAO$OREC); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LOREC="; 
          C<8,10>LINE = DEC(WSAO$LOREC);
          C20 = OCT(WSAO$LOREC);
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LWSA=";
          C<7,10>LINE = DEC(SPEC$LWSA); 
          C20 = OCT(SPEC$LWSA); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " IRRL=";
          C<7,10>LINE = DEC(REC$IRRL);
          C20 = OCT(REC$IRRL);
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " WSAO=";
          C<7,10>LINE = DEC(WSAO$START);
          C20 = OCT(WSAO$START);
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          END 
          $END
  
CONTROL EJECT;
  
          LCODE = 6000; 
          S$CMALF(P<CODE$>, LCODE, 2, 0); 
          CODE$LENGTH = LCODE;
          CODE$USED = 0;
          S$LOAD("S$CMGFS");
          # GET AVAILABLE SPACE (AT LEAST 14000 OCTAL)                 #
          S$CMGFS (MAXFREE, 1, 1, 6144);
          S$ULOAD("S$CMGFS"); 
#     DETERMINE FORMAT OF INTERNAL RECORD                              #
  
          S$INFO(INITMESS);           # TELL USER WHATS HAPPENING      #
          S$LOAD("S$STREC");                     # LOAD S$STREC        #
          S$STREC(SPEC$, REC$, MAXFREE);
          S$ULOAD("S$STREC");                    # THROW AWAY S$STREC  #
  
#     RESERVE SPACE FOR CODE                                           #
  
          # NOTE: IT IS FINE TO HAVE A LARGE LCODE HERE BECAUSE        #
          #       S$GNOPM SHRINKS CODE$ WHEN IT IS DONE GENERATING CODE#
  
  
          S$UMDSN(SPEC$, SMT$); 
  
#     GENERATE MERGE CODE                                              #
  
          S$INFO(MRGMESS);          # TELL USER WHATS HAPPENING    #
          S$LOAD("S$GNOPM");
          S$GNOPM(SMT$, REC$, SPEC$, WSAO$, CODE$);  # GEN CODE    #
                                                    # AND SHRINK CODE$ #
  
          S$ULOAD("S$GNOPM"); 
          S$CMALF(P<WSA$>, SPEC$LWSA, 0, 0);
          WSAO$START = P<WSA$>; 
          $BEGIN
          PRINTWSAO;
          LINE = "*** ONE-PASS MERGE CODE ***"; 
          S$PRTCD(LINE);
          S$DSASM(CODE$); 
          $END
          S$EXECU(CODE$, WSA$, SMT$); 
          S$CMFRF(WSA$);
          S$CMFRF(CODE$); 
          IF SPEC$VERIFY THEN 
              S$ULOAD("S$VDATA"); 
          END 
          TERM
