PROCEDURE ,010006 ;+ ; 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 contains all the text formatting ; action routines. ; ; ; Written: 22-Sep-75, -0.0.0-, D.N. Cutler ; ; Modified: July-78, -0.5.0-, J. Berntsen ; Added Table of Contents ; ; Modified: 17-Jan-80, -1.0.0-, Henry R. Tumblin ; Produced Duke supported version ; ; Verified: 17-Jan-80, -1.0.0-, Henry R. Tumblin ; ; Modified: 26-May-80, -1.0.1-, Jon Berntsen ; Modified: 16-June-80, -1.0.2-, Jon Berntsen ; Corrected Table of Contents errors ; Modified: 7-July-80, -1.0.2-, Jon Berntsen ; Correct list element errors ; ; Modified: 06-oct-80, -1.0.3-, John D. Leonard ; Use global for Header switch ; ; Modified: 13-Oct-80, -1.0.4-, John D. Leonard ; Added 'BLANK' keyword to .HEADER command to omit 'PAGE' ; ; Modified: 30-Oct-81, -1.0.5-, John D. Leonard ; Fixed bug in chapter processing to TOC, saving BF.END not BF.LEN ; ; Modified: 03-Nov-81, -1.0.6-, John D. Leonard ; Changed .LIST command "spacing" argument to 1/8 line type argument. ; Interpreted as amount of white space preceding a list element. ; Changed .ELS so it does not do any spacing. ; Also preserved LSTVS across list commands so the default does not ; keep getting reset and changed in nested list commands. ; ;- .SBTTL MCALLS AND RUNOFF DEFINITIONS ; all command routines are entered with: ; ; R4=Address of number conversion routine. ; R5=Address of flag word f.1. ; ; local data ; ; output text ; DATA FMTCMD,LCL APNMG: .ASCIZ /Appendix / ; appendix heading prototype CHAPT: .ASCIZ /Chapter / ; chapter heading prototype LOWER: .ASCIZ /LOWER/<0>"page " ; Lower case page MIXED: .ASCIZ /MIXED/<0>"Page " ; Mixed case page .IF DF A$$RAP BLANK: .ASCIZ /BLANK/<0>" " ; omit 'page' .ENDC NOTET: .ASCIZ /Note/ ; note heading prototype UPPER: .ASCIZ /UPPER/<0>/PAGE/<' > ; upper case page PAGW: .ASCIZ /Page/ ; page header TOCMSG: .ASCIZ /Table of Contents/ ; table of contents label TOCCNT: .ASCIZ / (Continued)/ .EVEN .SBTTL APNDX - APPENDIX COMMAND ;+2 ; The APPENDIX command starts a new appendix using the ; text as the title of the appendix. ; ; The format of the appendix command is : ; ; .APPENDIX text ;-2 CODE FMTCM .ENABL LSB APNDX:: MOV #APNMG,-(SP) ; set address of appendix heading CLRB $CHRFL ; Turn off roman numerals BR 10$ ; .SBTTL CHR - CHAPTER COMMAND, Roman Numeral Conversion ;+2 ; The CHR command is identical to the CHAPTER command with ; the exception of using ROMAN numeral chapter numbers. ; This mode is reset by a CHAPTER command. ; ; The format of the chapter command is : ; ; .CHR text ;-2 CHR:: INCB $CHRFL ; Turn on roman numeral chapters MOV #CHAPT,-(SP) ; Point to chapter header protype BR 10$ ; Go to common code .SBTTL CHPTR - CHAPTER COMMAND ;+2 ; The CHAPTER command starts a new chapter using the text ; as the title of the chapter. ; ; The format of the chapter command is : ; ; .CHAPTER text ;-2 CHPTR:: MOV #CHAPT,-(SP) ; set address of chapter heading CLRB $CHRFL ; Turn off Roman numbering 10$: MOV #TTLBUF,R4 ; Point to buffer CALL INIBUF ; Init buffer MOV #STTLBF,R4 ; Point to buffer CALL INIBUF ; Init buffer MOV PLMARG,LMARG ; set left margin MOV PRMRG,RMARG ; set right margin BIS #FILLF!JUSTF!PJUSTF,(R5) ; set fill and justify flags CALL PAGEC ; break current page INCB CHPTN ; increment chapter # now CLR PAGENO ; set initial page number TSTNE LINEC,15$ ; not at top of page already? INC PAGENO ; increment page number 15$: MOV #<6*DIVPL>,R2 ; set line count CALL SKIPN ; skip seven lines MOV #CHPTN+4,R0 ; point to last level # CLR (R0) ; clear level numbers CLR -(R0) ; ... CLRB -(R0) ; ... CMPEQ #CHAPT,(SP),30$ ; chapter command ? ; output appendix header MOV PRMARG,R2 ; calculate space count to heading SUB PLMARG,R2 ; Calculate width of page ASR R2 ; Divide by two for centering ADD EBSIZ,R2 ; shift for change bar ADD RIGSHI,R2 ; Add space for right shift ADD PLMARG,R2 ; Add in left margin SUB #5.,R2 ; Account for space of chapter # CALL NSPAC ; space to chapter heading MOV (SP),S1 ; set address of output heading CALL FMSG ; output heading INC APNDN ; increment appendix number MOVB APNDN,R1 ; get appendix number ADD #'A-1,R1 ; convert to upper case letter CALL FOUT ; output letter MOV #<2*DIVPL>,R2 ; set line count CALL SKIPN ; skip two lines 30$: CALL SETTL ; move title to buffer MOV PRMARG,R2 ; Get right margin SUB TTLBUF+BF.LEN,R2 ; Get title length SUB PLMARG,R2 ; the left margin CMPNE #CHAPT,(SP),40$ ; chapter command ? MOV CHPTN,R0 ; allow for chapter number TSTB $CHRFL ; Use roman numerals ? BEQ 32$ ; EQ - no MOV R2,R3 ; Save length so far MOV #MSGBF,R4 ; Point to buffer CALL INIBUF ; Initialize MOV R4,R1 ; Use temp buffer CLR R2 ; Use upper case Roman numerals CALL ROMAN ; Convert to roman SUB R2,R3 ; Less length of roman numeral string MOV R3,R2 ; Leave length in R2 BR 34$ ; 32$: CALL PPGNO ; get number of characters 34$: SUB #3.,R2 ; allow for .0[space] 40$: ASR R2 ; Divide to center up chapter string ADD EBSIZ,R2 ; shift for change bar ADD RIGSHI,R2 ; Add space for right shift ADD PLMARG,R2 ; Add in left margin CALL NSPAC ; space to start of text CMPNE #CHAPT,(SP),50$ ; chapter command ? TSTB $CHRFL ; Roman numerals ? BEQ 44$ ; EQ - no MOV #MSGBF,R5 ; Point to converted roman numeral CALL PSTRPA ; Output to file BR 46$ ; 44$: MOVB CHPTN,R0 ; get chapter number CALL DECPRT ; output current chapter number 46$: MOVB #'.,R1 ; output a . CALL FOUT ; ... MOVB #'0,R1 ; Output a 0 CALL FOUT ; ... MOVB #40,R1 ; Output a [SPACE] CALL FOUT ; ... 50$: MOV #TTLBUF,R4 ; point to title descriptor MOV BF.PTR(R4),-(SP) ; ... MOV BF.LEN(R4),-(SP) ; Was in error , BF.END !, fixed 10/30/81 JDL CALL PSTRPA ; output contents of title buffer MOV #TTLBUF,R4 ; Point back to title buffer MOV (SP)+,BF.LEN(R4) ; Restore context MOV (SP)+,BF.PTR(R4) ; ... ; Output chapter line to TOC file MOV #3,R3 ; blank,chapter line, and one level deep line CALL TTESTP ; test for room on page CMP TLNCNT,#4 ; top of page ? BLE 55$ ; LE - yes, don't put in blank line CALL TCRLF ; skip line on toc file INC TLNCNT ; increment line counters 55$: MOV PLMARG,R2 ; ADD #2,R2 ; set for either chap. or appndx CMPNE #CHAPT,(SP),100$ ; chapter or appendix ? MOVB CHPTN,R0 ; TSTB $CHRFL ; Use roman numerals ? BEQ 60$ ; EQ - no MOV R2,-(SP) ; Save length so far MOV #MSGBF,R4 ; Point to buffer CALL INIBUF ; Initialize buffer MOV R4,R1 ; Point to buffer to use CLR R2 ; Use upper case Roman numerals CALL ROMAN ; Convert to roman MOV #8.,R1 ; Get total length SUB R2,R1 ; Less length of converted string BLE 59$ ; LE - then quit MOV BF.ADR(R4),R3 ; Get address of string MOV R3,R0 ADD R2,R0 ; Get address of end of string ADD #8.,R3 ; Get address of end of buffer MOV R3,BF.PTR(R4) ; Save addrss of end of buffer MOV #8.,BF.LEN(R4) ; Set length to 8 characters 56$: MOVB -(R0),-(R3) ; Transfer characters SOB R2,56$ 57$: MOVB #40,-(R3) ; Fill leading characters with spaces SOB R1,57$ 59$: SUB #8.,(SP) ; Minus length so far MOV (SP)+,R2 ; Leave in R2 BR 110$ ; 60$: CALL PPGNO ; find # of char. in chap. # BR 110$ ; 100$: DEC R2 ; 110$: CALL TNSPAC ; space over # of spaces CMPNE #CHAPT,(SP)+,120$ ; chapter or appendix MOVB CHPTN,R0 ; TSTB $CHRFL ; Roman numerals ? BEQ 112$ ; EQ - no MOV BF.ADR(R4),BF.PTR(R4) ; Point to start of buffer 111$: CALL GCI ; Get a character .WORD 130$ ; Go here when through CALL TFOUT ; Output the character BR 111$ ; Loop till thru 112$: CALL DECPR ; print chapter number BR 130$ ; 120$: MOVB APNDN,R1 ; get the appendix number ADD #'A-1,R1 ; convert to ascii CALL TFOUT ; output to toc file 130$: MOVB #'.,R1 ; put in .0 after number CALL TFOUT ; ... MOVB #'0,R1 ; CALL TFOUT ; MOVB #40,R1 ; also a space CALL TFOUT ; MOV PLMARG,TOCIND ; save indent space # ADD #5,TOCIND ; add 5 to indent space MOV PRMARG,R0 ; SUB PLMARG,R0 ; SUB #13.,R0 ; account for indent MOV R0,TOCLNL ; save line length in char MOV #TTLBUF,R4 ; CALL TPSTRP ; output to toc file CALL INIBUF ; Init buffer MOV #<4*DIVPL>,R2 ; set line count in half line feeds JMP SKIPN ; skip four lines .DSABL LSB .SBTTL HEADP - HEADER COMMAND ;+2 ; The HEADER command defines how the page headers ; are to be processed. UPPER means all upper case ; BLANK means to omit 'page' in heading for page number. ; LOWER means all lower case and MIXED means UPPER ; and lower case. ; ; The format of the header command is : ; ; .HEADER MIXED ! UPPER ! LOWER ! BLANK ;-2 HEADP:: CALL $FRCND ; force to logical end of line .IF NDF A$$RAP MOV #UPPER,R2 ; assume upper case specified .IFF MOV #BLANK,R2 ; assume blank specified .ENDC CMPEQ #CR,R1,25$ ; carriage return? CMPEQ #SEMI,R1,25$ ; semicolon? CALL CCINUC ; read first character .IF DF A$$RAP CMPEQB R1,(R2)+,10$ ; first character match? MOV #UPPER,R2 ; see if its upper case .ENDC CMPEQB R1,(R2)+,10$ ; first character match? MOV #MIXED,R2 ; assume 'mixed' keyword CMPEQB R1,(R2)+,10$ ; first character match? MOV #LOWER,R2 ; assume 'lower' keyword CMPNEB R1,(R2)+,10$ ; first character mismatch? 10$: TSTEQB (R2),30$ ; no more characters to match? CALL CCINUC ; read another character CMPEQB R1,(R2)+,10$ ; character match? 20$: JMP ILCM ; illegal command 25$: TSTNEB (R2)+,25$ ; search for end of string DEC R2 ; adjust for following increment 30$: INC R2 ; point to page prototypeOn MOV #PAGHD,R1 ; point to page header area 40$: MOVB (R2)+,(R1)+ ; move prototype BNE 40$ ; if ne more to go MOV #NLHDR,$HDRSW ; set to print page headers RETURN ; .SBTTL NHEAD - NOHEADER COMMAND ;+2 ; The NO HEADER command inhibits the printing of ; page headers. A page header consists of the title/page ; number line and the subtitle line. ; ; The format of the no header command is : ; ; .NO HEADER ;-2 NHEAD:: CLR $HDRSW ; set to not print page headers RETURN ; .SBTTL HEADR - HEADER LEVEL COMMAND ;+2 ; The HEADER LEVEL command defines a header for a chapter ; or other paragraph. ; ; The format of the HEADER LEVEL command is : ; ; .HEADER LEVEL level_number(1-5) header_string ;-2 HEADR:: CALL (R4) ; get heading level number 10$: JMP ILCM ; must be level number DEC R3 ; reduce level by one CMP R3,#4. ; legal level number? BHI 10$ ; if hi no ADD #CHPTN+1,R3 ; point to level counter INCB (R3)+ ; increment level number 20$: CMP R3,#CHPTN+5 ; end of level numbers? BHI 30$ ; if hi yes CLRB (R3)+ ; clear next level number BR 20$ ; 30$: TSTEQB -(R3),30$ ; zero level? MOV R3,-(SP) ; save address of last level to print ; mov #8.,r3 ; set test page value MOV PARPT,R3 ; get paragraph spacing ADD PARSP,R3 ; and number of lines between paragraphs ADD #4,R3 ; number for header MOV R3,R1 MOV NSPNG,R0 ; .IF NDF R$$EIS ; If no EIS, then use $MUL CALL $MUL ; get total number of half lines .IFF ; If EIS, then just multiply. MUL R1,R0 ; Get total number in divisions per line .ENDC ;R$$EIS MOV R1,R3 ; CALL TESTP ; test if page should be broken MOV LINEC,R2 ; SUB #DIVPL,R2 ; CMP $HDRSW,R2 ; in header region of page? BGE 33$ ; if ge yes MOV #<3*DIVPL>,R2 ; set line count CALL SKIPN ; skip three lines 33$: MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; CLR SDBUF+BF.LEN ; reset buffer[A MOV #SDBUF,R5 ; get address of secondary buffer descriptor MOV #SDWCI,R3 ; set address of write character routine MOV PLMARG,R2 ; get value of left margin ADD INDCT,R2 ; add in indentation ADD EBSIZ,R2 ; shift for change bar ADD RIGSHI,R2 ; Add space for right shift CLR INDCT ; CALL NSPAC ; space to left margin 35$: MOV #CHPTN,R2 ; point to chapter/level table MOVB APNDN,R1 ; get current appendix number BEQ 37$ ; if eq none INC R2 ; point past chapter number ADD #'A-1,R1 ; convert to ascii character CALL (R3) ; write character in buffer BR 55$ ; 37$: MOVB (R2)+,R0 ; get chapter number BNE 50$ ; if ne chapter oriented document CMPNE R2,(SP),40$ ; not header level 1? INC (SP) ; print trailing zero 40$: MOVB (R2)+,R0 ; get next level number 50$: CALL CVTNM ; convert chapter/level number CMP R2,(SP) ; last number converted? BHI 60$ ; if hi yes 55$: MOV #PD,R1 ; write period into buffer CALL (R3) ; BR 40$ ; 60$: MOV (SP)+,TOCIND ; 80$: MOV #' ,R1 ; get a space character CALL (R3) ; write two spaces into buffer CALL (R3) ; CALL SHFUC ; shift to upper case for heading line CALL SETBF ; transfer remainder of line to buffer MOV R5,R4 ; set address of line descriptor MOV BF.ADR(R4),-(SP) ; Save current context MOV BF.PTR(R4),-(SP) ; ... MOV BF.END(R4),-(SP) ; ... MOV BF.LEN(R4),-(SP) ; ... MOV R4,-(SP) CALL PSTRPA ; output contents of title buffer MOV (SP)+,R4 ; Restore pointer MOV (SP)+,BF.LEN(R4) ; Restore context MOV (SP)+,BF.END(R4) ; ... MOV (SP)+,BF.PTR(R4) ; ... MOV (SP)+,BF.ADR(R4) ; ... MOV TOCIND,R0 ; set flag for level CMP #CHPTN+3,R0 ; header level 3,4, or 5 ? BHI 90$ ; hi - no MOV NSPNG,R2 ; set line count BR 100$ ; skip one line 90$: MOV #5.,R1 ; for chapter number ADD PLMARG,R1 ; for left margin TSTB CHPTN+2 ; BEQ 95$ ; ADD #6.,R1 ; for header level #1 95$: MOV R1,TOCIND ; store indent NEG R1 ; ADD PRMARG,R1 ; for left margin SUB #8.,R1 ; for page number MOV R1,TOCLNL ; line length MOV #1,R3 ; See if enough room for this entry CALL TTESTP ; test for room MOV TOCIND,R2 ; CALL TNSPAC ; MOV R5,R4 ; CALL TPSTRP ; MOV #<2*DIVPL>,R2 ; set line count 100$: JMP SKIPN ; skip two lines .SBTTL INHDR -- INCREMENT HEADER LEVEL COMMAND ;+2 ; The IHL command allows the header level to be incremented ; without using a HEADER LEVEL command. ; ; The format of the INCREMENT HEADER LEVEL command is : ; ; .IHL ;-2 INHDR:: CALL (R4) ; get heading level number 110$: JMP ILCM ; must be level number DEC R3 ; reduce level by one CMP R3,#4. ; legal level number? BHI 110$ ; if hi no ADD #CHPTN+1,R3 ; point to level counter INCB (R3)+ ; increment level number 120$: CMP R3,#CHPTN+5 ; end of level numbers? BHI 130$ ; if hi yes CLRB (R3)+ ; clear next level number BR 120$ ; 130$: RETURN .sbttl shdr -- set header level command ; +2 ; the shl command sets header level m to the ; value n. ; ; The format of the SET HEADER LEVEL command is : ; ; .SHL m,n ;-2 SHDR:: CALL (R4) ; get header level number 140$: JMP ILCM ; must be level number DEC R3 ; reduce level by one CMP R3,#4. ; legal level number? BHI 140$ ; if hi no MOV R3,-(SP) ; save CALL (R4) ; get number to set CLR R3 ; no number set = 0 NOP ; required MOV (SP)+,R0 ; get header number ADD #CHPTN+1,R0 ; point to level counter MOVB R3,(R0)+ ; set level number 150$: CMP R0,#CHPTN+5 ; end of level numbers? BHI 160$ ; if hi yes CLRB (R0)+ ; clear next level number BR 150$ ; 160$: RETURN ; .sbttl listc - list command ;+2 ; The LIST command starts an indented list with ; spacing n. ; ; The format of the LIST command is : ; ; .LIST n ;-2 LISTC:: .if df A$$RAP MOV SP,$MFAC ; Set for 1/8 line type argument .iftf CALL (R4) ; get list verticle spacing MOV LSTVS,R3 ; default to current spacing .ift CLR $MFAC ; Reset the condition .endc CMP R3,#<5*DIVPL> ; legal value? BHI 30$ ; if hi no MOV LSTKP,R0 ; get current list stack pointer .if df A$$RAP MOV LSTVS,(R0)+ ; Save current list spacing .endc MOVB LMARG,(R0)+ ; save left margin MOVB LSTCT,(R0)+ ; save list element count MOV F.1,(R0)+ ; save flag word MOV CMADR,(R0)+ ; save expected command address .if ndf A$$RAP CMP R0,#LSTK+<5*3*2> ; list stack overflow? .iff CMP R0,#LSTK+<5*4*2> ; list stack overflow? .endc BHI 30$ ; if hi yes MOV R0,LSTKP ; save new list stack pointer MOV R3,LSTVS ; set new list verticle spacing BIS #SPECF,(R5) ; set special processing flag CLRB LSTCT ; clear current list element number MOV #LSLMAR,R4 ; assume embedded list indent .if ndf A$$RAP CMPNE #LSTK+<3*2>,R0,10$ ; not first item in stack? .iff CMPNE #LSTK+<4*2>,R0,10$ ; not first item in stack? .endc MOV #LOLMAR,R4 ; set for initial list indent 10$: ADD LMARG,R4 ; calculate new left margin CMP R4,RMARG ; overlap right margin? BLT 20$ ; if lt no DIAG LSTERR ; MOV LMARG,R4 ; reinitialize to left margin 20$: MOV R4,LMARG ; set new left margin MOV ELSTC,CMADR ; set expected command address RETURN ; 30$: JMP ILCM ; .SBTTL LSTEL - LIST ELEMENT COMMAND ;+ ; The LIST ELEMENT command adds an numbered item to the ; currently active list. If no list is active, then ; an error message is generated. ; ; The format of the LIST ELEMENT command is : ; ; .LE [test_page_value] list_element_text ;- ; LSTPRO - PROLOGUE FOR TESTPAGE ON LIST COMMANDS ; Test page number [n] is multiplied by spacing factor in TESTP0. LSTPRO::CALL (R4) ; get list page test count MOV LSTPT,R3 ; default is current value CMP R3,PNLPG ; value within reason? BLOS 5$ ; LOS - then ok JMP ILCM ; Else bad command 5$: MOV R3,LSTPT ; set new list page test count CALL TESTP0 ; test if page should be broken MOV LSTVS,R1 ; get list element verticle spacing CALL LSTTP ; perform list spacing RETURN ; LSTEL -- LSTEL:: CALL LSTPRO ; Prologue for list processing MOV #-5,INDCT ; indent list element four spaces INC LSTCT ; increment list element number MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; initialise descriptor CLR SDBUF+BF.LEN ; reset buffer ; Insure that the list element # is right justified in the field MOV #SDBUF,R5 ; point to secondary input line desc. MOV #'#,R1 ; Set up quoted space character CMP LSTCT,#99. ; > 99 ? BHI 15$ ; HI - then don't insert leading spaces CALL SDWCI ; Else insert space CMP LSTCT,#9. ; > 9 ? BHI 15$ ; HI - then don't bother CALL SDWCI ; Else insert space 15$: MOVB LSTCT,R0 ; get current element number CALL CVTNM ; convert number to ascii MOV #'.,R1 ; Output a ., CALL SDWCI ; ... MOV #'#,R1 ; Quoted space(#) CALL SDWCI ; write quoted space into buffer LSTCOM: CALL $FRCND ; force to logical end of command CALL CCIN ; read break character CALL SDWCI ; write character into secondary buffer LINEP: COMB $SDISW ; set secondary input flag MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; Reset buffer pointer TST (SP)+ ; clean stack CALL LINSET ; reset line parameters JMP TEXT ; process text .SBTTL LSTELA -- LIST ELEMENT COMMAND (ALPHABETIC) ;+2 ; The LIST ALPHABETIC command adds an alphabetically ; numbered item to the currently active list. If a list ; is not active, then an error message is generated. ; ; The format of the LIST ALPHABETIC command is : ; ; .LA [test_page_value] list_item_string ;-2 LSTELA::CALL LSTPRO MOV #-5,INDCT ; indent list element four spaces INC LSTCT ; increment list element number MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; CLR SDBUF+BF.LEN ; reset buffer MOV #SDBUF,R5 ; point to secondary input line desc. .IF NDF R$$EIS ; If no EIS, use $DIV MOVB LSTCT,R0 ; get current element number DEC R0 ; decrement count by 1 to make a come out right MOV #26.,R1 ; 26 letters in alphabet CALL $DIV ; see where in alphabet .IFF ; If EIS, then just use DIV MOV LSTCT,R1 ; Get current element number DEC R1 ; Decrement count by 1 to make it come out CLR R0 ; Clear high order of number. DIV #26.,R0 ; See where in alphabet .ENDC ;R$$EIS MOV R1,-(SP) ; Save R1 MOV #'#,R1 ; Set quote character CALL SDWCI ; Insert two leading spaces MOV (SP)+,R1 ; Restore R1 TSTEQ R0,200$ ; any remainder MOV R1,R2 ; yes, have two characters MOV R0,R1 ADD #140,R1 ; force lower case alphabetic CALL SDWCI ; store in buffer MOV R2,R1 ; get next character BR 201$ 200$: MOV R1,-(SP) ; Preserve R1 MOV #'#,R1 ; Store quoted space CALL SDWCI ; put in buffer MOV (SP)+,R1 ; Restore R1 201$: ADD #141,R1 ; force lower case alphabetic CALL SDWCI ; store in buffer MOV #'.,R1 ; Store .# in buffer CALL SDWCI MOV #'#,R1 ; Store quoted space CALL SDWCI ; put in buffer BR LSTCOM ; finish in lstel .sbttl LIST ELEMENT COMMAND (WITHOUT NUMBERING) ;+2 ; The LIST ELEMENT WITHOUT NUMBERING command inserts ; an unnumbered item into the currently active list. If ; a list is not active, then an error message will be ; generated. ; ; The format of the LIST ELEMENT WITHOUT NUMBERING command is : ; ; .LEN [test_page_value] list_string ;-2 LSTELN::CALL LSTPRO ; MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; CLR SDBUF+BF.LEN ; reset buffer MOV #SDBUF,R5 ; point to secondary input line descriptor BR LSTCOM ; Go to common code .DSABL LSB .SBTTL LSTELB - LIST ELEMENT COMMAND (WITH BULLET) ;+ ; The LIST ELEMENT (with bullet) command adds an numbered item to the ; currently active list. If no list is active, then ; an error message is generated. ; ; The format of the LIST ELEMENT (with bullet) command is : ; ; .LEB [test_page_value] list_element_text ;- LSTELB::CALL LSTPRO ; MOV #-2,INDCT ; indent list element two spaces MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; initialise descriptor CLR SDBUF+BF.LEN ; reset buffer ; Insure that the list element # is right justified in the field MOV #SDBUF,R5 ; point to secondary input line desc. MOV #157,R1 ; Set up "o" character CALL SDWCI ; Insert "o" character MOV #'#,R1 ; Set up quoted space character CALL SDWCI ; Insert space JMP LSTCOM ; Go to common code .SBTTL ELIST - END LIST COMMAND ;+ ; The END LIST command terminates a list. ; ; The format of the END LIST command is : ; ; .END LIST ;- ELIST:: MOV LSTKP,R0 ; get current list stack pointer MOV -(R0),CMADR ; restore expected command address MOV -(R0),R1 ; get flag byte and spacing count BITNE #SPECF,R1,10$ ; special processing previously active? BIC #SPECF,(R5) ; clear special processing active flag 10$: MOVB -(R0),LSTCT ; restore previous list element number MOVB -(R0),LMARG ; restore previous left margin .if df A$$RAP MOV -(R0),LSTVS ; Restore vertical list spacing .iftf MOV R0,LSTKP ; save new list stack pointer .ift RETURN ; .iff MOV #LFSPAC,R2 ; set final skip count .endc ELIST1: MOV LINEC,R1 SUB #,R1 CMP $HDRSW,R1 ; In header region of page? BGE 20$ ; Yes, don't bother spacing JMP SKIPN ; skip lines 20$: RETURN .SBTTL LSTC -- List element using string supplied ;+2 ; This variation of the list element command ; will take as an argument a 1 to LSTCNC character ; user string and use it in place of the list ; element number. The format of the command ; would then be: ; ; .LEC [Test Page Value] 'string';List element string ;-2 LSTCNC = 5 LSTC:: CALL LSTPRO ; MOV #-,INDCT ; Indent list element four spaces MOV #SDBUF,R5 ; Point to buffer MOV BF.ADR(R5),BF.PTR(R5) ; Initialise descriptor CLR BF.LEN(R5) ; Reset buffer 30$: CALL CCIN ; Get break character ; Flush up to leading ' BITB #CHAEC,CHATBL(R1) ; End of command ? BEQ 32$ ; EQ - not yet JMP ILCM ; Else badly formed command 32$: BITB #CHASP,CHATBL(R1) ; Spacing character ? BNE 30$ ; NE - yes, flush character CMPB R1,#'' ; Leading ' ? BNE 30$ ; Not yet CALL CCIN ; Get next character ; Now save the string 34$: BITB #CHAEC,CHATBL(R1) ; End of command ? BNE 40$ ; NE - then assume end of string BITB #CHASP,CHATBL(R1) ; Spacing character ? BNE 34$ ; Flush spacing character CMPB R1,#'' ; End of string ? BEQ 40$ ; Eq - then complete CALL SDWCI ; Insert character into the buffer 36$: CALL CCIN ; Read a character CMPB SDBUF+BF.LEN,#LSTCNC ; > 4 characters specified BLOS 34$ ; LOS - then it's still ok JMP ILCM ; Else illegal command 40$: CMP SDBUF+BF.LEN,#LSTCNC ; 4 characters specified ? BEQ 50$ ; EQ -then buffer is filled MOV #'#,R1 ; Else insert quoted space CALL SDWCI ; Insert into buffer BR 40$ ; And loop ; Now right justify the string in the buffer 50$: CLR R0 ; Clear loop counter 52$: INC R0 ; Bump up counter CMP R0,#LSTCNC ; Have we been here 5 times ? BEQ 60$ ; Eq - yes, leave MOV SDBUF+BF.ADR,R3 ; Get pointer ADD #,R3 ; Point to end of string CMPB (R3),#'# ; Space ? BNE 60$ ; NE - then all thru MOV #,R2 ; Set count 54$: MOVB -1(R3),(R3) ; Move a byte DEC R3 ; One less SOB R2,54$ ; Loop till thru MOVB #'#,(R3) ; Replace with a quoted space BR 52$ ; And loop 60$: MOV #'#,R1 ; Insert a trailing blank CALL SDWCI ; ... JMP LSTCOM ; Go to common code .sbttl LSTL -- List element indenting item ;+2 ; The LEL command will allow a list to be created with ; the first line not indented and all subsequent ; lines indented. ; ; The format of the LEL command is: ; ; .LEL [test page value]; List element string ;-2 LSTL:: CALL LSTPRO ; MOV #-4,INDCT ; Indent list element four spaces CALL LINSET ; Set up for a new line TST (SP)+ ; Clean return address off stack CALL CCIN ; Get break character CMPB R1,#CR ; Carriage return ? BNE 20$ ; NE - no MOVB R1,GCSCH ; Else better leave it there 20$: JMP TEXT ; And start processing next line .sbttl LSTR -- List elements using roman numerals ;+2 ; The LER command will allow a list to be created with ; roman numeral list counts. This command should not be ; used in conjunction with any other list element command ; since this will indent 8 instead of 5. ; ; The format of the LER command is: ; ; .LER [test page value]; List element string ;-2 LSTR:: CALL LSTPRO ; MOV #-10.,INDCT ; indent list element INC LSTCT ; increment list element number MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; initialise descriptor CLR SDBUF+BF.LEN ; reset buffer MOV #SDBUF,R1 ; point to secondary input line desc. MOV LSTCT,R0 ; Get number to be converted MOV SP,R2 ; Make it lower case roman numeral CALL ROMAN ; Convert to roman numeral MOV #SDBUF,R5 ; Point to buffer descriptor 10$: CMP BF.LEN(R5),#8. ; > 8 characters ? BHIS 20$ ; HIS - then skip around MOV #'#,R1 ; Insert quoted space CALL SDWCI ; Write character into buffer BR 10$ ; Loop till thru ; Now right justify the string in the buffer 20$: MOV SDBUF+BF.ADR,R3 ; Get pointer ADD #7,R3 ; Point to end of string CMPB (R3),#'# ; Space ? BNE 30$ ; NE - then all thru MOV #7,R2 ; Set count 54$: MOVB -1(R3),(R3) ; Move a byte DEC R3 ; One less SOB R2,54$ ; Loop till thru MOVB #'#,(R3) ; Replace with a quoted space BR 20$ ; And loop 30$: MOV #'.,R1 ; Output a ., CALL SDWCI ; ... MOV #'#,R1 ; Quoted space(#) CALL SDWCI ; write quoted space into buffer JMP LSTCOM ; And go to common code .SBTTL NOTEC -- Note center command ;+2 ; The NTC command is almost identical to the NOTE ; command with the exception that the it centers the ; text given as an argument. This command BLANKS 2, ; reduces both margins by 15, centers the text, then ; BLANKS 1. ; ; The format of the NTC command is : ; ; .NTC [text] ;-2 NOTEC:: MOV #1,-(SP) ; Say which BR NOT ; .SBTTL NOTE - NOTE COMMAND ;+2 ; The NOTE command starts an indented note. This command ; BLANKS 2, reduces both margins by 15, and starts with ; text, and then BLANKS 1. ; ; The format of the NOTE command is : ; ; .NOTE [text] ;-2 NOTE:: CLR -(SP) ; Say which NOT:: MOV #<8.*DIVPL>,R3 ; set page test count CALL TESTP ; test if page should be broken MOV LINEC,R2 ; SUB #2,R2 ; CMP $HDRSW,R2 ; in header region of page? BGE 3$ ; if ge yes MOV #NHSPAC,R2 ; set line count CALL SKIPN ; skip lines 3$: MOV #NPMARG*2,R3 ; assume at left margin MOV #RMARG,R4 ; point to right margin count MOV (R4)+,-(SP) ; calculate spread in margins TSTEQ (R4),7$ ; at left margin? MOV #NSMARG*2,R3 ; set secondary indent value 7$: SUB (R4),(SP) ; CMP R3,(SP)+ ; spread large enough? BLT 10$ ; if lt yes DIAG NOTERR ; CLR R3 ; indicate no adjustment 10$: MOV (R4),NOTLM ; save current left margin MOV -(R4),NOTRM ; save current right margin ASR R3 ; reduce to actual margin reduction SUB R3,(R4)+ ; reduce right margin ADD R3,(R4) ; increase left margin MOV (R5),NOTSV ; save current flags word BIS #FILLF!JUSTF!PJUSTF!SPECF!NOTF,(R5) ; set flags MOV CMADR,NOTCM ; save current expected command address MOV ENOTE,CMADR ; set expected command address MOV SDBUF+BF.ADR,SDBUF+BF.PTR ; Initialise descriptor CLR SDBUF+BF.LEN ; reset buffer MOV #SDBUF,R5 ; Get address of secondary input descriptor TSTEQ (SP)+,14$ ; Is it NOTE or NOTEC ? CALL SETBF ; transfer text to buffer CLR R2 TSTNE BF.LEN(R5),30$ ; any text given? BR 15$ ; Put in note 14$: CALL $FRCND ; Force to end of command CMPEQ GCSCH,#CR,15$ ; End of command ? CALL LINSET ; No, do rest of text JMP LIN ; Without note 15$: MOV #NOTET,R3 ; point to note text prototype 20$: MOVB (R3)+,R1 ; get next character in string BEQ 30$ ; if eq done MOV R5,R4 ; set descriptor address CALL WCI ; write character in buffer BR 20$ ; 30$: MOV RMARG,R2 ; calculate space count to center note text SUB BF.LEN(R5),R2 ; Less length of buffer SUB LMARG,R2 ; ASR R2 ; ADD LMARG,R2 ; ADD EBSIZ,R2 ; shift for change bar ADD RIGSHI,R2 ; Add space for right shift CALL NSPAC ; space to text position MOV R5,R4 ; set address of line descriptor CALL PSTRPA ; output note text MOV #NASPAC,R2 ; set line count JMP SKIPN ; skip lines .SBTTL ENOTC - END NOTE COMMAND ;+2 ; The END NOTE command terminates the NOTE command, BLANKs ; 2 and reverts the margins and spacing modes to their ; settings before the last NOTE command. ; ; The format of the END NOTE command is: ; ; .END NOTE ;-2 ENOTC:: MOV NOTSV,(R5) ; restore flags word MOV NOTCM,CMADR ; restore previous expected command address MOV NOTRM,RMARG ; increase right margin MOV NOTLM,LMARG ; decrease left margin MOV #NFSPAC,R2 ; set skip count JMP ELIST1 ; skip lines .SBTTL NAPDX - NUMBER APPENDIX COMMAND ;+2 ; The NUMBER APPENDIX command supplies a letter to be used ; for a subsequent APPENDIX command. ; ; The format of the NUMBER APPENDIX command is : ; ; .NUMBER APPENDIX a ;-2 .ENABL LSB NAPDX:: CALL CCINUC ; read next character BITB #CHASP,CHATBL(R1) ; Spacing character? BNE NAPDX ; Yes - read until nonspace. BITB #CHAUC,CHATBL(R1) ; Upper case character? BEQ 10$ ; EQ - no SUB #'A,R1 ; set for next appendix command MOVB R1,APNDN ; RETURN ; .SBTTL NCHPT - NUMBER CHAPTER COMMAND ;+2 ; The NUMBER CHAPTER command supplies a number to be used in ; a subsequent CHAPTER command. ; ; The format of the NUMBER CHAPTER command is : ; ; .NUMBER CHAPTER n ;-2 NCHPT:: CALL (R4) ; get chapter number 10$: JMP ILCM ; must be a chapter number DEC R3 ; back off number by one CMP #255.,R3 ; legal chapter number? BLOS 10$ ; if los no MOVB R3,CHPTN ; set for next chapter command RETURN ; .DSABL LSB .SBTTL CVTNM - CONVERT NUMBER TO ASCII ZERO SUPPRESSED ; CVTNM: .IF NDF R$$EIS ; IF no EIS, use $DIV MOV #10.,R1 ; set divisor CALL $DIV ; divide .IFF ; If EIS, use DIV MOV R0,R1 ; Get number into R1 CLR R0 ; Clear high order. DIV #10.,R0 ; Divide by 10. .ENDC ;R$$EIS MOV R1,-(SP) ; save remainder TSTEQ R0,10$ ; no more digits to convert? CALL CVTNM ; convert another 10$: MOV (SP)+,R1 ; retrieve character ADD #'0,R1 ; convert to ascii SDWCI: MOV R5,R4 ; set address of line descriptor JMP WCI ; write character in buffer .SBTTL TPSTRP -- MOVE TEXT TO TABLE OF CONTENTS TPSTRP::MOV BF.ADR(R4),TS1 ; Get starting address MOV BF.ADR(R4),R1 ; Get base ADD BF.LEN(R4),R1 ; Add in length CLRB (R1) ; Make an ASCIZ string MOV TS1,R2 ; get start of buffer MOV R2,R1 ; Remove any underline and super/subscript characters 70$: MOVB (R1)+,R0 ; get char BEQ 75$ ; EQ - then all thru scan CMPB R0,#ULCHS ; equal to underline char, subscript or super BLE 70$ ; LE - Then it's OK CMPB R0,#QTS ; equal to quoted space BNE 71$ ; NE - then place back in buffer INC R0 ; make equal to space 71$: MOVB R0,(R2)+ ; no, store back in buffer BR 70$ ; Loop till thru 75$: MOV R2,BF.PTR(R4) ; Save end of line pointer MOV BF.PTR(R4),BF.LEN(R4) ; SUB BF.ADR(R4),BF.LEN(R4) ; Calculate new length ; Now figure out the amount of indentation necessary MOV TOCIND,R3 ; GET STARTING IDENT for level 0 MOV R3,R1 ; MOV R3,R2 ; ... TSTB CHPTN+1 ; Is it within a chapter ? BEQ 76$ ; EQ - no ADD #6,R2 ; indent for header level 1 with chapter TSTB CHPTN+2 ; Is it top level chapter ? BEQ 76$ ; EQ - yes ADD #3,R2 ; add 3 for header level 2 76$: MOV R2,TOCIND ; save new indent TSTB CHPTN+1 ; is it a chapter entry? BEQ 80$ ; yes, skip next part SUB R1,R2 ; get number of spaces indented MOV R2,INDCNT ; save actual indent count MOV BF.ADR(R4),R0 ; point to start of buffer ; Find the number of spaces in the header number 77$: CMPB (R0)+,#' ; check for a space BNE 77$ ; NE - then loop until found INC R0 MOV R0,R1 ; find number of characters in header number SUB BF.ADR(R4),R0 ; number of characters SUB R0,R2 ; Less indentation in line (Should have minus) BEQ 80$ ; EQ - then don't bother with rest of line BLE 85$ ; Number less than zero move other way MOV BF.PTR(R4),R0 ; Point to end of buffer ADD R2,BF.LEN(R4) ; This should fix problem ADD BF.PTR(R4),R2 ; Add in offset MOV R2,BF.PTR(R4) ; Restore correct length CMPB (R0)+,(R2)+ ; Shift for start ; Now right justify the line in the buffer 78$: MOVB -(R0),-(R2) ; move characters to right for extra spaces CMP R0,R1 ; At end yet ? BGE 78$ ; GE - not yet 79$: MOVB #' ,-(R2) ; put in extra spaces to even line CMP R2,R1 ; Through yet ? BGE 79$ ; GE - not yet BR 80$ 85$: MOV R1,R2 ; Set up to take out a space MOV BF.LEN(R4),R0 TSTB (R2)+ 86$: MOVB (R2)+,(R1)+ SOB R0,86$ DEC BF.LEN(R4) ; Reduced length by 1 DEC BF.PTR(R4) 80$: MOV TOCLNL,R2 ; get line length 90$: MOV R2,ERRLNL ; save line length MOV BF.PTR(R4),R0 SUB TS1,R0 ; Get total # characters left CMP R0,R2 ; greater than # in line BGT 100$ ; yes MOV R0,R2 ; no, start transfer of char BEQ 200$ ; eq - then skip transfer BR 120$ 100$: INC R2 ; check last character available MOV BF.ADR(R4),R0 ADD R2,R0 ; Get address of last possible character 110$: CMPB -(R0),#' ; is char a space BEQ 115$ ; yes DEC R2 ; no,decrement counter and try again BGT 110$ 115$: DEC R2 ; decrement counter to account for last char CMP R2,INDCNT ; found spaces between number and line? BGT 120$ ; no, move line DIAG TOCER ; something is wrong MOV ERRLNL,R2 ; get line length - fill line up ; cannot do anything else 120$: ADD R2,R3 ; get total char in line count 130$: MOVB @TS1,R1 ; get character CALL TFOUT ; put in buffer INC TS1 ; Point to next character SOB R2,130$ ; Loop till thru INC TS1 ; Skip over the space character CMP TS1,BF.PTR(R4) ; done with title BGE 200$ ; yes CALL TCRLF ; no, put in cr lf INC TLNCNT ; increment line count MOV TOCIND,R2 ; get indent MOV R2,R3 ; save indent CALL TNSPAC ; space over indent MOV PRMARG,R2 ; get page width SUB PLMARG,R2 ; ... SUB R3,R2 ; line length BR 90$ ; and go back for more 200$: MOV R3,R2 ; add # of char INC R2 ASR R2 ASL R2 CMP R2,R3 ; odd # of char BEQ 210$ INC R3 ; yes, put in . MOVB #'.,R1 CALL TFOUT 210$: MOV PRMARG,R2 ; find # of . to put in SUB R3,R2 SUB #8.,R2 ASR R2 BEQ 230$ ; no filler or required 220$: MOVB #' ,R1 CALL TFOUT MOVB #'.,R1 ; put in period CALL TFOUT DEC R2 BGT 220$ ; done 230$: TST APNDN ; doing an appendix BEQ 240$ MOV #3,R2 ; yes CALL TNSPAC MOVB APNDN,R1 ADD #'A-1,R1 CALL TFOUT BR 250$ 240$: MOV #4,R2 ; yes, put in chapter # - page # MOVB CHPTN,R0 CALL PPGNO CALL TNSPAC MOVB CHPTN,R0 CALL DECPR 250$: MOVB #'-,R1 CALL TFOUT MOV PAGENO,R0 .if ndf A$$RAP TSTEQ $NUMLW,260$ ; numbering low middle of page? INC R0 .endc 260$: CALL DECPR CALL TCRLF ; put in cr lf INC TLNCNT ; increment line count ; tst (sp)+ ; pop stack RETURN .SBTTL TTESTP -- TEST TOC PAGE .ENABL LSB TTESTP::MOV R3,-(SP) TST TLNCNT ; Has the TOC been initialized yet ? BEQ 330$ ; EQ - yes ADD TLNCNT,R3 ; add current # to requested # ADD #3,R3 ; Plus 3 lines of footer for TOC CMP R3,TPNLPG ; large than # on page BGT 400$ ; no, return JMP 300$ 400$: MOV TPNLPG,R2 SUB TLNCNT,R2 DEC R2 ; Don't space to bottom, leave room for page no. 340$: CALL TCRLF DEC R2 BGT 340$ MOV TPAGNO,R0 ; Get page number MOV #TOCPUF,R1 ; start page # to roman numeral MOV #1,R2 ; Use lower case roman numerals INC R0 ; make it start with 2 500$: TST R0 ; page # = 0 BLE 560$ ; LE - then skip TOC page number CALL ROMAN ; Covert to a roman numeral 560$: MOV TOCPUF+BF.LEN,R1 ; get number of characters MOV PRMARG,R2 ; Get perm. right margin SUB PLMARG,R2 ; Minus the left margin SUB R1,R2 ; Minus the page number ASR R2 ; Divide by 2 ADD PLMARG,R2 ; Add in space before page number MOV R2,R3 ; Place into argument register ADD R1,R3 ; Add length of page number CALL TNSPAC ; Space over to page number MOV TOCPUF+BF.ADR,TOCPUF+BF.PTR ; Reset buffer pointer 565$: MOV #TOCPUF,R4 ; Point to input buffer CALL GCI ; Get character from buffer .WORD 566$ ; Go here when thru CALL TFOUT ; Output character to TOC buffer BR 565$ ; And loop until the buffer is empty 566$: MOV TOCPUF+BF.ADR,TOCPUF+BF.PTR ; Reset buffer pointer TSTEQ $DATET,570$ ; put in the toc date MOV PRMARG,R2 ; yes SUB R3,R2 SUB #8.,R2 CALL TNSPAC MOV #DATTBF,R2 CALL TMSGM ; put in date 570$: INC TPAGNO MOV #FF,R1 ; yes, skip with ff to new page CALL TFOUT CMP (SP),#100. ; end of toc BEQ 300$ ; yes 330$: .if df A$$RAP MOV TMARG,R2 ; Get top margin BLE 332$ ; LT or EQ 0 331$: CALL TCRLF ; Space down SOB R2,331$ ; Loop till done .iff CALL TCRLF ; skip four lines CALL TCRLF CALL TCRLF CALL TCRLF .endc 332$: MOV PRMARG,R2 ; get right margin SUB PLMARG,R2 ; subtract left margin SUB #17.,R2 ; subtract # char in toc mesg TST TLNCNT ; first page BEQ 320$ ; yes SUB #12.,R2 ; no, subtract continued msg 320$: ASR R2 ; divide by 2 ADD PLMARG,R2 ; add left margin back in CALL TNSPAC ; space over to center text MOV #TOCMSG,R2 ; put in toc msg CALL TMSGM TST TLNCNT ; first page BEQ 310$ ; yes MOV #TOCCNT,R2 ; put in continued msg CALL TMSGM 310$: CALL TCRLF CALL TCRLF MOV PRMARG,R2 SUB #5,R2 ; calculate space for page heading CALL TNSPAC ; skip spaces MOV #PAGW,R2 ; put in page line CALL TMSGM CALL TCRLF ; put in a blank line CALL TCRLF MOV #4,TLNCNT ; reset line counter 300$: TST (SP)+ RETURN ; ; put char in toc buf ; TMSGM:: MOVB (R2)+,R1 ; get character BEQ 410$ ; done? CALL TFOUT BR TMSGM 410$: RETURN .DSABL LSB .SBTTL DATA AREA DATA FMTCMD ERRLNL: .WORD 0 INDCNT: .WORD 0 TOCPUF::DH 20. .END