*DECK S$STREC 
          PROC  S$STREC(SPEC$, REC$, MAXFREE);
  
#**       S$STREC$ - SET REC$                                          #
#                                                                      #
#     CALLING SEQUENCE-                                                #
#         S$STREC(SPEC$, REC$, MAXFREE):                               #
#                                                                      #
#     GIVEN-                                                           #
#         SPEC$ = USER SPECIFICATION.                                  #
#         REC$ = ARRAY TO HOLD FORMAT OF INTERNAL RECORD.              #
#         MAXFREE = MAXIMUM AVAILABLE FIXED BLOCK SIZE.                #
#                                                                      #
#     DOES-                                                            #
#         SETS REC$ = FORMAT OF INTERNAL RECORD.                       #
#         SETS SPEC$LWSA = MAXIMUM LENGTH FOR WSA$ DURING SORT OR MERGE#
  
  
          BEGIN 
  
*CALL A 
  
*CALL KTSW$ 
  
*CALL KT$ 
*CALL REC$
  
*CALL SPEC$ 
  
*CALL MACHINE 
  
          ITEM  I            I;        # INDEX TO SPEC$                #
          ITEM  IRL          I;        # INTERNAL RECORD LENGTH (BITS) #
          ITEM  L            I;        # A LENGTH IN BITS              #
          ITEM  LF           I;        # LENGTH OF FIXED PART          #
          ITEM  LK           I;        # LENGTH OF KEY INFORMATION     #
          ITEM  LKA          I;        # LENGTH OF KEYS W/OUT ALTER    #
          ITEM  LL           I;        # LENGTH OF LENGTH FIELD        #
          ITEM  LOREC        I;        # LENGTH FOR OUTPUT RECORD      #
          ITEM  LTRN         I;        # LENGTH OF TOURNAMENT (S$ALCS) #
          ITEM  MAXRECS      I;        # MAXIMUM NUMBER OF REC. SLOTS  #
          ITEM  MINLWSA      I;        # MINIMUM FOR SPEC$LWSA         #
          ITEM  PLATLWSA     I;        # PLATEAU VALUE FOR SPEC$LWSA   #
          ITEM  RATIO        R;        # RATIO OF VOL. TO PLATEAU VOL. #
          ITEM  UNUSED       I;        # TENTATIVE UNUSED WORDS, S$ALCS#
          ITEM  USED         I;        # NON-VARIABLE USED WORDS,   "  #
          ITEM  MAXFL        I;        # MAXIMUM FIELD LENGTH          #
          ITEM  MAXFREE      I;        # AVAILABLE FIXED BLOCK SIZE    #
          ITEM  LMIN         I; 
          ITEM  LMAX         I; 
          ITEM  N            I;        # SCRATCH                       #
          ITEM  LINE         C(60);    # FOR PRINTOUT OF REC$          #
          ITEM  C20          C(20); 
          ITEM  C10          C(10); 
          ITEM  EXTKEYBITS   I; 
          ITEM  INTSUMBITS   I; 
          ITEM  EXTSUMBITS   I; 
          ITEM  LENGTH       I; 
          ITEM HUGENUM      I;
  
          BASED ARRAY CONVERTER [0:0] S(1); 
              BEGIN 
              ITEM CONVERTL U(0,0,60);
              END 
          XREF
*CALL S$CALLR 
  
          XREF ITEM S$TBL1; 
          XREF PROC S$GTMFL;           # GET MAXIMUM FIELD LENGTH      #
          XREF PROC S$PRTCD;
          XREF PROC S$ABORT;
  
  
          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 DISJOINT; 
  
          CONTROL INERT;
  
CONTROL EJECT;
          # MAKE S$TBL1 ACCESSIBLE TO THIS PROCEDURE USING             #
          # THE BASED ARRAY CONVERTER.  S$TBL1 IS A TABLE OF           #
          # INTERNAL BINARY LENGTHS WHICH CORRESPOND TO THE            #
          # LENGTHS OF NUMERIC_XX KEYS                                 #
  
          P<CONVERTER> = LOC(S$TBL1); 
  
  
#     SET REC$LR = LENGTH OF FIELD FOR RECORD NUMBER                   #
  
          # WE HAVE A MINOR PROBLEM IN THAT WE CANNOT EXACTLY COMPUTE  #
          # THE MAXIMUM NUMBER OF SLOTS FOR RECORDS IN THE WORKING     #
          # STORAGE AREA UNTIL WE KNOW SPEC$LWSA, AND WE DO NOT KNOW   #
          # SPEC$LWSA UNTIL AFTER REC$IRRL IS COMPUTED.                #
          # WE SOLVE THIS PROBLEM BY MAKING AN ESTIMATE THAT IS SURE   #
          # TO BE ON THE HIGH SIDE. THIS WILL CAUSE THE LR FIELD TO BE #
          # 2 OR 3 BITS LARGER THAN STRICTLY NECESSARY. BUT IT WILL    #
          # HOPEFULLY NOT INCREASE REC$IRRL. (THERE IS ONE CHANCE IN   #
          # 30 OR 20 THAT REC$IRRL WILL INCREASE BY ONE WORD.)         #
          # (THE VALUE OF 65000 ALONG WITH THE *WHILE* TEST COPES WITH #
          # SPEC$LWSA UP TO NEARLY 400000B.                            #
          # WE ALSO NEED TO KNOW THE INTERNAL SIZE OF A RECORD, BUT    #
          # SPEC$MRL OR SPEC$FIXLEN BYTES IS A GOOD ESTIMATE.          #
          IF SPEC$FIXED THEN
              MAXRECS = 65000 / ((SPEC$FIXLEN + WORD - 1) / WORD);
          ELSE
              MAXRECS = 65000 / ((SPEC$MRL    + WORD - 1) / WORD);
          N = 2;
          FOR L = 1 STEP 1 WHILE N LQ MAXRECS DO
              N = N + N;
          REC$LR = L; 
          IRL = 1 + 1 + REC$LR;            # BIT 58 TO MARK SUM-DELETE #
  
#     SET REC$LK1 + REC$LK2 = LENGTH OF FIELD FOR KEYS                 #
  
          LK = 0;                      # LENGTH OF KEY INFORMATION     #
          LKA = 0;                     # LENGTH OF KEYS W/OUT ALTER    #
          EXTKEYBITS = 0; 
          FOR I = SPEC$1STKEY WHILE I NQ 0 DO 
              BEGIN 
              L = BYTE*SPEC$KEYNBYT[I] + SPEC$KEYNBIT[I]; 
              EXTKEYBITS = EXTKEYBITS + L;
#***#         GOTO KTSW$[SPEC$KEYTYPE[I]];
          DISPLAY:  
              IF NOT SPEC$KEYALT[I]  THEN 
                  LKA = LKA + L;
#***#         GOTO DONEKEY; 
          FLOAT: GOTO DONEKEY;
          INTEGER: GOTO DONEKEY;
          LOGICAL: GOTO DONEKEY;
          NUMERICLS:  
          NUMERICTS: L = L - 6;        # SUBTRACT ONE BYTE             #
                                       # FOR SEPARATE SIGN             #
          NUMERICNS:  
          NUMERICFS:  
          NUMERICTO:  
          NUMERICLO:  
                  L = L / 6;           # GET NUMBER OF BYTES           #
                                       #   NOT BITS                    #
  
          # NOW FIGURE OUT HOW MANY BITS ARE NEEDED IN THE             #
          # INTERNAL RECORD, BY LOOKING IN THE TABLE -CONVERTL-        #
          # A.K.A. S$TBL1. ALL THESE KEY TYPES ARE INTERNALLY          #
          # MAINTAINED AS SIGNED INTEGERS, EVEN NUMERIC_NS             #
          # THEREFORE, ONE BIT NEEDS TO BE ADDED TO THE LENGTH IN      #
          # -CONVERTL-, AND, FOR THE CASE WHERE THE KEY IS MORE        #
          # THAN 10 CHARACTERS LONG, THEY WILL BE INVERTED IN          #
          # SEPARATE CLUMPS, EACH OF WHICH IS 35 BITS LONG             #
  
          # EXPLANATION OF HORRIBLY COMPLICATED FORMULA                #
          #                                                            #
          # IF L IS 5 (BYTES), THEN LINE 1 OF THE FORMULA WILL         #
          # EVALUATE TO ZERO (L/10=0). LINE TWO WILL EVALUATE TO       #
          # WHATEVER IS IN S$TBL1[5] BECAUSE ((L/10)*10)=0.            #
          # THE THIRD LINE WILL EVALUATE TO ONE, WHICH GIVES US        #
          # ONE EXTRA BIT FOR THE SIGN.#
  
          # IF L IS 45, THEN LINE ONE WILL EVALUATE TO                 #
          # 4 * S$TBL1[10] WHICH IS 4*34. THAT TAKES CARE OF THE BIG   #
          # CLUMPS. THE SECOND LINE WILL EVALUATE TO S$TBL1[5],        #
          # WITH 5 BEING THE RESULT OF 45-40.                          #
          # THE THIRD LINE WILL BE 45+9=54..54/10 IS 5 EXTRA BITS,     #
          # ONE FOR EACH OF THE FIVE CLUMPS.                           #
  
                  L = (( CONVERTL[10] ) * ( L / 10 ) +
                       CONVERTL[L-((L/10)*10)]
                       +(L+9)/10);          # GET EXTRA BITS           #
              GOTO DONEKEY; 
PACKED: 
PACKEDNS: 
##LEADING:  
##TRAILING: 
##SEPARATE: 
              GOTO DONEKEY; 
DONEKEY:      LK = LK + L;
              I = SPEC$NEXTKEY[I];
              END 
  
          IF IRL + LK LQ BYTE*WORD THEN 
              BEGIN 
              REC$LK1 = LK; 
              REC$LK2 = 0;
              END 
          ELSE
              BEGIN 
              REC$LK1 = BYTE*WORD - IRL;
              REC$LK2 = LK - REC$LK1; 
              END 
          IRL = IRL + REC$LK1 + REC$LK2;
  
#     SET REC$LO1 + REC$LO2 = LENGTH OF FIELD FOR ORDINAL              #
  
          IF SPEC$RETAIN THEN 
              BEGIN 
              N = 2;
              HUGENUM = 10000000; 
              IF HUGENUM LS SPEC$ENRHIGH THEN 
                  HUGENUM = SPEC$ENRHIGH; 
              FOR L = 1 STEP 1 WHILE N LQ HUGENUM DO
                  N = N + N;
              IF IRL + L LQ BYTE*WORD THEN
                  BEGIN 
                  REC$LO1 = L;
                  REC$LO2 = 0;
                  END 
              ELSE
          IF IRL LQ BYTE*WORD THEN
                  BEGIN 
                  REC$LO1 = BYTE*WORD - IRL;
              REC$LO2 = L - REC$LO1;
                  END 
          ELSE
              BEGIN 
              REC$LO1 = 0;
              REC$LO2 = L;
              END 
              END 
          ELSE
              BEGIN 
              REC$LO1 = 0;
              REC$LO2 = 0;
              END 
          IRL = IRL + REC$LO1 + REC$LO2;
  
#     SET REC$LS1+REC$LS2 = LENGTH OF FIELD FOR SUM FIELDS             #
  
          INTSUMBITS = 0; 
          EXTSUMBITS = 0; 
          IF SPEC$1STSUM NQ 0 THEN
              BEGIN 
  
              FOR I = SPEC$1STSUM WHILE I NQ 0 DO 
                  BEGIN 
                  LENGTH = SPEC$SMLENE[I];
                  EXTSUMBITS = EXTSUMBITS + LENGTH; 
                  IF SPEC$SUMREP[I] GR 1 THEN 
                      EXTSUMBITS = EXTSUMBITS + LENGTH *
                            (SPEC$SUMREP[I] - 1); 
                  IF ( SPEC$SUMTYPE[I] NQ KT$T"LOGICAL" ) 
                                      AND 
                     ( SPEC$SUMTYPE[I] NQ KT$T"INTEGER" ) THEN
                      BEGIN 
                      IF ( SPEC$SUMTYPE[I] EQ KT$T"NUMERICLS" ) 
                                          OR
                         ( SPEC$SUMTYPE[I] EQ KT$T"NUMERICTS" ) THEN
                          LENGTH = LENGTH - 6;
                      LENGTH = LENGTH / 6;
                      IF LENGTH GR 17 THEN S$ABORT("S$STREC-1");
                      LENGTH = CONVERTL[LENGTH] + 1;
                      END 
                  SPEC$SMLENI[I] = LENGTH;
                  IF SPEC$SUMREP[I] GR 1 THEN 
                      LENGTH = LENGTH * SPEC$SUMREP[I]; 
                  INTSUMBITS = INTSUMBITS + LENGTH; 
                  I = SPEC$NEXTSUM[I];
                  END 
  
              LK = INTSUMBITS;
  
  
              IF IRL+LK LQ BYTE*WORD THEN 
                  BEGIN 
                  REC$LS1 = LK; 
                  REC$LS2 = 0;
                  END 
              ELSE
                  BEGIN 
  
                  IF IRL LS BYTE*WORD THEN
                      BEGIN 
                      REC$LS1 = BYTE*WORD-IRL;
                      REC$LS2 = LK-REC$LS1; 
                      END 
                  ELSE
                      BEGIN 
                      REC$LS1= 0; 
                      REC$LS2 = LK; 
                      END 
                  END 
  
              IRL = IRL+REC$LS1+REC$LS2;
              END 
          ELSE
              BEGIN 
              REC$LS1 = 0;
              REC$LS2 = 0;
              END 
  
          REC$LV1 = 0;
          REC$LV2 = 0;  # NO ONE KNOWS THE PURPOSE OF THESE # 
#    SET REC$LL1 + REC$LL2 = LENGTH OF LENGTH FIELD                    #
  
          IF SPEC$FIXED THEN
              BEGIN 
              REC$LL1 = 0;
              REC$LL2 = 0;
              END 
          ELSE
              BEGIN 
              N = SPEC$MRL - SPEC$MNR;
              FOR LL = 0 WHILE N NQ 0 DO
                  BEGIN 
                  LL = LL + 1;
                  N = N / 2;
                  END 
              IF IRL + LL LQ BYTE*WORD THEN 
                  BEGIN 
                  REC$LL1 = LL; 
                  REC$LL2 = 0;
                  END 
              ELSE
              IF IRL LS BYTE*WORD THEN
                  BEGIN 
                  REC$LL1 = BYTE*WORD - IRL;
                  REC$LL2 = LL - REC$LL1; 
                  END 
              ELSE
                  BEGIN 
                  REC$LL1 = 0;
                  REC$LL2 = LL; 
                  END 
              END 
          IRL = IRL + REC$LL1 + REC$LL2;
  
#     SET REC$LF1 + REC$LF2 = LENGTH OF FIXED PART OF RECORD           #
  
          IF SPEC$FIXED THEN
              LF = BYTE*SPEC$FIXLEN;
          ELSE
              LF = BYTE*SPEC$MNR; 
  
          LF = LF - (EXTKEYBITS + EXTSUMBITS);
  
                             # ADD THE LENGTH OF THE KEYS W/OUT ALTER  #
          LF = LF + LKA;     # SINCE THOSE KEYS ARE ADDED TO THE END   #
  
          IF IRL + LF LQ BYTE*WORD THEN 
              BEGIN 
              REC$LF1 = LF; 
              REC$LF2 = 0;
              END 
          ELSE
          IF IRL LQ BYTE*WORD THEN
              BEGIN 
              REC$LF1 = BYTE*WORD - IRL;
              REC$LF2 = LF - REC$LF1; 
              END 
          ELSE
              BEGIN 
              REC$LF1 = 0;
              REC$LF2 = LF; 
              END 
          IRL = IRL + REC$LF1 + REC$LF2;
  
#     RESERVE SPACE FOR THE VARIABLE-LENGTH PORTION OF THE RECORD      #
  
          IF NOT SPEC$FIXED THEN
              IRL = IRL + BYTE*(SPEC$MRL - SPEC$MNR) + 1; 
  
#     FINALLY SET REC$IRRL                                             #
  
          REC$IRRL = (IRL - 1)/(BYTE*WORD); 
          IF NOT SPEC$FIXED THEN REC$IRRL = REC$IRRL + 1; 
  
CONTROL EJECT;
  
#     NOW THAT WE KNOW REC$IRRL (THE INTERNAL RECORD LENGTH FOR A      #
#     SLOT IN THE RECORD STORAGE AREA), WE CAN COMPUTE SPEC$LWSA.      #
#                                                                      #
#     WE SET SPEC$LWSA BASED ON THE ESTIMATED NUMBER OF RECORDS        #
#     SPECIFIED BY THE USER, AND THE OTHER CHARACTERISTICS OF THE RUN. #
#                                                                      #
#     THE USER SHOULD SET ENR TO THE ACTUAL NUMBER OF RECORDS  FOR US  #
#     TO USE A REASONABLE AMOUNT OF MEMORY.                            #
#     THE USER SHOULD SET ENR TO MORE THAN THE ACTUAL NUMBER  FOR US   #
#     TO USE MORE THAN THE USUAL AMOUNT OF MEMORY.  THIS MIGHT BE      #
#     APPROPRIATE IF THE USER KNOWS SYSTEM WORKLOAD WILL BE LIGHT.     #
#     THE USER SHOULD SET ENR TO LESS THAN THE ACTUAL NUMBER  FOR US   #
#     TO USE LESS THAN THE USUAL AMOUNT OF MEMORY.  THIS MIGHT BE      #
#     APPROPRIATE IF THE USER KNOWS SYSTEM WORKLOAD IS SO HEAVY THAT   #
#     THE USUAL JOB WILL NOT GET IN AT ALL UNLESS IT RUNS AT LESS      #
#     THAN A CERTAIN FIELD LENGTH.                                     #
#                                                                      #
#     IF THIS IS A COBOL SORT (IE. S$CALLR = 2 OR 3 AND ENR=ENRDEFAULT)#
#     THEN WE CANNOT INCREASE MEMORY BEYOND A MINIMUM AMOUNT BECAUSE   #
#     THE SPACE USED BY THE CALLER MAY PUSH THE TOTAL UNACCEPTABLY HIGH#
#                                                                      #
#     IF THIS IS A FORTRAN SORT (I.E. S$CALLR = 2 OR 3) THE USER CAN   #
#     SPECIFY ENR.  IF IT IS MORE THAN ENRDEFAULT WE WILL INCREASE     #
#     MEMORY.                                                          #
#                                                                      #
#     IF THIS IS A STAND-ALONE SORT OR MERGE (I.E. S$CALLR = 1 OR 4)   #
#     THEN WE CONTROL THE ENVIRONMENT AND CAN USE MUCH MORE MEMORY.    #
#     IN THIS CASE WE START WITH THE MINIMUM REASONABLE AMOUNT OF      #
#     MEMORY AND CLIMB SO WE REACH A PLATEAU WHERE THE TOTAL MEMORY    #
#     IS ABOUT 74000B (BECAUSE MANY SITES HAVE SEVERELY RESTRICT JOBS  #
#     USING 100000B). THIS PLATEAU IS  FOR 250,000 TO 500,000          #
#     RECORDS OF 500 CHARACTERS EACH.  BEYOND THIS RANGE MEMORY USAGE  #
#     INCREASES TO ABOUT 200000B.                                      #
#                                                                      #
#     IF ENR IS SMALL THE TENTATIVE SPEC$LWSA MAY BE SO LARGE THAT AN  #
#     IN-MEMORY SORT IS POSSIBLE (I.E. NO FINAL MERGE).  THEN WE CAN   #
#     REDUCE SPEC$LWSA TO THE SMALLEST AMOUNT THAT STILL ALLOWS THE    #
#     IN-MEMORY SORT.                                                  #
#                                                                      #
#     ANOTHER CASE OF SMALL ENR IS WHERE A FINAL MERGE IS REQUIRED     #
#     BUT WORST-CASE ORDERING OF RECORDS STILL DOES NOT REQUIRE AN     #
#     INTERMEDIATE MERGE.  THEN WE CAN REDUCE SPEC$LWSA TO THE         #
#     SMALLEST AMOUNT THAT STILL DOES NOT NEED AN INTERMEDIATE MERGE,  #
#     POSSIBLY BY ALLOWING THE NUMBER OF INTERMEDIATE STRING FILES TO  #
#     INCREASE TO THE MAXIMUM FOR THE FINAL MERGE.                     #
#                                                                      #
#     WE MUST ALSO BE ABLE TO HANDLE 5000-CHARACTER RECORDS.           #
#     CONSIDERING THE FLAK WE HAVE GOTTEN ABOUT NOT SORTING REOCRDS    #
#     LONGER THAN 5000 CHARACTERS (EVEN THOUGH WE STILL CANNOT ALWAYS  #
#     GUARANTEE TO SORT THESE SUPER-LONG RECORDS) WE SHOULD TRY TO NOT #
#     DO ANYTHING THAT UNNECCESARILY RESTRICTS SUPER-LONG RECORDS.     #
#                                                                      #
#     OUR EFFORTS TO SHRINK OUR MEMORY USAGE MUST HANDLE THE CASE      #
#     WHERE ENR IS NOT THE ACTUAL NUMBER OF RECORDS.  THE INTERMEDIATE #
#     AND FINAL MERGE PHASES MUST STILL BE EXECUTABLE, EVEN IF THEY    #
#     MIGHT NOT BE EFFICIENT.                                          #
#                                                                      #
#     OF COURSE, WE MUST BE ABLE TO HANDLE THE CASE OF A MERGE AS      #
#     WELL AS A SORT.                                                  #
  
  
          SPEC$LWSA = 16000;
          IF SPEC$SORT THEN 
              BEGIN # WE ARE DOING A SORT # 
          IF SPEC$ENRHIGH GR -1 THEN
              BEGIN  # USER SPECIFIED ENR FOR SORT #
              # NOW SET DESIRABLE SPEC$LWSA,                           #
              #  THEN CHOP IT OFF IF IT EXCEEDS MAXLWSA                #
  
              PLATLWSA = 16000 + O"10000";     # SPEC$LWSA FOR PLATEAU #
                  RATIO = (SPEC$ENRHIGH * (REC$IRRL + 1) * 1.0) / 
                          (500000 * 50); # 1.0 : AVOID INTEGER COMP.# 
              IF RATIO GR 1.0 THEN
                  BEGIN # 1,000,000 500-CHAR RECS SHOULD REACH MAXLWSA #
                  IF RATIO GR 2.0 THEN
                      SPEC$LWSA = MAXLWSA;
                  ELSE
                      SPEC$LWSA = PLATLWSA
                                + (RATIO - 1.0)* (MAXLWSA - PLATLWSA);
                  END # 1,000,000 500-CHAR RECS SHOULD REACH MAXLWSA #
              ELSE
              IF RATIO GR 0.5 THEN
                  BEGIN # BETWEEN 250,000 AND 500,000 500-CHAR RECORDS #
                  SPEC$LWSA = PLATLWSA;  # AIM FOR JUST LESS THAN 100K #
                  END # BETWEEN 250,000 AND 500,000 500-CHAR RECORDS   #
              ELSE
                  BEGIN # LESS THAN 250,000 500-CHAR RECORDS #
  
                  # TRY TO REDUCE SPEC$LWSA FOR SHORT SORTS            #
                  #  (THIS CODE PARALLELS SOME CODE IN S$ALCS)         #
                  IF SPEC$FIXED THEN
                      LOREC = (SPEC$FIXLEN + WORD - 1)/WORD;
                  ELSE
                      LOREC = (SPEC$MRL + WORD - 1)/WORD + 1; 
                      # (S$GNCVE MAY CLOBBER LAS WORD + 1) #
             # COMPUTE SIZE OF CIO-BUFFER  FOR COMMENT SEE S$ALCS # 
  
                  IF (REC$IRRL + 1) GR PRU THEN 
                      BEGIN 
                      LMAX = REC$IRRL + 1;
                      LMIN = PRU; 
                      END 
                  ELSE
                      BEGIN 
                      LMAX = PRU; 
                      LMIN = REC$IRRL + 1;
                      END 
                  # LOWEST BUFFERSIZE GREATER LCIOB # 
                  USED = ((((LCIOB - LMIN) + (LMAX -1))/LMAX) * LMAX
                              + LMIN) 
                              + LOREC + (PRU + 1 + FET);
                  UNUSED = SPEC$LWSA - USED;
                  LTRN = UNUSED / (REC$IRRL + 1); 
                  LTRN = LTRN - 1;  # FOR WINNER #
                  IF LTRN GR SPEC$ENRHIGH THEN
                      BEGIN # IF ENR IS RIGHT, NO FINAL MERGE NEEDED #
                      # REDUCE SPEC$LWSA TO COMPLETELY FILL TOURNAMENT #
                      SPEC$LWSA = USED +
                      (SPEC$ENRHIGH + 2) * (REC$IRRL + 1) + 
                       100; # (JUST IN CASE!) # 
                      END # IF ENR IS RIGHT, NO FINAL MERGE NEEDED #
                  ELSE
                  IF 14 * LTRN GR SPEC$ENRHIGH THEN 
                      BEGIN # (ABOVE "14" IS MAXIMUM NUMBER OF FILES   #
                            #  INTO FINAL MERGE PHASE - SEE S$MGDSN.)  #
                            # IF ENR IS RIGHT, REVERSE-ORDER INPUT FILE#
                            #  WILL PRODUCE <= 14 STRING FILES, SO     #
                            #  INTERMEDIATE MERGE IS NOT NECESSARY.    #
                      # REDUCE SPEC$LWSA SO EXACTLY 14 STRINGS FORMED  #
                      SPEC$LWSA = USED +
                      (SPEC$ENRHIGH/14 + 2) * (REC$IRRL + 1) +
                       100; # (JUST IN CASE!) # 
                      END # JUST REDUCED SPEC$LWSA AND STILL AVOIDED   #
                          #  AN INTERMEDIATE MERGE.                    #
                  END # LESS THAN 250,000 500-CHAR RECORDS #
  
              # IF SPEC$LWSA CANNOT HANDLE LARGE RECORDS, INCREASE IT  #
                  END # SPEC$ENRHIGH SPECIFIED #
  
          # LWSA SHOULD BE LARGE ENOUGH FOR ALL SORTPHASES #
          # MOST MEMORY IS NEEDED AT FINAL MERGE #
          # MINIMUM BUFFERSIZE IS REC$IRRL + 1 + PRU  # 
          # MEMORY FOR TOURNAMENT = 14 * (REC$IRRL + 1) # 
          # MEMORY FOR OUTPUT-RECORD = SPEC$MRL BYTES # 
  
              MINLWSA = 28 * REC$IRRL + 14 * PRU + SPEC$MRL/WORD
                         + 100; 
              MINLWSA = MINLWSA + 500; # SPEC$LWSA WILL BE REDUCED #
                 # LEAVE ENOUGH MEMORYWORDS FOR WSA IF CODE   # 
                 # OF FINAL MERGE IS LARGER THAN INITIAL# 
              IF MINLWSA LS 5500 THEN MINLWSA = 5500; 
                  # LOWER WSA DOESNOT REDUCE MAXFL AND GIVES #
                  # ALMOST NO PERFORMANCE IMPROVEMENT AND IS #
                  # EXPENSIVE IF MUCH MERGING WILL BE DONE   #
                  # USER GETS MINIMAL WORKABLE WSA IF ENR = 1#
              IF SPEC$LWSA LS MINLWSA THEN
                  SPEC$LWSA = MINLWSA;
              END # WE ARE DOING A SORT # 
          ELSE
              BEGIN # WE ARE DOING A MERGE #
              SPEC$LWSA = 16000;      # WHAT IT WAS BEFORE THIS MOD... #
              END # WE ARE DOING A MERGE #
  
          # AT THIS POINT, CHECK IF WE HAVE ENOUGH SPACE               #
          # MAXFREE IS PASSED FROM S$SRTPH                             #
  
          IF SPEC$LWSA GR MAXFREE THEN
             SPEC$LWSA = MAXFREE; 
  
          $BEGIN
          LINE = " SPEC$LWSA="; 
          C<11,10>LINE = DEC(SPEC$LWSA);
          C20 = OCT(SPEC$LWSA); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
          $END
CONTROL EJECT;
  
          $BEGIN
          FOR I = SPEC$1STSUM WHILE I NQ 0 DO 
              BEGIN 
              LINE = " SPEC$SUMTYPE[***]=**********"; 
              C10 = DEC(I); 
              C<14,3>LINE = C<0,3>C10;
              C<19,10>LINE = DEC(SPEC$SUMTYPE[I]);
              S$PRTCD(LINE);
              LINE = " SPEC$SUMBIT[***]=**********";
              C<13,3>LINE = C<0,3>C10;
              C<18,10>LINE = DEC(SPEC$SUMBIT[I]); 
              S$PRTCD(LINE);
              LINE = " SPEC$SMLENE[***]=**********";
              C<13,3>LINE = C<0,3>C10;
              C<18,10>LINE = DEC(SPEC$SMLENE[I]); 
              S$PRTCD(LINE);
              LINE = " SPEC$SUMREP[***]=**********";
              C<13,3>LINE = C<0,3>C10;
              C<18,10>LINE = DEC(SPEC$SUMREP[I]); 
              S$PRTCD(LINE);
              LINE = " SPEC$SUMOFF[***]=**********";
              C<13,3>LINE = C<0,3>C10;
              C<18,10>LINE = DEC(SPEC$SUMOFF[I]); 
              S$PRTCD(LINE);
              LINE = " SPEC$SMLENI[***]=**********";
              C<13,3>LINE = C<0,3>C10;
              C<18,10>LINE = DEC(SPEC$SMLENI[I]); 
              S$PRTCD(LINE);
              LINE = " SPEC$NEXTSUM[***]=**********"; 
              C<14,3>LINE = C<0,3>C10;
              C<19,10>LINE = DEC(SPEC$NEXTSUM[I]);
              S$PRTCD(LINE);
              I = SPEC$NEXTSUM[I];
              END # FOR # 
          LINE = " LR=";
          C<5,10>LINE = DEC(REC$LR);
          C20 = OCT(REC$LR);
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LK1="; 
          C<5,10>LINE = DEC(REC$LK1); 
          C20 = OCT(REC$LK1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LK2="; 
          C<5,10>LINE = DEC(REC$LK2); 
          C20 = OCT(REC$LK2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LO1="; 
          C<5,10>LINE = DEC(REC$LO1); 
          C20 = OCT(REC$LO1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LO2="; 
          C<5,10>LINE = DEC(REC$LO2); 
          C20 = OCT(REC$LO2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LS1="; 
          C<5,10>LINE = DEC(REC$LS1); 
          C20 = OCT(REC$LS1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LS2="; 
          C<5,10>LINE = DEC(REC$LS2); 
          C20 = OCT(REC$LS2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LV1="; 
          C<5,10>LINE = DEC(REC$LV1); 
          C20 = OCT(REC$LV1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LV2="; 
          C<5,10>LINE = DEC(REC$LV2); 
          C20 = OCT(REC$LV2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LL1=" ;
          C<5,10>LINE = DEC(REC$LL1); 
          C20 = OCT(REC$LL1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LL2="; 
          C<5,10>LINE = DEC(REC$LL2); 
          C20 = OCT(REC$LL2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LF1="; 
          C<5,10>LINE = DEC(REC$LF1); 
          C20 = OCT(REC$LF1); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " LF2="; 
          C<5,10>LINE = DEC(REC$LF2); 
          C20 = OCT(REC$LF2); 
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          LINE = " IRRL=";
          C<6,10>LINE = DEC(REC$IRRL);
          C20 = OCT(REC$IRRL);
          C<20,6>LINE = C<14,6>C20; 
          S$PRTCD(LINE);
  
          S$PRTCD(0); 
          $END
  
          END  # S$STREC #
          TERM
