*DECK S$SRTPH 
          PROC  S$SRTPH(SPEC$); 
  
#**       S$SRTPH -  SORT PHASE                                        #
#                                                                      #
#     CALLING SEQUENCE-                                                #
#         S$SRTPH(SPEC$):                                              #
#                                                                      #
#     GIVEN-                                                           #
#         SPEC$ = USER SPECIFICATION                                   #
#                                                                      #
#     DOES-                                                            #
#         SORTS ACCORDING TO SPEC$.                                    #
#         SORTED RECORDS ARE HANDLED ACCORDING TO SPEC$.               #
  
  
          BEGIN 
  
*CALL A 
  
          BASED 
*CALL CODE$ 
  
*CALL FMTBL$
  
          BASED 
*CALL IMTBL$
  
*CALL REC$
  
*CALL SPEC$ 
  
          BASED 
*CALL STRTBL$ 
  
*CALL WSAF$ 
  
*CALL WSAI$ 
  
          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;            # GET FIXED BLOCK SIZE          #
              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$ALCF;            # ALLOCATE WSA$ FOR FNLMRG      #
              PROC S$ABORT; 
              PROC  S$ABT;
              PROC  S$CLEAR;         # UNLOAD INTERMEDIATE FILES       #
              PROC  S$DSASM;           # DIS-ASSEMBLE CODE$            #
              PROC  S$EXECU;           # EXECUTE GENERATED CODE        #
              PROC  S$GNFMG;           # GENERATE FNLMRG-CODE          #
              PROC  S$GNIMG;           # GENERATE INTMRG-CODE          #
              PROC  S$GNSRT;           # GENERATE SORT CODE            #
              PROC  S$LOAD;            # LOAD A CAPSULE                #
            PROC S$MDRD;
              PROC  S$MGDSN;           # MERGE DESIGN                  #
              PROC S$PRTCD; 
              PROC  S$RTNFL;
              PROC  S$SETCD;           # SET CODE$ FROM A FILE         #
              PROC  S$STREC;           # SET REC$                      #
              PROC  S$ULOAD;           # UNLOAD A CAPSULE              #
              PROC  S$INFO;            # DISPLAY CONSOLE MESSAGE       #
              END 
  
          BASED ARRAY WSA$ [0:0]; 
              ITEM  WSA$WORD     U(0, 0,60);
  
          ITEM  INDXFIT      I=0;      # INDEX TO CURRENT VALUE        #
                             # IN FITARRAY                             #
          ITEM  LINE         C(60); 
          ITEM  LCODE        I;        # LENGTH OF CODE BLOCK          #
          ITEM  SHORT        B;        # TRUE IFF SHORT SORT           #
          ITEM  ORD          I=0;      # KEEP REC ORDINAL FOR LONG-CODE#
          ITEM  MAXFREE      I;        # MAXIMUM AVAILABLE SPACE       #
          ITEM NSTRINGS;
  
          #   CONSOLE OR DAYFILE MESSAGES TO INDICATE SORT STATUS      #
  
          ITEM CLEARMESS C(40) = "SORT5 - CLEARING INTERMEDIATE FILES"; 
          ITEM INITMESS C(40) = "SORT5 - READING INPUT";
          ITEM LONGMESS C(40) = "SORT5 - STILL READING INPUT";
          ITEM SHORTMESS C(40) = "SORT5 - FINISHING SHORT SORT";
          ITEM MDMESS C(40) = "SORT5 - MERGE DESIGN PHASE"; 
          ITEM IMMESS C(40) = "SORT5 - INTERMEDIATE MERGE PHASE"; 
          ITEM FMMESS C(40) = "SORT5 - FINAL MERGE PHASE";
  
  
          CONTROL DISJOINT; 
  
          CONTROL INERT;
  
CONTROL EJECT;
  
          # RESERVE SPACE FOR STRTBL$ BEFORE SPEC$LWSA                 #
          S$CMALF(P<STRTBL$>,LSTRTBL+65, 2, 0); 
  
#     RESERVE SPACE FOR CODE                                           #
  
          # SET THE AMOUNT OF MEMORY TO BE USED TO HOLD AND            #
          # EXECUTE EACH ONE OF THE VARIOUS CODE$S - INIT-CODE,        #
          # SHORT-CODE, LONG-CODE, INTERMEDIATE-MERGE-CODE, AND        #
          # FINAL-MERGE-CODE. THIS NUMBER SHOULD BE REVIEWED FOR       #
          # PERFORMANCE TUNING                                         #
  
          # NOTE: IT IS FINE TO HAVE A LARGE LCODE HERE BECAUSE        #
          #       S$GNSRT SHRINKS CODE$ WHEN IT IS DONE GENERATING CODE#
          LCODE = 6000; 
          S$CMALF(P<CODE$>, LCODE, 2, 0); 
          CODE$LENGTH = LCODE;
          CODE$USED = 0;
  
          # GET MAXIMUM AVAILABLE SPACE                                #
          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 AND SPEC$LWSA          #
          S$LOAD("S$STREC");
          S$STREC(SPEC$, REC$, MAXFREE);
          S$ULOAD("S$STREC"); 
  
  
#     GENERATE SORT CODE                                               #
  
          S$LOAD("S$GNSRT");                     # LOAD CAPSULE        #
          S$GNSRT(REC$, SPEC$, CODE$);           # CODE$ = INIT-CODE   #
                             # SHORT-CODE AND LONG-CODE ARE PUT ON A   #
                             # FILE ACCESSIBLE BY S$SETCD.   CODE$ IS  #
                             # SHRUNK TO MAXIMUM OF ALL 3 -CODES.      #
          S$ULOAD("S$GNSRT");                    # UNLOAD CAPSULE      #
$BEGIN
          LINE = "***** INIT-CODE *****"; 
          S$PRTCD(LINE);
          S$DSASM(CODE$);              # DIS-ASSEMBLE CODE$ ONTO FILE  #
$END
  
  
  
  
#     ALLOCATE WORKING STORAGE AREA                                    #
  
          S$CMALF(P<WSA$>,SPEC$LWSA, 0, 0); 
  
          S$INFO(INITMESS); 
#     INITIALIZE TOURNAMENT AND RECORD STORAGE AREA                    #
  
          S$EXECU(CODE$, WSA$, SHORT, INDXFIT, ORD);
                             # USE WSA$, SET SHORT,INDXFIT             #
  
#     PROCESS ACCORDING TO WHETHER WE HAVE A SHORT SORT                #
  
          IF SHORT  THEN               # IF SHORT SORT                 #
              BEGIN 
              S$CMFRF(STRTBL$); 
              S$INFO(SHORTMESS);
              S$SETCD(CODE$, "SHORT-CODE");      # CODE$ = SHORT-CODE  #
$BEGIN
              LINE = "***** SHORT-CODE *****";
              S$PRTCD(LINE);
              S$DSASM(CODE$);          # DIS-ASSEMBLE CODE$ ONTO FILE  #
$END
              S$EXECU(CODE$, WSA$);              # USE WSA$            #
              S$CMOP2;                 # LET CMM MEM DOWN              #
              END 
          ELSE                         # IF LONG SORT                  #
              BEGIN 
              S$RTNFL;
              S$INFO(LONGMESS); 
              S$SETCD(CODE$, "LONG-CODE");       # CODE$ = LONG-CODE   #
$BEGIN
              LINE = "***** LONG-CODE *****"; 
              S$PRTCD(LINE);
              S$DSASM(CODE$);  # DISASSEMBLE CODE ON TO FILE #
$END
              # EXECUTE LONG-CODE USING WSA$ TO PRODUCE STRTBL$        #
              S$EXECU(CODE$, WSA$, STRTBL$, INDXFIT, ORD);
  
              S$CMOP2;                 # LET CMM MEM DOWN              #
              S$CMFRF(WSA$);           # MAKE ROOM FOR S$MGDSN         #
              SPEC$LWSA =SPEC$LWSA - 500; # AVOID MEMORY FRAGMENT. #
              IF (STRTBL$LEN GR 14) AND SPEC$OWNT THEN
                  BEGIN 
                  S$CMALF(P<WSA$>, SPEC$LWSA, 0, 0);
                  END 
              ELSE
                  BEGIN 
                  S$CMFRF(CODE$); 
                  END 
  
              IF STRTBL$LEN GQ LSTRTBL-1 THEN 
                  BEGIN    # FILE ZZZZZ3Z CONTAINS STRING DESC. # 
                  NSTRINGS = STRTBL$LEN;  # SAVE STRTBL$LEN # 
                  S$CMFRF(STRTBL$);    # FREE OLD STRTBL$ SPACE # 
                  S$CMALF(P<STRTBL$>, NSTRINGS+65, 0, 0); 
                  STRTBL$LEN = NSTRINGS;  # RESTORE NSTRINGS #
                  # READ FILE ZZZZZ3Z INTO NEW STRTBL$ SPACE #
                  S$MDRD(LOC(STRTBL$ENTRY[1]),
                       STRTBL$LEN+64); # +64 FOR CIO READ   # 
                  END 
  
              # ESTIMATED LENGTH RATIO BETWEEN STRTBL$ AND IMTBL$ # 
              NSTRINGS = STRTBL$LEN + (STRTBL$LEN/2); 
  
#     RESERVE SPACE FOR IMTBL$                                         #
  
              IF NSTRINGS GR IMTBL$LEN THEN 
                  S$CMALF(P<IMTBL$>, NSTRINGS, 0, 0); 
              ELSE
                  S$CMALF(P<IMTBL$>,IMTBL$LEN,0,0); 
  
              IF (STRTBL$LEN GR 14) AND SPEC$OWNT THEN
                  BEGIN 
                  S$CMFRF(WSA$);
                  S$CMFRF(CODE$); 
                  END 
              S$INFO(MDMESS); 
              S$LOAD("S$MGDSN");       # LOAD S$MGDSN                  #
              # CONVERT STRTBL$ INTO A SPECIFICATION OF THE SEQUENCE   #
              # OF MERGE PASSES TO BE DONE (IMTBL$ AND FMTBL$).        #
                  S$MGDSN(STRTBL$, IMTBL$, FMTBL$, SPEC$, REC$);
  
              S$ULOAD("S$MGDSN");      # MAKE ROOM FOR CODE GENERATORS #
              S$CMFRF(STRTBL$);        # RELEASE SPACE HELD FOR STRTBL$#
  
              IF IMTBL$NSECTS NQ 0 THEN 
                  BEGIN                # INTERMEDIATE MERGE(S) NEEDED  #
                  # GET SOMEPLACE TO PUT THE GENERATED CODE            #
                  # (LCODE IS STILL SET LARGE FROM BEGINNING)          #
              S$CMALF(P<CODE$>, LCODE, 2, 0);  # SHRINKABLE AT LWA     #
              CODE$LENGTH = LCODE;
                  CODE$USED = 0;
                  S$LOAD("S$GNIMG");   # LOAD GENERATOR FOR INTMRG-CODE#
                  # GENERATE INTMRG-CODE INTO CODE$                    #
                  S$GNIMG(IMTBL$, REC$, SPEC$, CODE$);
$BEGIN
                  LINE = "***** INTER-MERGE *****"; 
                  S$PRTCD(LINE);
                  S$DSASM(CODE$);      # DIS-ASSEMBLE CODE$ ONTO "CODE"#
$END
                  S$ULOAD("S$GNIMG");            # MAKE ROOM FOR WSA$  #
                  S$CMALF(P<WSA$>, SPEC$LWSA, 0, 0);
                  S$INFO(IMMESS); 
                  S$EXECU(CODE$, WSA$, IMTBL$);  # EXECUTE INTMRG-CODE #
                  S$CMFRF(WSA$);       # MAKE ROOM FOR FNLMRG GENERATOR#
                  S$CMFRF(CODE$);      # MAKE ROOM FOR FNLMRG GENERATOR#
                  S$INFO(CLEARMESS);
                  S$CLEAR(FMTBL$);   # UNLOAD INTERMEDIATE FILES       #
                  END  # INTERMEDIATE MERGE(S) #
  
              S$INFO(FMMESS); 
              S$CMFRF(IMTBL$);         #RELEASE SPACE HELD BY IMTBL$   #
  
              # GET SOMEPLACE TO PUT THE GENERATED FNLMRG-CODE         #
          S$CMALF(P<CODE$>, LCODE, 2, 0);  #SHRINKABLE AT LWA          #
          CODE$LENGTH = LCODE;
              CODE$USED = 0;
              S$LOAD("S$GNFMG");       # LOAD GENERATOR FOR FNLMRG-CODE#
              # ALLOCATE USAGE OF WSA$ FOR FINAL MERGE                 #
              S$ALCF(FMTBL$, REC$, SPEC$, WSAF$);          # SET WSAF$ #
              # GENERATE FNLMRG-CODE INTO CODE$                        #
              S$GNFMG(FMTBL$, REC$, SPEC$, WSAF$, CODE$); 
$BEGIN
              LINE = "***** FINAL-MERGE *****"; 
              S$PRTCD(LINE);
              S$DSASM(CODE$);          # DIS-ASSEMBLE CODE$ ONTO "CODE"#
              S$DSASM(CODE$); 
$END
              S$ULOAD("S$GNFMG");                # MAKE ROOM FOR WSA$  #
  
              S$CMALF(P<WSA$>, SPEC$LWSA, 0, 0);
              S$EXECU(CODE$, WSA$);              # EXECUTE FNLMRG-CODE #
              S$RTNFL;
              END 
  
#     FREE SPACE                                                       #
  
          S$CMFRF(WSA$);               # FREE WORKING STORAGE AREA     #
          S$CMFRF(CODE$);              # FREE CODE SPACE               #
  
          END  # S$SRTPH #
          TERM
