PROCEDURE ,010001 ;+ ; Copyright (c) 1976 ; Digital Equipment Corporation, Maynard, Mass. ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the inclu- ; sion of the above copyright notice. This software, or any ; other copies thereof, may not be provided or otherwise made ; Available to any other person except for use on such system ; and to one who agrees to these license terms. Title to and ; ownership of the software shall at all times remain in DEC. ; ; The information in this software is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation. ; ; DEC assumes no responsibility for the use or reliability of its ; software on equipment which is not supplied by DEC. ; ; Abstract: This module inserts an item into the Index list ; ; Written: 1-Jun-72, -0.0.0-, L. Wade ; ; Modified: 12-Jan-80, -1.0.0-, Henry R. Tumblin ; Produced Duke supported version ; ; Verified: 12-Jan-80, -1.0.0-, Henry R. Tumblin ; ; Modified: 06-Nov-81, -1.0.1-, John D. Leonard ; No need to change page number for number page lower condition. ;- .sbttl Runoff Definitions .GLOBL APNDN ; current appendix letter .GLOBL CHPTN ; current chapter number .GLOBL CR ; carriage return .GLOBL GCIN ; get character from input file .GLOBL PAGENO ; current page number .GLOBL S1 ; temporary accumulator .GLOBL XFIRST ; pointer to first index block pointer .GLOBL $FRCND ; force to logical end of command ; index globals .GLOBL INDEX ; module entry point .SBTTL INDEX FLAGS AND DEFINITONS ; index flags IDXCF = 1 ; case difference flag IDXRF = 2 ; repeated item flag ; Index link block offsets ID.FWD = 0 ; foward pointer ID.BCK = ID.FWD + 2; back pointer ID.TXT = ID.BCK + 2; asciz text pointer ID.PNO = ID.TXT + 2; page number ID.CHA = ID.PNO + 2; chapter/appendix number. ID.LEN = ID.CHA + 2; length of index block header .SBTTL Local data DATA INDEXD,LCL IDXFLG: .BLKW 1 ; index flags word ICBUF: .BLKB 52. ; index item buffer ICBFE = .-2 .SBTTL Start mainline ;+ ; **-INDEX-add index item to index data ;- CODE INDEX ; set up index p-sect ; ; This command inserts index text into the index ; list, which is a circular linked list. ; First copy the index string into the temporary string ; area. The maximum length of an index string is ; currently 52 bytes. If the index string is too long, then ; it will be truncated to 52 characters, and a diagnostic ; message generated. INDEX:: MOV #ICBUF,R0 ; get address of index item buffer MOV R0,R5 ; copy index item buffer address 10$: CLR (R0)+ ; clear index item buffer CMP R0,#ICBFE ; At end of holding buffer ? BLOS 10$ ; LOS - not yet MOV #,R3 ; end test on buffer CLR IDXFLG ; Reset flags CALL $FRCND ; force to logical end of command ; Get the index string from the input file. INDX1: CALL GCIN ; read character from file CMPEQ R1,#CR,INDX2 ; end of line? MOVB R1,(R5)+ ; store character of index data DEC R3 ; loop if room BGT INDX1 ; GT - go back for more ; ; Tell user that their index string is being truncated ; and print same. DIAG IDTRNC ; Output truncate message ; Insure that the string is word aligned for ; insertion into the INDEX TEXT buffer. INDX2: BITEQ #1,R5,10$ ; check for boundary alignment DEC R5 ; back up one byte 10$: SUB #ICBUF-2,R5 ; calculate length of asciz string MOV R5,S1 ; save for later use MOV XFIRST,R2 ; get address of first item so far BEQ INDXV ; if none, list is empty. start it. .sbttl Scan for index match ; This loop scans the index list for a match for ; this index item. If found, then the pointer in the ; index list to the index text will point to the same item ; and only the entry block is entered, and no new text ; is inserted. If a match isn't found, then a new entry is ; created. ; R0 - Character from old string ; R1 - Character from new string ; R2 - Pointer to INDEX list ; R3 - Pointer to existing index item asciz string ; R4 - Pointer to item eligable to be added ; R5 - Not used ; Initialize INDXL2: BIC #IDXCF,IDXFLG ; clear case difference flag MOV 4(R2),R3 ; address of asciz of old item MOV #ICBUF,R4 ; pointer to new item ; Compare strings INDXL1: MOVB (R3)+,R1 ; get char of old MOVB (R4)+,R0 ; and one of new CMPEQ R1,R0,10$ ; same before case merge? BIS #IDXCF,IDXFLG ; set case difference flag 10$: BITB #CHALC,CHATBL(R1) ; Is it lower case? BEQ 20$ ; EQ - no BIC #40,R1 ; Convert to upper case 20$: BITB #CHALC,CHATBL(R0) ; Is it lower case ? BEQ 30$ ; EQ - no BIC #40,R0 ; Convert to upper case 30$: CMPNE R1,R0,40$ ; not same? TSTNE R1,INDXL1 ; end of strings? 40$: CMPEQ R1,R0,INDX4 ; which is first? BGT INDX3 ; new one is first, and different ; Get the next link in the index list IDX4A: MOV (R2),R3 ; no. old one is first. look further BEQ INDX5 ; end of list. new is last MOV R3,R2 ; move link to a BR INDXL2 ; look further .sbttl Add item to list ; R0 - Backward pointer ; R1 - Not used ; R2 - Pointer to INDEX list ; R3 - Not used ; R4 - Pointer to item eligable to be added ; R5 - Not used INDX3: BIT #IDXRF,IDXFLG ; Repeated item ? BNE IDX4B ; EQ - no, then insert normally CALL INDXAD ; add item with page no to storage (unlinked? MOV 2(R2),R0 ; who preceded old? BNE 10$ ; anyone? MOV R4,XFIRST ; no. new is first of all. 10$: MOV R4,2(R2) ; new is predecessor of old MOV R2,(R4) ; old is successor of new, no predecessor MOV R0,2(R4) ; set old predecessor BEQ 20$ ; if eq none MOV R4,(R0) ; make new one be his successor 20$: RETURN ; .SBTTL Repeated Item INDX4: BIT #IDXCF,IDXFLG ; Check case flag BNE INDX3 ; case difference? BIS #IDXRF,IDXFLG ; set repeated item flag BR IDX4A ; go look for last occurrence. IDX4B: MOV 2(R2),R2 ; at end of repeat. get last one. IDX4C: CALL INDXAP ; add pointers only (with page. no link) MOV 4(R2),4(R4) ; new points to same text as old MOV (R2),R0 ; get previous successor of old MOV R4,(R2) ; make new succeed old TSTEQ R0,10$ ; no old next? MOV R4,2(R0) 10$: MOV R0,(R4)+ ; old successor is successor of new MOV R2,(R4) ; old is predecessor of new RETURN ; .sbttl Add new item to list ; add a new item to the list. ; R2 - pointer to current index block ; R4 - pointer to newly allocated index block INDX5: BIT #IDXRF,IDXFLG ; repeated item ? BNE IDX4C ; ne - yes, then add pointers only CALL INDXAD ; create text and pointer block with pageno MOV R4,ID.FWD(R2) ; make new follow old CLR ID.FWD(R4) ; clear forward link MOV R2,ID.BCK(R4) ; and old precede new. RETURN ; .sbttl Empty List, create initial entry ; R4 - pointer to newly allocated block ; XFIRST - pointer to head of index list INDXV: CALL INDXAD ; create text and pointer block, page no MOV R4,XFIRST ; this is first item (and only) CLR ID.FWD(R4) ; no links at all CLR ID.BCK(R4) RETURN ; .sbttl Add index link block to list INDXAD: CALL INDXAX ; allocate item and buffer MOV R4,-(SP) ; save base of new item CLR ID.FWD(R4) ; clear forward link CLR ID.BCK(R4) ; clear backward link MOV R4,ID.TXT(R4) ; set pointer to ADD #ID.LEN,ID.TXT(R4) ; asciz text area MOV ID.TXT(R4),R4 ; point to text area ; move text into block area MOV #ICBUF,R0 ; transfer text into buffer MOV S1,R1 ; get count of bytes in index item 10$: MOVB (R0)+,(R4)+ ; transfer index item DEC R1 ; any more bytes to move? BGT 10$ ; if gt yes MOV (SP)+,R4 ; restore base of index. RETURN ; .SBTTL ALLOCATE LINK BLOCK .ENABL LSB INDXAP: CLR R1 ; indicate no additional storage BR 10$ ; .SBTTL ALLOCATE LINK BLOCK AND ASCIZ BUFFER INDXAX: MOV S1,R1 ; indicate buffer storage needed 10$: ADD #ID.LEN,R1 ; compute length of area. CALL ALLOC ; allocate the area. MOV R1,R4 ; return the area allocated. MOV PAGENO,ID.PNO(R4) ; insert page number .if ndf A$$RAP TST $NUMLW ; Numbering pages at bottom ? BEQ 20$ ; EQ - no INC ID.PNO(R4) ; Else bump up page number .endc 20$: CLR ID.CHA(R4) ; assume no chapter/appendix MOVB APNDN,ID.CHA(R4) ;insert current appendix BNE 30$ ; if NE - we were in an appendix MOVB CHPTN,ID.CHA(R4) ; EQ - then we were in a chapter. BEQ 30$ ; EQ - No! not in anything! COMB ID.CHA+1(R4) ; designate chapter number 30$: RETURN ; .DSABL LSB .END