* 02/13/76 -- 14:00
* MODULE NAME: INDEX
* NUMBER: 16
* PURPOSE: COMPILE AN INDEX OR TABLE OF CONTENTS
*
* ENTRY POINTS:
         DEF      C16INDEX
*
*
* EXTERNAL REFERENCES:
         REF      S27RHDR           READ HDR RECORD
         REF      S27RTXT           READ TEXT RECORD
         REF      S27RCPY,S27WCPY   READ/WRITE INDEX FILE
         REF      S03SETPR,S03RELPR OPEN/RELEASE PRINT (INDEX) FILE
         REF      S03OPNPR,S03CLSPR OPEN/CLOSE PRINT (INDEX) FILE
         REF      S27PRINT          PRINT A RECORD TO TERMINAL
         REF      S08FNDPG          CONVERT LINE KEY TO PAGE NO.
         REF      S35LINE           CONVERT LINE KEY TO LINE NO. EBCDIC
         REF      S35CNVRT          CONVERT LINE NO. TO EBCDIC
         REF      S07RDTAG          READ TAG RECORD
         REF      S15SINDX,S15XINDX READ AUXILIARY 'FILES'
         REF      S05LOC            SEARCH A LINE FOR A PHRASE
         REF      S12WRD            GET A WORD FROM A LINE
         REF      S07HASH           HASH A WORD TO GET A KEY
         REF      S09RDATN          READ ATTN-ATTN SEQUENCE
         REF      S29STD            RTN TO PRINT MESSAGES AT TERMINAL
         REF      FILEFLG           FILE OUTPUT FLAG
         REF      BATCHFLG          BATCH MODE FLAG
         REF      PRINTBRK          BREAK ROUTINE ADDR
*
*
         SYSTEM   TEXTDEF
         SYSTEM   ITEMDEF
*
*
            INVAFSTA
            INVCMDSTA
            INVWSSTA
            INVHDRSTA
         INVPRSTA
         PAGE
*
*
*
         DEF      16P,16D
*
16P      EQU      %
         DATA     X'16'             MODULE NUMBER
         DATA     X'021376'         DATE
         DATA     X'1100'           TIME
*
*
            INVTAGSTA
*
         TITLE    '** INDEX (16) **'
         PAGE
*
*********************************************************************
*********************************************************************
*
C16INDEX EQU      %                 ENTRY POINT
*
*
*          SAVE LINK REGISTER
           SAVRTN
*
         BAL,SRTN S03RELPR          RELEASE PRINT (INDEX) FILE
         LI,AC1   #OUT
         BAL,SRTN S03OPNPR          RE-OPEN PRINT FILE OUT
         LI,AC1   #SAVE
         BAL,SRTN S03CLSPR          SAVE EMPTY FILE FOR INOUT OPEN
*
         LI,D1    0                 IF BATCH MODE
         STB,D1   BATCHFLG          OUTPUT THRU M:LO
         LW,D1    FILEFLG           IF FILE MODE
         STB,D1   FILEFLG           OUTPUT THRU M:LO
*
*
*        GET LINE WIDTH FOR DOCUMENT
         GET,D1   #WIDTH            GET WIDTH
         STW,D1   WIDTH             SAVE IT IN'WIDTH'
*
*
*        GET INVOKE COMMAND OPTIONS
         LI,X1    4
LOOP     EQU      %
         JNEZ,D1  (#FLAGS,X1),SAVEOPTN
         BDR,X1   LOOP
SAVEOPTN EQU      %
         STW,X1   TYPEOPTN          SAVE IT
*
*
*        GET LINE # OPTN & SET UP 1ST PG # IF REQD
         GET,D1   #FLAGS,:K(5)      GET LINE NO. OPTION FLAG
         STW,D1   LINEOPTN            SAVE IT IN LINEOPTN
         CI,D1    0                 TEST IT
         BNE      OPENPRNT          BRANCH IF SET
*
         JEZ,D1   (#DSHW,:K(1)),PG1 BRANCH IF NO 1ST PG # GIVEN
         LCW,D1   D1                -(GIVEN PG #)
         STW,D1   AC2               TRANSFER IT TO AC2
         B        CALL
*
PG1      EQU      %                 NO 1ST PG # GIVEN
         LI,AC2   -1                1ST PG IS PG #1
*
CALL     EQU      %                 CALL S08FNDPG TO FORMAT DOC
         GET,D1   #FKEY               1ST LINE IN DOC
         BAL,SRTN S08FNDPG
         B        CONT
OPENPRNT EQU      %
         BAL,SRTN S03SETPR          OPEN PRINT (INDEX) FILE
         LI,D1    -1
         PUT,D1   PR:LPFLG          SET LP FLAG TO INDEX
         BRKCTRL  PRINTBRK          SET BREAK ROUTINE FOR INDEX BY LINE
CONT     EQU      %
*
*
*
*
         LW,D1    L(#TAGKEY)        INITIALIZE TITLEKEY
         STW,D1   TITLEKEY
         LW,D1    L(#OVFLKEY)       AND OFLOKEY
         STW,D1   OFLOKEY
*
*        GET TWO BUFFERS
*
         LI,BUF1  BA(STDX1BUF)      FIRST BUFFER
         STW,BUF1 BATAGBUF           BA(BUFFER) TO BATAGBUF
*                                       (ALSO BATXTBUF,BAOFLOBF)
         SLS,BUF1 -2
         STW,BUF1 TAGBUF             WA(BUFFER) TO TAGBUF (SETS UP
*                                    DATADEF ITEMS TAG:TYPE,TAG:NCTAG)
*
         LI,BUF1  BA(STDX2BUF)      SECOND BUFFER
         STW,BUF1 BANDXBUF           BA(BUFFER)
         SLS,BUF1 -2
         STW,BUF1 NDXBUF            WA(BUFFER)
*
*
*        BRANCH ACCORDING TO INDEX TYPE
         LW,X1    TYPEOPTN
         B        %,X1
         B        FULLNDX           FULL INDEX
         B        BLKNDX            BLOCK INDEX
         B        TAGNDX            INDEX-TAG INDEX
         B        TTLNDX            TITLE-TAG INDEX (TABLE OF CONTENTS)
*
         PAGE     FULL INDEX
*
*********************************************************************
*********************************************************************
*
FULLNDX  EQU      %
*
*
         GET,D1   #FKEY             GET KEY OF FIRST LINE IN DOC
         STW,D1   AC2                 TRANSFER IT TO AC2
NXTLINE  EQU      %
         LW,BUF2  BATXTBUF
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RTXT           READ A DOCUMENT LINE
         CI,AC1   0                 IF AC1=0, EOF
         BLE      DUMP
*
         STW,AC2  TXTKEY            SAVE KEY OF LINE
*
*
         JEZ,D1   (AF:NXTPG,:K(2)),EXCLNDX    BRANCH IF NO 'S' FILE
         PAGE     FULL INDEX WITH 'S' (SELECTED WORD) AUX. FILE
*
*
***********************************************************************
************************************************************************ *
*
*
         STW,AC1  TXTPTR            SAVE # CHARS IN LINE
         LI,X1    -1
*
*
*        GET A WORD FROM 'S' FILE
*
*
NXTWD2   EQU      %
         BAL,SRTN S15SINDX          GET WORD/PHRASE FROM 'S' FILE
         CI,AC1   0                   IF AC1=0, NO MORE WDS IN 'S' FILE
         BLE      RESETTXT
*                 SEARCH TEXT LINE FOR 'S' WORD/PHRASE
         STW,X1   X2                BA('S' FILE WORD/PHRASE) TO X2
         STB,AC1  X2                PUT # CHARS IN FIRST BYTE OF X2
         STW,X2   SAVEX2              SAVE IT
         LW,X1    BATXTBUF          ADDR OF TEXT LINE TO SEARCH
         LW,AC1   TXTPTR            LENGTH OF LINE
SRCHLINE EQU      %
         BAL,SRTN S05LOC
         CI,AC2   0                 IF AC2 =0,    PHRASE NOT FOUND
         BG       FOUND             GO GET NEXT 'S' FILE WORD/PHRASE
         LI,X1    0                 SET X1=0 FOR READ NEXT 'S' WORD
         B        NXTWD2            GO READ IT
*
*
FOUND    EQU      %                 'S' WD/PHRASE FOUND ON LINE TXTKEY
         STW,X1   BAWORD            SAVE BA('S' WORD/PHR ON TEXT LINE)
         SW,X1    BATXTBUF          CALC DISP OF WORD ON LINE
         STW,X1   BPTR                SAVE IT
*
*
*                 FIRST CHECK IF WORD/PHRASE IS ISOLATED
         LW,X1    BAWORD
         AI,X1    -1                TEST CHAR BEFORE WORD/PHRASE
         LB,D1    0,X1
         CI,D1    LC('A')           LOWER CASE 'A'
         BGE      TRYAGAIN          TRY AGAIN TO FIND 'S' WORD/PHRASE
         AI,X1    1                 TEST CHAR AFTER WORD/PHRASE
         AW,X1    AC2
         LB,D1    0,X1
         CI,D1    LC('A')           LOWER CASE 'A'
         BGE      TRYAGAIN          TRY AGAIN TO FIND 'S' WORD/PHRASE
*
*                 WORD/PHRASE IS ISOLATED
         STW,AC2  NCHARS            SAVE # CHARS IN WORD/PHRASE
*
         BAL,SRTN S16HASH           GET/CREATE INDEX REC FOR WORD/PHRASE
*
         BAL,SRTN S16NMBR           GET LINE/PAGE NO. EBCDIC
*
         BAL,SRTN S16ADD            ADD REF. TO INDEX
*
*
TRYAGAIN EQU      %
         LW,X1    BAWORD            CALC NEW STARTING ADDR
         AW,X1    AC2
         LW,AC1   BATXTBUF          CALC CHARS LEFT IN TXTBUF
         AW,AC1   TXTPTR
         SW,AC1   X1
         LW,X2    SAVEX2            RESTORE 'S' WORD ADDR & COUNT
         B        SRCHLINE
         PAGE     FULL INDEX WITHOUT 'S' (SELECTED WORD) AUXILIARY FILE,
*                 WITH OR WITHOUT 'X' (EXCLUDE-FROM-INDEX) AUX. FILE
*********************************************************************
*********************************************************************
*
EXCLNDX  EQU      %
*
*
         LW,X2    BATXTBUF          SET TXTPTR AT 1ST CHAR OF LINE
         AI,X2    1                   SKIP CONTROL BYTE
         STW,X2   TXTPTR              STORE IT
         AI,AC1   -1                DECREMENT CHAR COUNTER FOR CTRL BYTE
         STW,AC1  CHARSLFT            SAVE IT
*
*
*        GET A WORD ON THE DOCUMENT LINE
*
*
NXTWRD   EQU      %                 GET A WORD FROM TXTBUF
         LW,AC1   CHARSLFT
         LW,X1    TXTPTR
         BAL,SRTN S12WRD
         CI,AC2   0                 IF AC2=0, NO MORE WORDS ON THIS LINE
         BLE      RESETTXT            GO GET ANOTHER LINE
*
         STW,X2   TXTPTR            SAVE X2=BA(NEXT CHAR AFTER THIS WD)
         STW,X1   BAWORD            SAVE X1=BA(1ST CHAR IN WORD FOUND)
         STW,AC2  NCHARS            SAVE AC2=# CHARS IN WORD FOUND
         STW,AC1  CHARSLFT          SAVE AC1=# CHARS LEFT IN LINE
*
TST1ST   EQU      %                 IF 1ST CHAR OF WORD IS NOT
         LW,X3    BAWORD              ALPHANUMERIC, PEEL IT OFF
         LB,D1    0,X3
         CI,D1    LC('A')
         BGE      TSTLAST
         MTW,1    BAWORD
         MTW,-1   NCHARS
         BLEZ     NXTWRD
         B        TST1ST
TSTLAST  EQU      %
         LW,X3    NCHARS            IF LAST CHAR OF WORD IS NOT
         AW,X3    BAWORD              ALPHANUMERIC, PEEL IT OFF
         AI,X3    -1
         LB,D1    0,X3
         CI,D1    LC('A')
         BGE      ALPHA
         MTW,-1   NCHARS
         B        TSTLAST
*
*
*        IS THIS WORD IN 'X' FILE?
*
*
ALPHA    EQU      %
*
         JEZ,D1   (AF:NXTPG,:K(3)),HASH      BRANCH IF NO 'X' FILE
         LW,X1    BAWORD            FIND OUT IF WORD IS IN 'X' FILE
         LW,AC1   NCHARS
         BAL,SRTN S15XINDX
         CI,AC1   0                   IF AC1 NOT=0, WORD IS IN 'X' FILE,
         BNEZ     NXTWRD              GO GET NEXT WORD ON THIS LINE
*
*
HASH     EQU      %
         LW,D1    BAWORD            CALC DISP. OF WORD ON LINE
         SW,D1    BATXTBUF
         AI,D1    -1
         STW,D1   BPTR                SAVE IT
*
*
         BAL,SRTN S16HASH           GET/CREATE INDEX REC. FOR THIS WORD
*
*
         BAL,SRTN S16NMBR           GET LINE/PAGE NO. FOR THIS REF.
*
         BAL,SRTN S16ADD            ADD IT TO INDEX BUFFER AND WRITE IT
*
         B        NXTWRD
*
*
RESETTXT EQU      %                 RESET READ-NEXT PTR FOR TEXT FILE
         LI,AC2   0                   SET AC2=0 FOR READ NEXT
         B        NXTLINE
         PAGE
*
**********************************************************************
***********************************************************************
*
S16HASH  EQU      %
*
*
*    CALLED BY    BAL,SRTN   S16HASH
*     IN:  BAWORD=BA(WORD/PHRASE TO BE HASHED)
*          NCHARS=NUMBER OF CHARS IN WORD/PHRASE
*     OUT: INDEXKEY=KEY OF INDEX RECORD CONTAINING THIS WORD
*          INDEXPTR=NUMBER OF CHARS IN NDXBUF
*
*
         SAVRTN
*
         LW,X1    BAWORD
         LW,AC1   NCHARS
         BAL,SRTN S07HASH           GET A HASHED KEY
RDHASH   EQU      %
         STW,AC2  INDEXKEY          SAVE IT
         LW,BUF2  BANDXBUF
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY           READ AN INDEX RECORD
         CI,AC2   0                 IF AC2=0, NO SUCH RECORD
         BLE      BUILD               GO BUILD ONE
         STW,AC1  INDEXPTR          SAVE # CHARS IN INDEX RECORD
*
*                                   RECORD EXISTS, IS IT SAME WORD/PHRASE?
         LI,X1    8                 GET # CHARS IN INDEX WORD/PHRASE
         LB,D1    *NDXBUF,X1
         CW,D1    NCHARS            COMPARE # CHARS
         BNE      TNXTHASH          IF NOT SAME, CAN'T BE SAME PHRASE
*
*                                   SAME # CHARS, COMPARE ACTUAL CHARS
         LW,D2    BANDXBUF          CALC ADDR OF INDEX REC WORD/PHRASE
         AI,D2    9                   SKIP CONTROL BYTES
         LW,DX2   BAWORD            ADDR OF DOC WORD/PHRASE
         STB,D1   DX2                 CHAR COUNT
         CBS,D2   0                 COMPARE CHAR STRINGS
         BNE      TNXTHASH          BRANCH IF NOT SAME
*
GETLAST  EQU      %                 SAME
         LW,AC2   *NDXBUF           TEST FOR OFLOW RECORD
         BEZ      HASHEND           BRANCH IF NONE
*
         LW,BUF2  BANDXBUF          READ OFLOW RECORD
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY
         STW,AC2  INDEXKEY          SAVE KEY OF OFLOW RECORD
         STW,AC1  INDEXPTR            AND # BYTES
         B        GETLAST           NOW GO TEST IT FOR FURTHER OFLOW
*
TNXTHASH EQU      %
         LI,X3    1                 NOT SAME, SEE IF RECORD HAS NXTHASH
         LW,AC2   *NDXBUF,X3
         BNEZ     RDHASH            RECORD HAS NXTHASH REC., GO TRY  IT
*
*                 RECORD DOESN'T HAVE A NXTHASH, GET ONE FOR IT
         LW,AC2   INDEXKEY
         MTW,1    OFLOKEY           GET A NXTHASH
         LW,D1    OFLOKEY
         STW,D1   *NDXBUF,X3        PUT IT IN 2ND WORD OF NDXBUF
         STW,D1   INDEXKEY          AND IN INDEXKEY
         LW,BUF3  BANDXBUF          WRITE REC BACK TO TEXT FILE
         LW,AC1   INDEXPTR
         BAL,SRTN S27WCPY
*
*
*
*
BUILD    EQU      %                 BUILD NEW INDEX RECORD IN NDXBUF
         LI,D1    0
         STW,D1   *NDXBUF           NO OVERFLOW
         LI,X3    1
         STW,D1   *NDXBUF,X3        NO NXTHASH
         LW,D2    NCHARS            PUT # CHARS IN BYTE 8
         LI,X1    8
         STB,D2   *NDXBUF,X1
*                                   MOVE WORD EBCDIC INTO NDXBUF
         LW,D1    BAWORD            ADDR. OF WORD
         LW,DX1   BANDXBUF          ADDR. OF BUFFER
         AI,DX1   9                   SKIP CONTROL BYTES
         STB,D2   DX1                 # CHARS TO FIRST BYTE OF DX1
         MBS,D1   0                 MOVE WORD
         AI,D2    9                 +9 CHARS FOR 9 CONTROL BYTES
         STW,D2   INDEXPTR          PUT IT IN INDEXPTR
*
HASHEND  EQU      %
*
*
         RETURN
*
         PAGE     BLOCK OR INDEX-TAG INDEX
*
*********************************************************************
*********************************************************************
*
BLKNDX   EQU      %                 BLOCK INDEX
*
*
         LI,D1    4                  SET NDXTYPE FLAG TO 4 FOR BLOCK NDX
         STW,D1   NDXTYPE
         B        SETUP
*
**********************************************************************
**********************************************************************
*
TAGNDX   EQU      %                 TAG INDEX
*
*
         LI,D1    2                  SET NDXTYPE FLAG TO 2 FOR TAG NDX
         STW,D1   NDXTYPE
*
*
SETUP    EQU      %
         LW,AC2   L(#TAGKEY)        INITIALIZE TAG FILE KEY
*
*
*        STEP 1:  SET UP INDEX FILE WITH EBCDIC FOR ALL BLOCKS/TAGS
*
*
         LW,BUF2  BATAGBUF          READ-BUFFER ADDRESS
         LW,BUF3  BANDXBUF          WRITE-BUFFER ADDRESS
NXTTAGR  EQU      %
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RHDR           READ TAG RECORD INTO TAGBUF
         CI,AC1   0                  IF AC1=0, EOF OR NO SUCH REC
         BG       RDOK1
         CI,SR3   3                   IF SR3=3, EOF HIT
         BE       COMPILE
         CI,SR3   1                   IF SR3=1, NO SUCH RECORD
         BE       NXTTAGR           GO READ NEXT REC (AC2 ALREADY=0)
*
RDOK1    EQU      %
*
         GET,D1   *TAG:TYPE         IS THIS TYPE OF TAG FOR WHICH INDEX
         CW,D1    NDXTYPE             REQUESTED?
         BNE      RESETTAG            IF NOT, BRANCH TO READ NEXT TAG
*
WRITE    EQU      %                 CREATE INDEX RECORD
         LI,D1    0                 ZERO IN 1ST & 2ND WORDS OF INDEX
         STW,D1   *NDXBUF             BUFFER (NO OFLOW OR NXTHASH)
         LI,X1    1
         STW,D1   *NDXBUF,X1
*
*        # CHARS IN BLOCK/TAG TO BYTE 8 OF NDXBUF
         GET,D2   *TAG:NCTAG
         LI,X1    8
         STB,D2   *NDXBUF,X1
*
*        MOVE TAG EBCDIC TO NDXBUF
         LW,D1    BATAGBUF          ADDRESS OF SOURCE BYTE STRING
         AI,D1    #TAGDISP            (TAG EBCDIC) TO D1
         LW,DX1   BANDXBUF          ADDRESS OF DESTINATION BYTE STRING
         AI,DX1   9                   (INDEX BUFFER) TO D1 U 1=DX1
         STB,D2   DX1                 # CHARS IN LEFTMOST BYTE OF DX1
         MBS,D1   0
         AI,D2    9                 # OF BYTES IN NDXBUF
         STW,D2   AC1               TRANSFER IT TO AC1
*                                   (KEY TO WRITE STILL IN AC2)
         BAL,SRTN S27WCPY           WRITE INDEX BUFFER TO INDEX FILE
*
*
RESETTAG EQU      %
         LI,AC2   0                 RESET AC2=0 AND
         B        NXTTAGR             BRANCH TO READ NEXT TAG RECORD
         PAGE     TEXT FILE SET UP WITH EBCDIC FOR ALL BLOCKS/TAGS,
*                 NOW COMPILE ACTUAL INDEX
*
*
COMPILE  EQU      %
         GET,D1   #FKEY             GET FIRST KEY IN DOCUMENT
         STW,D1   AC2                 TRANSFER IT TO AC2
NXTHDR   EQU      %
         LI,BUF2  BA(HDRSTA)        READ HEADER RECORD
         LI,AC1   SZHDRSTA            (AC2=#FKEY,READ RECORD #FKEY)
         BAL,SRTN S27RHDR             (AC2=0,READ NEXT RECORD     )
         CI,AC1   0                 IF AC2=0, EOF OR NO SUCH REC
         BG       RDOK2
         CI,SR3   3                   IF SR3=3, EOF HIT
         BE       MERGE
         CI,SR3   1                  IF SR3=1, NO SUCH RECORD
         BE       NXTHDR
RDOK2    EQU       %
         CW,AC2   L(#TAGKEY)       IF AC2.GE.#TAGKEY, INDEX COMPLETE,
         BGE      MERGE               BRANCH
         STW,AC2  HDRKEY            SAVE KEY OF LAST HEADER RECORD READ
*
*
*
         GET,X1   HDR:NTAGS         GET # OF TAGS ON THIS LINE
         AI,X1    1
         STW,X1   HNTAGS            SAVE IT
NXTTAG   EQU      %
         MTW,-1   HNTAGS            DECREMENT HNTAGS
         LW,X1    HNTAGS
         BGEZ     CONTINUE
         LI,AC2   0                 NO MORE TAGS ON THIS LINE,RESET AC2
         B        NXTHDR              =0 AND BRANCH TO READ NEXT HDR REC
CONTINUE EQU      %
         GET,D1   HDR:TAGDISP,X1    GET DISP. ON LINE OF X1TH TAG
         STW,D1   BPTR                SAVE IT
         GET,D1   HDR:TAGKEY,X1     GET KEY FOR X1TH TAG IN D1
         LI,D2    3                   PUT KEY BYTE COUNT IN 1ST BYTE
         STB,D2   D1                    OF KEY
         STW,D1   AC2                 TRANSFER TO AC2
         LW,BUF2  BANDXBUF            INDEX BUFFER ADDRESS
RTXT     EQU      %
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY           READ INDEX RECORD WITH KEY=AC2
         CI,AC2   0                 IF AC2=0,NO SUCH RECORD,BRANCH TO
         BLE      NXTTAG              GET NEXT TAG ON THIS LINE
         LW,D1    *NDXBUF           TEST FIRST WORD IN INDEX BUFFER
         BEZ      NUMBER              IF ZERO,NO OFLOW FOR THIS RECORD
         LW,AC2   *NDXBUF             IF NONZERO,GO GET OFLOW RECORD
         B        RTXT                  IN INDEX BUFFER
*
*
NUMBER   EQU      %
         STW,AC1  INDEXPTR          SAVE #CHARS IN INDEX RECORD
         STW,AC2  INDEXKEY          SAVE KEY OF INDEX RECORD
*
         BAL,SRTN S16NMBR           GET LINE/PAGE NO. FOR LINE HDRKEY
*
         BAL,SRTN S16ADD            ADD THIS REF TO INDEX
*
         B        NXTTAG            GO GET NEXT TAG/BLOCK ON THIS LINE
         PAGE      MAKE ONE LAST PASS OVER BLOCK/TAG INDEX
*
*
MERGE    EQU      %
*
*
         LW,AC2   L(#OVFLKEY)       FIRST POSS. OFLOW KEY IN INDEX
NXTREC   EQU      %
         LW,BUF2  BAOFLOBF          READ AN OFLOW RECORD INTO OFLOW BUF
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY
         CI,AC1   0                 IF AC1=0, EOF OR NO SUCH RECORD
         BG       RDOK3
         CI,SR3   3                 IF SR3=3, EOF HIT
         BE       DUMP
         CI,SR3   1                 IF SR3=1, NO SUCH RECORD,
         BE       NXTREC              TRY AGAIN
RDOK3    EQU      %
         STW,AC2  OFLOKEY           SAVE AC2=KEY
         STW,AC1  OFLOPTR           SAVE AC1=# CHARS
         LI,X1    8                 PICK UP CHAR COUNT
         LB,AC1   *TAGBUF,X1          (TAGBUF SAME AS OFLOBUF)
         BEZ      RDNXTOFL          IF ZERO, GO READ NEXT OFLO RECORD
*
GETKEY   EQU      %                 HASH BLK/TAG EBCDIC & GET KEY
         LW,X1    BAOFLOBF          CALC ADDR OF 1ST CHAR
         AI,X1    9                   SKIP CONTROL BYTES
         BAL,SRTN S07HASH           HASH BLOCK TAG CHARS
*
RDNDX    EQU      %                 READ INDEX RECORD WITH HASHED KEY
         STW,AC2  INDEXKEY          SAVE KEY
         LW,BUF2  BANDXBUF
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY
         CI,AC2   0                 IF AC2=0, NO SUCH RECORD
         BG       TST               BRANCH IF RECORD EXISTS
*
         LW,BUF3  BAOFLOBF          RECORD DOESN'T EXIST,
         LW,AC1   OFLOPTR             WRITE THIS ONE THERE
         LW,AC2   INDEXKEY
         BAL,SRTN S27WCPY
         B        RESETNDX
*
TST      EQU      %                 RECORD EXISTS, POINT IT AT THIS ONE
         LI,X1    1                 GET NXTHASH KEY
         LW,D1    *NDXBUF,X1
         BLEZ     ADDNXT            BRANCH IF NXTHASH=0, ELSE
         LW,AC2   D1                TRANSFER NXTHASH KEY TO AC2
         B        RDNDX             GO READ NXTHASH RECORD
*
ADDNXT   EQU      %
         LW,D1    OFLOKEY           PUT OFLOKEY IN 2ND WORD OF NDXBUF
         STW,D1   *NDXBUF,X1
         LW,BUF3  BANDXBUF
         BAL,SRTN S27WCPY           WRITE NDXBUF BACK TO INDEX FILE
*
*
RESETNDX EQU      %                 RESET PTR FOR READ NEXT
         LI,AC1   0                 SIZE=0
         LW,AC2   OFLOKEY
         BAL,SRTN S27RCPY
*
*
RDNXTOFL EQU      %
         LI,AC2   0                 SET AC2=0 FOR READ NEXT
         B        NXTREC
         PAGE     TITLE INDEX (TABLE OF CONTENTS)
*
*********************************************************************
*********************************************************************
*
TTLNDX   EQU      %
*
*
         GET,D1   #FKEY             GET FIRST KEY IN DOCUMENT
         STW,D1   AC2               TRANSFER IT TO AC2
RHDR     EQU      %                 READ A HEADER RECORD
         LI,AC1   SZHDRSTA
         LI,BUF2  BA(HDRSTA)
         BAL,SRTN S27RHDR
         CI,AC1    0                IF AC1=0, EOF OR NO SUCH REC
         BG       RDOK4
         CI,SR3   3                   IF SR3=0, EOF HIT
         BE       DUMP
         CI,SR3   1                  IF SR3=1, NO SUCH RECORD
         BE       RHDR
RDOK4    EQU      %
         GET,D1   #LKEY             IF AC2>#LKEY, END OF DOC,
         CW,AC2   D1
         BG       DUMP                DUMP INDEX
         STW,AC2  HDRKEY            SAVE KEY OF THIS RECORD
         GET,D1   HDR:NTAGS         GET # OF TAGS ON THIS LINE
         AI,D1    1
         STW,D1   HNTAGS            SAVE IT
NXTTAG2  EQU      %
         MTW,-1   HNTAGS            DECREMENT # TAGS ON THIS LINE
         LW,X1    HNTAGS            GET IT IT X1
         BGZ      CONT2             BRANCH IF MORE TAGS LEFT ON LINE
         LI,AC1   0                 RESET PTR FOR READ NEXT
         LW,AC2   HDRKEY
         BAL,SRTN S27RHDR
*
         LI,AC2   0
         B        RHDR
CONT2    EQU      %
         GET,D1   HDR:TAGDISP,X1    GET DISPLACEMENT FOR X1TH TAG
         STW,D1   BPTR              SAVE IT
         GET,D1   HDR:TAGKEY,X1     GET KEY FOR X1TH TAG
         LI,D2    3                 NOW PUT KEY BYTE COUNT IN FIRST BYTE
         STB,D2   D1                    OF KEY
         STW,D1   AC2                 TRANSFER IT TO AC2
         LW,BUF2  BATAGBUF
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RHDR           READ TAG RECORD WITH KEY=AC2
         GET,D1   *TAG:TYPE         GET TAG TYPE
         CI,D1    3                   IS IT A TITLE TAG?
         BNE      NXTTAG2             NO,BRANCH
*
*
*                 BUILD AN INDEX RECORD
         LI,D2    0                 ZERO OUT 1ST TWO CONTROL WORDS
         STW,D2   *NDXBUF             OF NDXBUF
         LI,X1    1
         STW,D2   *NDXBUF,X1
*                                   BLANK OUT REST OF INDEX BUFFER
         LI,D2    ' '                 (DOESN'T HURT TO PUT A BLANK IN
         LW,D1    NDXBUF              CHAR COUNT BYTE OF TITLE INDEX
         AI,D1    2                   RECORD (BYTE 8) - WON'T EVER CHECK
         STB,D2   *D1                 IT)
         LW,X1    WIDTH
BLNKOUT  EQU      %
         STB,D2   *D1,X1
         BDR,X1   BLNKOUT
*
         GET,D1   *TAG:TLEVEL       GET TITLE LEVEL
         SLS,D1   1                   *2
         STW,D1   INDEXPTR            SAVE IT
*
*                                   MOVE TITLE EBCDIC TO NDXBUF
         LW,D1    BATAGBUF          CALC.ADDR OF SOURCE BYTE STRING
         AI,D1    #TAGDISP
         LW,DX1   BANDXBUF          CALC.ADDR OF DEST. BYTE STRING
         AW,DX1   INDEXPTR
         AI,DX1   9                 +9 FOR 9 CONTROL BYTES
         GET,D2   *TAG:NCTAG        # CHARS TO BE MOVED
         STB,D2   DX1               PUT IT IN 1ST BYTE OF DX1
         MBS,D1   0                 MOVE TITLE EBCDIC
*
*
         BAL,SRTN S16NMBR           CONVERT HDRKEY TO LINE/PG.NO. EBCDIC
         CI,AC2   0                 IF AC2=0, IGNORE THIS REF
         BE       NXTTAG2
*
*   MOVE LINE/PAGE NO. EBCDIC TO NDXBUF
         LI,D1    AC1*4             SOURCE BYTE STRING ADDR
*                                   CALC DEST. BYTE STRING ADDR.
         LW,DX1   BANDXBUF          BA(INDEX BUFFER)
         AW,DX1   WIDTH             +LINE WIDTH
         AI,DX1   1                 +9 FOR 1ST 9 CONTROL BYTES
*                                   -8 FOR 8 CHARS IN LINE/PG # REF
         LI,D2    8                 CHARACTER COUNT TO 1ST BYTE OF DX1
         STB,D2   DX1
         MBS,D1   0                 MOVE LINE/PG.NO. EBCDIC TO NDXBUF
*
         LW,AC2   TITLEKEY          WRITE INDEX BUFFER TO TEXT FILE
         LW,BUF3  BANDXBUF
         LW,AC1   WIDTH
         AI,AC1   9                 +9 FOR 1ST 9 CONTROL BYTES
         BAL,SRTN S27WCPY
         MTW,1    TITLEKEY            UPDATE TITLEKEY
         B        NXTTAG2           GO CHECK NEXT TAG ON THIS LINE
         PAGE
*
*********************************************************************
*********************************************************************
*
S16NMBR  EQU      %
*
*
*  THIS ROUTINE CONVERTS A LINE KEY TO A LINE OR PAGE NUMBER(EBCDIC),
*  DEPENDING ON WHETHER OR NOT 'LINE' OPTION SPECIFIED (DEFAULTS TO PAGE)
*    CALLED BY:     BAL,SRTN    S16NMBR
*    IN: HDRKEY(TXTKEY) = KEY TO BE CONVERTED TO LINE/PG #
*        BPTR   = DISP. OF 1ST CHAR OF WORD ON LINE 'KEY'
*    OUT:AC1,AC2= EBCDIC FOR LINE/PAGE NUMBER, TRAILING BLANKS
*        IF AC2=0, LINE DOES NOT APPEAR ON STD PAGE(BLOCK DEF NEVER
*          CALLED OUT, HEADING/FOOTING, EMBEDDED COMMAND, ETC.)
*
*
*  SAVE  LINK REGISTER
         SAVRTN
*
         LW,D1    LINEOPTN          BRANCH IF LINE NO. OPTION
         BNEZ     LINE
*                                   PAGE NUMBER OPTION
         LI,AC2   1                 SET AC2=1E/FIRST PAGE NO. FLAG
         LW,D1    HDRKEY                KEY OF LINE TO FIND PG.NO. OF
         BAL,SRTN S08FNDPG              GET PG.NO.
         CI,AC2   0                 IF AC2=0, BRANCH TO END
         BE       ENDNMBR
         CW,AC1   BPTR                  IF AC1<=BPTR,PHRASE STARTS ON
         BLE      EBCDIC                  THIS PAGE
         AI,AC2   -1                    PHRASE STARTS ON THE PREVIOUS PG
EBCDIC   EQU      %                     CONVERT PG.NO. TO EBCDIC
         STW,AC2  AC1                   TRANSFER PG.NO. TO AC1
         BAL,SRTN S35CNVRT
         STW,AC2  AC1                   TRANSFER PG.NO. EBCDIC TO AC1
         LW,AC2   L('    ')             BLANK OUT AC2
         B        ENDNMBR
*
LINE     EQU      %                 LINE NUMBER OPTION
         LW,AC2   HDRKEY                KEY OF LINE TO FIND LINE NO. OF
         BAL,SRTN S35LINE               GET LINE NO. EBCDIC IN AC1 & AC2
*
ENDNMBR  EQU      %
*
*
*  RESTORE LINK REGISTER
         RETURN
         PAGE
*
**********************************************************************
**********************************************************************
*
S16ADD   EQU      %
*
*
*  THIS ROUTINE ADDS A LINE OR PAGE NUMBER REFERENCE TO THE END OF THE
*  INDEX BUFFER(NDXBUF) AND WRITES IT BACK TO TEXT FILE.
*  ALSO CHECKS FOR OVERFLOW OF LINE WIDTH AND,
*  IF SO, CREATES AN OVERFLOW RECORD FOR THIS REFERENCE AND WRITES IT.
*    CALLED BY:   BAL,SRTN   S16ADD
*    IN:  AC1,AC2=EBCDIC FOR LINE/PAGE NUMBER
*                 (IF AC2=0, NO CHANGE TO INDEX RECORD)
*         INDEXPTR=# OF BYTES NOW IN INDEX BUFFER (INCL CONTROL BYTES)
*         WIDTH=SPECIFIED LINE WIDTH FOR DOCUMENT
*         OFLOKEY=LAST OVERFLOW RECORD KEY USED (UPDATED BY THIS ROUTINE
*         INDEXKEY=KEY OF INDEX RECORD BEING UPDATED
*    OUT: ADDS LINE/PAGE NO. REF TO INDEX BUFFER AND WRITES IT BACK TO
*           TXT FILE (ALSO OVERFLOW RECORD IF REQUIRED).
*
*
         SAVRTN
*
         CI,AC2   0                 IF AC2=0, BRANCH TO END
         BE       ENDADD
*
*        PUT COMMA AT END OF INDEX BUFFER
         LW,X1    INDEXPTR              PTR TO END OF INDEX BUFFER
         LI,D1    ','                   COMMA CHAR
         STB,D1   *NDXBUF,X1            PUT COMMA AT END OF INDEX BUFFER
         MTW,1    INDEXPTR              UPDATE INDEX PTR
*
*        PACK LINE/PAGE NUMBER EBCDIC
         LI,X1    -1                    PACK LINE/PG.NO. FROM AC1/AC2 TO
         LI,X2    -1                      EBCDICNO,STRIPPING BLANKS &
PACK     EQU      %                       COUNTING NO.OF NON-BLANK CHARS
         AI,X2    1                 INCREMENT AC1/AC2 COUNTER
         CI,X2    7                 BRANCH IF END OF AC1/AC2
         BG       TESTOFLO
         LB,D2    AC1,X2            GET A CHAR FROM AC1/AC2
         CI,D2    ' '                 IF A BLANK, GO GET ANOTHER CHAR
         BE       PACK
         AI,X1    1                   NOT A BLANK, INCREMENT EBCDICNO
         STB,D2   EBCDICNO,X1         COUNTER AND PACK CHAR IN EBCDICNO
         B        PACK
*
*        TEST IF ADDING THIS REF WILL OFLOW LINE WIDTH
TESTOFLO EQU      %
         AI,X1    1                 +1 FOR TRUE COUNT
         STW,X1   NEBCDIC           # CHARS PACKED IN EBCDICNO
         LW,D2    INDEXPTR          CALC HOW LONG LINE IN INDEX BUFFER
         AW,D2    NEBCDIC             WILL BE IF WE ADD THIS REF
         AI,D2    -7                +1 FOR LEADING BLANK,
*                                     +1 TO LEAVE SPACE FOR A COMMA TO
*                                     ADD NEXT REF,
*                                     -9 FOR 9 CONTROL BYTES
         CW,D2    WIDTH             BRANCH IF THIS REF WILL NOT OFLOW
         BLE      NOOFLOW             INDEX BUFFER
*
*        ADDING THIS REF WOULD OVERFLOW LINE WIDTH, GET AN OFLOW REC
*          FIRST GET OFLOW KEY AND WRITE PRESENT REC BACK TO INDEX FILE
OFLOW    EQU      %
         MTW,1    OFLOKEY           UPDATE OFLOW RECORD KEY
         LW,AC2   OFLOKEY             PUT IT IN AC2
         LI,AC1   0                   ZERO BUFFER SIZE
         BAL,SRTN S27RCPY           READ INDEX RECORD W/KEY=OFLOKEY
         CI,AC2   0                   IF AC2 NOT=0, REC. ALREADY EXISTS,
         BNE      OFLOW                 TRY AGAIN
*
         LW,D1    OFLOKEY           PUT OFLOW REC KEY IN 1ST WORD
         STW,D1   *NDXBUF             OF INDEX BUFFER
         LW,BUF3  BANDXBUF          INDEX BUFFER ADDR
         LW,AC1   INDEXPTR          NO. OF CHARS TO WRITE
         LW,AC2   INDEXKEY          KEY TO WRITE
         BAL,SRTN S27WCPY           WRITE INDEX BUFFER BACK TO NDX FILE
*
*
*          NOW BUILD OFLOW RECORD
         LI,D2    0                 NOW ZERO OUT 1ST & 2ND WORDS OF
         STW,D2   *NDXBUF             INDEX BUFFER (NO OFLOW AND
         LI,X2    1
         STW,D2   *NDXBUF,X2        NO NXTHASH)
         AI,X2    1
         LW,D2    L(X'00404040')    ZERO IN CHAR COUNT, THEN 3 BLANKS
         STW,D2   *NDXBUF,X2
         LI,D2    12                AND UPDATE INDEXPTR ACCORDINGLY
         STW,D2   INDEXPTR
         LW,D2    OFLOKEY           AND SET INDEXKEY=OFLOKEY
         STW,D2   INDEXKEY
*
*
*
*        ADD LINE/PAGE NUMBER REF AND WRITE REC BACK TO INDEX FILE
NOOFLOW  EQU      %
         LI,D2    ' '               PUT A BLANK BEFORE THE LINE/PAGE NO.
         LW,X2    INDEXPTR
         STB,D2   *NDXBUF,X2
         MTW,1    INDEXPTR          AND UPDATE INDEXPTR
*
         LI,D1    BA(EBCDICNO)      MOVE LINE/PG # TO INDEX BUFFER
         LW,DX1   BANDXBUF
         AW,DX1   INDEXPTR
         LW,D2    NEBCDIC
         STB,D2   DX1
         MBS,D1   0
*
*
         LW,BUF3  BANDXBUF          WRITE INDEX RECORD BACK TO NDX FILE
         LW,AC1   INDEXPTR
         AW,AC1   NEBCDIC           + NO. OF CHARS IN THIS REF.
         LW,AC2   INDEXKEY
         BAL,SRTN S27WCPY
*
ENDADD   EQU      %
      RETURN
         PAGE     INDEX COMPLETE, NOW DUMP IT OUT
*
**********************************************************************
**********************************************************************
*
DUMP     EQU      %
*
*
         LI,D1    1                 INITIALIZE NXTHFLAG
         STW,D1   NXTHFLAG
         MTW,0    FILEFLG           FILE OUTPUT MODE
         BNEZ     GETTAG            YES, SKIP MESSAGE
         MTW,0    BATCHFLG          BATCH MODE
         BGZ      GETTAG            YES, SKIP MESSAGE
*
         LI,AC1   16                'SIGNAL WHEN READY' MESSAGE
         BAL,SRTN S29STD              PRINT IT
GETTAG   RES      0
         LW,AC2   L(#TAGKEY)        1ST POSSIBLE KEY IN INDEX
*
PRNTPAGE EQU      %                 PRINT ONE PAGE OF INDEX
         STW,AC2  SAVEKEY           SAVE AC2
         GET,D1   #DEPTH            PAGE DEPTH FOR DOCUMENT
         STW,D1   LINESLFT
         MTW,0    FILEFLG           FILE OUTPUT MODE
         BNEZ     RESKEY            YES, SKIP READ
         MTW,0    BATCHFLG          BATCH MODE
         BGZ      RESKEY            YES, SKIP READ
         BAL,SRTN S09RDATN          PICK UP ATTN-ATTN SIGNAL TO START
         CI,SR3   #CR                 IF ATTN-RETURN, ABORT
         BE       FINI
RESKEY   RES      0
         LW,AC2   SAVEKEY           RESTORE AC2
*
NXTNDX   EQU      %
         MTW,-1   LINESLFT          DECREMENT LINE COUNT
         BLZ      PRNTPAGE            GO PRINT ANOTHER PAGE
         LW,BUF2  BANDXBUF          INDEX BUFFER ADDR
         LI,AC1   #STDBUFSZ
         BAL,SRTN S27RCPY           READ AN INDEX RECORD
         CI,AC1   0                  IF AC1=0, EOF OR NO SUCH REC
         BG        RDOK5
         CI,SR3   3                 IF SR3=3, EOF HIT
         BE       FINI
         MTW,1    LINESLFT          ELSE NO SUCH RECORD, INCREMENT
         B        NXTNDX              LINESLFT AND BRANCH
RDOK5    EQU      %
         CW,AC2   L(X'03F00000')
         BGE      FINI
         LW,D2    NXTHFLAG          TEST NXTHFLAG
         BEZ      NONXTH
         LI,X1    1                 SAVE NXTHASH KEY
         LW,D1    *NDXBUF,X1
         STW,D1   NXTHASH
*
NONXTH   EQU      %
         LW,D2    L(#OVFLKEY)
         CW,AC2   D2
         BGE      TSTEND
         STW,AC2  INDEXKEY
         B        WRTNDX
TSTEND   EQU      %
         LW,D1    OFLOFLAG          IF REC WITH KEY GREATER THAN E00000
         BEZ      FINI              READ & OFLOFLAG=0, INDEX ALL DUMPED
*
WRTNDX   EQU      %
         LI,D1    #CR               PUT A RETURN AFTER LAST BYTE
         LW,X1    AC1
         STB,D1   *NDXBUF,X1
         LW,BUF1  BANDXBUF          WRITE INDEX BUFFER TO TERMINAL
         AI,BUF1  9                   SKIP CONTROL BYTES
         AI,AC1   -8                  -9 FOR 9 CONTROL BYTES,+1 FOR RET
         BAL,SRTN S27PRINT
*                                   REC PRINTED, NOW TEST FOR OFLOW
         LI,D1    1                 SET OFLOFLAG=1
         STW,D1   OFLOFLAG
         LW,AC2   *NDXBUF           GET KEY FOR OFLOW RECORD IN AC2
         BEZ      TSTNXTH           BRANCH IF NO OFLOW
         LI,D1    0                 RESET NXTHFLAG TO ZERO
         STW,D1   NXTHFLAG
         B        NXTNDX            GO READ OFLOW RECORD
*
*
*                 ALL OFLOWS PRINTED, NOW TEST FOR NXTHASH
TSTNXTH  EQU      %
         LI,D1    1                 SET NXTHFLAG=1
         STW,D1   NXTHFLAG
         LW,AC2   NXTHASH           GET NXTHASH KEY IN AC2
         BNEZ     NXTNDX            GO READ NXTHASH RECORD NXTHASH
*
         LI,AC1   0                 NO NXTHASH, RESET FOR READ NEXT
         STW,AC1  OFLOFLAG          RESET OFLOFLAG
         LW,AC2   INDEXKEY            PTR FOR READ NEXT
         BAL,SRTN S27RCPY
         LI,AC2   0
         B        NXTNDX
*
*
FINI     EQU      %                 INDEX DUMPED TO TERMINAL
         MTW,0    FILEFLG           FILE OUTPUT MODE
         BEZ      DUMPRTN           NO
         LI,AC1   76                SET UP 'INDEX COMPLETED' MSG
         BAL,SRTN S29STD            GO PRINT MESSAGE
*
*
DUMPRTN  RES      0
         LI,AC2   0
         BAL,SRTN S08FNDPG          WRAP UP AND SAVE PRINT FILE
*
*  S08FNDPG DOES NOT RETURN HERE  *
*
         RETURN                     RESTORE LINK REGIS. AND RETURN
         PAGE
*
**********************************************************************
**********************************************************************
*
*
*        DATA AREA - LOCAL VARS
*
16D      CSECT    0                 START OF LOCALS
WIDTH    RES      1                 LINE WIDTH FOR DOC
BAOFLOBF EQU      %                 BA(OFLOW BUFFER)
BATXTBUF EQU      %
BATAGBUF RES      1                 BA(TAG BUFFER)
BANDXBUF RES      1                 BA(INDEX BUFFER)
NDXBUF   RES      1                 WA(INDEX BUFFER)
NDXTYPE  RES      1                 INDEX TYPE (1=TAG,3=BLOCK)
LASTPGNO RES      1                 SAVES LAST PG.NO. RETD FROM S08FNDPG
BPTR     RES      1                 SAVES CHAR.PTR.TO TAG ON LINE
TITLEKEY EQU      %
INDEXKEY RES      1                 KEY OF RECORD IN INDEX FILE
SAVEKEY  EQU      %
OFLOKEY  RES      1                 SAVES KEY OF LAST OFLOW REC WRITTEN
TXTKEY   EQU      %
HDRKEY   RES      1                 SAVES KEY OF RECORD IN HDR FILE
HNTAGS   RES      1                 NUMBER OF TAGS ON A LINE
NXTHASH  RES      1                 SAVES PTR TO NEXT TAG RECORD
NCHARS   RES      1
CHARSLFT RES      1
BAWORD   RES      1
EBCDICNO RES      2
NEBCDIC  RES      1
OFLOPTR  EQU      %
INDEXPTR RES      1                 POINTER TO END OF INDEX BUFFER
TXTPTR   RES      1
TYPEOPTN RES      1
LINEOPTN RES      1
OFLOFLAG RES      1
NXTHFLAG RES      1
SAVEX2   EQU      %
LINESLFT RES      1
         USECT    #PLOC             RETURN TO PROCEDURAL CSECT
         END
