*DECK QUSORT
          IDENT  QUSORT 
          COMMENT  CALLING INTERFACE TO SORT/MERGE
QUSORT    TITLE  QUSORT - CALLING INTERFACE TO SORT/MERGE 
          SYSCOM             SO CAN ACCESS SYMBOLS RA.LWP AND RA.SSW
          LIST   -L          *CALL ENVIRON FOLLOWS
*CALL ENVIRON 
          LIST   L
*CALL MACRO 
          LIST   -L          *CALL NUMOPT FOLLOWS 
*CALL NUMOPT
          LIST   L
          SPACE  5,5
          LIST   F
USESORT4  IFEQ   SORT5,ABSENT 
*  PARAMETERS TO THE SORT MODULE ARE PASSED FROM THE SYNTAX OVERLAYS
*  INTO A TABLE IN HIGH CORE.  THE TABLE ADDRESS IS IN -SORTBL-.
*  THE LAYOUT OF THE PARAMETER TABLE IS 
*         1)     ADDRESS OF INPUT FILE FIT
*         2)     ADDRESS OF OUTPUT FILE FIT (MAY BE SAME AS INPUT)
*         3)     SORT KEYS
*         4)     COLLATING SEQUENCE (1 TO 64 CHARACTERS, 10 CHARS/WORD) 
*         5)     COLLATING LITERAL LENGTH 
          USE    /SORTBL/ 
SORTBL    BSS    0           ADDRESS OF SORT TABLE
INPUT     EQU    0                 INPUT POINTER IN SORT KEY BUFFER 
OUTPUT    EQU    INPUT+1          OUTPUT POINTER IN SORT KEY BUFFER 
KEY       EQU    OUTPUT+1          KEY   POINTER IN SORT KEY BUFFER 
SEQ       EQU    KEY+201           SEQ   POINTER IN SORT KEY BUFFER 
SEQCNT    EQU    SEQ+8            SEQCNT POINTER IN SORT KEY BUFFER 
          USE    0
* 
INFIT     FILE   FO=SQ       FIT FOR INPUT FILE TO SORT 
OUTFIT    FILE   FO=SQ       FIT FOR OUTPUT SORTED FILE. MAY BE SAME
*                            AS INPUT FILE. 
  
 SMCAPS   EQU    5670B       APPROXIMATE SIZE REQUIRED FOR ALL THE SORT 
                             CAPSULES. THIS VALUE, WHEN ADDED TO THE GAP
                             AVAILABLE BELOW HHA, GIVES THE SIZE WE PASS
                             TO SORT IN THE S.SRTSZ CALL. SORT WILL 
                             USE PART OF THIS SPACE FOR DATA, AND PART
                             FOR CAPSULES. THE TRICK IS TO TELL SORT THE
                             RIGHT SIZE SUCH THAT IT WILL REQUEST THE 
                             DATA BLOCK SIZE THAT FITS IN OUR GAP BELOW 
                             HHA. *SMCAPS* SHOULD BE @ *MAXCAPS* AS 
                             DEFINED IN *MACPRO* OF SORT/MERGE. 
          EJECT 
*  FOLLOWING ARE SKELETON OF SORT MACROS EXPANSION. 
*  ACTUAL PARAMETERS ARE FETCHED FROM THE TABLE IN HIGH CORE AND
*  PATCHED INTO THE SKELETON.  THE REMAINING EMPTY SLOTS ARE THEN 
*  SQUEEZED OUT.
          SPACE  2
SORTIT    RJ     =XSMCON7 
          DATA   10H END SORT 
          DATA   10H OPTIONS                                            000530
          DATA   0                 TURN OFF VERIFY OPTION               000540
          DATA   1                 TURN ON RETAIN OPTION                000550
          DATA   0                 TURN OFF VOLDUMP OPTION              000560
          DATA   0                 TURN OFF NODUMP OPTION               000570
          DATA   0                 TURN OFF (DUMP,NN) OPTION            000580
          DATA   1                 TURN ON COMMON OPTION                000590
          DATA   10HENDOPTIONS                                          000600
          DATA   10H  FILES 
FILEIN    DATA   0
          VFD    3/2,3/2,36/0,18/INFIT   INPUT FILE, CLOSE NO REW AT END
FILEOUT   DATA   0
          VFD    3/1,3/2,36/0,18/OUTFIT OUTPUT FILE, CLOSE NO REW AT END
          DATA   10H END FILES
BEGKEY    DATA   10H   KEY
          BSSZ   248               ROOM FOR UP TO 25 KEYS 
ENDKEY    DATA   10H END KEY
BEGSEQ    DATA   10H SEQUENCE 
          BSSZ   65 
ENDSEQ    DATA   10H END  SEQ 
  
 OC=BEGIN BSS    0           BEGINNING OF TABLES FOR -UNIQUE- PROCESSING
          DATA   H*   KEY*         BEGINNING OF KEY TABLE 
          DATA   1                 STARTING CHAR POSITION  (LEFT MOST)
          DATA   1                 STARTING BIT  POSITION  (LEFT MOST)
 OC=MRL1  DATA   0                 NUMBER OF WHOLE BYTES (FILL WITH MRL)
          DATA   0                 NUMBER OF BITS LEFT OVER 
          DATA   5                 KEY TYPE - 5 MEANS *DISPLAY* 
          DATA   H*DISPLAY*        COLLATING SEQUENCE - DISPLAY CODE
          DATA   0                 ASCEND/DESCEND - 0 FOR ASCENDING 
          DATA   0                 SIGN - 0 FOR NO SIGN 
          DATA   H* END KEY*       END OF KEY TABLE 
  
          DATA   H* OWNCODE*       BEGINNING OF OWNCODE TABLE 
 OC=MRL2  DATA   0                 MRL OF INPUT FILE
          VFD    30/CHKUNIQ,30/5   EXIT 5 FOR PROCESSING DUPLICATE KEYS 
          DATA   H*ENDOWNCODE*     END OF OWNCODE TABLE 
 OC=LENG  EQU    *-OC=BEGIN  LENGTH OF TABLES FOR PROCESSING -UNIQUE- 
  
  
JPLOAD10  JP     LOAD10            INSTRUCTION TO RESTART US WHEN SORT DONE 
*         --
 LOAD10   SX6    1
          SA6    PRIMARY
          SX7    B0 
          SA7    SECONDY
          RJ     =XLOADX0          GET OUT OF OVERLAY 
          EJECT 
*  THIS IS THE PLACE WHERE THE PARAMETERS ARE PLACED INTO THE SKELETON. 
          ENTRY  QUSORT 
QUSORT    JP   *+400000B
* 
          SA1    SORTBL      GET PARAMETER TABLE ADDRESS
          SA2    X1+INPUT    GET INPUT FIT ADDRESS
          SB2    FILEIN 
          SB3    INFIT
          RJ     SETFILE     MOVE FROM FIT TO LOW CORE
* 
          SA1    SORTBL 
          SA2    X1+OUTPUT   GET OUTPUT FILE ADDRESS
          SB2    FILEOUT
          SB3    OUTFIT 
          RJ     SETFILE     MOVE TO-FIT TO LOW CORE
* 
          SB1    1
          SB3    6           EACH KEY ENTRY IN HIGH CORE HAS 6 WORDS
          SA1    SORTBL 
          SA1    X1+KEY-1    POINT A1 ONE WORD BEFORE KEY PARAM 
          SB6    BEGKEY-1    POINT B6 ONE WORD BEFORE -KEY- MACRO 
          SB4    8                 LIMIT OF WORDS PER KEY 
MOVEKEY   SA2    BEGKEY            READ UP THE WORD KEY 
          BX6    X2 
          SB6    B6+B1
          SA6    B6 
          SB5    B0                CNT OF WORDS PER KEY 
MOVEPAR   SB5    B5+B1             INCREMEMT CNT
          NE     B5,B3,SKIP 
          SA4    SORTBL 
          SA4    X4+SEQ            GET NAME OF COLUMN SEQ 
          BX6    X4 
          SA1    A1+B1
          EQ     JUMP 
*         --
SKIP      SA1    A1+B1             READ UP NEXT PARAM 
          BX6    X1 
JUMP      SB6    B6+B1
          SA6    B6 
          NE     B5,B4,MOVEPAR
* 
*   IF CNT = LIMIT,READ NEXT WORD AND LOOK FOR END KEY
* 
          SA4    ENDKEY 
          BX6    X4 
          SA5    A1+B1             READ UP NEXT WORD
          IX4    X6-X5
          SB6    B6+B1       UPDATE POINTER TO END OF LIST
          SA6    B6          (X6) = 10H END KEY 
          NZ     X4,MOVEKEY        GO MOVE ANOTHER KEY
          SA1    BEGSEQ 
          BX6    X1 
          SA6    A6+B1             STORE BEG OF SEQUENCE TABLE
          SA1    SORTBL 
          SA1    X1+SEQ            GET SEQ NAME 
          BX6    X1 
          SA6    A6+B1             STORE SEQ NAME IN SORT TBL 
          MX0    6                 A CHAR MASK
          SA2    A1+8              READ UP CHAR COUNT 
          LX0    6
          SB6    X2-1              B6= CHAR CNT 
          SB6    X2                B6= CHAR CNT 
          SB3    10          CHAR PER WORD LIMIT
LOOP      SA1    A1+B1
          SB4    B0                CHARS PER WORD COUNT 
LOOP1     LX1    6
          BX6    X1*X0             MASK OUT ONE CHAR
          SA6    A6+B1             STORE ONE CHAR PER WORD
          SB6    B6-1              SUBTRACT 1 FROM CHAR CNT 
          EQ     B6,B0,OUT         FINISHED 
          SB4    B4+B1
          NE     B4,B3,LOOP1
          EQ     LOOP 
*         --
OUT       MX5    1
          LX5    59 
          IX6    X5+X6             SET BIT 58 OF LAST CHAR
          SA6    A6                STORE
          SA4    ENDSEQ 
          BX6    X4 
          SA6    A6+B1
          SX5    A6+B1             (X5) = ADDR OF NEXT WORD TO FILL 
          SA1    =XSORTUNI         EXTERNAL ITEM -SORTUNIQUE- 
          ZR     X1,NO.UNIQ        IF NO UNIQUE PROCESSING
          SA1    SORTBL      (X1) = FWA OF SORT TABLES
          SA1    X1+INPUT    (X1) = ADDR OF INPUT FIT 
          FETCH  X1,MRL,X6,4   FETCH MRL OF INPUT FIT INTO X6 
          SA6    OC=MRL1           STORE MRL IN KEY TABLE 
          SA6    OC=MRL2           STORE MRL IN OWNCODE TABLE 
          MOVE   OC=BEGIN,OC=LENG,X5   MOVE THE TABLE INTO POSITION 
          SX5    X5+OC=LENG        (X5) = ADDR OF NEXT WORD TO FILL 
NO.UNIQ   SA1    JPLOAD10          (X1) = JP INSTR. TO GET US RESTARTED 
          BX6    X1 
          SA6    X5                STORE JP AT END OF TABLES FOR SORT 
          MX0    42D
          SA1    RA.LWP      (X1) = 42/STUFF,18/-DABA 
          BX1    -X0-X1      (X1) = DABA
          SA2    RA.SSW+104B       (X2) = 42/STUFF,18/HHA 
          BX2    -X0*X2      (X2) = HHA 
          IX6    X2-X1       (X6) = GAP BETWEEN HHA AND DABA
          SX6    X6-6        (X6) = GAP, BUT LEAVING ROOM FOR CMM 
          SX6    X6+SMCAPS   (X6) = SIZE OF BUFFER TO REQUEST FROM SORT 
*                                   SUCH THAT MOST OF GAP IS USED.
          SA6    SORTBUF     STORE FOR CALL TO S.SRTSZ
          SX1    SORTBUF     LOCATION CONTAINING SIZE OF SORT BUFFER
          RJ     =XS.SRTSZ   SET BUFFER SIZE
          RJ     =XS.BELOW   USE BUFFER SPACE BELOW HHA 
          SA1    ASORTBL     ADDRESS OF SORT BLOCK
          RJ     =XCMM$FRF   FREE BLOCK 
          SX6    0
          SA6    SORTBL      CLEAR INDICATOR WE HAD CM
          EQ     SORTIT 
*         --
ASORTBL   VFD    60/SORTBL   ADDRESS OF SORT TABLE FOR FREECM CALL
SORTBUF   CON    0           CONTAINS BUFFER SIZE FOR SORT (0=DEFAULT)
* 
* 
*  THIS PROCEDURE PLACES THE FILE NAME IN THE -FILES- MACRO SKELETON, 
*  MOVES THE FIT FROM HIGH TO LOW CORE, CLEANS UP THE FIT 
*  ENTRY PARAMETERS ARE 
*                X2 = A(FIT) IN HIGH CORE (FROM-FIT)
*                B2 = A(FILES MACRO) WHERE TO PLACE THE FILE NAME 
*                B3 = A(FIT) IN LOW CORE  (TO FIT)
SETFILE   DATA   0
          MX0    42 
          SA2    X2          GET LFN
          BX6    X0*X2       CLEAR TRAILING BITS IN LFN 
          SA6    B2          STORE LFN IN -FILES- MACRO SKELETON
          SX3    B3                (X3) = NEW FIT ADDR  (MOVE PRESERVES)
          MOVE   A2,LFIT,X3  MOVE THE FIT TO LOW CORE 
          SX6    0           TO CLEAR SOME FIT FIELD
          STORE  X3,FWB=0    TO GET NEW ADJUSTED BUFFERS
          STORE  X3,LT=UL    INSURE MASS STORAGE FILES ONLY 
          EQ     SETFILE
*         --
          EJECT 
CHKUNIQ   TITLE  SORT OWNCODE TO ELIMINATE DUPLICATE RECORDS
**        CHKUNIQ - ELIMINATES DUPLICATE RECORDS
* 
*              THIS ROUTINE IS CALLED WHEN SORT FINDS TWO RECORDS WHOSE 
*         KEYS MATCH EXACTLY. SINCE THE TABLES FOR THE PROCESSING OF
*         THE -UNIQUE- OPTION SPECIFY THE ENTIRE RECORD AS A KEY, THIS
*         ROUTINE IS CALLED ONLY IF THE RECORDS ARE EXACTLY THE SAME. 
* 
* 
*         ENTRY  - (A2) = ADDR OF RECORD.1
*                  (X0) = 30/CHLENGTH.1,30/WDLENGTH.1 
*                  (A3) = ADDR OF RECORD.2
*                  (X4) = 30/CHLENGTH.2,30/WDLENGTH.2 
* 
*         EXIT   JUMP TO RETURN ADDRESS+1 TO ELIMINATE DUPLICATE RECORD 
* 
*         USES   A - 1
*                X - 1
*                B - 2
* 
*         CALLS  NONE 
  
  
 CHKUNIQ  SUBR               ENTRY... EXIT IS THROUGH B2
          SA1    CHKUNIQ           (X1) = 30/EQ RTN ADDR, 30/0
          AX1    30D
          SB2    X1+1              (B2) = RTN ADDR + 1
          JP     B2                JUMP TO ELIMINATE DUPLICATE RECORD 
  
USESORT4  ENDIF 
          SPACE  4
          END 
